/**
 * components.css
 *
 * Every component here reads ONLY the semantic surface variables from
 * tokens.css — never a raw colour token. That is what lets one button, one
 * card, one pill and one input be correct everywhere they appear, and what let
 * the portal leave its Void field for Paper on 25 Sep, and the whole site move
 * to Ollie's five colours on 20 Oct, without a component being rewritten.
 *
 * The 20 Oct roles: the page is Pearl Grey, every surface that carries words
 * is Light Grey, type is Black, and Black fills only the footer and the
 * call-to-action blocks, with White words (.bpc-on-black in tokens.css).
 * Orange fills buttons and draws rules and accents; it is never a word's
 * colour. tests/e2e/contrast.test.mjs holds every word to those pairings.
 */

/* ---- Box model ----------------------------------------------------------
 * Inputs, buttons and textareas do not inherit border-box from WordPress, so
 * a width:100% field adds its padding and border on top of the 100% and
 * overflows its container. On a phone that is a horizontal scrollbar on every
 * form page — which is the opposite of the "one-thumb forms" the Design
 * Master asks for.
 */

*,
*::before,
*::after {
	box-sizing: border-box;
}

/* ---- Ground ------------------------------------------------------------ */

body {
	background-color: var(--bpc-field);
	color: var(--bpc-type);
	font-family: var(--bpc-font-sans);
	font-size: 1.0625rem;
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

/* ---- Focus -------------------------------------------------------------
 * "Visible hairline, not a rainbow ring." One rule, every focusable thing.
 */

/*
 * The ring is the strong rule, not the element's own colour (21 Oct): it
 * sits outside the element, on the ground around it, so it takes that
 * ground's line colour. Black on the two greys (11.47:1 on Light Grey,
 * 4.44:1 on Pearl Grey), White on the Black footer and closing block
 * (17.18:1). Drawn in currentColor, a button's ring was its Black words,
 * set 3px out onto the Black block: invisible.
 */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
	outline: var(--bpc-hairline) solid var(--bpc-rule-strong, currentColor);
	outline-offset: 3px;
	border-radius: var(--bpc-radius);
}

/* ---- Buttons -----------------------------------------------------------
 * Brooklyn orange pills with Ink words in spaced capitals, a soft sheen on
 * top and a warm shadow under, and an arrow on the ones that take you
 * somewhere: the July site's buttons, which Ollie asked for back on 26 Sep
 * ("can it be like the design before with a cool ui look … Let's implement
 * a Brooklyn orange to comment the grey"; brick, of three). Ink on Brooklyn
 * orange is 4.79:1; Snow on it would fail, so the words stay Ink. Before
 * that, the same day: Petal Light, 8px corners. Before that: Dark Petal fill, Ink type —
 * the Design Master's Ink fill is overridden by Ollie's 25 Sep "stop using
 * black as backgrounds"; the ratios are in tokens.css.
 *
 * A mid-grey slab with near-black type at 500 read as flat, almost disabled:
 * it had no edge against Paper or Snow. So the primary carries a 1px Ink
 * border — a line, not a fill — and its words are set at 600. The focus
 * hairline sits 3px outside that border, so the two never merge.
 */

/* ---- Form controls inherit the brand -----------------------------------
 *
 * A browser's own stylesheet does not give buttons and inputs the page's
 * typeface — it gives them the system font, which on this machine resolves to
 * Arial. The Design Master bans Arial by name, and the brand lint reads source
 * files, so it can never see a typeface the browser supplies at render time.
 * Caught by measuring the rendered page instead: the menu's submenu toggle and
 * the calendar's month arrows were both setting in Arial.
 *
 * Inheriting the family alone, not the size: several controls set their own
 * size deliberately and inheriting that would move the layout.
 */

button,
input,
select,
textarea,
optgroup {
	font-family: inherit;
	letter-spacing: inherit;
}

.bpc-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	min-height: 3rem;
	padding: 0.9rem 1.75rem;
	border: var(--bpc-hairline) solid var(--bpc-btn-edge);
	border-radius: var(--bpc-radius-button);
	background-color: var(--bpc-btn-fill);
	color: var(--bpc-btn-type);
	font-family: var(--bpc-font-sans);
	font-size: 0.875rem;
	font-weight: 600;
	letter-spacing: 0.14em;
	line-height: 1;
	text-transform: uppercase;
	text-decoration: none;
	cursor: pointer;
	transition: background-color var(--bpc-dur) var(--bpc-ease), border-color var(--bpc-dur) var(--bpc-ease), color var(--bpc-dur) var(--bpc-ease), box-shadow var(--bpc-dur) var(--bpc-ease), opacity var(--bpc-dur-quick) var(--bpc-ease), transform var(--bpc-dur) var(--bpc-ease);
}

/*
 * Everything you can tap clears 44x44.
 *
 * Measured on the built pages: the core button came out at 43px, the menu
 * toggle at 36, the social discs at 40, and the header's login link had no
 * height of its own at all. None of those is far off, and all of them are the
 * difference between hitting the thing and hitting the gap beside it on a
 * phone. .bpc-btn already cleared it; these are the ones that did not.
 */
.wp-element-button,
.wp-block-button__link {
	min-height: 2.75rem;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

/* The header's targets — the bar, the Menu button, Client login — are sized
 * with the header, further down. */

/*
 * Footer links are navigation stacked in a column, so they take the full tap
 * height. Links inside a sentence are left alone: padding those would break
 * the line they sit in, and an inline link is the one recognised exception to
 * the 44px rule.
 */
.bpc-footer__stack a {
	display: inline-flex;
	align-items: center;
	min-height: 2.75rem;
}

/*
 * With a mouse the footer's rows close up (Ollie, 26 Sep: "make footer
 * smaller, far too big", then "tighten the footer"): 28px a link, over
 * WCAG 2.5.8's 24. On a touchscreen they keep the full 44.
 */
@media (pointer: fine) {
	.bpc-footer__stack a,
	.bpc-footer .bpc-footer__legal a {
		min-height: 1.75rem;
	}
}

/*
 * Whatever is under the footer is the footer's Black (20 Oct): the room a
 * phone keeps for the tab bar and the cookie note, and the screen's foot
 * under a short page. A shadow the footer casts straight down, so nothing
 * is laid out again and nothing can be scrolled to.
 */
.bpc-footer {
	box-shadow: 0 100vh 0 100vh var(--bp-black);
}

/* ---- The footer ---------------------------------------------------------
 * White on Black since 20 Oct (Ollie's pairing for the footer, 17:1), the
 * logo White, the button the site's orange; every colour in it comes from
 * the on-black roles in tokens.css, so the rules below name none.
 *
 * Ollie, 26 Sep, "footer design", choosing A of three: the footer mirrors the
 * header, each column after a fine line like the header's own.
 * Then, the same day: "Under the logo have the contact details &
 * socials" and "I don't want a lot of gaps or bulky looking". So: the grey
 * bridge with the email and the social links under it; Catering
 * and Brooklyn (every page); Policies; and "Got a date in mind?" with
 * Request a date as the site's primary button. Under a fine line: the name,
 * and the policies again.
 *
 * Laid out here, not by the part's own column widths, so the two footer
 * parts stay byte-identical and nothing in the editor changes. From 1200 the
 * five sit in one row. On an iPad the first four do, and the date runs under
 * them as one slim line with its button at the end. On a phone the logo and
 * its details, then Catering and Brooklyn side by side, then the date; the
 * policies are the bar's own "Privacy · Terms".
 */
.bpc-footer__grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--wp--preset--spacing--30, 1rem);
	padding-block-end: var(--wp--preset--spacing--30, 1rem);
}

.bpc-footer__grid > * {
	margin: 0 !important;
}

.bpc-footer__brand,
.bpc-footer__cta {
	grid-column: 1 / -1;
}

@media (max-width: 51.99rem) {
	.bpc-footer__policies {
		display: none;
	}
}

/*
 * An iPad: the logo's column is wider than the others, for the email address,
 * which cannot wrap. The date is one line under the four.
 */
@media (min-width: 52rem) and (max-width: 74.99rem) {
	.bpc-footer__grid {
		grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr));
	}

	.bpc-footer__brand {
		grid-column: auto;
	}

	.bpc-footer .bpc-footer__cta {
		display: flex;
		flex-wrap: wrap;
		align-items: baseline;
		column-gap: 1rem;
		padding-block-start: var(--wp--preset--spacing--30, 1rem);
		border-block-start: var(--bpc-hairline) solid var(--bpc-rule);
	}

	.bpc-footer .bpc-footer__cta p {
		margin: 0;
	}

	.bpc-footer .bpc-footer__cta p:last-child {
		margin-inline-start: auto;
	}

	/*
	 * The sign-up for occasional notes (the office's own list since 22 Oct,
	 * PR #91) where "Got a date in mind?" was: still one slim line, its
	 * label and line on the left, the box and Sign up side by side at the
	 * end.
	 */
	.bpc-footer .bpc-footer__cta:has(> .bpc-newsletter) {
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto;
		align-items: center;
		column-gap: 1.5rem;
	}

	.bpc-footer .bpc-footer__cta:has(> .bpc-newsletter) > p {
		grid-column: 1;
	}

	.bpc-footer .bpc-footer__cta > .bpc-newsletter {
		grid-column: 2;
		grid-row: 1 / span 2;
		margin: 0;
		flex-direction: row;
		align-items: center;
	}

	.bpc-footer .bpc-footer__cta > .bpc-newsletter input[type="email"] {
		width: 15rem;
	}

	.bpc-footer .bpc-footer__cta > .bpc-newsletter__note {
		grid-column: 2;
		margin-inline-start: 0;
	}
}

@media (min-width: 75rem) {
	.bpc-footer__grid {
		grid-template-columns: minmax(0, 1.4fr) minmax(0, 0.9fr) minmax(0, 0.8fr) minmax(0, 1fr) minmax(0, 1.2fr);
		column-gap: 0;
		padding-block-end: var(--wp--preset--spacing--40, 1.5rem);
	}

	.bpc-footer__grid > * {
		grid-column: auto;
		padding-inline: clamp(1rem, 1.6vw, 1.75rem);
		border-inline-start: var(--bpc-hairline) solid var(--bpc-rule);
	}

	.bpc-footer__grid > :first-child {
		padding-inline-start: 0;
		border-inline-start: 0;
	}

	.bpc-footer__grid > :last-child {
		padding-inline-end: 0;
	}
}

.bpc-footer__brand {
	--bpc-logo-h: 3rem;
}

.bpc-footer__stack {
	margin: 0;
	font-size: 0.9375rem;
}

.bpc-footer__col .bpc-eyebrow,
.bpc-footer__cta .bpc-eyebrow {
	margin-block: 0 0.25rem;
}

.bpc-footer__cta p:not(.bpc-eyebrow) {
	margin-block: 0 0.5rem;
}

/* The page links read as a menu, not as underlined text. */
.bpc-footer .bpc-footer__stack a {
	color: var(--bpc-type);
	text-decoration: none;
}

.bpc-footer .bpc-footer__stack a:hover {
	color: var(--bpc-type-strong);
	text-decoration: underline;
	text-decoration-color: var(--bpc-accent);
	text-underline-offset: 0.3em;
}

/*
 * Signed in, Sign out after Your portal: a phone's way out when no script
 * has run to open the menu sheet, which is where Sign out otherwise is
 * (functions.php, brooklyn_footer_login_for_session). From the iPad up the
 * header's portal card holds it, so the footer there stays as it was.
 */
.bpc-footer__out {
	display: none;
}

@media (max-width: 47.99rem) {
	.bpc-footer__out {
		display: inline;
	}
}

/* "Got a date in mind?": its link is the site's primary button. */
.bpc-footer__cta p:not(.bpc-eyebrow) {
	font-size: 0.9375rem;
}

.bpc-footer__cta p:last-child > a:only-child {
	display: inline-flex;
	align-items: center;
	min-height: 2.75rem;
	padding: 0 1.25rem;
	border: var(--bpc-hairline) solid var(--bpc-btn-edge);
	border-radius: var(--bpc-radius-button);
	background-color: var(--bpc-btn-fill);
	color: var(--bpc-btn-type);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	text-decoration: none;
	transition: background-color var(--bpc-dur) var(--bpc-ease), box-shadow var(--bpc-dur) var(--bpc-ease), transform var(--bpc-dur) var(--bpc-ease);
}

.bpc-footer__cta p:last-child > a:only-child::after {
	content: "\2002\2192" / "";
	letter-spacing: 0;
}

.bpc-footer__cta p:last-child > a:only-child:hover {
	background-color: var(--bpc-btn-fill-hover);
	color: var(--bpc-btn-type);
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
	.bpc-footer__cta p:last-child > a:only-child:hover {
		box-shadow: 0 0.5rem 1rem -0.625rem color-mix(in srgb, var(--bpc-shadow) 45%, transparent);
		transform: translateY(-1px);
	}
}

/* Under a fine line: the name, and the social links. */
.bpc-footer__bar {
	gap: var(--wp--preset--spacing--30, 1rem);
	padding-block-start: var(--wp--preset--spacing--20, 0.5rem);
	border-block-start: var(--bpc-hairline) solid var(--bpc-rule);
}

.bpc-footer__legal {
	margin: 0;
	color: var(--bpc-type-quiet);
	font-size: 0.8125rem;
}

.bpc-footer .bpc-footer__legal a {
	display: inline-flex;
	align-items: center;
	min-height: 2.75rem;
	color: var(--bpc-type-quiet);
	text-decoration: none;
}

.bpc-footer .bpc-footer__legal a:hover {
	color: var(--bpc-type-strong);
}

/* Under the logo: the email and the social links. */
.bpc-footer__contact {
	margin-block-start: 0.5rem;
}

.bpc-footer__contact .bpc-social {
	margin-block-start: 0.25rem;
	margin-inline-start: -0.5rem;
	gap: 0;
}

.bpc-btn:hover {
	background-color: var(--bpc-btn-fill-hover);
	color: var(--bpc-btn-type);
}

/* A 1px settle. No bounce — the Design Master refuses it. */
.bpc-btn:active {
	transform: translateY(1px);
}

.bpc-btn--secondary {
	background-color: transparent;
	border-color: var(--bpc-btn-secondary-edge, var(--bpc-rule)); /* the portal's is Black at 60% (21 Oct) */
	color: var(--bpc-type);
}

.bpc-btn--secondary:hover {
	background-color: transparent;
	border-color: var(--bpc-type);
	color: var(--bpc-type);
}

/**
 * Pay now — "large, impossible to miss". Dark Petal on the portal's Paper,
 * full width and taller than any other button, and the only filled button on
 * the dashboard: everything else there is secondary, so nothing competes.
 */
.bpc-btn--pay {
	width: 100%;
	min-height: 3.75rem;
	font-size: 1.125rem;
}

/* ---- Cards -------------------------------------------------------------
 * "Snow on Paper. Soft separation, no heavy shadow." (Graphite on Void went
 * with the Void field on 25 Sep.)
 */

/*
 * A card is Light Grey on the Pearl Grey field (Snow on Paper until 20
 * Oct), and that tonal step is the whole separation. It used to carry a
 * hairline outline as well, which did the same job a second time and
 * turned every card into an outlined rounded rectangle — the most generic
 * shape in interface design, and the one thing on the page that did not
 * read as print.
 *
 * Room inside it, but not a band of it: 1.5rem above and below since 21
 * Oct, not 4rem ("Much tighter … less padding in cards", Ollie, 13 Oct),
 * when the agreement card stood 277px tall for an eyebrow, a line and a
 * button.
 */
.bpc-card {
	background-color: var(--bpc-card);
	border: 0;
	border-radius: var(--bpc-radius);
	padding: var(--bpc-card-pad-y, var(--wp--preset--spacing--40, 1.5rem)) var(--bpc-card-pad-x, var(--wp--preset--spacing--50, 2.5rem));
}

/*
 * In the portal (21 Oct, "White cards, thin line") a card is White on the
 * page's warm white, and one fine Light Grey edge is the whole separation:
 * no grey slab and no shadow. The edge is the card's border, so the room
 * inside it stays the card's own padding.
 */
body.bpc-field-portal :is(.bpc-card, .bpc-portal__next, .bpc-flow, .bpc-dayplan-page, .bpc-tasting, .bpc-signin),
body.bpc-field-portal .bpc-portal > p:not([class]) {
	border: var(--bpc-hairline) solid var(--bpc-card-edge);
}

/* A form inside the sign-in card lends it its room, not a second edge. */
body.bpc-field-portal .bpc-signin > .bpc-flow {
	border: 0;
}

/*
 * In the portal (21 Oct), one room inside every card: the card's own
 * padding (--bpc-card-pad-y and -x, tokens.css) and nothing on top of it.
 * The first line starts at the padding and the last ends at it, so a card
 * is as tall as what it says, the words of every card start on the same
 * line, and no band of empty room opens at a card's foot. The small
 * capitals over a card sit close over what they name.
 */
body.bpc-field-portal :is(.bpc-card, .bpc-portal__next, .bpc-dayplan-page, .bpc-tasting) > :first-child {
	margin-block-start: 0;
}

body.bpc-field-portal :is(.bpc-card, .bpc-portal__next, .bpc-dayplan-page, .bpc-tasting) > :last-child {
	margin-block-end: 0;
}

body.bpc-field-portal :is(.bpc-card, .bpc-portal__next) > .bpc-eyebrow:first-child {
	margin-block-end: 0.5rem;
}

/*
 * A card's own section titles ("What happens next", "Good to know"): real
 * headings since 26 Sep, set small in the display italic rather than as
 * spaced-capital labels ("Get rid of clutter ie sub headers").
 */
.bpc-card__title {
	margin-block-end: 0.5rem;
	font-family: var(--bpc-font-display);
	font-style: italic;
	font-weight: 400;
	font-size: 1.375rem !important;
	line-height: 1.2;
	letter-spacing: 0;
	text-transform: none;
	color: var(--bpc-type);
}

/*
 * Cards laid out as a set finish level. An outline hid a ragged bottom edge
 * well enough; a solid fill does not, and two blocks of Snow ending at
 * different heights is the first thing the eye finds.
 *
 * Opt-in, not blanket: a card sitting beside a long form is a sidebar, and
 * stretching that one to match its neighbour turns it into a tall empty
 * rectangle. Only cards that are peers of each other take this.
 */
.wp-block-column > .bpc-card--even,
.wp-block-column > .wp-block-group.bpc-card--even {
	height: 100%;
}

/* ---- Pills and chips ---------------------------------------------------
 * Petal Light fill, Ink type. Status pills stay quiet.
 */

.bpc-pill {
	display: inline-flex;
	align-items: center;
	gap: 0.375rem;
	padding: 0.3125rem 0.75rem;
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-pill-fill);
	color: var(--bpc-pill-type);
	font-size: 0.8125rem;
	font-weight: 500;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	white-space: nowrap;
}

/*
 * Paid, All set: the quiet green as the pill's edge, the words Black. The
 * green is a mark, not type: on Light Grey it is 3.82:1, short of AA for
 * small words (20 Oct).
 */
.bpc-pill--positive {
	background-color: transparent;
	box-shadow: inset 0 0 0 var(--bpc-hairline) var(--bpc-status-paid);
	color: var(--bpc-type);
}

.bpc-pill--quiet,
.bpc-pill--locked {
	background-color: transparent;
	box-shadow: inset 0 0 0 var(--bpc-hairline) var(--bpc-rule);
	color: var(--bpc-type-quiet);
}

/* ---- Inputs ------------------------------------------------------------
 * "Mist border, generous height, label above."
 */

.bpc-field {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	margin-block-end: 1.5rem;
}

.bpc-label {
	font-size: 0.8125rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--bpc-type-quiet);
}

.bpc-input,
.bpc-textarea,
.bpc-select {
	width: 100%;
	min-height: 3.25rem;
	padding: 0.875rem 1rem;
	border: var(--bpc-hairline) solid var(--bpc-input-border);
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-input-fill);
	color: var(--bpc-type);
	font-family: var(--bpc-font-sans);
	font-size: 1rem; /* never below 16px — smaller zooms the page on iOS */
	line-height: 1.4;
	transition: border-color var(--bpc-dur) var(--bpc-ease);
}

.bpc-textarea {
	min-height: 8rem;
	resize: vertical;
}

.bpc-input:hover,
.bpc-textarea:hover {
	border-color: var(--bpc-type-quiet);
}

.bpc-input::placeholder,
.bpc-textarea::placeholder {
	color: var(--bpc-type-hint);
	opacity: 1;
}

.bpc-help {
	font-size: 0.8125rem;
	color: var(--bpc-type-quiet);
}

/*
 * An error and a help message sit in the same place, at the same size, and the
 * palette has no red to tell them apart — there are eight greys and no hue at
 * all. Ink against graphite is a 1.41:1 difference: on a rejected form, the
 * one line that matters looks like all the others.
 *
 * So the difference is structural rather than chromatic. The rule on the
 * inline edge is 2px, the same weight the invalid input's border takes, which
 * makes the field and its message read as one thing. It is drawn in
 * currentColor, so it works unchanged on the dark portal surface.
 */
.bpc-error {
	font-size: 0.8125rem;
	font-weight: 500;
	color: var(--bpc-type);
	border-inline-start: 2px solid currentColor;
	padding-inline-start: var(--wp--preset--spacing--20, 0.5rem);
}

/* Nothing to say, nothing to draw. */
.bpc-error:empty,
.bpc-error[hidden] {
	display: none;
}

.bpc-input[aria-invalid="true"],
.bpc-textarea[aria-invalid="true"] {
	border-color: var(--bpc-type);
	border-width: 2px;
}

/* ---- The header -----------------------------------------------------------
 * Logo · the menu bar · the client portal section. Ollie, 25 Sep: "The header
 * should be our logo - The menu bar and client portal section like discussed
 * before." On a laptop or an iPad the menu is a visible row of links; on a
 * phone it folds into one Menu button that lets a panel down over the page.
 *
 * Selectors cover both the core Navigation block (marketing header, so the
 * menu stays editable in the Site Editor) and plain markup rendered by the
 * portal plugin.
 */

/*
 * The breakpoint is 48rem (768px) — the narrowest iPad in portrait. Core's
 * Navigation block folds at a fixed 600px and offers no setting for it, which
 * would put a cramped five-link bar on large phones held sideways. So the
 * fold is moved here, in CSS, and core's own script still does the opening
 * and closing: it only ever adds and removes `is-menu-open`.
 */

:root {
	/*
	 * The lockup is 176×168 at source. 72px tall on a laptop or iPad keeps the
	 * BROOKLYN line readable without the header becoming a banner; 56px on a
	 * phone keeps the bar under 90px so the page starts where a thumb is.
	 * In the main header it is 52–56px, and 44px pinned on
	 * scroll; see `.bpc-header--main` below.
	 *
	 * 56 is the top of the phone range on purpose. At 54 the engraved
	 * "—PIZZA & CO.—" line under BROOKLYN came out about 4px tall, which is
	 * not reading, it is texture. It is still small at 56 — the accessible
	 * name carries the full name — and a phone crop of the artwork (bridge
	 * and BROOKLYN, with a larger subline) is a question for Ollie.
	 */
	--bpc-logo-h: 3.5rem;
	--bpc-logo-ratio: calc(176 / 168);
}

@media (min-width: 48rem) {
	:root {
		--bpc-logo-h: 4.5rem;
	}
}

/* ---- Phones: the slim header ---------------------------------------------
 * Ollie, 28 Sep: "Mobile app ui design for the website", "Looks like an
 * app". At rest a phone's header is the bridge, and only the bridge (below).
 * Scrolled, it becomes a slim 56px band: the header's wrapper is sticky at a
 * negative top, so its upper strip slides away with the page and nothing on
 * the page moves; the logo settles into the band at 72%. Once the page's
 * large title has gone under the band, the same words arrive in its middle,
 * small, with the orange full stop (a copy, hidden from screen readers;
 * assets/js/app.js makes it and sets the classes below). The sign-in page
 * centres its logo, so its band holds the logo alone. Without the script
 * the header scrolls away as it always has. iPad and up keep header.js's
 * slim header, unchanged.
 */

@media (max-width: 47.99rem) {
	/* A press answers with the site's own pressed states, not the browser's
	   blue flash, the surest sign of a web page on a phone. */
	html {
		-webkit-tap-highlight-color: transparent;
	}

	/*
	 * The logo only. Ollie, 28 Sep: "You don't need the top client portal /
	 * menu bit on mobile then can have the logo only ?", and then, of the
	 * ways to do it, "Menu in the bottom bar". On the site's headers the
	 * menu button, the portal icon and the greeting step out; the logo
	 * stays, and still links home. (The portal's own header keeps its menu
	 * at the top on a phone too: "Menu at the top instead", 21 Oct.) The tab bar's last tab, Menu, opens the menu sheet,
	 * and the sheet opens with the portal: Client portal signed out, the
	 * client's own screens and Sign out signed in (functions.php,
	 * brooklyn_menu_sheet_top). The menu itself stays in each header, at no
	 * size, so its sheet is still the one core opens and closes.
	 */
	.bpc-header .bpc-nav .wp-block-navigation__responsive-container-open,
	.bpc-header--main .bpc-header__account {
		display: none !important;
	}

	/*
	 * The <nav> alone: core gives the list inside it the same class. Hidden
	 * as well as sizeless, so a screen reader does not find an empty "Main"
	 * among the landmarks; its sheet, once open, is shown and heard.
	 */
	.bpc-header nav.bpc-nav {
		position: absolute;
		inset-block-start: 0;
		inset-inline-start: 0;
		width: 0;
		height: 0;
		visibility: hidden;
	}

	.bpc-header nav.bpc-nav .wp-block-navigation__responsive-container.is-menu-open {
		visibility: visible;
	}

	.bpc-header--main,
	.bpc-header--minimal {
		background-color: var(--bpc-chrome);
	}

	.bpc-app .wp-site-blocks > :has(> .bpc-header--main),
	.bpc-app .wp-site-blocks > :has(> .bpc-header--minimal) {
		position: sticky;
		top: calc(-1 * var(--bpc-app-hide, 2rem));
		z-index: 100;
	}

	.bpc-app-top {
		position: absolute;
		inset-block-start: 0;
		inset-inline-start: 0;
		width: 1px;
		height: 4px;
		pointer-events: none;
	}

	.bpc-app .bpc-header .bpc-logo {
		transition: transform var(--bpc-dur-slow) var(--bpc-ease-out);
	}

	.bpc-app.is-compact .bpc-header .bpc-logo {
		transform: translateY(var(--bpc-app-shift, 1rem)) scale(0.72);
		transform-origin: 0 50%;
	}

	.bpc-app.is-compact .bpc-header--minimal .bpc-logo {
		transform-origin: 50% 50%;
	}

	/*
	 * Centred on the screen, clear of the logo on its left; with nothing on
	 * the right since the header became the logo alone (28 Sep), a longer
	 * title has the room the menu and the portal icon took.
	 */
	.bpc-apptitle {
		position: absolute;
		inset-inline: 5.5rem;
		inset-block-end: 1px;
		display: flex;
		align-items: center;
		justify-content: center;
		height: 3.5rem;
		overflow: hidden;
		font-family: var(--bpc-font-display);
		font-size: 1.25rem;
		font-style: italic;
		line-height: 1;
		white-space: nowrap;
		color: var(--bpc-type);
		opacity: 0;
		transform: translateY(0.5rem);
		transition:
			opacity var(--bpc-dur) var(--bpc-ease),
			transform var(--bpc-dur-slow) var(--bpc-ease-out);
		pointer-events: none;
	}

	.bpc-apptitle::after {
		content: "." / "";
		color: var(--bpc-type);
	}

	.bpc-app.is-titled .bpc-apptitle {
		opacity: 1;
		transform: none;
	}

	.bpc-header--minimal .bpc-apptitle {
		display: none;
	}
}

@media (max-width: 47.99rem) and (prefers-reduced-motion: reduce) {
	.bpc-app .bpc-header .bpc-logo,
	.bpc-apptitle {
		transition: none;
	}

	.bpc-apptitle {
		transform: none;
	}
}

/* ---- The logo ------------------------------------------------------------
 * The bridge lockup is Premium Black on the light grounds and Premium White
 * on Black (Ollie, 20 Oct: "Logos are black on light grounds and white on
 * black"). It takes the type colour of wherever it stands, so the footer's
 * Black turns it White with no rule of its own; every header, the holding
 * page and the slim bar use this one rule. Until 20 Oct it was painted Dark
 * Petal (25 Sep, "Have all logos like this").
 */

.bpc-logo {
	display: block;
	flex: none;
	width: calc(var(--bpc-logo-h) * var(--bpc-logo-ratio));
	height: var(--bpc-logo-h);
	color: var(--bpc-type-strong);
	line-height: 0;
	text-decoration: none;
}

.bpc-logo__art {
	display: block;
	width: 100%;
	height: 100%;
	background-color: currentColor;
	-webkit-mask: url("../brand/bridge-lockup.png") center / contain no-repeat;
	mask: url("../brand/bridge-lockup.png") center / contain no-repeat;
}

.bpc-header .wp-block-html,
.bpc-header p:has(> .bpc-logo) {
	margin: 0;
	line-height: 0;
}

/* ---- The bar ------------------------------------------------------------- */

/*
 * The header sits above the page it heads. It carries a view-transition-name,
 * which makes it a stacking context, and everything fixed or dropped down
 * inside it — Catering's card, the phone panel — can only ever be as high as
 * the header itself. Without a z-index of its own, the page behind the panel
 * (which is transformed while the panel is open, and so becomes a stacking
 * context of its own, later in the document) painted straight over it.
 * Measured and seen: the hero was drawn across the menu.
 *
 * 100 is above the tab bar (90), so the open panel covers it too.
 */
.bpc-header {
	position: relative;
	z-index: 100;
	background-color: var(--bpc-chrome); /* the header carries the menu: Light Grey, Black words (20 Oct); White in the portal (21 Oct) */
}

.bpc-header__inner {
	gap: var(--wp--preset--spacing--30, 1rem);
}

.bpc-header__account {
	flex: none;
}

/*
 * From the iPad up the header is one flat row on the page's own Paper: the
 * lockup on the left, the menu centred in the room left over, the portal
 * section on the right, all on one level.
 *
 * Ollie, 25 Sep: "Client portal should be on same level logo", and then, of
 * the brushed-silver bar that followed: "it look like 200s … need to
 * modernised … get rid of the second colours the client portal ect icons …
 * get rid of the stupid 3d". So there is no bar: no gradient, no bevel, no
 * shadow, no rounded panel and no second grey. The header is the page's own
 * colour, and only a hairline marks where it ends once it is pinned. Nothing
 * in it is black.
 *
 * The greeting and the progress are stacked, not side by side, so a
 * signed-in client's header fits on an iPad across (1024) without the menu
 * giving up its spacing.
 */
@media (min-width: 48rem) {
	.bpc-header--main {
		--bpc-logo-h: 3.25rem;
		padding-block: 1rem !important;
		background-color: var(--bpc-chrome);
	}

	/*
	 * The logo on the left, the portal on the right, and the menu in the
	 * middle of the bar — the middle of the page, not of the room left
	 * between the two. Ollie, 26 Sep, of the space between the logo and the
	 * menu when it sat on the right: "so many gaps", choosing this from three.
	 * Two equal outer columns keep the middle one centred whatever the logo
	 * and the portal measure.
	 */
	.bpc-header--main .bpc-header__inner {
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
		align-items: center;
		gap: clamp(1rem, 2vw, 2rem);
		min-height: 3.5rem;
	}

	.bpc-header--main .bpc-header__inner > :first-child {
		justify-self: start;
	}

	.bpc-header--main .bpc-header__inner > .bpc-nav {
		justify-self: center;
		min-width: 0;
	}

	.bpc-header--main .bpc-header__inner > .bpc-header__account {
		justify-self: end;
	}

	/*
	 * Core right-aligns the menu (the part's own `justifyContent: right`,
	 * printed as a layout class, and again on the list inside the responsive
	 * container); the bar centres it again, all the way down, so no layer of
	 * it pushes aside what the one above centred.
	 */
	.bpc-header--main .bpc-nav.bpc-nav,
	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open),
	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-close,
	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-dialog,
	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-container-content,
	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container {
		justify-content: center;
	}

	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open),
	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-close,
	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-dialog,
	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-container-content {
		flex: 1 1 auto;
		width: 100%;
	}

	.bpc-header--main .bpc-header__inner > .bpc-header__account {
		flex: none;
	}
}

@media (min-width: 64rem) {
	.bpc-header--main {
		--bpc-logo-h: 3.5rem;
	}
}

/*
 * On scroll: the header stays.
 *
 * Once the header has scrolled out of sight, assets/js/header.js marks it
 * `is-condensed` and the same row comes back pinned to the top, a little
 * slimmer, on Paper with its Dark Petal hairline under it — flat, no shadow. The
 * script first fixes the height of the space the header stood in, so nothing
 * on the page moves when the header leaves the flow. Back at the top the
 * class goes.
 *
 * `padding-block` wins over the block's own inline padding only with
 * !important; it is the one place the header's height is not the editor's.
 */
@media (min-width: 48rem) {
	.bpc-header--main.is-condensed {
		--bpc-logo-h: 2.75rem;
		position: fixed;
		inset: var(--wp-admin--admin-bar--height, 0px) 0 auto 0;
		padding-block: 0.5rem !important;
		border-block-end: var(--bpc-hairline) solid var(--bpc-chrome-rule);
		animation: bpc-header-in var(--bpc-dur-quick) var(--bpc-ease) both;
	}

	/*
	 * An anchor jumped to lands below the pinned header, not under it: 64px
	 * of header, and a little air.
	 */
	html:has(.bpc-header--main) {
		scroll-padding-top: calc(var(--wp-admin--admin-bar--height, 0px) + 5.5rem);
	}
}

@keyframes bpc-header-in {
	from {
		transform: translateY(-100%);
	}

	to {
		transform: translateY(0);
	}
}

@media (prefers-reduced-motion: reduce) {
	.bpc-header--main.is-condensed {
		animation: none;
	}
}

.bpc-nav .wp-block-navigation__container,
.bpc-nav.wp-block-navigation > ul {
	gap: clamp(1rem, 2.4vw, 1.75rem);
	align-items: center;
}

.bpc-nav .wp-block-navigation-item__content,
.bpc-nav__link {
	position: relative;
	display: inline-flex;
	align-items: center;
	min-height: 2.75rem;
	padding-block: 0;
	color: var(--bpc-type-quiet);
	font-family: var(--bpc-font-sans);
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	transition: color var(--bpc-dur) var(--bpc-ease);
}

.bpc-nav .wp-block-navigation-item__content:hover,
.bpc-nav .current-menu-item > .wp-block-navigation-item__content,
.bpc-nav__link:hover,
.bpc-nav__link[aria-current="page"] {
	color: var(--bpc-type-strong);
	text-decoration: none;
}

/*
 * The weight shift is faked with a text-shadow rather than font-weight, so the
 * item never changes width and the whole bar never reflows on hover.
 */
.bpc-nav .wp-block-navigation-item__content:hover,
.bpc-nav .current-menu-item > .wp-block-navigation-item__content,
.bpc-nav__link:hover,
.bpc-nav__link[aria-current="page"] {
	text-shadow: 0.35px 0 0 currentColor;
}

/* The hairline that draws in under the word, left to right. */
.bpc-nav .wp-block-navigation-item__content::after,
.bpc-nav__link::after {
	content: "";
	position: absolute;
	inset-inline: 0;
	bottom: 0.625rem;
	height: var(--bpc-hairline);
	background-color: var(--bpc-accent);
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform var(--bpc-dur) var(--bpc-ease);
}

.bpc-nav .wp-block-navigation-item__content:hover::after,
.bpc-nav .wp-block-navigation-item__content:focus-visible::after,
.bpc-nav .wp-block-navigation-item:hover > .wp-block-navigation-item__content::after,
.bpc-nav .current-menu-item > .wp-block-navigation-item__content::after,
.bpc-nav__link:hover::after,
.bpc-nav__link:focus-visible::after,
.bpc-nav__link[aria-expanded="true"]::after,
.bpc-nav__link[aria-current="page"]::after {
	transform: scaleX(1);
}

/* A 1px settle on click. No bounce — the Design Master refuses it. */
.bpc-nav .wp-block-navigation-item__content:active,
.bpc-nav__link:active {
	transform: translateY(1px);
}

/*
 * Catering's ▾. Core draws it as a small button of its own, which is what
 * lets a keyboard open the list without following the link. It is given the
 * bar's full height and 24px of width — WCAG 2.5.8's minimum — so it is not a
 * 12px target sitting beside a 44px one.
 *
 * On the bar (below) the box is narrowed so the space after the chevron is
 * the menu's own gap; before that the gap after Catering was the nav gap plus
 * the toggle's empty width — 42px against 14 at 834 — and the bar read as
 * having a hole in it.
 *
 * Its own box, too: clear of the G, so its focus hairline (2px out, square
 * like the other hairlines) does not cut into the word.
 */
.bpc-nav .wp-block-navigation__submenu-icon {
	display: inline-flex;
	align-items: center;
	justify-content: flex-start;
	width: 1.5rem;
	height: 2.75rem;
	margin: 0 0 0 0.25rem;
	padding: 0 0 0 0.25rem;
	border-radius: 0;
	color: var(--bpc-type-quiet);
	transition: color var(--bpc-dur) var(--bpc-ease);
}

.bpc-nav .wp-block-navigation__submenu-icon:focus-visible {
	outline-offset: 2px;
	border-radius: 0;
}

.bpc-nav .wp-block-navigation__submenu-icon svg {
	width: 0.625rem;
	height: 0.625rem;
	stroke: currentColor;
	transition: transform var(--bpc-dur) var(--bpc-ease);
}

/* The chevron turns when the card is out, and only then — see the Escape rules below. */
.bpc-nav .wp-block-navigation-item:hover > .wp-block-navigation__submenu-icon,
.bpc-nav .wp-block-navigation-item:focus-within > .wp-block-navigation__submenu-icon,
.bpc-nav .wp-block-navigation__submenu-icon[aria-expanded="true"] {
	color: var(--bpc-type);
}

.bpc-nav .wp-block-navigation-item:hover > .wp-block-navigation__submenu-icon svg,
.bpc-nav .wp-block-navigation-item:focus-within > .wp-block-navigation__submenu-icon svg,
.bpc-nav .wp-block-navigation__submenu-icon[aria-expanded="true"] svg {
	transform: rotate(180deg);
}

/* ---- Catering, dropping down ---------------------------------------------
 * A flat Snow card with a Mist hairline and one soft, low shadow — enough to
 * lift it off Paper, nothing more. Opens on hover and on keyboard focus —
 * core handles both; this only decides how it looks arriving.
 */

.bpc-nav .wp-block-navigation__submenu-container {
	min-width: 14rem;
	padding-block: 0.375rem;

	/*
	 * !important only because core prints the overlay colour on this list as
	 * a preset class (`has-paper-background-color`), and preset classes are
	 * !important. The card is Snow; Paper would be no card at all. Inside the
	 * phone panel core's own transparent !important is more specific and wins,
	 * which is right: there the list is part of the panel, not a card.
	 */
	background-color: var(--bpc-card) !important;
	border: var(--bpc-hairline) solid var(--bpc-rule);
	border-radius: var(--bpc-radius);
	opacity: 0;
	transform: translateY(-4px);
	transition: opacity var(--bpc-dur) var(--bpc-ease),
		transform var(--bpc-dur) var(--bpc-ease);
}

/*
 * The card hangs 12px below the item, with air under the toggle's focus
 * hairline. An invisible strip bridges the gap, or a pointer moving down from
 * Catering would fall out of :hover on the way and the card would shut.
 */
.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .has-child > .wp-block-navigation__submenu-container {
	inset-inline: 0 auto;
	margin-block-start: 0.75rem;
	border-color: var(--bpc-rule);
	border-radius: var(--bpc-radius);
	box-shadow: 0 0.75rem 1.5rem -1rem color-mix(in srgb, var(--bpc-shadow) 20%, transparent);
}

.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .has-child > .wp-block-navigation__submenu-container::before {
	content: "";
	position: absolute;
	inset-inline: 0;
	bottom: 100%;
	height: 1rem;
}

.bpc-nav .wp-block-navigation-item:hover > .wp-block-navigation__submenu-container,
.bpc-nav .wp-block-navigation-item:focus-within > .wp-block-navigation__submenu-container,
.bpc-nav .wp-block-navigation-submenu[data-wp-context]:has(:focus-visible) > .wp-block-navigation__submenu-container,
.bpc-nav .wp-block-navigation-submenu__toggle[aria-expanded="true"] ~ .wp-block-navigation__submenu-container {
	opacity: 1;
	transform: translateY(0);
}

.bpc-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	display: flex;
	width: 100%;
	min-height: 2.75rem;
	padding: 0 1.25rem;
	color: var(--bpc-type);
	font-size: 0.875rem;
	font-weight: 400;
	letter-spacing: 0.01em;
	text-transform: none;
	transition: background-color var(--bpc-dur) var(--bpc-ease);
}

/*
 * Core edges this list in 15% black at a higher specificity; the card's
 * hairline is Mist, like every other rule on the site.
 */
.bpc-nav.wp-block-navigation .has-child .wp-block-navigation__submenu-container {
	border-color: var(--bpc-rule);
}

/*
 * Opening on keyboard focus. Core opens a submenu on :focus-within only when
 * it has no toggle button of its own (`open-on-hover-click` is excluded), and
 * leaves the keyboard to the toggle and its script. Tabbing onto Catering
 * should show what is under it without a second key, so the card opens on
 * focus-within here as it does on hover.
 */
.bpc-nav .has-child:focus-within > .wp-block-navigation__submenu-container {
	visibility: visible;
	overflow: visible;
	width: auto;
	height: auto;
	min-width: 14rem;
}

/* Inside the card the hairline would read as a divider, not a hover. */
.bpc-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content::after {
	content: none;
}

.bpc-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
	background-color: var(--bpc-card-hover);
	color: var(--bpc-type);
}

/* Focus inside the card sits within it, not over its edge. */
.bpc-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content:focus-visible {
	outline-offset: -3px;
}

/*
 * Catering stays a small card (Ollie, 26 Sep: "Drop down menu is far to big
 * shouldn't be like that"). It was a panel the full width of the header, with
 * a name, the four in two columns and a Request a date button; now it is its
 * four, one under another, and the Catering link itself goes to the page
 * that lists them.
 */
.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .bpc-mega > .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	white-space: nowrap;
}

/*
 * Putting it away again.
 *
 * Opening on focus and hover is only half of WCAG 1.4.13: what opens that way
 * has to close on Escape, and what the toggle announces has to be what is on
 * screen (4.1.2). Two cases shut the card whatever hover and focus say:
 *
 * - The toggle has focus and does not say it is expanded. That is where
 *   core's own Escape handler leaves focus after closing a list it opened,
 *   and it is the Tab stop after the Catering link, where a keyboard user
 *   expects a closed disclosure they can open with Enter. Before this the
 *   card stayed fully visible beside a button announcing "collapsed".
 *   (Not `[aria-expanded="false"]`: core's script writes the attribute when
 *   it starts, and the server's markup has none.)
 * - Escape was pressed while the card was out on hover or on focus of the
 *   Catering link, which core's script does not handle at all. assets/js/
 *   nav.js marks the item `is-dismissed` and clears the mark when the
 *   pointer or focus leaves it, or the toggle is pressed.
 *
 * Opened with the toggle (aria-expanded="true") the card stays out: core
 * owns that state, and its Escape sets it back to false.
 *
 * Only on the bar. In the phone panel the list is part of the panel.
 */
.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .has-child:has(> .wp-block-navigation-submenu__toggle:not([aria-expanded="true"]):focus-visible) > .wp-block-navigation__submenu-container,
.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .has-child.is-dismissed:not(:has(> [aria-expanded="true"])) > .wp-block-navigation__submenu-container {
	visibility: hidden;
	opacity: 0;
	transform: translateY(-4px);
}

.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .has-child > .wp-block-navigation-submenu__toggle:not([aria-expanded="true"]):focus-visible svg,
.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .has-child.is-dismissed:not(:has(> [aria-expanded="true"])) > .wp-block-navigation__submenu-icon svg {
	transform: none;
}

/* ---- The menu, in the header ---------------------------------------------
 * Spaced capitals in Ink on Paper, with the Dark Petal hairline drawing in
 * under a word on hover and staying under the page you are on (the rules
 * above). Core gives every item, and Catering's ▾, `background-color:
 * inherit`; here they are transparent.
 */
@media (min-width: 48rem) {
	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item,
	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation__submenu-icon {
		background-color: transparent;
	}

	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content,
	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .has-child > .wp-block-navigation__submenu-icon {
		color: var(--bpc-type);
	}

	/*
	 * The words as words: sentence case at 15px, not spaced capitals. Ollie,
	 * 25 Sep: "Menu bar needs to be better", choosing this from three.
	 */
	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content {
		font-size: 0.9375rem;
		letter-spacing: 0.01em;
		text-transform: none;
	}

	/* In the grey of the site's type (26 Sep); Ink under the pointer and for the page you are on. */
	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content {
		color: var(--bpc-type);
	}

	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content:is(:hover, [aria-current="page"]),
	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item:is(:hover, .current-menu-item) > .wp-block-navigation-item__content {
		color: var(--bpc-type-strong);
	}

	/*
	 * Catering's ▾ keeps its 24px target (WCAG 2.5.8), clear of the G so
	 * its focus hairline does not cut the word. The chevron glyph sits half
	 * the menu's gap after the word — the same half-gap that stands either
	 * side of every | on the bar (Ollie, 1 Oct: "few gaps in the menu bar"),
	 * so word, ▾, | and word keep one rhythm: the glyph's left edge is
	 * margin plus the 4px pad, together gap/2. The 10px of target past the
	 * glyph Catering takes back from the gap after it, so from the chevron
	 * to the | after it is gap/2 again. The target, and its hairline, still
	 * stop short of the next word. (Outside the main header there is no
	 * --bpc-nav-gap and the fallback keeps the old 8px.)
	 */
	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .has-child > .wp-block-navigation__submenu-icon {
		width: 1.5rem;
		margin: 0 0 0 calc(var(--bpc-nav-gap, 1rem) / 2 - 0.25rem);
	}

	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .has-child {
		margin-inline-end: -0.625rem;
	}
}

/*
 * On a touchscreen — an iPad, where the bar shows and there is no hover —
 * the ▾ is how Catering's card opens, so it gets a full 44px finger target
 * rather than WCAG's 24px minimum. The chevron sits in the middle of it, and
 * Catering takes back as much of the gap after it as keeps the target clear
 * of the next word, so the row still reads evenly. A finger target that must
 * not touch the next word outranks the bar's strict half-gap rhythm here.
 */
@media (min-width: 48rem) and (pointer: coarse) {
	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .has-child > .wp-block-navigation__submenu-icon {
		justify-content: center;
		width: 2.75rem;
		margin: 0;
		padding: 0;
	}

	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .has-child {
		margin-inline-end: -1rem;
	}
}

/*
 * 768–1023: the menu closes up a little to share the row with the lockup and
 * the portal, and the greeting and progress wait for a wider screen (below).
 * The portal is the same way in.
 */
@media (min-width: 48rem) and (max-width: 63.99rem) {
	.bpc-header--main .bpc-nav .wp-block-navigation__container {
		gap: 1rem;
	}

	.bpc-header--main .bpc-nav .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content {
		font-size: 0.875rem;
	}
}

/* ---- The portal section ---------------------------------------------------
 * The header's one action, on the same level as the logo: a round person
 * icon, the way into the client portal. Ollie, 25 Sep: "client portal
 * should be icon", choosing it from three. Signed out it goes to the login
 * page; signed in, straight to the portal, with a small Dark Petal dot on
 * it to say so, and — from 1024 up — the greeting ("Good morning" and the
 * client's first name, by their clock; the name alone without JavaScript),
 * with the booking's progress under it (bpc/booking-progress), beside it.
 *
 * Raised: Ollie, 26 Sep, "3d effect portal icon". The one thing in the
 * header with depth, so it reads as the thing to press: a Snow disc lit from
 * above — a bright top edge, a Mist foot, two soft Ink shadows under it —
 * with the Ink glyph on it. It lifts a pixel under the pointer and presses in
 * while its menu is open. Greys only, and with reduced motion it does not
 * move. The words "Client portal" stay in the link, at no
 * size, so a screen reader and a search engine still read them; on hover and
 * keyboard focus they appear under the icon as a small label, so nobody has
 * to guess what a person icon means. The label's own text is given no
 * spoken alternative, so it is not read twice.
 */

.bpc-header__login {
	position: relative;
	margin: 0;
}

.bpc-header__login > a,
.bpc-account > summary {
	--bpc-icon-user: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.3'><circle cx='8' cy='5.4' r='2.8'/><path d='M2.6 14.4c.6-3 2.8-4.7 5.4-4.7s4.8 1.7 5.4 4.7'/></svg>");

	--bpc-raise-edge: color-mix(in srgb, var(--bpc-shadow) 45%, var(--bpc-sheen));
	--bpc-raise-rest:
		inset 0 1px 0 var(--bpc-sheen),
		inset 0 -2px 3px color-mix(in srgb, var(--bpc-shadow) 12%, transparent),
		0 1px 2px color-mix(in srgb, var(--bpc-shadow) 16%, transparent),
		0 6px 14px -6px color-mix(in srgb, var(--bpc-shadow) 34%, transparent);
	--bpc-raise-lift:
		inset 0 1px 0 var(--bpc-sheen),
		inset 0 -2px 3px color-mix(in srgb, var(--bpc-shadow) 12%, transparent),
		0 2px 3px color-mix(in srgb, var(--bpc-shadow) 16%, transparent),
		0 10px 20px -8px color-mix(in srgb, var(--bpc-shadow) 40%, transparent);
	--bpc-raise-press:
		inset 0 2px 4px color-mix(in srgb, var(--bpc-shadow) 18%, transparent),
		inset 0 -1px 0 var(--bpc-sheen),
		0 1px 0 var(--bpc-sheen);

	position: relative;
	display: block;
	width: 2.75rem;
	height: 2.75rem;
	border: var(--bpc-hairline) solid var(--bpc-raise-edge);
	border-radius: 50%;
	background-color: var(--bpc-card);
	background-image: linear-gradient(180deg, var(--bpc-card) 35%, color-mix(in srgb, var(--bp-black) 9%, var(--bp-light-grey)) 100%);
	box-shadow: var(--bpc-raise-rest);
	color: var(--bpc-type);
	font-size: 0;
	line-height: 0;
	text-decoration: none;
	transition: box-shadow var(--bpc-dur) var(--bpc-ease), transform var(--bpc-dur) var(--bpc-ease);
}

/* Centred on its own: the words beside it are there, at no size, and take no room. */
.bpc-header__login > a::before,
.bpc-account > summary::before {
	content: "";
	position: absolute;
	inset: 0;
	margin: auto;
	width: 1.125rem;
	height: 1.125rem;
	background-color: currentColor;
	-webkit-mask: var(--bpc-icon-user) center / contain no-repeat;
	mask: var(--bpc-icon-user) center / contain no-repeat;
}

.bpc-header__login > a::after,
.bpc-account > summary::after {
	content: "Client portal" / "";
	position: absolute;
	top: calc(100% + 0.5rem);
	right: 0;
	padding: 0.5rem 0.75rem;
	border: var(--bpc-hairline) solid var(--bpc-rule);
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-card);
	color: var(--bpc-type);
	font-family: var(--bpc-font-sans);
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	line-height: 1;
	text-transform: uppercase;
	white-space: nowrap;
	pointer-events: none;
	opacity: 0;
	transform: translateY(-4px);
	transition: opacity var(--bpc-dur) var(--bpc-ease), transform var(--bpc-dur) var(--bpc-ease);
}

.bpc-header__login > a:hover,
.bpc-header__login > a:focus-visible,
.bpc-account:not([open]) > summary:hover,
.bpc-account:not([open]) > summary:focus-visible {
	box-shadow: var(--bpc-raise-lift);
	transform: translateY(-1px);
}

/* Pressed: while the pointer is down, and for as long as the menu is open. */
.bpc-header__login > a:active,
.bpc-account > summary:active,
.bpc-account[open] > summary {
	background-image: linear-gradient(180deg, color-mix(in srgb, var(--bp-black) 12%, var(--bp-light-grey)) 0%, var(--bpc-card) 100%);
	box-shadow: var(--bpc-raise-press);
	transform: translateY(1px);
}

.bpc-header__login > a:hover::after,
.bpc-header__login > a:focus-visible::after,
.bpc-account:not([open]) > summary:hover::after,
.bpc-account:not([open]) > summary:focus-visible::after {
	opacity: 1;
	transform: none;
}

/* Signed in: a small orange dot on the circle, ringed in the header's Light Grey. */
.bpc-header__login.is-signed-in::after {
	content: "";
	position: absolute;
	top: 0.0625rem;
	right: 0.0625rem;
	width: 0.625rem;
	height: 0.625rem;
	border: 2px solid var(--bpc-chrome);
	border-radius: 50%;
	background-color: var(--bpc-accent);
	pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
	.bpc-header__login > a,
	.bpc-header__login > a::after,
	.bpc-account > summary,
	.bpc-account > summary::after,
	.bpc-account__menu,
	.bpc-account__item a::after {
		transition: none;
		animation: none;
	}

	.bpc-header__login > a,
	.bpc-account > summary {
		transform: none !important;
	}
}

/*
 * Signed in, the icon opens the portal's card. Ollie, 26 Sep, "portal drop
 * down menu": a Snow card hung from the header, like Catering's, so the two
 * menus in the header are one family. A <details>, so it works with no script; the summary drops
 * the browser's own triangle and is the icon.
 *
 * At the head, on Paper: "Client portal" in spaced capitals, the client's
 * first name in the display italic, and the event's date and how far off it
 * is. Then each screen as an entry of two lines — its name, and what it is
 * for in the quiet grey — beside a small raised disc with its own glyph, the
 * icon's depth in miniature; an arrow draws in on the one under the pointer.
 * Sign out at the foot, quieter.
 *
 * Then, the same day, with a picture of the old site's header: "small
 * detailed lines separators within the header darker grey". So the card's
 * parts are divided by Dark Petal hairlines — under the head, over Sign out —
 * and what it offers follows the account and the booking
 * (brooklyn_account_menu()): the step the booking is waiting on carries a
 * small outlined Next.
 */
.bpc-account > summary {
	list-style: none;
	cursor: pointer;
}

.bpc-account > summary::-webkit-details-marker {
	display: none;
}

/* The site's own focus: an Ink hairline just outside the circle, not the browser's ring. */
.bpc-account > summary:focus-visible,
.bpc-header__login > a:focus-visible {
	outline: var(--bpc-hairline) solid var(--bpc-rule-strong);
	outline-offset: 3px;
}

.bpc-account__menu {
	position: absolute;
	top: calc(100% + 0.875rem);
	right: 0;
	z-index: 2;
	width: min(20rem, calc(100vw - 2rem));
	margin: 0;
	padding: 0 0 0.5rem;
	overflow: hidden;
	list-style: none;
	border: var(--bpc-hairline) solid var(--bpc-rule);
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-card);
	box-shadow:
		0 1px 2px color-mix(in srgb, var(--bpc-shadow) 8%, transparent),
		0 1.5rem 3rem -1.5rem color-mix(in srgb, var(--bpc-shadow) 30%, transparent);
	animation: bpc-account-in var(--bpc-dur) var(--bpc-ease) both;
}

.bpc-account__head {
	margin: 0 0 0.5rem;
	padding: 1.25rem 1.25rem 1rem;
	border-block-end: var(--bpc-hairline) solid var(--bpc-rule-detail);
}

.bpc-account__head > * {
	margin: 0;
}

.bpc-account__head .bpc-eyebrow {
	color: var(--bpc-type-quiet);
}

.bpc-account__who {
	margin-block-start: 0.375rem;
	color: var(--bpc-type);
	font-family: var(--bpc-font-display);
	font-size: 1.625rem;
	font-style: italic;
	line-height: 1.15;
}

.bpc-account__when {
	margin-block-start: 0.375rem;
	color: var(--bpc-type-quiet);
	font-family: var(--bpc-font-sans);
	font-size: 0.8125rem;
	line-height: 1.4;
}

.bpc-account__item a {
	--bpc-glyph: none;

	position: relative;
	display: grid;
	grid-template-columns: 2.25rem minmax(0, 1fr);
	column-gap: 0.875rem;
	align-items: center;
	min-height: 3.5rem;
	margin: 0 0.5rem;
	padding: 0.5rem 2.25rem 0.5rem 0.75rem;
	border-radius: var(--bpc-radius);
	color: var(--bpc-type);
	font-family: var(--bpc-font-sans);
	text-decoration: none;
}

/* The small raised disc, and the screen's glyph on it. */
.bpc-account__item a::before {
	content: "";
	grid-row: 1 / span 2;
	width: 2.25rem;
	height: 2.25rem;
	border: var(--bpc-hairline) solid color-mix(in srgb, var(--bpc-rule-strong) 35%, var(--bpc-card));
	border-radius: 50%;
	background:
		var(--bpc-glyph) center / 1rem no-repeat,
		linear-gradient(180deg, var(--bpc-card) 35%, color-mix(in srgb, var(--bp-black) 9%, var(--bp-light-grey)) 100%);
	box-shadow:
		inset 0 1px 0 var(--bpc-sheen),
		0 1px 2px color-mix(in srgb, var(--bpc-shadow) 14%, transparent),
		0 4px 8px -4px color-mix(in srgb, var(--bpc-shadow) 28%, transparent);
}

/* The glyphs are drawn in Premium Black (#111111): a background image cannot take currentColor. */
.bpc-account__item--booking a {
	--bpc-glyph: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23111111' stroke-width='1.2' stroke-linecap='round'><rect x='2.5' y='3.5' width='11' height='10' rx='1'/><path d='M2.5 6.5h11M5.5 2v3M10.5 2v3'/></svg>");
}

.bpc-account__item--menu a {
	--bpc-glyph: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23111111' stroke-width='1.2' stroke-linecap='round' stroke-linejoin='round'><path d='M2.6 4.2Q8 1.4 13.4 4.2L8 14.4Z'/><path d='M3.6 6.1Q8 4 12.4 6.1'/><circle cx='7' cy='8.4' r='.7'/><circle cx='9.2' cy='9.8' r='.7'/><circle cx='7.9' cy='11.8' r='.5'/></svg>");
}

.bpc-account__item--pay a {
	--bpc-glyph: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23111111' stroke-width='1.2' stroke-linecap='round'><rect x='1.8' y='3.8' width='12.4' height='8.4' rx='1'/><path d='M1.8 6.6h12.4M4.3 10h2.4'/></svg>");
}

.bpc-account__item--agreement a {
	--bpc-glyph: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23111111' stroke-width='1.2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 1.8h5.4L12.5 5v9.2H4Z'/><path d='M9.2 1.8V5h3.3M6 8h4.4M6 10.4h2.6'/></svg>");
}

.bpc-account__item--enquiry a {
	--bpc-glyph: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23111111' stroke-width='1.2' stroke-linejoin='round'><rect x='1.8' y='3.5' width='12.4' height='9' rx='1'/><path d='m2.2 4 5.8 4.6L13.8 4'/></svg>");
}

.bpc-account__item--admin a {
	--bpc-glyph: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23111111' stroke-width='1.2'><rect x='2' y='2' width='5' height='5' rx='.6'/><rect x='9' y='2' width='5' height='5' rx='.6'/><rect x='2' y='9' width='5' height='5' rx='.6'/><rect x='9' y='9' width='5' height='5' rx='.6'/></svg>");
}

.bpc-account__label {
	align-self: end;
	font-size: 1rem;
	font-weight: 500;
	line-height: 1.3;
}

.bpc-account__note {
	grid-column: 2;
	align-self: start;
	color: var(--bpc-type-quiet);
	font-size: 0.8125rem;
	line-height: 1.4;
}

/* A screen with no note centres its one line on the disc. */
.bpc-account__item a:not(:has(.bpc-account__note)) .bpc-account__label {
	grid-row: 1 / span 2;
	align-self: center;
}

/* The arrow: drawn in on the entry under the pointer. */
.bpc-account__item a::after {
	content: "→" / "";
	position: absolute;
	top: 50%;
	right: 0.875rem;
	color: var(--bpc-type);
	font-size: 1rem;
	line-height: 1;
	opacity: 0;
	transform: translate(-4px, -50%);
	transition: opacity var(--bpc-dur) var(--bpc-ease), transform var(--bpc-dur) var(--bpc-ease);
}

.bpc-account__item a:hover,
.bpc-account__item a:focus-visible {
	background-color: var(--bpc-card-hover);
}

.bpc-account__item a:hover::after,
.bpc-account__item a:focus-visible::after {
	opacity: 1;
	transform: translate(0, -50%);
}

.bpc-account__menu a:focus-visible {
	outline: var(--bpc-hairline) solid var(--bpc-rule-strong);
	outline-offset: -3px;
}

/* The step the booking is waiting on: a small outlined tag, and a darker edge on its disc. */
.bpc-account__tag {
	display: inline-block;
	margin-inline-start: 0.5rem;
	padding: 0.1875rem 0.4375rem;
	border: var(--bpc-hairline) solid var(--bpc-rule-strong);
	border-radius: var(--bpc-radius);
	color: var(--bpc-type-quiet);
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	line-height: 1;
	text-transform: uppercase;
	vertical-align: 0.125em;
}

.bpc-account__item.is-next a::before {
	border-color: var(--bpc-rule-strong);
}

/* Sign out: under a fine Dark Petal line, and quieter than the screens. */
.bpc-account__out {
	margin: 0.5rem 1.25rem 0;
	padding-block-start: 0.5rem;
	border-block-start: var(--bpc-hairline) solid var(--bpc-rule-detail);
}

.bpc-account__out a {
	display: flex;
	align-items: center;
	min-height: 2.75rem;
	margin-inline: -0.75rem;
	padding: 0 0.75rem;
	border-radius: var(--bpc-radius);
	color: var(--bpc-type-quiet);
	font-family: var(--bpc-font-sans);
	font-size: 0.875rem;
	text-decoration: none;
}

.bpc-account__out a:hover {
	background-color: var(--bpc-card-hover);
	color: var(--bpc-type-strong);
}

@keyframes bpc-account-in {
	from {
		opacity: 0;
		transform: translateY(-4px);
	}
}

/* ---- Fine lines ------------------------------------------------------------
 * Ollie, 26 Sep, with a picture of the old site's header: "small detailed
 * lines separators within the header darker grey … small details like this
 * we need to add within the site". The header's parts are marked by Dark
 * Petal hairlines (--bpc-rule-strong), one pixel, never a box: one under the
 * whole header, a short upright one between the menu and the portal, and
 * between the rows of the phone's menu. Mist stays for the edges of cards and fields.
 */
.bpc-header--main {
	border-block-end: var(--bpc-hairline) solid var(--bpc-chrome-rule);
}

@media (min-width: 48rem) {
	.bpc-header--main .bpc-header__account {
		position: relative;
		padding-inline-start: clamp(1rem, 2vw, 1.5rem);
	}

	.bpc-header--main .bpc-header__account::before {
		content: "";
		position: absolute;
		inset-block: 0;
		inset-inline-start: 0;
		width: var(--bpc-hairline);
		height: 1.75rem;
		margin-block: auto;
		background-color: var(--bpc-rule-strong);
	}
}

.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__container > .wp-block-navigation-item {
	border-block-end-color: var(--bpc-rule-strong);
}

/*
 * Between the menu names: Ollie, 26 Sep, "add something in between the menu
 * names | or -". The | as one of the fine lines — a Dark Petal hairline the
 * height of a capital, halfway between two names. The gap between the names
 * becomes padding either side of each, so the line can sit in the middle of
 * it without the bar changing width. Catering's chevron box already ends at
 * its mark on the bar (see the chevron above), so the line after it sits
 * halfway too.
 */
@media (min-width: 48rem) {
	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container {
		--bpc-nav-gap: 1rem;

		gap: 0;
	}

	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item {
		padding-inline: calc(var(--bpc-nav-gap) / 2);
	}

	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item:first-child {
		padding-inline-start: 0;
	}

	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item:last-child {
		padding-inline-end: 0;
	}

	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item + .wp-block-navigation-item {
		background: linear-gradient(var(--bpc-rule-strong), var(--bpc-rule-strong)) no-repeat left center / var(--bpc-hairline) 0.875rem;
	}
}

@media (min-width: 64rem) {
	.bpc-header--main .bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container {
		--bpc-nav-gap: var(--wp--preset--spacing--40, 1.5rem);
	}
}

/*
 * The site menu in a header without a menu bar (the sign-in page, the
 * portal): only ever a phone's sheet (patterns/site-menu.php).
 */
@media (min-width: 48rem) {
	.bpc-nav--sheet {
		display: none !important;
	}
}

/*
 * Gallery is in the menu on a phone only (28 Sep). It left the tab bar for
 * Street, and the menu sheet is where a phone finds it; the bar on an iPad
 * and a laptop keeps its five, as it was.
 */
@media (min-width: 48rem) {
	.bpc-nav .wp-block-navigation__container > .wp-block-navigation-item.bpc-nav__phone {
		display: none;
	}
}

/*
 * The greeting — "Good morning, Ollie" by the client's clock (header.js),
 * the name alone without JavaScript, never "Hi" (Ollie, 1 Oct: "that should
 * not say hi"): the display face, in italic, the way a host would say it.
 */
.bpc-header__hi {
	margin: 0;
	color: var(--bpc-type);
	font-family: var(--bpc-font-display);
	font-size: 1rem;
	font-style: italic;
	line-height: 1.25;
	white-space: nowrap;
}

.bpc-header .bpc-progress {
	min-height: 2.75rem;
}

/*
 * Below 1024 there is no room on the row for the greeting and the progress;
 * the portal icon still takes a signed-in client straight to both, and its
 * dot says they are signed in. On a phone the tab bar's Portal tab is there
 * as well.
 */
@media (max-width: 63.99rem) {
	.bpc-header__hi {
		display: none;
	}
}

@media (min-width: 48rem) and (max-width: 63.99rem) {
	.bpc-header--main .bpc-header__account > .bpc-progress {
		display: none;
	}
}

/*
 * From 1024: the greeting over the progress in one column, then the icon
 * spanning both. Either can be missing — no first name on the account, or no
 * booking yet — and the icon still sits on the row's middle line.
 */
@media (min-width: 64rem) {
	.bpc-header--main .bpc-header__account:has(> .bpc-header__hi, > .bpc-progress) {
		display: grid;
		grid-template-columns: auto auto;
		align-items: center;
		column-gap: 1.5rem;
		row-gap: 0;
	}

	.bpc-header--main .bpc-header__account > .bpc-header__hi {
		grid-column: 1;
		grid-row: 1;
	}

	/*
	 * No booking yet, so no progress line: the greeting stands alone, and
	 * alone it spans both rows, so it sits centred on the icon's own middle
	 * (Ollie, 1 Oct: "its too high in the header") instead of keeping to the
	 * top row of a stack that is not there.
	 */
	.bpc-header--main .bpc-header__account:not(:has(> .bpc-progress)) > .bpc-header__hi {
		grid-row: 1 / span 2;
	}

	/* And the other way about: a progress line with no first name to greet. */
	.bpc-header--main .bpc-header__account:not(:has(> .bpc-header__hi)) > .bpc-progress {
		grid-row: 1 / span 2;
	}

	.bpc-header--main .bpc-header__account > .bpc-progress {
		grid-column: 1;
		grid-row: 2;
		min-height: 1.5rem;
		font-size: 0.75rem;
	}

	.bpc-header--main .bpc-header__account > .bpc-progress .bpc-progress__rail {
		width: 2.5rem;
	}

	.bpc-header--main .bpc-header__account > .bpc-header__login {
		display: flex;
		align-items: center;
		align-self: stretch;
		grid-column: 2;
		grid-row: 1 / span 2;
	}

}

/* ---- Below 48rem: the menu button -----------------------------------------
 * Core's own three-line icon (the part asks for it with `hasIcon`), and its
 * cross to close, each a 44px target. The buttons are named "Open menu" and
 * "Close menu" by core for a screen reader.
 */

/* Core sets these two buttons' type with a thrice-repeated class; one more wins. */
.bpc-nav .wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open,
.bpc-nav .wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close {
	/*
	 * No display here. This selector outweighs the fold below, and a display
	 * set on it put the Menu button back on every laptop.
	 */
	align-items: center;
	justify-content: center;
	min-width: 2.75rem;
	min-height: 2.75rem;
	padding: 0;
	color: var(--bpc-type);
	font-family: var(--bpc-font-sans);
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	transition: color var(--bpc-dur) var(--bpc-ease);
}

@media (max-width: 47.99rem) {
	.bpc-nav .wp-block-navigation__responsive-container-open:not(.always-shown),
	.bpc-nav .is-menu-open .wp-block-navigation__responsive-container-close {
		display: inline-flex;
	}

	.bpc-nav .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
		display: none;
	}
}

@media (min-width: 48rem) {
	.bpc-nav .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: none;
	}
}

.bpc-nav .wp-block-navigation__responsive-container-open svg,
.bpc-nav .wp-block-navigation__responsive-container-close svg {
	width: 1.5rem;
	height: 1.5rem;
	fill: currentColor;
}

/* ---- The panel: a sheet from the bottom -----------------------------------
 * Depth through motion, as agreed on 17 Sep, because the Design Master bans
 * clay 3D and glassmorphism by name.
 *
 * 28 Sep ("Looks like an app"): the menu is a sheet that rises from the
 * bottom edge, into the thumb's reach, instead of a panel dropping from the
 * top. Core's script still opens and closes it; this is its dress, and
 * assets/js/app.js puts it away as it came. The page behind steps back to
 * 0.96 and dims, as before; a light Graphite veil goes over everything; the
 * sheet is Snow with a Mist grab handle and 16px top corners; its items are
 * the display italic on Mist hairlines, each with the orange arrow, and the
 * page you are on ends in the orange full stop. Tap the veil, drag the
 * sheet down, the close button or Escape: each puts it away. It only ever
 * opens on a phone, and every rule for it is inside the phone query.
 */

@media (max-width: 47.99rem) {
	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open {
		inset: 0 !important;
		display: flex;
		flex-direction: column;
		justify-content: flex-end;
		height: 100dvh;
		max-height: none;
		padding: 0;
		background-color: transparent !important;
		color: var(--bpc-type);
		box-shadow: none;

		/* Core fades the whole container in; here the veil fades and the sheet rises. */
		animation: none;

		/*
		 * Not a scroll box. Core focuses the first item as it opens, and a
		 * scrollable container scrolled the rising sheet straight into place,
		 * so it popped up instead of sliding. The sheet scrolls itself.
		 */
		overflow: clip !important;
	}

	/* The veil, on its own layer: core's fill on the container is !important
	   and cannot fade. */
	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open::before {
		content: "";
		position: fixed;
		inset: 0;
		background-color: color-mix(in srgb, var(--bpc-shadow) 22%, transparent);
		animation: bpc-veil-in 280ms var(--bpc-ease) both;
		pointer-events: none;
	}

	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__responsive-close {
		position: relative;
		width: 100%;
		max-width: none;
		max-height: 86dvh;
		margin: 0;
		overflow-y: auto;
		overscroll-behavior: contain;
		padding: 0.5rem var(--wp--preset--spacing--40, 1.5rem) calc(1.5rem + env(safe-area-inset-bottom, 0px));
		background-color: var(--bpc-card);
		border-radius: var(--bpc-radius-sheet, 1rem) var(--bpc-radius-sheet, 1rem) 0 0; /* 16px on the site; the portal's one small radius there (21 Oct) */
		box-shadow: 0 -1.5rem 3rem -1.5rem color-mix(in srgb, var(--bpc-shadow) 28%, transparent);
		animation: bpc-sheet-up 460ms var(--bpc-ease-out) both;
		touch-action: pan-y;
	}

	.bpc-nav .is-menu-open .wp-block-navigation__responsive-dialog {
		position: relative;
		min-height: 0;
	}

	/* The grab handle: a Mist bar, the thing you would reach for. */
	.bpc-nav .is-menu-open .wp-block-navigation__responsive-dialog::before {
		content: "";
		display: block;
		width: 2.25rem;
		height: 0.25rem;
		margin: 0 auto 0.75rem;
		border-radius: 0.125rem;
		background-color: var(--bpc-rule);
	}

	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__responsive-container-close {
		top: 0.5rem;
		right: -0.5rem;
	}

	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__responsive-container-content {
		width: 100%;
		align-items: flex-start;
		justify-content: flex-start;
		padding-block-start: 2.25rem;
	}

	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__container,
	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__container.items-justified-right {
		width: 100%;
		gap: 0;
		align-items: stretch;
		justify-content: flex-start;
		text-align: left;
	}

	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__container > .wp-block-navigation-item {
		width: 100%;
		align-items: stretch;
		justify-content: flex-start;
		border-block-end: var(--bpc-hairline) solid var(--bpc-rule);
	}

	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__container > .wp-block-navigation-item:last-child {
		border-block-end: 0;
	}

	/* A list to read: the display italic, at a size worth the screen. */
	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation-item__content {
		display: flex;
		align-items: center;
		min-height: 3.25rem;
		font-family: var(--bpc-font-display);
		font-size: clamp(1.5rem, 6vw, 2rem);
		font-style: italic;
		font-weight: 400;
		letter-spacing: 0;
		line-height: 1.2;
		text-transform: none;
		color: var(--bpc-type);
		text-shadow: none;
	}

	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content {
		justify-content: space-between;
		width: 100%;
		min-height: 3.5rem;
		font-size: 1.75rem;
	}

	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation-item__content::after {
		content: none;
	}

	/* Every row leads somewhere: the site's orange arrow, at its right edge. */
	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content::after {
		content: "\2192" / "";
		position: static;
		height: auto;
		font-family: var(--bpc-font-sans);
		font-size: 1rem;
		font-style: normal;
		color: var(--bpc-type);
		background: none;
		transform: none;
	}

	/* The page you are on ends in the orange full stop, as its title does. */
	.bpc-nav .is-menu-open [aria-current="page"] .wp-block-navigation-item__label::after,
	.bpc-nav .is-menu-open .current-menu-item > a .wp-block-navigation-item__label::after {
		content: "." / "";
		color: var(--bpc-type);
	}

	.bpc-nav .is-menu-open [aria-current="page"],
	.bpc-nav .is-menu-open .current-menu-item > a {
		color: var(--bpc-type-strong) !important;
	}

	/*
	 * Catering's three pages: chips under it, one thumb-width each, rather
	 * than a card dropping down as on the bar. Each is a 44px target, and a
	 * focused one's hairline wraps the whole word.
	 */
	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__submenu-container,
	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__responsive-container-content .has-child .wp-block-navigation__submenu-container {
		display: flex !important;
		flex-flow: row wrap;
		gap: 0.5rem;
		width: 100%;
		padding: 0 0 1rem !important;
		background: transparent !important;
		transform: none;
	}

	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__submenu-container .wp-block-navigation-item__content {
		min-height: 2.75rem;
		padding: 0 1rem !important;
		border-radius: 999px;
		background-color: transparent;
		box-shadow: inset 0 0 0 var(--bpc-hairline) var(--bpc-rule-strong);
		font-family: var(--bpc-font-sans);
		font-size: 0.9375rem;
		font-style: normal;
		font-weight: 500;
		letter-spacing: 0;
		text-transform: none;
		color: var(--bpc-type) !important;
	}

	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__submenu-container .wp-block-navigation-item__content:active {
		background-color: var(--bpc-card-hover);
	}

	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__submenu-icon {
		display: none;
	}

	/*
	 * The top of the sheet: the portal (functions.php,
	 * brooklyn_menu_sheet_top). Signed out, Client portal as the outlined
	 * button across the sheet; signed in, their portal's screens, the list
	 * the header's card holds from the iPad up, set into the sheet.
	 */
	.bpc-nav .is-menu-open .bpc-sheet-portal {
		display: block;
		width: 100%;
		margin: 0 0 0.75rem;
	}

	.bpc-nav .is-menu-open .bpc-sheet-portal .wp-block-button__link {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 100%;
		min-height: 3rem;
	}

	.bpc-nav .is-menu-open .bpc-sheet-portal .bpc-account__menu {
		position: static;
		width: auto;
		margin: 0;
		box-shadow: none;
		border-radius: var(--bpc-app-radius, 8px);
		animation: none;
	}

	/* Behind the veil the tab bar dims: the sheet is the thing to act on. */
	body:has(.bpc-nav .is-menu-open) .bpc-tabs {
		opacity: 0.35;
	}

	/* Put away: the sheet goes back down and the veil lifts (app.js). */
	.bpc-nav .is-menu-open.is-closing::before {
		animation: bpc-veil-out 240ms var(--bpc-ease) both;
	}

	.bpc-nav .is-menu-open.is-closing .wp-block-navigation__responsive-close {
		animation: bpc-sheet-down 240ms var(--bpc-ease) both;
	}

	.bpc-nav .is-menu-open.is-dragging .wp-block-navigation__responsive-close {
		animation: none;
		transition: none;
	}
}

/* Only ever inside the phone's open sheet. */
.bpc-sheet-portal {
	display: none;
}

@keyframes bpc-veil-in {
	from {
		opacity: 0;
	}
}

@keyframes bpc-veil-out {
	to {
		opacity: 0;
	}
}

@keyframes bpc-sheet-up {
	from {
		transform: translateY(100%);
	}
}

@keyframes bpc-sheet-down {
	to {
		transform: translateY(100%);
	}
}

/*
 * The page steps back while the sheet is up.
 *
 * Only main and the footer move. The header is the sheet's ancestor, and a
 * transform on an ancestor becomes the containing block for anything fixed
 * inside it — the sheet would be pinned to a shrinking header instead of the
 * screen.
 *
 * The footer is found by what it holds: the template part around it is a
 * plain <div> since 26 Sep, so the page has one footer landmark, not a
 * footer inside a footer.
 */
.wp-site-blocks > main,
.wp-site-blocks > :has(> .bpc-footer) {
	transform-origin: 50% 0;
	transition: transform 420ms var(--bpc-ease), opacity 420ms var(--bpc-ease);
}

body:has(.bpc-nav .wp-block-navigation__responsive-container.is-menu-open) .wp-site-blocks > main,
body:has(.bpc-nav .wp-block-navigation__responsive-container.is-menu-open) .wp-site-blocks > :has(> .bpc-footer) {
	transform: scale(0.96);
	opacity: 0.5;
}

/* The items arrive one after another, quickly enough not to be a performance. */
.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__container > .wp-block-navigation-item {
	animation: bpc-menu-item-rise 320ms var(--bpc-ease) both;
}

@keyframes bpc-menu-item-rise {
	from {
		opacity: 0;
		transform: translateY(0.75rem);
	}

	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.bpc-nav .is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(1) { animation-delay: 140ms; }
.bpc-nav .is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(2) { animation-delay: 190ms; }
.bpc-nav .is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(3) { animation-delay: 240ms; }
.bpc-nav .is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(4) { animation-delay: 290ms; }
.bpc-nav .is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(5) { animation-delay: 340ms; }
.bpc-nav .is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(6) { animation-delay: 390ms; }
.bpc-nav .is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(7) { animation-delay: 440ms; }

/*
 * Motion is a preference, not a decoration. With it switched off the sheet
 * is simply there: no rise, no veil fading, no scale. The page behind still
 * dims, because that is a change of emphasis rather than movement.
 */
@media (prefers-reduced-motion: reduce) {
	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open,
	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open::before,
	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-close,
	.bpc-nav .is-menu-open.is-closing::before,
	.bpc-nav .is-menu-open.is-closing .wp-block-navigation__responsive-close,
	.bpc-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__container > .wp-block-navigation-item {
		animation: none;
	}

	.wp-site-blocks > main,
	.wp-site-blocks > :has(> .bpc-footer) {
		transition: none;
	}

	body:has(.bpc-nav .wp-block-navigation__responsive-container.is-menu-open) .wp-site-blocks > main,
	body:has(.bpc-nav .wp-block-navigation__responsive-container.is-menu-open) .wp-site-blocks > :has(> .bpc-footer) {
		transform: none;
	}
}

/* ---- The portal and the minimal headers ---------------------------------- */

.bpc-header--minimal {
	align-items: center;
}

/*
 * The portal's own header (the logo row and the menu at the top) is drawn
 * under "The portal, redesigned" at the end of this file (plan R1).
 */

/* ---- Featured on -------------------------------------------------------
 * Third-party directory badges (the pattern of 13 Sep, featured-on.php),
 * each one flat Ink whatever its own colours (Ollie, 13 Oct: "The featured
 * on logos should be black"), by the same filter as the home page's row,
 * which the group carries when it has a badge in it. Sized to one optical
 * weight rather than one pixel height, so a wordmark and a roundel look equal.
 */

.bpc-featured {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 2.5rem 3.5rem;
}

.bpc-featured img {
	max-height: 2.25rem;
	width: auto;
	filter: url(#bpc-featured-tone);
}

/* ---- Rules -------------------------------------------------------------
 * A separator on a page is one of the site's fine lines (Ollie, 26 Sep:
 * "small details like this we need to add within the site"): Dark Petal,
 * one pixel. So is the line over the footer, which the part draws in Mist
 * inline; the stylesheet has the last word so both footer parts stay as they
 * are in the editor. Mist is left for the edges of cards and fields.
 */

.bpc-rule {
	height: var(--bpc-hairline);
	border: 0;
	background-color: var(--bpc-rule-strong);
}


/* ---- Social links ------------------------------------------------------
 * Ollie, 26 Sep: "socials icons make black … logo only". Each network's own
 * mark in Ink, no disc and no circle; it steps back to the grey under the
 * pointer. The box round it is the tap target, drawn in nothing: 44px on a
 * touchscreen, 32px with a mouse.
 */

.bpc-social {
	display: flex;
	gap: 0.75rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.bpc-social a {
	display: grid;
	place-items: center;
	width: 2.75rem;
	height: 2.75rem;
	border-radius: var(--bpc-radius);
	color: var(--bpc-type-strong);
	transition: color var(--bpc-dur) var(--bpc-ease);
}

@media (pointer: fine) {
	.bpc-social a {
		width: 2rem;
		height: 2rem;
	}
}

.bpc-social a:hover {
	color: var(--bpc-accent);
}

.bpc-social svg {
	width: 1.125rem;
	height: 1.125rem;
	fill: currentColor;
}

/* ---- Display headline --------------------------------------------------
 * "Italic display, large, modest tracking, full stop when it is a finished
 * line." The full stop is the writer's job; the tracking is ours.
 */

.bpc-display {
	font-family: var(--bpc-font-display);
	font-style: italic;
	font-weight: 300;
	line-height: 1.08;
	letter-spacing: -0.005em;
}

/* ---- Small tracked caps ------------------------------------------------ */

.bpc-eyebrow {
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--bpc-type-quiet);
}

/* ---- Skip link --------------------------------------------------------- */

.bpc-skip-link {
	position: absolute;
	left: -9999px;
	z-index: 999;
	padding: 1rem 1.5rem;
	background-color: var(--bpc-card);
	color: var(--bpc-type);
}

.bpc-skip-link:focus {
	left: 1rem;
	top: 1rem;
}

/*
 * The skip link WordPress prints on a block theme (.skip-link) brings its
 * own greys, dark grey on pale grey. On focus it is the header's Light
 * Grey with Black words and the house ring, as every other focused thing.
 */
body .skip-link.screen-reader-text:focus {
	background-color: var(--bpc-card);
	color: var(--bpc-type);
	font-family: var(--bpc-font-sans);
	font-size: 0.875rem;
	font-weight: 500;
	box-shadow: none;
	outline: var(--bpc-hairline) solid var(--bpc-rule-strong);
	outline-offset: 2px;
	border-radius: var(--bpc-radius);
}

/* ---- Hero -------------------------------------------------------------- */

/*
 * The line on the left, the Airstream on the right, as the home page was in
 * July (Ollie, 26 Sep: "I want it like this the way we had it before but
 * better"). The photograph is held between 22rem and 32rem tall, never a
 * whole screen, and never dimmed: nothing is set on it. Below 1024 the two
 * stack, the line first.
 */
.bpc-hero {
	display: grid;
	gap: var(--wp--preset--spacing--40, 1.5rem);
	padding-block: var(--wp--preset--spacing--40, 1.5rem) 2rem;
}

.bpc-hero > * {
	margin: 0 !important;
}

.bpc-hero__text > * + * {
	margin-block-start: var(--wp--preset--spacing--30, 1rem) !important;
}

.bpc-hero__text > .wp-block-buttons {
	margin-block-start: var(--wp--preset--spacing--40, 1.5rem) !important;
	align-items: center;
	gap: var(--wp--preset--spacing--40, 1.5rem);
}

.bpc-hero__photo {
	height: clamp(18rem, 50vw, 26rem);
	overflow: hidden;
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-pill-fill);
}

.bpc-hero__photo img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 50% 62%;
}

/*
 * The opening line breaks where its own full stop falls, so it sets its own
 * measure. A character limit here would put the break in the wrong place and
 * lose the turn from "experience" to "proof".
 */
.bpc-hero__line {
	text-wrap: balance;
	font-size: clamp(2.25rem, 4.2vw, 3.75rem) !important;
	line-height: 1.04;
	letter-spacing: -0.01em;
}

@media (min-width: 64rem) {
	.bpc-hero {
		grid-template-columns: repeat(12, minmax(0, 1fr));
		align-items: center;
		gap: var(--wp--preset--spacing--50, 2.5rem);
	}

	.bpc-hero__text {
		grid-column: 1 / 6;
	}

	.bpc-hero__photo {
		grid-column: 6 / -1;
		height: clamp(20rem, 50vh, 28rem);
	}
}

/* On a phone the photograph runs to both edges, under the line. */
@media (max-width: 47.99rem) {
	.bpc-hero__photo {
		margin-inline: calc(var(--wp--style--root--padding-left, 1rem) * -1) calc(var(--wp--style--root--padding-right, 1rem) * -1) !important;
		height: 15rem;
		border-radius: 0;
	}

	.bpc-hero__photo img {
		object-position: 50% 70%;
	}

	.bpc-hero__line {
		font-size: 2.125rem !important;
	}
}

/*
 * The quiet link beside a button: the words and an arrow on a Light Grey
 * chip (20 Oct: small type is never on Pearl Grey). Used for "See our
 * catering" beside Request a date, so the page has one primary action and
 * a way on.
 */
.wp-block-button.bpc-btn-link .wp-block-button__link {
	min-height: 2.75rem;
	padding-inline: 0.625rem;
	border: 0;
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-card);
	box-shadow: none;
	color: var(--bpc-type);
	font-size: 0.8125rem;
	font-weight: 500;
}

/*
 * A step closer to the button it sits beside, so on a laptop the two keep
 * one row in the hero's five columns, as they did before the chip (and so
 * the cookie note, in the corner, never covers the second).
 */
.wp-block-buttons:has(> .bpc-btn-link) {
	column-gap: var(--wp--preset--spacing--30, 1rem) !important;
}

.wp-block-button.bpc-btn-link .wp-block-button__link::after,
.bpc-more a::after {
	content: "\2002\2192" / "";
	display: inline-block;
	letter-spacing: 0;
	transition: transform var(--bpc-dur) var(--bpc-ease);
}

.wp-block-button.bpc-btn-link .wp-block-button__link:hover {
	background-color: var(--bpc-card-hover);
	box-shadow: none;
	transform: none;
	color: var(--bpc-type-strong);
}

.wp-block-button.bpc-btn-link .wp-block-button__link:hover::after,
.bpc-more a:hover::after {
	transform: translateX(0.25rem);
}

.bpc-more a {
	font-weight: 500;
}

/* ---- Not found (the 404 page) -------------------------------------------
 * 26 Sep: "No 404 should just be a 404 or you've been burned or something
 * matching our branding / With a animation or something". A big 404 in the
 * display italic, its 0 a pizza drawn like the bridge lockup: fine Black
 * lines, a hatched crust, a stippled top, a little char, orange only in the
 * pepperoni's hairline, all on a Light Grey card. It turns slowly on the peel, half a turn,
 * then rests, and one thin wisp of smoke rises. Then one line, one sentence
 * and the way home, centred.
 *
 * With reduced motion the pizza sits still and there is no smoke.
 */
.bpc-sr {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.bpc-404 {
	padding: var(--wp--preset--spacing--40, 1.5rem);
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-card);
	text-align: center;
}

.bpc-404 > * {
	margin-block: 0 !important;
}

.bpc-404__code {
	margin: 0;
	font-family: var(--bpc-font-display);
	font-style: italic;
	font-weight: 400;
	font-size: clamp(7rem, 26vw, 15rem);
	line-height: 1;
	letter-spacing: -0.02em;
	color: var(--bpc-type);
}

.bpc-404__glyphs {
	display: inline-flex;
	align-items: center;
	gap: 0.04em;
}

.bpc-404__zero {
	position: relative;
	display: inline-block;
	width: 0.74em;
	height: 0.74em;
	margin-inline: 0.02em;
	/* Sits on the numerals' own middle, not the line's. */
	transform: translateY(0.04em);
}

.bpc-404__pizza {
	display: block;
	width: 100%;
	height: 100%;
	overflow: visible;
}

.bpc-404__turn {
	transform-box: fill-box;
	transform-origin: 50% 50%;
}

.bpc-404__rim,
.bpc-404__cut,
.bpc-404__hatch,
.bpc-404__pephatch {
	fill: none;
	stroke: var(--bpc-rule-strong);
	stroke-linecap: round;
}

.bpc-404__rim {
	stroke-width: 1.4;
}

.bpc-404__cut {
	stroke-width: 0.7;
	stroke: var(--bpc-rule-strong);
}

.bpc-404__hatch {
	stroke-width: 0.6;
}

.bpc-404__char {
	fill: none;
	stroke: var(--bpc-type);
	stroke-width: 0.9;
	stroke-linecap: round;
}

.bpc-404__stipple {
	fill: none;
	stroke: var(--bpc-rule-strong);
	stroke-width: 1.3;
	stroke-linecap: round;
}

.bpc-404__pep {
	fill: none;
	stroke: var(--bpc-accent);
	stroke-width: 0.9;
}

.bpc-404__pephatch {
	stroke-width: 0.5;
}

.bpc-404__smoke {
	position: absolute;
	inset-inline: 0;
	inset-block-end: 90%;
	width: 100%;
	height: 60%;
	overflow: visible;
	pointer-events: none;
}

.bpc-404__wisp {
	transform-box: fill-box;
	fill: none;
	stroke: var(--bpc-rule-strong);
	stroke-width: 1.2;
	stroke-linecap: round;
	opacity: 0;
}

.bpc-404__line {
	margin-block-start: var(--wp--preset--spacing--40, 1.5rem) !important;
	font-family: var(--bpc-font-display);
	font-style: italic;
	font-size: var(--wp--preset--font-size--heading, 2.25rem);
	line-height: 1.1;
	color: var(--bpc-type);
}

.bpc-404__lede {
	margin-block-start: var(--wp--preset--spacing--20, 0.5rem) !important;
	font-size: 1.125rem;
	color: var(--bpc-type-quiet);
}

.bpc-404__actions {
	margin-block-start: var(--wp--preset--spacing--50, 2.5rem) !important;
	gap: var(--wp--preset--spacing--40, 1.5rem);
}

@media (prefers-reduced-motion: no-preference) {
	/*
	 * Turned on the peel: half a turn, eased, then a rest; the other half,
	 * then a rest. Twelve seconds for the whole turn, so it never hurries.
	 */
	.bpc-404__turn {
		animation: bpc-peel 12s var(--bpc-ease) infinite;
	}

	.bpc-404__wisp {
		animation: bpc-smoke 6s ease-out 1s infinite;
	}

	.bpc-404__line,
	.bpc-404__lede,
	.bpc-404__actions {
		animation: bpc-arrive var(--bpc-dur-reveal) var(--bpc-ease-out) both;
	}

	.bpc-404__lede {
		animation-delay: 120ms;
	}

	.bpc-404__actions {
		animation-delay: 240ms;
	}
}

@keyframes bpc-peel {
	0%,
	15% {
		transform: rotate(0deg);
	}

	35%,
	65% {
		transform: rotate(180deg);
	}

	85%,
	100% {
		transform: rotate(360deg);
	}
}

@keyframes bpc-smoke {
	0% {
		opacity: 0;
		transform: translateY(15%);
	}

	30% {
		opacity: 0.55;
	}

	100% {
		opacity: 0;
		transform: translateY(-25%);
	}
}

/* ---- Breadcrumbs --------------------------------------------------------
 * 26 Sep: "Add breadcrumbs". Over each page's heading: Home, the page above,
 * the page. Small and quiet, in the sentence case of the menu rather than
 * spaced capitals (no more sub-header labels, the same day), with a slash
 * between. The page itself is not a link.
 *
 * The trail is small type, so it is never on the Pearl Grey (20 Oct). Since
 * 21 Oct it is the header's second line: a Light Grey bar the width of the
 * screen, straight under the header's rule, closed by a hairline, the trail
 * starting where the page's title does. (On 20 Oct it was a Light Grey chip
 * floating over the title, a tag on the page.) The bar is drawn the way the
 * header's band is, with a border image that runs to both edges, so the
 * trail stays in the page's own column on every template. It is pulled up
 * by the room above it (the page's top padding and the gap under the
 * header, --bpc-main-top and the block gap), so it meets the header.
 */
main:has(.bpc-breadcrumbs) {
	--bpc-main-top: var(--wp--preset--spacing--50, 2.5rem);
	padding-block-start: var(--bpc-main-top) !important;
}

.bpc-breadcrumbs {
	/* !important: core's layout zeroes a first child's top margin, at a higher weight. */
	margin-block: calc(-1 * (var(--bpc-main-top, 2.5rem) + var(--wp--style--block-gap, 1.5rem))) var(--wp--preset--spacing--40, 1.5rem) !important;
	padding-block: 0.5rem;
	/*
	 * The element's own ground is the bar's too, under the border image, so
	 * whatever reads its colours finds Light Grey. The hairline is the rule
	 * as it looks on Light Grey, mixed solid, so it reads the same over the
	 * element's ground and over the Pearl Grey either side of it.
	 */
	background-color: var(--bpc-card);
	border-image: linear-gradient(to bottom, var(--bpc-card) calc(100% - var(--bpc-hairline)), color-mix(in srgb, var(--bp-black) 28%, var(--bpc-card)) 0) fill 0 // 0 100vmax;
	font-size: 0.875rem;
	line-height: 1.4;
	color: var(--bpc-type-quiet);
}

.bpc-breadcrumbs ol {
	display: flex;
	flex-wrap: wrap;
	margin: 0;
	padding: 0;
	list-style: none;
}

.bpc-breadcrumbs li + li::before {
	content: "/" / "";
	margin-inline: 0.5em;
	color: var(--bpc-type);
}

.bpc-breadcrumbs a {
	color: var(--bpc-type-quiet);
	text-decoration: underline;
	text-decoration-color: var(--bpc-rule-strong);
	text-underline-offset: 0.2em;
}

.bpc-breadcrumbs a:hover {
	color: var(--bpc-type-strong);
}

.bpc-breadcrumbs [aria-current="page"] {
	color: var(--bpc-type);
}

/* ---- Phones: the large title ---------------------------------------------
 * 28 Sep ("Looks like an app"). On a phone the page's title is the large
 * title an app opens on: the display italic, larger, close under the header,
 * with the trail above it cut to one step back ("‹ Home", "‹ Catering"),
 * a 44px target with an orange chevron, on the header's Light Grey second
 * line. The rest of the trail stays in the page for screen readers, and
 * the structured data is unchanged. As the title
 * goes under the slim header it shrinks a little and fades (scroll-driven,
 * no script), and arrives in the header's band instead.
 */

@media (max-width: 47.99rem) {
	main:has(.bpc-breadcrumbs) {
		--bpc-main-top: 0.75rem;
	}

	main:has(> .bpc-breadcrumbs) {
		padding-block-start: 0.75rem !important;
	}

	/* The sign-in page (the minimal header): its title comes up to the logo too. */
	.wp-site-blocks:has(.bpc-header--minimal) > main {
		padding-block-start: 1.5rem !important;
	}

	main > h1.wp-block-post-title,
	.wp-site-blocks:has(.bpc-header--minimal) main h1 {
		margin-block: 0.25rem 1.25rem !important;
		font-size: clamp(2.75rem, 12.5vw, 3.5rem) !important;
		line-height: 1 !important;
		letter-spacing: -0.012em;
		text-wrap: balance;
		transform-origin: 0 100%;
	}

	.bpc-breadcrumbs {
		margin-block-end: 1rem !important;
		padding-block: 0;
	}

	.bpc-breadcrumbs li {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
	}

	.bpc-breadcrumbs li:nth-last-child(2) {
		position: static;
		width: auto;
		height: auto;
		overflow: visible;
		clip-path: none;
	}

	.bpc-breadcrumbs li:nth-last-child(2)::before {
		content: none;
	}

	.bpc-breadcrumbs li:nth-last-child(2) a {
		display: inline-flex;
		align-items: center;
		gap: 0.375rem;
		min-height: 2.75rem;
		margin-inline-start: -0.25rem;
		padding-inline: 0.25rem 0.5rem;
		font-size: 0.9375rem;
		color: var(--bpc-type-quiet);
		text-decoration: none;
	}

	.bpc-breadcrumbs li:nth-last-child(2) a::before {
		content: "" / "";
		width: 0.5rem;
		height: 0.5rem;
		border-block-end: 1.5px solid var(--bpc-accent);
		border-inline-start: 1.5px solid var(--bpc-accent);
		transform: rotate(45deg);
		transition: transform var(--bpc-dur) var(--bpc-ease);
	}

	.bpc-breadcrumbs li:nth-last-child(2) a:active::before {
		transform: translateX(-3px) rotate(45deg);
	}

	@supports (animation-timeline: view()) {
		@media (prefers-reduced-motion: no-preference) {
			main > h1.wp-block-post-title,
			.wp-site-blocks:has(.bpc-header--minimal) main h1 {
				animation: bpc-title-condense linear both;
				animation-timeline: view(block 3.5rem 0);
				animation-range: exit 0% exit 100%;
			}
		}
	}
}

@keyframes bpc-title-condense {
	to {
		opacity: 0;
		transform: scale(0.82);
	}
}

/* ---- Where else we go -----------------------------------------------------
 * 26 Sep: "Add internal links". At the foot of each brochure, the other
 * brochures and the questions page, by name, each with the orange arrow,
 * in a row that wraps. On its own hairline, like every section.
 */
.bpc-related {
	position: relative;
	margin-block-start: var(--wp--preset--spacing--50, 2.5rem);
	padding-block-start: var(--wp--preset--spacing--40, 1.5rem);
	border-block-start: var(--bpc-hairline) solid var(--bpc-rule-strong);
}

.bpc-related::before {
	content: "";
	position: absolute;
	inset-block-start: -1px;
	inset-inline-start: 0;
	width: 2.5rem;
	height: 2px;
	background: var(--bpc-accent);
}

.bpc-related__title {
	margin: 0;
	font-size: var(--wp--preset--font-size--heading, 2rem);
}

.bpc-related__links {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem 2.5rem;
	margin: var(--wp--preset--spacing--30, 1rem) 0 0;
	padding: 0;
	list-style: none;
}

.bpc-related__link {
	display: inline-flex;
	align-items: center;
	min-height: 2.75rem;
	font-family: var(--bpc-font-display);
	font-style: italic;
	font-size: 1.375rem;
	color: var(--bpc-type);
	text-decoration: none;
}

.bpc-related__link::after {
	content: "\2002\2192" / "";
	color: var(--bpc-type);
	font-style: normal;
	transition: transform var(--bpc-dur) var(--bpc-ease);
}

.bpc-related__link:hover::after {
	transform: translateX(0.25rem);
}

/* ---- Gallery strip ----------------------------------------------------- */

.bpc-gallery-strip.wp-block-gallery {
	gap: var(--wp--preset--spacing--30, 1rem);
}

.bpc-gallery-strip .wp-block-image img {
	border-radius: var(--bpc-radius);
}

/* ---- The home page, editorial ---------------------------------------------
 * Ollie, 25 Sep, choosing between three home pages: "Editorial and
 * spacious". No photographs yet, so the page is made of type, hairlines and
 * room, the way a good menu or a printed programme is.
 *
 * Every section on it is set the same way (`.bpc-ed`): a Dark Petal hairline
 * across the top with the orange stroke on it, the section's name in spaced
 * capitals where it has one, the heading, and what the section says across
 * the width under it.
 *
 * No number before the name (Ollie, 12 Oct: "I don't like the 123 look").
 * The sections were counted "01 — ", "02 — " by the stylesheet; they are
 * not a sequence, so the hairline and the stroke open each one and the
 * name stands on its own.
 *
 * On a phone and an iPad in portrait the two columns stack, heading first.
 * No Snow cards: a hairline over each item does the work a card did.
 */

.bpc-ed {
	border-block-start: var(--bpc-hairline) solid var(--bpc-rule-strong);
}

/*
 * From 1024 the heading runs across the top and what the section says fills
 * the width under it. Ollie, 26 Sep: "So many gaps we need to fix the UI".
 * The heading used to sit in a left third of its own and stay in view, and
 * under it the column stood empty for the whole of the section.
 */
@media (min-width: 64rem) {
	.bpc-ed {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		align-items: start;
		gap: var(--wp--preset--spacing--40, 1.5rem);
	}

	/*
	 * Core's constrained layout gives every child a max-width and auto
	 * margins; in the grid the columns are the measure.
	 */
	.bpc-ed > * {
		max-width: none !important;
		margin: 0 !important;
	}

	/*
	 * The heading, and a section's only part, take the full width. The gap
	 * between two parts is the gap inside each, so What we offer's four read
	 * as one even row.
	 */
	.bpc-ed > :first-child,
	.bpc-ed > :nth-child(2):last-child {
		grid-column: 1 / -1;
	}
}

/* The first section after the photograph needs no hairline over it. */
.bpc-hero + .bpc-ed {
	border-block-start: 0;
}

/*
 * The facts strip — the price per head, and since 13 Oct nothing beside
 * it. A Light Grey band (20 Oct: the figure's label is small type, and
 * small type is never on Pearl Grey); until then it was flat on Paper
 * between two Dark Petal hairlines (Ollie, 25 Sep: "get rid of the second
 * colours"). It takes the full width (a hairline between figures, were
 * there ever more than one) instead of huddling in a narrow column in the
 * middle. It is on Catering and the four event pages.
 *
 * The band is drawn by the portal plugin (bpc/facts) with the Light Grey
 * preset class (Petal Light on a page saved before 20 Oct), and preset
 * classes are !important, so this has to be too.
 */
.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display) {
	padding-inline: var(--wp--preset--spacing--40, 1.5rem) !important;
	border: 0;
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-card) !important;
}

.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display) > .wp-block-columns {
	max-width: none !important;
}

/* Each figure sits right over what it counts. */
.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display) > .wp-block-columns > .wp-block-column > * + * {
	margin-block-start: 0.25rem !important;
}

/* The band closes with its own hairline; the section after it does not add a second. */
.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display) + .bpc-ed {
	border-block-start: 0;
}

/*
 * On a phone the figures sit two by two, not as six lines down the
 * screen (26 Sep: "I don't want a lot of gaps or bulky looking").
 */
@media (max-width: 47.99rem) {
	.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display) > .wp-block-columns {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--wp--preset--spacing--40, 1.5rem) var(--wp--preset--spacing--30, 1rem);
	}

	.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display) > .wp-block-columns > .wp-block-column {
		margin: 0 !important;
	}
}

@media (min-width: 48rem) {
	.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display) > .wp-block-columns > .wp-block-column + .wp-block-column {
		padding-inline-start: var(--wp--preset--spacing--40, 1.5rem);
		border-inline-start: var(--bpc-hairline) solid var(--bpc-rule-strong);
	}
}

/* An offer, or a reason: on a Light Grey card (20 Oct), the stroke on its top edge. */
.bpc-offer {
	height: 100%;
	padding: 1.25rem var(--wp--preset--spacing--40, 1.5rem) 1.375rem;
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-card);
}

.bpc-offer > * {
	max-width: none !important;
}

/* ---- The home page, as it was in July, better (26 Sep) -------------------
 * Ollie, with a screenshot of July's home page: "I want it like this the
 * way we had it before but better". The opening, then street trading beside
 * its photograph, the four occasions in circles, and "Fired fresh" to close.
 * Flat on Paper, a Dark Petal hairline between each, no bands of a second
 * colour and no gold.
 */

/*
 * The home page's sections sit straight under one another: each has its own
 * hairline and its own room, so the page's block gap between them would be a
 * second, empty margin on top ("So many gaps and over padding", 26 Sep).
 */
main > :is(.bpc-street, .bpc-catering, .bpc-about, .bpc-featured-on) {
	margin-block-start: var(--wp--preset--spacing--30, 1rem) !important;
}

/*
 * Street trading: when, large, on the left, and what, beside it (26 Sep, of
 * three: "the date, large"). On a phone the date sits over the words.
 */
.bpc-street {
	display: grid;
	gap: var(--wp--preset--spacing--30, 1rem);
	align-items: center;
	padding: var(--wp--preset--spacing--40, 1.5rem);
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-card);
}

.bpc-street > *,
.bpc-street__text > * {
	margin: 0 !important;
}

.bpc-street__when {
	font-family: var(--bpc-font-display);
	font-style: italic;
	font-weight: 300;
	font-size: clamp(2.5rem, 5vw, 3.75rem);
	line-height: 0.95;
	color: var(--bpc-type);
}

.bpc-street__text > .wp-block-heading {
	margin-block-start: 0.3rem !important;
}

.bpc-street__text > p:last-child {
	margin-block-start: 0.5rem !important;
	font-size: 1.0625rem;
}

@media (min-width: 48rem) {
	.bpc-street {
		grid-template-columns: auto minmax(0, 1fr);
		gap: var(--wp--preset--spacing--50, 2.5rem);
	}

	.bpc-street__when {
		padding-inline-end: var(--wp--preset--spacing--50, 2.5rem);
		border-inline-end: var(--bpc-hairline) solid var(--bpc-rule-strong);
	}
}

/*
 * The outlined button: the same size and type as the filled one, an Ink
 * edge, no fill. For a way on that sits beside, or below, the page's one
 * filled button without competing with it.
 */
.wp-block-button.bpc-btn-outline .wp-block-button__link {
	background-color: transparent;
	border: var(--bpc-hairline) solid var(--bpc-btn-edge);
	color: var(--bpc-type-strong);
}

.wp-block-button.bpc-btn-outline .wp-block-button__link:hover {
	border-color: var(--bpc-type);
}

/* Our catering: four circles, each one the way into its page. */
.bpc-catering {
	padding-block: 2rem;
}

.bpc-types {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 11rem));
	justify-content: center;
	gap: var(--wp--preset--spacing--40, 1.5rem) var(--wp--preset--spacing--50, 2.5rem);
	margin-block-start: var(--wp--preset--spacing--30, 1rem) !important;
}

.bpc-types > * {
	margin: 0 !important;
}

.bpc-type {
	position: relative;
	padding: 0.75rem 0.75rem 0.5rem;
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-card);
	text-align: center;
}

.bpc-type__photo {
	margin: 0 !important;
	aspect-ratio: 1;
	overflow: hidden;
	border-radius: 50%;
	background-color: var(--bpc-pill-fill);
	box-shadow: 0 0 0 var(--bpc-hairline) var(--bpc-rule-strong);
}

.bpc-type__photo img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition:
		transform 600ms var(--bpc-ease-out),
		opacity var(--bpc-dur-reveal) var(--bpc-ease-out);
}

.bpc-type__name {
	margin: 0.5rem 0 0 !important;
	font-family: var(--bpc-font-display);
	font-style: italic;
	font-size: 1.25rem;
	line-height: 1.2;
}

.bpc-type__name a {
	color: var(--bpc-type);
	text-decoration: none !important;
}

.bpc-type__name a::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: var(--bpc-radius);
}

.bpc-type__name a::after {
	content: "\2002\2192" / "";
	display: inline-block;
	font-family: var(--bpc-font-sans);
	font-style: normal;
	font-size: 0.875rem;
	color: var(--bpc-type-quiet);
	transition: transform var(--bpc-dur) var(--bpc-ease), color var(--bpc-dur) var(--bpc-ease);
}

.bpc-type__name a:focus-visible {
	outline: none;
}

.bpc-type__name a:focus-visible::before {
	outline: 2px solid var(--bpc-rule-strong);
	outline-offset: 4px;
}

@media (hover: hover) {
	.bpc-type:hover .bpc-type__photo img {
		transform: scale(1.06);
	}

	.bpc-type:hover .bpc-type__name a,
	.bpc-type:hover .bpc-type__name a::after {
		color: var(--bpc-type-strong);
	}

	.bpc-type:hover .bpc-type__name a::after {
		transform: translateX(0.25rem);
	}
}

/* A phone: two by two. */
@media (max-width: 47.99rem) {
	.bpc-types {
		grid-template-columns: repeat(2, minmax(0, 9.5rem));
		gap: var(--wp--preset--spacing--40, 1.5rem) var(--wp--preset--spacing--40, 1.5rem);
	}

	.bpc-type__name {
		font-size: 1.125rem;
	}
}

/*
 * As featured on (29 Sep): "Home page we need to add at the bottom featured
 * on section". The last section, over the footer; since 20 Oct a Light
 * Grey card, since its eyebrow is small type (it was opened by a fine line
 * on the page's Paper). On 1 Oct the badges came, with "Make all same size
 * and colour": under the eyebrow, a row of badges, each in the same box,
 * each in the same one colour. The boxes are bare — no card, no line, no
 * fill ("Get rid of the white background", also 1 Oct) — so the badges sit
 * straight on the band's own ground; the box is only the shared cell that
 * keeps the four aligned and one size.
 * The box is a little wider than tall and each badge is fitted in whole, so
 * a round badge fills its height and a wide one its width, and the two look
 * the same size (the round ones' area and the wide ones' come out alike).
 * The colour is the palette's black, whole (Ollie, 13 Oct: "The featured
 * on logos should be black"; the Brooklyn orange before), Premium Black
 * since 20 Oct and called Ink here. The theme's badges are already flat Ink
 * on nothing, and so is the copy the
 * theme makes of an upload (inc/featured-ink.php); a badge with no such
 * copy, a drawing say, is put into the same Ink by the band's own filter
 * (--tone). Every badge stands at full strength, so it is black and never
 * a grey; under the pointer or the keyboard it eases back a little, and the
 * colour never changes.
 *
 * A laptop takes the four on one row, 128 by 104px each. A phone takes them
 * two and two, 120 by 96px (data-count says how many; five or more go in
 * threes), the rows centred.
 */
.bpc-featured-on {
	padding: 1.5rem var(--wp--preset--spacing--40, 1.5rem);
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-card);
	text-align: center;
}

/*
 * Kind words from recent events (bpc/testimonials; 6 Oct 2026): clients'
 * own words, approved, each over a quiet first name and occasion. No
 * stars, no score, no average. One column on a phone; side by side from a
 * tablet, each as wide as it needs and never narrower than 16rem.
 */
.bpc-testimonials {
	padding: 1.5rem var(--wp--preset--spacing--40, 1.5rem);
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-card);
}

.bpc-testimonials__label {
	margin: 0 0 1.25rem;
	text-align: center;
}

.bpc-testimonials__list {
	display: grid;
	gap: 1.5rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 48rem) {
	.bpc-testimonials__list {
		grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
		gap: 2rem;
	}
}

.bpc-testimonials__item,
.bpc-testimonials__figure {
	margin: 0;
	min-inline-size: 0;
}

.bpc-testimonials__words {
	margin: 0;
	padding: 0;
	border: 0;
}

.bpc-testimonials__words p {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--lead, 1.125rem);
	font-style: italic;
	line-height: 1.5;
	color: var(--bpc-type-strong);
	overflow-wrap: anywhere;
}

.bpc-testimonials__words p::before {
	content: "\201C";
}

.bpc-testimonials__words p::after {
	content: "\201D";
}

.bpc-testimonials__who {
	margin-block-start: 0.5rem;
	font-size: 0.875rem;
	color: var(--bpc-type-quiet);
}

.bpc-featured-on > * {
	margin: 0 !important;
}

.bpc-featured-on__list {
	--bpc-badge-w: 8rem;
	--bpc-badge-h: 6.5rem;
	--bpc-badge-gap: 1.5rem;

	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--bpc-badge-gap);
	margin-block-start: 1rem !important;
	margin-inline: auto !important;
	padding: 0;
	list-style: none;
}

.bpc-featured-on__item {
	display: block;
	margin: 0 !important;
}

/* The image fills the box's inside and is fitted in whole, centred. */
.bpc-featured-on__badge {
	display: block;
	box-sizing: border-box;
	inline-size: var(--bpc-badge-w);
	block-size: var(--bpc-badge-h);
	padding: 0.5rem 0.75rem;
	text-decoration: none;
}

.bpc-featured-on__logo {
	display: block;
	inline-size: 100%;
	block-size: 100%;
	object-fit: contain;
	opacity: 1;
	transition: opacity var(--bpc-dur) var(--bpc-ease);
}

.bpc-featured-on__logo--tone {
	filter: url(#bpc-featured-tone);
}

.bpc-featured-on__tone {
	position: absolute;
	inline-size: 0;
	block-size: 0;
	overflow: hidden;
}

a.bpc-featured-on__badge:is(:hover, :focus-visible) .bpc-featured-on__logo {
	opacity: 0.64;
}

a.bpc-featured-on__badge:focus-visible {
	outline: 2px solid var(--bpc-rule-strong);
	outline-offset: 3px;
}

@media (max-width: 47.99rem) {
	.bpc-featured-on__list {
		--bpc-badge-w: 7.5rem;
		--bpc-badge-h: 6rem;
		--bpc-badge-gap: 1rem;

		max-inline-size: calc(3 * var(--bpc-badge-w) + 2 * var(--bpc-badge-gap));
	}

	.bpc-featured-on__list[data-count="4"] {
		max-inline-size: calc(2 * var(--bpc-badge-w) + var(--bpc-badge-gap));
	}

	/*
	 * On a phone the band is a band, not a card (21 Oct; Ollie, 13 Oct:
	 * "hairlines not boxes"): Light Grey the width of the screen, a Black
	 * hairline over it and under it, no corners. It is painted by a border
	 * image that runs to both edges, as the breadcrumb's line is, so the
	 * badges keep the page's column. From an iPad up it is the last
	 * section of the home page's one Light Grey run (below).
	 */
	main > .bpc-featured-on {
		border-radius: 0;
		background-color: var(--bpc-card);
		border-image: linear-gradient(to bottom, var(--bpc-rule-strong) var(--bpc-hairline), var(--bpc-card) 0 calc(100% - var(--bpc-hairline)), var(--bpc-rule-strong) 0) fill 0 // 0 100vmax;
	}
}

@media (prefers-reduced-motion: reduce) {
	.bpc-featured-on__logo {
		transition: none;
	}
}

/* Fired fresh: centred, on a Light Grey card. */
.bpc-about {
	padding: 1.5rem var(--wp--preset--spacing--40, 1.5rem) 2rem !important;
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-card);
}

.bpc-about__lede {
	font-size: 1.125rem;
	line-height: 1.6;
}

/*
 * The block that closes a page: a call to action, so White on Black (Ollie,
 * 20 Oct: "white on black for the footer and call-to-action blocks"), the
 * line on the left and the orange button on the right, with room above it
 * and below. Its words take the on-black roles from tokens.css.
 */
.bpc-closing {
	margin-block: var(--wp--preset--spacing--50, 2.5rem) !important;
	border: 0;
	border-radius: var(--bpc-radius);
}

.bpc-closing h2 {
	margin: 0;
}

.bpc-closing p {
	margin: 0;
}

@media (min-width: 48rem) {
	.bpc-closing {
		padding: var(--wp--preset--spacing--40, 1.5rem) var(--wp--preset--spacing--50, 2.5rem) !important;
	}
}

@media (prefers-reduced-motion: reduce) {
	.bpc-type__photo img,
	.bpc-type__name a::after,
	.bpc-more a::after,
	.wp-block-button.bpc-btn-link .wp-block-button__link::after {
		transition: none;
	}

	.bpc-type:hover .bpc-type__photo img,
	.bpc-type:hover .bpc-type__name a::after,
	.bpc-more a:hover::after,
	.wp-block-button.bpc-btn-link .wp-block-button__link:hover::after {
		transform: none;
	}
}

/* ---- Phones: sections in cards ------------------------------------------
 * 28 Sep ("Looks like an app"). A phone reads in cards: a section's heading
 * stays on the Paper and what it holds sits on a Snow card, 8px corners, a
 * one-pixel soft lift and no heavy shadow (the Design Master's "soft
 * separation"). The orange stroke that opens a section moves onto the top
 * edge of its card. Nothing is added: no icons, no new words.
 */

@media (max-width: 47.99rem) {
	:root {
		--bpc-app-radius: 8px;
		--bpc-app-card-pad: 1.25rem;
		--bpc-app-lift: 0 1px 2px color-mix(in srgb, var(--bpc-shadow) 5%, transparent);
	}

	.bpc-ed {
		padding-block-start: 2rem !important;
		border-block-start: 0;
	}

	.bpc-ed::before {
		inset-block-start: 0.75rem !important;
		inset-inline-start: var(--wp--style--root--padding-left, 1.5rem) !important;
	}

	.bpc-ed .bpc-display,
	.bpc-ed h2 {
		font-size: 2rem !important;
		line-height: 1.1;
	}

	/*
	 * How it works: one Snow card, its three steps in reading order, a
	 * hairline between them. No "01 02 03" in front (Ollie, 12 Oct: "I don't
	 * like the 123 look"): the names say the order (Enquire, Quote and
	 * deposit, Your portal), and a plain hairline between them, as in the
	 * Good to know and menu cards. The words take the full width of the card
	 * the numbers used to indent.
	 */
	.bpc-steps {
		gap: 0 !important;
		margin-block-start: 1rem !important;
		padding: 0.25rem var(--bpc-app-card-pad);
		background-color: var(--bpc-card);
		border-radius: var(--bpc-app-radius);
		box-shadow: var(--bpc-app-lift);
	}

	.bpc-steps > .wp-block-column {
		margin: 0 !important;
		padding-block: 1rem;
	}

	.bpc-steps > .wp-block-column + .wp-block-column {
		border-block-start: var(--bpc-hairline) solid var(--bpc-rule);
	}

	.bpc-steps .bpc-rule {
		display: none;
	}

	.bpc-steps h3 {
		margin: 0 !important;
	}

	.bpc-steps p {
		margin: 0.375rem 0 0 !important;
	}

	/*
	 * The facts: the figures in one Snow card, side by side, sharing the
	 * width equally however many there are; a fixed column count would
	 * leave part of the card empty.
	 */
	.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display) {
		margin-block: 1.5rem !important;
		padding: 1rem 0 !important;
		border: 0;
		border-radius: var(--bpc-app-radius);
		background-color: var(--bpc-card) !important;
		box-shadow: var(--bpc-app-lift);
	}

	.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display)::before {
		inset-inline-start: var(--bpc-app-card-pad) !important;
		inset-block-start: 0 !important;
	}

	.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display) > .wp-block-columns {
		grid-template-columns: none !important;
		grid-auto-flow: column;
		grid-auto-columns: minmax(0, 1fr);
		gap: 0 !important;
	}

	.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display) > .wp-block-columns > .wp-block-column {
		padding-inline: 0.75rem;
		text-align: center;
	}

	.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display) > .wp-block-columns > .wp-block-column + .wp-block-column {
		border-inline-start: var(--bpc-hairline) solid var(--bpc-rule);
	}

	.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display) .bpc-display {
		font-size: 1.375rem !important;
	}

	.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display) .bpc-eyebrow {
		font-size: 0.625rem !important;
		line-height: 1.35;
	}

	/*
	 * The menus: a card per group, the group's name at its top (20 Oct: the
	 * name is small type, so it is on the card, not on the Pearl Grey above
	 * it).
	 */
	.bpc-menus__group + .bpc-menus__group {
		margin-block-start: 1.25rem;
	}

	.bpc-menus__group {
		padding: 0.875rem var(--bpc-app-card-pad) 0.25rem !important;
		border-radius: var(--bpc-app-radius) !important;
		box-shadow: var(--bpc-app-lift);
	}

	.bpc-menus__heading {
		margin-block-end: 0 !important;
	}

	.bpc-menus__list {
		padding: 0 !important;
	}

	.bpc-menus__item {
		display: flex;
		align-items: center;
		min-height: 3rem;
		border-block-start: 0 !important;
		border-block-end: var(--bpc-hairline) solid var(--bpc-rule) !important;
	}

	.bpc-menus__item:last-child {
		border-block-end: 0 !important;
	}

	.bpc-menus__note {
		padding-inline: var(--bpc-app-card-pad);
	}

	/* The closing block: Black, its button across its width. */
	.bpc-closing {
		gap: 1.25rem !important;
		padding: 1.5rem var(--bpc-app-card-pad) !important;
		border: 0;
		border-radius: var(--bpc-app-radius);
		box-shadow: var(--bpc-app-lift);
	}

	.bpc-closing::before {
		inset-inline-start: var(--bpc-app-card-pad) !important;
		inset-block-start: 0 !important;
	}

	.bpc-closing > .wp-block-buttons,
	.bpc-closing > .wp-block-buttons > .wp-block-button,
	.bpc-closing .wp-block-button__link {
		width: 100%;
	}

	.bpc-closing .wp-block-button__link {
		display: flex;
		align-items: center;
		justify-content: center;
		min-height: 3.25rem;
	}

	/* Where else we go: an inset list, a row per page, each with its arrow. */
	.bpc-related {
		padding-block-start: 1.25rem;
		border-block-start: 0;
	}

	.bpc-related::before {
		inset-block-start: 0;
	}

	.bpc-related__links {
		flex-direction: column;
		gap: 0 !important;
		padding: 0 var(--bpc-app-card-pad) !important;
		background-color: var(--bpc-card);
		border-radius: var(--bpc-app-radius);
		box-shadow: var(--bpc-app-lift);
	}

	.bpc-related__links > li + li {
		border-block-start: var(--bpc-hairline) solid var(--bpc-rule);
	}

	.bpc-related__link {
		justify-content: space-between;
		width: 100%;
		min-height: 3.25rem;
	}
}

/* ---- An iPad and up: the same cards (20 Oct) --------------------------------
 * Ollie's pairings put body text on Light Grey, never on Pearl Grey, so
 * from the iPad up a section holds its words on the cards a phone already
 * uses: the heading on the Pearl Grey ground, what it says on Light Grey.
 * The steps are one card, their columns side by side; the pages to go on
 * to are one card, their names in a row.
 */
@media (min-width: 48rem) {
	.bpc-steps {
		padding: var(--wp--preset--spacing--40, 1.5rem) !important;
		border-radius: var(--bpc-radius);
		background-color: var(--bpc-card);
	}

	.bpc-related {
		padding-block-start: var(--wp--preset--spacing--40, 1.5rem);
	}

	.bpc-related__links {
		padding: 0.5rem var(--wp--preset--spacing--40, 1.5rem);
		border-radius: var(--bpc-radius);
		background-color: var(--bpc-card);
	}
}

/* ---- Phones: swipe rows ----------------------------------------------------
 * 28 Sep ("Looks like an app"). A row of cards that runs off the right edge,
 * so the next one peeks in and says "swipe". The row scrolls inside itself,
 * snapping card by card; the page never scrolls sideways. It runs to the
 * screen's edges and its first card lines up with the text above it, whatever
 * the row sits in. Where the browser can, a quiet row of dots sits under it,
 * the current one a short orange dash; elsewhere the peek says it.
 *
 * - What we offer: the four offers as Snow cards at 78%. The pattern wraps
 *   its two rows of two in one `bpc-swipe` group; on a phone the rows step
 *   aside (display: contents) so the four are one row. From the iPad up the
 *   group is a plain flow group and the rows are as they were.
 * - Our catering: the four circles, each snapping to the middle in turn, the
 *   one in the middle full size and its neighbours waiting a little smaller
 *   (scroll-driven, no script). The circle, with its Dark Petal hairline, is
 *   the card: nothing is put behind it.
 * - The gallery strip: 4:5 frames at 72%.
 * reveal.js leaves the cards in these rows alone, so none waits hidden off
 * to the side.
 */

@media (max-width: 47.99rem) {
	.bpc-swipe,
	.bpc-types,
	.bpc-gallery-strip.wp-block-gallery {
		--bpc-app-gutter: max(var(--wp--style--root--padding-left, 1.5rem), calc(50vw - 50%));
		display: flex !important;
		flex-wrap: nowrap !important;
		justify-content: flex-start !important;
		gap: 0.75rem !important;
		margin-inline: calc(50% - 50vw) !important;
		padding: 0.25rem var(--bpc-app-gutter) 0.75rem !important;
		overflow-x: auto;
		overscroll-behavior-inline: contain;
		scroll-snap-type: x mandatory;
		scroll-padding-inline: var(--bpc-app-gutter);
		scrollbar-width: none;
	}

	.bpc-swipe::-webkit-scrollbar,
	.bpc-types::-webkit-scrollbar,
	.bpc-gallery-strip::-webkit-scrollbar {
		display: none;
	}

	.bpc-swipe > .wp-block-columns {
		display: contents;
	}

	.bpc-swipe > .wp-block-columns > .wp-block-column,
	.bpc-types > *,
	.bpc-gallery-strip > * {
		flex: 0 0 auto;
		margin: 0 !important;
		scroll-snap-align: start;
	}

	/* The offers: Snow cards at 78% so the next one shows. */
	.bpc-swipe.bpc-swipe--offers {
		margin-block-start: 1rem !important;
	}

	.bpc-swipe.bpc-swipe--offers > .wp-block-columns > .wp-block-column {
		flex-basis: 78% !important;
		width: 78%;
	}

	.bpc-swipe--offers .bpc-offer {
		height: 100%;
		padding: 1.25rem var(--bpc-app-card-pad) 1.375rem;
		border-block-start: 0;
		border-radius: var(--bpc-app-radius);
		background-color: var(--bpc-card);
		box-shadow: var(--bpc-app-lift);
	}

	.bpc-swipe--offers .bpc-offer::before {
		inset-inline-start: var(--bpc-app-card-pad) !important;
		inset-block-start: 0 !important;
	}

	.bpc-swipe--offers .bpc-offer h3 {
		margin-block: 0.25rem 0.5rem !important;
		font-size: 1.5rem !important;
	}

	.bpc-swipe--offers .bpc-offer p {
		margin: 0 !important;
	}

	/* Our catering: one circle at a time, in the middle. */
	.bpc-types {
		--bpc-app-circle: min(58vw, 15rem);
		gap: 1rem !important;
		padding-inline: calc(50vw - var(--bpc-app-circle) / 2) !important;
		scroll-padding-inline: 0;
	}

	.bpc-types > .bpc-type {
		width: var(--bpc-app-circle);
		scroll-snap-align: center;
	}

	.bpc-types .bpc-type__name {
		margin-block-start: 0.875rem !important;
		font-size: 1.375rem;
	}

	.bpc-types > .bpc-type:active .bpc-type__photo {
		opacity: 0.92;
	}

	@supports (animation-timeline: view()) {
		@media (prefers-reduced-motion: no-preference) {
			.bpc-types .bpc-type__photo {
				animation: bpc-circle-focus linear both;
				animation-timeline: view(inline);
			}
		}
	}

	/* Photographs: 4:5 frames at 72%, 8px corners. */
	.bpc-gallery-strip > .wp-block-image {
		width: 72% !important;
		aspect-ratio: 4 / 5;
		overflow: hidden;
		border-radius: var(--bpc-app-radius);
		background-color: var(--bpc-pill-fill);
	}

	.bpc-gallery-strip > .wp-block-image img {
		width: 100%;
		height: 100% !important;
		object-fit: cover;
		border-radius: 0;
	}

	@supports selector(::scroll-marker) {
		:is(.bpc-swipe, .bpc-types, .bpc-gallery-strip) {
			scroll-marker-group: after;
		}

		:is(.bpc-swipe, .bpc-types, .bpc-gallery-strip)::scroll-marker-group {
			display: flex;
			justify-content: center;
			gap: 0.375rem;
			margin-block-start: 0.25rem;
		}

		:is(.bpc-swipe > .wp-block-columns > .wp-block-column, .bpc-types > *, .bpc-gallery-strip > *)::scroll-marker {
			content: "";
			width: 0.375rem;
			height: 0.375rem;
			border-radius: 50%;
			background-color: var(--bpc-rule);
			transition: width var(--bpc-dur) var(--bpc-ease), background-color var(--bpc-dur) var(--bpc-ease);
		}

		:is(.bpc-swipe > .wp-block-columns > .wp-block-column, .bpc-types > *, .bpc-gallery-strip > *)::scroll-marker:target-current {
			width: 1rem;
			border-radius: 0.1875rem;
			background-color: var(--bpc-accent);
		}
	}
}

@keyframes bpc-circle-focus {
	0%,
	100% {
		scale: 0.84;
	}

	50% {
		scale: 1;
	}
}

/* ---- Newsletter --------------------------------------------------------
 * Jetpack's subscription block ships its own look. Pull it onto the system:
 * Mist border, generous height, sentence-case button, no pill.
 */

.bpc-newsletter {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.5rem;
}

.bpc-newsletter input[type="email"] {
	width: 100%;
	box-sizing: border-box;
	min-height: 3rem;
	padding: 0.75rem 1rem;
	border: var(--bpc-hairline) solid var(--bpc-input-border) !important;
	border-radius: var(--bpc-radius) !important;
	background-color: var(--bpc-card);
	color: var(--bpc-type);
	font-family: var(--bpc-font-sans);
	font-size: 1rem;
}

.bpc-newsletter button[type="submit"] {
	min-height: 3rem;
	border: var(--bpc-hairline) solid var(--bpc-btn-edge) !important;
	border-radius: var(--bpc-radius-button) !important;
	background-color: var(--bpc-btn-fill) !important;
	color: var(--bpc-btn-type) !important;
	font-family: var(--bpc-font-sans);
	font-size: 0.875rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	font-weight: 600;
	text-transform: none;
	transition: background-color var(--bpc-dur) var(--bpc-ease);
}

.bpc-newsletter button[type="submit"]:hover {
	background-color: var(--bpc-btn-fill-hover) !important;
}

/* ---- Coming Soon --------------------------------------------------------
 * Brooklyn's holding page. Self-hosted, this is the whole response rather
 * than an overlay, so there is nothing underneath to hide.
 *
 * Still two locks. The PHP gate decides whether the document is sent at all;
 * this keeps .bpc-soon hidden unless the document said it was the holding
 * page, because the failure mode of one lock is a holding page appearing over
 * a live site.
 */

.bpc-soon {
	display: none;
}

.bpc-coming-soon .bpc-soon {
	position: fixed;
	inset: 0;
	z-index: 2147483000;
	display: grid;
	place-items: center;
	padding: var(--wp--preset--spacing--50, 2.5rem);
	background-color: var(--bpc-field);
	color: var(--bpc-type);
	overflow-y: auto;
}

.bpc-soon__inner {
	width: 100%;
	max-width: 52rem;
}

/* The bridge lockup, at the same sizes as the header: 56px on a phone, 72 above. */
.bpc-soon__wordmark {
	--bpc-logo-h: 3.5rem;

	margin: 0 0 var(--wp--preset--spacing--60, 4rem);
	line-height: 0;
}

@media (min-width: 48rem) {
	.bpc-soon__wordmark {
		--bpc-logo-h: 4.5rem;
	}
}

/*
 * Sized so each sentence holds its own line at full width. The line breaks at
 * its own full stop; at 4.25rem the first sentence wrapped mid-clause and the
 * turn from "experience" to "proof" was lost.
 */
.bpc-soon__line {
	margin: 0 0 var(--wp--preset--spacing--40, 1.5rem);
	font-size: clamp(1.875rem, 4.6vw, 3.25rem);
	text-wrap: balance;
}

.bpc-soon__note {
	margin: 0 0 var(--wp--preset--spacing--30, 1rem);
	max-width: 46ch;
	font-size: 1.0625rem;
	line-height: 1.5;
}

.bpc-soon__contact {
	margin: 0;
	padding-block-start: var(--wp--preset--spacing--40, 1.5rem);
	border-block-start: var(--bpc-hairline) solid var(--bpc-rule);
	font-size: 1.0625rem;
}

.bpc-soon__contact a {
	color: var(--bpc-type);
	text-decoration: none;
	border-block-end: var(--bpc-hairline) solid var(--bpc-rule-strong);
	padding-block-end: 0.125rem;
	transition: border-color var(--bpc-dur) var(--bpc-ease);
}

.bpc-soon__contact a:hover {
	border-block-end-color: var(--bpc-type);
}

/* ---- The phone tab bar --------------------------------------------------
 * Five destinations, within a thumb's reach, in the same place on every
 * screen. Phones only: on a laptop a fixed bar across the bottom is a
 * browser's download tray, not a site.
 *
 * 28 Sep, Ollie: "The menu bar at the bottom needs changing". Of three
 * choices he took all three:
 * - Home, Catering, Book the Airstream, Street and Portal, with Book the
 *   Airstream in the middle as a round Brooklyn-orange button, lifted a little
 *   above the bar's top edge. It is the bar's one filled thing, and its
 *   name is there for a screen reader rather than printed under it: the
 *   words do not fit a fifth of a phone and the calendar says it. Street
 *   (a map pin) took Gallery's place: on a phone people want to know where
 *   the trailer is; Gallery is in the menu.
 * - A floating bar: Snow, a Mist hairline, 22px corners and one soft, small
 *   shadow, standing 12px in from the sides and 12px off the bottom edge
 *   (above the home indicator). Not glass, not blurred, not raised plastic.
 * - It slides away while you read down the page and comes back as soon as
 *   you scroll up (assets/js/app.js). Without the script, or with reduced
 *   motion, it simply stays.
 * Thin-line icons in Graphite, the current page's in Ink with a small orange
 * dot under it. A pill behind the current tab would be the one thing the
 * spec rules out by name.
 *
 * Then, the same day: "You don't need the top client portal / menu bit on
 * mobile then can have the logo only ?", and "Menu in the bottom bar". The
 * header is the logo alone, and the last tab is Menu (three lines, like the
 * rest), which opens the menu sheet (assets/js/app.js). Signed out the bar
 * is Home, Catering, Book, Street, Menu; signed in, Portal takes Street's
 * place. The bar now starts where the header's menu button stopped, below
 * 48rem, so there is no width at which neither is there.
 */

.bpc-tabs {
	display: none;
}

@media (max-width: 47.99rem) {
	/*
	 * The bar's measurements, written once.
	 *
	 * --bpc-tab-bar is the room the bar takes from the bottom of the screen,
	 * above the safe area: its own height and the gap under it. The page
	 * reserves that and --bpc-tab-lift more, so the last line of a page and
	 * the last button are never under the bar or the middle button over it.
	 * A hand-written reservation once drifted from the rendered height by a
	 * hairline; tests/e2e/portal-phone.test.mjs measures both.
	 */
	:root {
		--bpc-tab-target: 3.75rem;
		--bpc-tab-gap: 0.75rem;
		--bpc-tab-lift: 0.875rem;
		--bpc-tab-bar: calc(var(--bpc-tab-target) + var(--bpc-tab-gap));
		--bpc-tab-disc: 3.375rem;
	}

	.bpc-tabs {
		position: fixed;
		inset-inline: 0.75rem;
		inset-block-end: calc(var(--bpc-tab-gap) + env(safe-area-inset-bottom, 0px));
		z-index: 90;
		display: block;
		background-color: var(--bpc-chrome);
		border: var(--bpc-hairline) solid var(--bpc-rule);
		border-radius: 1.375rem;
		box-shadow: 0 0.375rem 1.25rem -0.5rem color-mix(in srgb, var(--bpc-shadow) 16%, transparent);
		transition:
			transform var(--bpc-dur-slow) var(--bpc-ease-out),
			opacity var(--bpc-dur) var(--bpc-ease);
	}

	/* Put away while reading down the page (app.js); never without it. */
	.bpc-tabs.is-tucked {
		transform: translateY(calc(100% + var(--bpc-tab-gap) + var(--bpc-tab-lift) + env(safe-area-inset-bottom, 0px)));
	}

	.bpc-tabs__list {
		display: grid;
		grid-auto-flow: column;
		grid-auto-columns: 1fr;
		margin: 0;
		padding: 0;
		list-style: none;
	}

	.bpc-tabs__link {
		position: relative;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		gap: 0.25rem;
		min-height: calc(var(--bpc-tab-target) - 2 * var(--bpc-hairline));
		padding-block: 0.375rem 0.625rem;
		text-decoration: none;
		color: var(--bpc-type);

		/*
		 * Depth through motion, not plastic: the tab answers the press by
		 * settling, rather than by pretending to be a raised object.
		 */
		transition: color var(--bpc-dur) var(--bpc-ease), transform var(--bpc-dur) var(--bpc-ease);
	}

	.bpc-tabs__link:active {
		transform: scale(0.94);
	}

	.bpc-tabs__icon {
		width: 1.375rem;
		height: 1.375rem;
		color: var(--bpc-type);
	}

	.bpc-tabs__label {
		font-size: 0.625rem;
		font-weight: 500;
		letter-spacing: 0.06em;
		text-transform: uppercase;
		line-height: 1;
	}

	/*
	 * Where you are: the word set bold, and a small orange dot under it. The
	 * weight carries it (21 Oct): every word on the bar is Black, and the
	 * dot alone is 2.05:1 on Light Grey.
	 */
	.bpc-tabs__link.is-current,
	.bpc-tabs__link.is-current .bpc-tabs__icon {
		color: var(--bpc-type-strong);
	}

	.bpc-tabs__link.is-current .bpc-tabs__label {
		font-weight: 700;
	}

	/* The sheet it opens is up: the Menu tab is Ink, like the page you are on. */
	.bpc-tabs__link--menu[aria-expanded="true"],
	.bpc-tabs__link--menu[aria-expanded="true"] .bpc-tabs__icon {
		color: var(--bpc-type-strong);
	}

	.bpc-tabs__link.is-current::after {
		content: "";
		position: absolute;
		inset-block-end: 0.25rem;
		inset-inline-start: 50%;
		width: 0.25rem;
		height: 0.25rem;
		margin-inline-start: -0.125rem;
		border-radius: 50%;
		background-color: var(--bpc-accent);
	}

	/*
	 * Book the Airstream: a round orange button in the middle, its top standing
	 * --bpc-tab-lift above the bar. A Light Grey ring round it sets it into
	 * the bar; the orange and its darker edge are the site's filled button's.
	 * The calendar on it is Black, as a button's words are (5.59:1).
	 */
	.bpc-tabs__link--primary {
		justify-content: flex-start;
		padding-block: 0;
	}

	.bpc-tabs__disc {
		display: grid;
		place-items: center;
		width: var(--bpc-tab-disc);
		height: var(--bpc-tab-disc);
		margin-block-start: calc(-1 * var(--bpc-tab-lift));
		border: var(--bpc-hairline) solid var(--bpc-btn-edge);
		border-radius: 50%;
		background-color: var(--bpc-btn-fill);
		box-shadow:
			0 0 0 0.25rem var(--bpc-chrome),
			0 0.375rem 0.875rem -0.375rem color-mix(in srgb, var(--bpc-shadow) 30%, transparent);
		transition: background-color var(--bpc-dur) var(--bpc-ease);
	}

	.bpc-tabs__disc .bpc-tabs__icon,
	.bpc-tabs__link--primary.is-current .bpc-tabs__disc .bpc-tabs__icon {
		width: 1.5rem;
		height: 1.5rem;
		color: var(--bpc-btn-type);
	}

	.bpc-tabs__link--primary:active .bpc-tabs__disc {
		background-color: var(--bpc-btn-fill-hover);
	}

	/* Named for a screen reader, not printed: the calendar says it. */
	.bpc-tabs__link--primary .bpc-tabs__label {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
	}

	.bpc-tabs__link--primary.is-current::after {
		inset-block-end: 0.3125rem;
	}

	.bpc-tabs__link:focus-visible {
		outline: var(--bpc-hairline) solid var(--bpc-rule-strong);
		outline-offset: -0.25rem;
		border-radius: 1rem;
	}

	/* So the last line of a page is not sitting underneath the bar. */
	body {
		padding-block-end: calc(var(--bpc-tab-bar) + var(--bpc-tab-lift) + env(safe-area-inset-bottom, 0px));
	}

	/*
	 * And whatever is scrolled to, a keyboard's focus or a field the
	 * browser brings into view, stops above the bar, never under it (WCAG
	 * 2.4.11). Without JavaScript the bar never tucks away, and on the
	 * agreement the "I agree" box could land behind it once its card was
	 * tighter (21 Oct). The cookie note's own room, when it is shown,
	 * takes this one's place.
	 */
	html {
		scroll-padding-block-end: calc(var(--bpc-tab-bar) + var(--bpc-tab-lift) + env(safe-area-inset-bottom, 0px));
	}

}

@media (max-width: 47.99rem) and (prefers-reduced-motion: reduce) {
	.bpc-tabs,
	.bpc-tabs__disc {
		transition: none;
	}

	/* Nothing travels: the bar simply stays. */
	.bpc-tabs.is-tucked {
		transform: none;
	}
}

/* ---- Motion -------------------------------------------------------------
 * Ollie, 26 Sep: "animations / transitions / click hover etc etc stuff ui".
 * One vocabulary, used everywhere, so the site moves like one thing:
 *
 * - Arriving: things fade in and rise a little (1rem), on --bpc-ease-out —
 *   quick, then settling — never a bounce, which the Design Master refuses.
 *   The opening line on arrival; sections as they scroll into view
 *   (assets/js/reveal.js); the entries of a menu as it opens, one after
 *   another, 40ms apart.
 * - Pointing: a button lifts a pixel and its shadow opens; a link in a
 *   sentence brings its underline in closer and darker; a field's edge goes
 *   to Ink with a soft Petal Light ring when it is being typed in.
 * - Pressing: everything that can be pressed settles 1px, at once. A
 *   button does more (27 Sep): a warm glow opens from where it was pressed,
 *   it gives a little, and its arrow darts on (assets/js/press.js).
 *
 * With reduced motion none of it moves: nothing is hidden, nothing rises,
 * and what changes, changes at once. Without JavaScript nothing is hidden.
 */

/* Arriving: the opening line and what follows it, one after another. */
@media (prefers-reduced-motion: no-preference) {
	.bpc-hero > .wp-block-group > * {
		animation: bpc-arrive var(--bpc-dur-reveal) var(--bpc-ease-out) both;
	}

	.bpc-hero > .wp-block-group > :nth-child(2) { animation-delay: 80ms; }
	.bpc-hero > .wp-block-group > :nth-child(3) { animation-delay: 160ms; }
	.bpc-hero > .wp-block-group > :nth-child(n + 4) { animation-delay: 240ms; }

	/* The photograph under it settles, a little larger to its own size. */
	.bpc-hero__photo img {
		animation: bpc-settle 1200ms var(--bpc-ease-out) both;
	}

	/*
	 * Sections as they scroll in. reveal.js marks what is below the fold
	 * `bpc-reveal` and sets its place in a row as --bpc-reveal-delay; what
	 * is already on screen is never hidden, so nothing blinks out on load.
	 */
	/* Hidden at once, below the fold; only the arrival is animated. */
	.bpc-reveal:not(.is-revealed) {
		opacity: 0;
		transform: translateY(1rem);
	}

	.bpc-reveal.is-revealed {
		transition:
			opacity var(--bpc-dur-reveal) var(--bpc-ease-out) var(--bpc-reveal-delay, 0ms),
			transform var(--bpc-dur-reveal) var(--bpc-ease-out) var(--bpc-reveal-delay, 0ms);
	}

	/* The four in Catering's card, one after another as it opens. */
	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .bpc-mega > .wp-block-navigation__submenu-container > li {
		opacity: 0;
		transform: translateY(0.5rem);
		transition: opacity var(--bpc-dur) var(--bpc-ease-out) var(--bpc-stagger, 0ms), transform var(--bpc-dur) var(--bpc-ease-out) var(--bpc-stagger, 0ms);
	}

	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .bpc-mega:is(:hover, :focus-within):not(.is-dismissed) > .wp-block-navigation__submenu-container > li,
	.bpc-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .bpc-mega > .wp-block-navigation-submenu__toggle[aria-expanded="true"] ~ .wp-block-navigation__submenu-container > li {
		opacity: 1;
		transform: none;
	}

	.bpc-mega > .wp-block-navigation__submenu-container > li:nth-child(2) { --bpc-stagger: 40ms; }
	.bpc-mega > .wp-block-navigation__submenu-container > li:nth-child(3) { --bpc-stagger: 80ms; }
	.bpc-mega > .wp-block-navigation__submenu-container > li:nth-child(4) { --bpc-stagger: 120ms; }

	/* The portal card's entries, the same way. */
	.bpc-account[open] .bpc-account__menu > li {
		animation: bpc-arrive var(--bpc-dur) var(--bpc-ease-out) both;
	}

	.bpc-account[open] .bpc-account__menu > li:nth-child(2) { animation-delay: 40ms; }
	.bpc-account[open] .bpc-account__menu > li:nth-child(3) { animation-delay: 80ms; }
	.bpc-account[open] .bpc-account__menu > li:nth-child(4) { animation-delay: 120ms; }
	.bpc-account[open] .bpc-account__menu > li:nth-child(n + 5) { animation-delay: 160ms; }
}

@keyframes bpc-settle {
	from {
		transform: scale(1.04);
	}
}

@keyframes bpc-arrive {
	from {
		opacity: 0;
		transform: translateY(1rem);
	}
}

/*
 * The arrow on a button that takes you somewhere: every button in a page's
 * content, and the enquiry form's. The portal's own buttons (Pay, Sign,
 * Back to your portal) go without, since some of them go back.
 */
.wp-block-button:not(.bpc-btn-link) > .wp-block-button__link::after,
.bpc-enquiry__submit::after {
	content: "\2002\2192" / "";
	display: inline-block;
	letter-spacing: 0;
	transition: transform var(--bpc-dur) var(--bpc-ease);
}

@media (hover: hover) {
	.wp-block-button:not(.bpc-btn-link) > .wp-block-button__link:hover::after,
	.bpc-enquiry__submit:hover::after {
		transform: translateX(0.25rem);
	}
}

/*
 * The sheen: a hairline of light along the top of every filled button and a
 * warm shadow under it, so the orange reads as a thing you can press rather
 * than a painted label.
 */
.bpc-btn:not(.bpc-btn--secondary),
.wp-block-button:not(.bpc-btn-link):not(.bpc-btn-outline) > .wp-block-button__link,
.bpc-footer__cta p:last-child > a:only-child,
.bpc-newsletter button[type="submit"] {
	box-shadow:
		inset 0 1px 0 color-mix(in srgb, var(--bpc-sheen) 32%, transparent),
		0 0.6rem 1.2rem -0.75rem color-mix(in srgb, var(--bpc-accent) 70%, var(--bpc-shadow));
}

/*
 * Pressed (Ollie, 27 Sep: "When CTA buttons are clicked let's have a
 * animation / effect"). assets/js/press.js puts `.is-pressed` on the button
 * with the point it was pressed at, and three things happen at once, over
 * about half a second:
 *
 * - the glow: a warm light opens out from under the finger across the
 *   button, the way heat comes off the oven door, and fades. It is the
 *   button's own ::before, clipped to its shape, under its words;
 * - the give: the button settles to 97% and comes straight back, with no
 *   overshoot, since the Design Master refuses bounce;
 * - the arrow, on a button that has one, darts on and comes back.
 *
 * On an orange button the light is Snow, faint and soft-edged; on an
 * outlined one, which has no fill for Snow to show on, it is the orange
 * itself, fainter still. A button written as a link ("See our catering →")
 * has no glow: its arrow darts, and that is all. With reduced motion none of
 * it happens.
 */
.bpc-btn,
.wp-block-button__link,
.bpc-footer__cta p:last-child > a:only-child,
.bpc-newsletter button[type="submit"] {
	--bpc-press-glow: color-mix(in srgb, var(--bpc-sheen) 42%, transparent);
	position: relative;
	isolation: isolate;
	-webkit-tap-highlight-color: transparent;
}

.bpc-btn--secondary,
.wp-block-button.bpc-btn-outline > .wp-block-button__link {
	--bpc-press-glow: color-mix(in srgb, var(--bpc-accent) 22%, transparent);
}

.wp-block-button.bpc-btn-link > .wp-block-button__link {
	--bpc-press-glow: transparent;
}

@media (prefers-reduced-motion: no-preference) {
	.is-pressed::before {
		content: "";
		position: absolute;
		inset: 0;
		z-index: -1;
		border-radius: inherit;
		background: radial-gradient(
			circle calc(var(--bpc-press-size, 200%) * 0.4) at var(--bpc-press-x, 50%) var(--bpc-press-y, 50%),
			var(--bpc-press-glow) 0,
			color-mix(in srgb, var(--bpc-press-glow) 45%, transparent) 45%,
			transparent 100%
		);
		pointer-events: none;
		animation: bpc-press-glow 560ms var(--bpc-ease-out) both;
	}

	.is-pressed {
		animation: bpc-press-give 360ms var(--bpc-ease-out);
	}

	.is-pressed::after {
		animation: bpc-press-dart 420ms var(--bpc-ease-out);
	}
}

@keyframes bpc-press-glow {
	from {
		clip-path: circle(0 at var(--bpc-press-x, 50%) var(--bpc-press-y, 50%));
		opacity: 1;
	}

	55% {
		opacity: 1;
	}

	to {
		clip-path: circle(calc(var(--bpc-press-size, 200%) / 2) at var(--bpc-press-x, 50%) var(--bpc-press-y, 50%));
		opacity: 0;
	}
}

@keyframes bpc-press-give {
	30% {
		scale: 0.97;
	}
}

@keyframes bpc-press-dart {
	40% {
		translate: 0.4rem 0;
	}
}

/*
 * Until 20 Oct Brooklyn orange marked the arrows that lead somewhere, the
 * date street trading starts and the full stop that ends a display heading.
 * Each is a word or a glyph, and orange is never a text colour now (Ollie,
 * 20 Oct), so they take the type colour; the orange is in the rules, the
 * strokes and the buttons.
 */
.bpc-street__when,
.bpc-stop {
	color: var(--bpc-type) !important;
}

/* The small marks beside words, likewise. */
.wp-block-button.bpc-btn-link .wp-block-button__link::after,
.bpc-more a::after,
.bpc-type__name a::after,
.bpc-dot {
	color: var(--bpc-type) !important;
}

/*
 * The small details (Ollie, 26 Sep: "Small details like that I want"):
 * - the page you are on is underlined in the menu, 2px, and marked on the
 *   phone's tab bar by its bold word and an orange dot;
 * - each home section's hairline starts with a short orange stroke;
 * - text you select is picked out in the light orange.
 * The underline under the page you are on is Black since 21 Oct: a mark
 * that says where you are has to read, and orange on the Light Grey bar is
 * 2.05:1 (Black is 11.47:1). Orange stays the hairline that draws in under
 * the pointer.
 */
.bpc-nav .current-menu-item > .wp-block-navigation-item__content::after,
.bpc-nav__link[aria-current="page"]::after {
	height: 2px;
	background-color: var(--bpc-rule-strong);
}

/*
 * The orange stroke, throughout (Ollie, 26 Sep: "small detail like this needs
 * to be implemented throughout the website"). Every fine line that opens
 * something starts with a short orange stroke: a section (2.5rem), an item
 * in a row of them (1.25rem), a separator, the facts strip, the closing card
 * and the footer. The stroke sits on the line, 2px over its 1px.
 */

:is(.bpc-ed, .bpc-street, .bpc-about, .bpc-offer, .bpc-closing, .bpc-footer, .bpc-rule, .bpc-featured-on),
.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display) {
	position: relative;
}


:is(.bpc-ed, .bpc-street, .bpc-about, .bpc-offer, .bpc-closing, .bpc-footer, .bpc-rule, .bpc-featured-on)::before,
.wp-block-group.alignwide:is(.has-light-grey-background-color, .has-petal-light-background-color):has(> .wp-block-columns > .wp-block-column > .bpc-display)::before {
	content: "";
	position: absolute;
	inset-block-start: -1px;
	inset-inline-start: 0;
	width: 2.5rem;
	height: 2px;
	background-color: var(--bpc-accent);
	pointer-events: none;
}

/* Items in a row, and the separators inside a section: a shorter stroke. */
:is(.bpc-offer, .bpc-rule)::before {
	width: 1.25rem;
}

/* A separator is the line itself, so its stroke sits on it, not above it. */
.bpc-rule::before {
	inset-block-start: 0;
	height: 100%;
	min-height: 2px;
}

/* The closing card's stroke runs along its top edge from the corner. */
.bpc-closing::before {
	inset-inline-start: -1px;
}

/* The footer starts on the page's edge, so its stroke starts where the text does. */
.bpc-footer::before {
	inset-inline-start: var(--wp--style--root--padding-left, 1.5rem);
}

/*
 * A page's title ends in a full stop, the same as a display heading:
 * "Weddings." It is drawn, not typed, so the title itself, and what a screen
 * reader or a search result reads, stays as it is. Black since 20 Oct; it
 * was orange.
 */
main > h1.wp-block-post-title::after {
	content: "." / "";
	color: var(--bpc-type);
}

/* A list's bullets and numbers, and a ticked box. */
:is(main, .bpc-portal) :is(ul, ol) > li::marker {
	color: var(--bpc-type);
}

input[type="checkbox"],
input[type="radio"] {
	accent-color: var(--bpc-accent);
}

::selection {
	background-color: var(--bpc-btn-fill-hover);
	color: var(--bpc-type-strong);
}

/*
 * Pointing: a filled button lifts a pixel and its shadow opens under it. A
 * secondary or outlined one only changes its edge, to the type colour: no
 * lift, no shadow (6 Oct). Pressed, every one settles 1px.
 */
.bpc-btn,
.wp-block-button__link {
	transition: background-color var(--bpc-dur) var(--bpc-ease), border-color var(--bpc-dur) var(--bpc-ease), color var(--bpc-dur) var(--bpc-ease), box-shadow var(--bpc-dur) var(--bpc-ease), opacity var(--bpc-dur-quick) var(--bpc-ease), transform var(--bpc-dur) var(--bpc-ease);
}

@media (hover: hover) {
	.bpc-btn:hover,
	.wp-block-button__link:hover {
		box-shadow:
			inset 0 1px 0 color-mix(in srgb, var(--bpc-sheen) 32%, transparent),
			0 0.75rem 1.4rem -0.75rem color-mix(in srgb, var(--bpc-accent) 70%, var(--bpc-shadow));
		transform: translateY(-1px);
	}

	/* :not(:active), so the 1px settle below still applies under the pointer. */
	.bpc-btn--secondary:hover:not(:active),
	.wp-block-button.bpc-btn-outline > .wp-block-button__link:hover:not(:active) {
		transform: none;
		box-shadow: none;
	}
}

/* Pressing: it settles, at once. */
.bpc-btn:active,
.wp-block-button__link:active {
	box-shadow: none;
	transform: translateY(1px);
	transition-duration: 60ms;
}

/**
 * Busy, after the pointing and pressing above so it wins over both.
 * Loading: "still button, short wait, no spinner circus."
 * The one busy rule, for every surface (6 Oct): the button holds its size
 * (the script freezes its width as its words change to "Saving…"), dims to
 * 75% and stops responding. It never lifts, never presses, and is never
 * `disabled`, which would drop its name and value from the post. No
 * spinner, no skeleton, no animation beyond the dim.
 */
.bpc-btn[aria-busy="true"] {
	opacity: 0.75;
	pointer-events: none;
	cursor: progress;
	transform: none;
	box-shadow: none;
	scale: none;
	animation: none;
}

/*
 * A press that turned into a post: the give, glow and dart stop the moment
 * the button is busy, so it holds its size while its words change (6 Oct).
 */
.bpc-btn[aria-busy="true"]::before,
.bpc-btn[aria-busy="true"]::after {
	animation: none;
}

/* A link in a sentence: the underline comes in closer and darker. */
:where(main, .bpc-footer) :where(p, li) > a:not([class], :has(svg)) {
	text-decoration-line: underline;
	text-decoration-thickness: var(--bpc-hairline);
	text-decoration-color: var(--bpc-rule-strong);
	text-underline-offset: 0.3em;
	transition: text-decoration-color var(--bpc-dur) var(--bpc-ease), text-underline-offset var(--bpc-dur) var(--bpc-ease), color var(--bpc-dur) var(--bpc-ease);
}

:where(main, .bpc-footer) :where(p, li) > a:not([class], :has(svg)):hover {
	color: var(--bpc-type-strong);
	text-decoration-color: var(--bpc-accent);
	text-underline-offset: 0.18em;
}

/* A field being typed in: a Black edge and the house ring round it (21 Oct: the soft orange glow measured under 2:1). */
.bpc-input,
.bpc-textarea,
.bpc-select {
	transition: border-color var(--bpc-dur) var(--bpc-ease), box-shadow var(--bpc-dur) var(--bpc-ease);
}

.bpc-input:focus,
.bpc-textarea:focus,
.bpc-select:focus {
	border-color: var(--bpc-type);
	box-shadow: none;
	outline: var(--bpc-hairline) solid var(--bpc-rule-strong);
	outline-offset: 2px;
}

/* The logo answers the pointer too, quietly. */
.bpc-logo {
	transition: opacity var(--bpc-dur) var(--bpc-ease);
}

.bpc-logo:hover {
	opacity: 0.75;
}

@media (prefers-reduced-motion: reduce) {
	.bpc-btn,
	.wp-block-button__link,
	:where(main, .bpc-footer) :where(p, li) > a:not([class], :has(svg)),
	.bpc-input,
	.bpc-textarea,
	.bpc-select,
	.bpc-logo {
		transition: none;
	}

	.bpc-btn:hover,
	.wp-block-button__link:hover,
	.bpc-btn:active,
	.wp-block-button__link:active {
		transform: none;
	}
}

@media print {
	.bpc-reveal {
		opacity: 1 !important;
		transform: none !important;
	}
}

/* ---- Moving between pages -----------------------------------------------
 * The app feeling that is not decoration: pages replace each other rather
 * than blinking white. Cross-document view transitions, so it costs no
 * JavaScript and browsers without them simply navigate as they always did.
 */

@view-transition {
	navigation: auto;
}

/*
 * The snapshot overlay never takes a click: a tap in the first moments
 * after a page change reaches the live new page underneath (6 Oct).
 */
::view-transition {
	pointer-events: none;
}

/* The old page steps back quickly; the new one fades in and rises a little. */
::view-transition-old(root) {
	animation: var(--bpc-dur-quick) var(--bpc-ease) both bpc-page-out;
}

::view-transition-new(root) {
	animation: var(--bpc-dur-slow) var(--bpc-ease-out) 60ms both bpc-page-in;
}

@keyframes bpc-page-out {
	to {
		opacity: 0;
	}
}

@keyframes bpc-page-in {
	from {
		opacity: 0;
		transform: translateY(0.5rem);
	}
}

/*
 * The furniture stays put while the content changes underneath it, which is
 * what makes it read as one app rather than as a series of page loads.
 */
.bpc-tabs {
	view-transition-name: bpc-tabs;
}

.bpc-header {
	view-transition-name: bpc-header;
}

/*
 * A phone knows which way it is going (28 Sep, "Looks like an app"): going
 * deeper, the new page pushes in from the right; going back (the back step
 * or the browser's back), from the left; a tab cross-fades, as tabs do. The
 * way is set by assets/js/direction.js as the new page is revealed. The
 * header and the tab bar stay put, as above.
 */
@media (max-width: 47.99rem) and (prefers-reduced-motion: no-preference) {
	::view-transition-old(root) {
		animation: 220ms var(--bpc-ease) both bpc-push-out;
	}

	::view-transition-new(root) {
		animation: 380ms var(--bpc-ease-out) both bpc-push-in;
	}

	html:active-view-transition-type(back)::view-transition-old(root) {
		animation-name: bpc-pop-out;
	}

	html:active-view-transition-type(back)::view-transition-new(root) {
		animation-name: bpc-pop-in;
	}

	html:active-view-transition-type(tab)::view-transition-old(root) {
		animation: var(--bpc-dur-quick) var(--bpc-ease) both bpc-page-out;
	}

	html:active-view-transition-type(tab)::view-transition-new(root) {
		animation: 280ms var(--bpc-ease-out) 40ms both bpc-fade-in;
	}
}

@keyframes bpc-push-in {
	from {
		opacity: 0;
		transform: translateX(3rem);
	}
}

@keyframes bpc-push-out {
	to {
		opacity: 0;
		transform: translateX(-1.5rem);
	}
}

@keyframes bpc-pop-in {
	from {
		opacity: 0;
		transform: translateX(-3rem);
	}
}

@keyframes bpc-pop-out {
	to {
		opacity: 0;
		transform: translateX(1.5rem);
	}
}

@keyframes bpc-fade-in {
	from {
		opacity: 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	@view-transition {
		navigation: none;
	}

	.bpc-tabs__link {
		transition: none;
	}

	.bpc-tabs__link:active {
		transform: none;
	}
}

/* ---- Arriving, and saying what changed (6 Oct, the motion pass) ----------
 * Motion only says what just changed. assets/js/direction.js marks how a
 * page arrived, as it is revealed:
 *
 * - warm (html.bpc-warm): by a view transition going back (the breadcrumb, a
 *   link up, or the browser's Back). The home page's opening has already
 *   arrived once, so it does not again. A visit forward still plays it;
 * - cold (html.bpc-cold): with no view transition, fresh rather than
 *   reloaded or stepped to through history: the return from Stripe, a link
 *   in an email, a new tab. A portal page fades in once. Opacity only: a
 *   rise would move money, contract words, status pills, Next up and the
 *   menu's lock sentence. A page that is the success itself does not fade:
 *   its full stop settles alone. The confirm page has none either: it is
 *   pressed at once (guard.js).
 */
html.bpc-warm .bpc-hero > .wp-block-group > * {
	animation: none;
}

@media (prefers-reduced-motion: no-preference) {
	html.bpc-cold :is(.bpc-portal, .bpc-portal-pay, .bpc-agreement, .bpc-enquiry__done.bpc-pencil, .bpc-enquiry__done.bpc-more, .bpc-flow__form.bpc-more, .bpc-menu, .bpc-venue, .bpc-login):not(.bpc-success, :has(.bpc-success)) {
		animation: bpc-fade-in var(--bpc-dur-slow) var(--bpc-ease-out) backwards;
	}

	/*
	 * A line whose words were just set (a status, an error) rises 4px into
	 * place. BPC.news() (flow.js) plays it again each time the words are
	 * set, even to the same words. Never a shake.
	 */
	.bpc-news {
		animation: bpc-news var(--bpc-dur) var(--bpc-ease-out) backwards;
	}

	.bpc-error:not(:empty):not([hidden]) {
		animation: bpc-news var(--bpc-dur) var(--bpc-ease-out) backwards;
	}
}

@keyframes bpc-news {
	from {
		opacity: 0;
		transform: translateY(var(--bpc-rise));
	}
}

/*
 * Success is one quiet mark. On the page that is the success itself
 * (.bpc-success: signed and sealed, the thanks back from Stripe, pencilled
 * in, the thanks for telling us more, the enquiry in the oven) the orange
 * full stop settles into place, once. It stays inline, so a heading never
 * wraps leaving the stop alone on a line, and drops by its own relative
 * offset: one glyph, once. A reload, Back or a restore of that page
 * (direction.js: html.bpc-again) shows the stop already in place.
 */
@media (prefers-reduced-motion: no-preference) {
	html:not(.bpc-again) .bpc-success .bpc-stop {
		position: relative;
		animation: bpc-stop-settle var(--bpc-dur-slow) var(--bpc-ease-out) var(--bpc-dur) backwards;
	}
}

@keyframes bpc-stop-settle {
	from {
		opacity: 0;
		top: -0.35em;
	}
}

/*
 * Or, when a payment lands later while the pay page is open, a tick that
 * draws on once, before the words (portal-pay view.js). Never at render,
 * never with the full stop. The amount never moves.
 */
.bpc-done-tick {
	width: 1em;
	height: 1em;
	margin-inline-end: 0.375em;
	vertical-align: -0.125em;
	fill: none;
	stroke: var(--bpc-status-paid);
	stroke-width: 1.5;
	stroke-linecap: round;
	stroke-linejoin: round;
	stroke-dasharray: 1;
}

@media (prefers-reduced-motion: no-preference) {
	.bpc-done-tick path {
		animation: bpc-tick-draw var(--bpc-dur-slow) var(--bpc-ease-out) 80ms backwards;
	}
}

@keyframes bpc-tick-draw {
	from {
		stroke-dashoffset: 1;
	}
}

/* ---- Skeletons ----------------------------------------------------------
 * Ollie, 26 Sep: "Implement Skeleton loaders". A photograph that has not
 * arrived yet holds its place as a soft grey shape, the frame it will fill
 * (the hero's rectangle, the catering circles), with a slow band of light
 * passing across it. When it lands it fades in over the shape. skeleton.js
 * adds `bpc-skeleton` only to photographs still on their way, and takes it
 * off when they load or fail.
 *
 * With reduced motion the shape stays and the sheen and fade do not move.
 * Buttons keep their own still loading state (above): no skeleton there.
 */
.bpc-skeleton {
	background-color: var(--bpc-pill-fill);
	background-image: linear-gradient(
		100deg,
		transparent 30%,
		color-mix(in srgb, var(--bpc-sheen) 55%, transparent) 50%,
		transparent 70%
	);
	background-size: 250% 100%;
	background-repeat: no-repeat;
	background-position: 100% 0;
}

/* Gone at once while it waits; only the arrival fades. */
.wp-block-image.bpc-skeleton img {
	opacity: 0;
	transition: none;
}

/* Low priority, so a photograph's own transition (the catering zoom) keeps it. */
:where(.wp-block-image) img {
	transition: opacity var(--bpc-dur-reveal) var(--bpc-ease-out);
}

@media (prefers-reduced-motion: no-preference) {
	.bpc-skeleton {
		animation: bpc-sheen 1.6s ease-in-out infinite;
	}
}

@media (prefers-reduced-motion: reduce) {
	:where(.wp-block-image) img {
		transition: none;
	}
}

@keyframes bpc-sheen {
	from {
		background-position: 100% 0;
	}

	to {
		background-position: 0 0;
	}
}

/* ---- The sign-in and Register (plan R1; the redesign's spec §2.11) -----------
 * In the portal's own header (the logo, "Your portal" and the Beta tag; no
 * menu, no Account) on the portal's light page: one White card with its
 * fine Light Grey edge. "Your portal." in the screen title's italic; Email,
 * a label over a plain box; the pill Email me a link; "or"; the outline
 * pill Sign in with a passkey (and Continue with Google, when it is set
 * up); then, under a hairline across the card, two rows standing alone,
 * Create an account and Book the Airstream. Register is the same with
 * First name, Surname and Email, and Sign in for the first row. From an iPad the
 * card is 440px, centred. Under it, Privacy and Terms (parts/footer-portal).
 */

body.bpc-field-portal .bpc-screen.bpc-signin-page {
	padding-block: 1.75rem 1.5rem;
}

@media (min-width: 48rem) {
	body.bpc-field-portal .bpc-screen.bpc-signin-page {
		padding-block: 2.5rem 2rem;
	}
}

/*
 * A page of words — the questions, the team, the policies — has them on one
 * Light Grey card under its title (20 Oct: body text is never on Pearl
 * Grey). A page whose title is set straight in main and whose content
 * holds words of its own, or a catering page still saved as words (a page
 * from before the catering patterns, with its own heading and paragraphs);
 * the catering pages as built and the portal carry cards of their own.
 */
main:has(> h1.wp-block-post-title) > .wp-block-post-content:has(> :is(p, h2, h3, h4, ul, ol, .wp-block-details, .wp-block-table, blockquote)),
.bpc-catering-page > .wp-block-post-content:has(> h1, > p:not([class*="bpc-"])) {
	padding: 1.25rem 1rem;
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-card);
}

@media (min-width: 48rem) {
	main:has(> h1.wp-block-post-title) > .wp-block-post-content:has(> :is(p, h2, h3, h4, ul, ol, .wp-block-details, .wp-block-table, blockquote)),
	.bpc-catering-page > .wp-block-post-content:has(> h1, > p:not([class*="bpc-"])) {
		padding: 2rem 2.5rem;
	}
}

body.bpc-field-portal .bpc-signin-page > .bpc-signin {
	display: block;
	max-width: none;
	margin: 0;
	padding: 1.375rem 1rem 0.375rem;
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-card);
}

@media (min-width: 48rem) {
	body.bpc-field-portal .bpc-signin-page > .bpc-signin {
		max-width: 27.5rem;
		margin-inline: auto;
		padding: 1.875rem 1.75rem 0.5rem;
	}
}

body.bpc-field-portal .bpc-signin > .bpc-flow {
	padding: 0;
	border: 0;
	border-radius: 0;
	background-color: transparent;
}

/* Once the link is on its way, the rows for someone new have nothing to offer: they go. */
.bpc-signin:has(.bpc-login__sent:not([hidden])) > .bpc-signin__new {
	display: none;
}

/* For someone new, under a hairline across the card: two rows, standing alone. */
body.bpc-field-portal .bpc-signin__new {
	margin: 1.125rem -1rem 0;
	padding-block-start: 0.25rem;
	border-block-start: var(--bpc-hairline) solid var(--bpc-rule);
}

@media (min-width: 48rem) {
	body.bpc-field-portal .bpc-signin__new {
		margin-inline: -1.75rem;
	}
}

body.bpc-field-portal .bpc-signin__new > * {
	margin: 0;
}

@media (min-width: 48rem) {
	body.bpc-field-portal .bpc-signin__new .bpc-row {
		padding-inline-start: 1.75rem;
	}

	body.bpc-field-portal .bpc-signin__new .bpc-rowlist > li + li::before {
		inset-inline-start: 1.75rem;
	}
}

/* ---- The home page under the hero: one run, from an iPad up (21 Oct) -------
 * The sections under the photograph (Street trading, Our catering, Fired
 * fresh, As featured on) were each their own Light Grey card on 20 Oct,
 * with Pearl Grey gaps between: boxes, where Ollie asked for "fine
 * hairlines between" sections and "hairlines not boxes" for As featured
 * on. So they join into one Light Grey run under the hero, edge to edge
 * across the page's column, a hairline with the orange stroke between one
 * and the next, the run's outer corners the only ones. The occasions in Our
 * catering sit straight on it. A phone keeps its app cards (28 Sep).
 */
@media (min-width: 48rem) {
	main > :is(.bpc-street, .bpc-catering, .bpc-about, .bpc-testimonials, .bpc-featured-on) {
		margin-block-start: 0 !important;
		padding: var(--wp--preset--spacing--40, 1.5rem) !important;
		border-radius: 0;
		border-block-start: var(--bpc-hairline) solid var(--bpc-rule-strong);
		background-color: var(--bpc-card);
	}

	/* The run starts under the hero, its top corners the sheet's. */
	main > .bpc-hero + :is(.bpc-street, .bpc-catering, .bpc-about, .bpc-testimonials, .bpc-featured-on) {
		margin-block-start: var(--wp--preset--spacing--30, 1rem) !important;
		border-block-start: 0;
		border-start-start-radius: var(--bpc-radius);
		border-start-end-radius: var(--bpc-radius);
	}

	main > .bpc-hero + :is(.bpc-street, .bpc-catering, .bpc-about, .bpc-testimonials, .bpc-featured-on)::before {
		display: none;
	}

	main > :is(.bpc-street, .bpc-catering, .bpc-about, .bpc-testimonials, .bpc-featured-on):last-child {
		border-end-start-radius: var(--bpc-radius);
		border-end-end-radius: var(--bpc-radius);
	}

	/* The occasions stand on the run, not on cards of their own. */
	main > .bpc-catering .bpc-type {
		padding: 0;
		border-radius: 0;
		background-color: transparent;
	}
}

/* ==========================================================================
 * The portal, redesigned (plan R1; Ollie's picks of 21 Oct)
 *
 * "The portal dosent look moderns ellegent", "I don't like the scroll long
 * design at all", "It seems dark also not very high end premium like our
 * brand is"; he picked "White cards, thin line", "Their day + one next
 * step", "No photos, clean type only", then, of the bottom tabs drawn for
 * him, "Menu at the top instead"; and that evening, "Cta more rounded I do
 * not want or like square !!!". So, in the portal's scope only
 * (body.bpc-field-portal: every portal screen, the sign-in and Register):
 *
 * - the header is the logo row (the logo, "Your portal" with the Beta tag,
 *   Account) and, under it, the menu at the top, which stays in view as
 *   the page moves: the logo row slides away and the menu row sticks;
 * - the header and every screen share one column, centred together: the
 *   screen on a phone, 640px from an iPad, 880px from 1100px;
 * - every button and call to action is a full pill in sentence case; the
 *   one orange pill per view, outline pills for the rest; pressed, it dims;
 * - cards and panels keep one small soft radius, 6px, and a fine Light
 *   Grey edge; no shadows, gradients, photos or slabs;
 * - the shared pieces every screen is built from: a row (a name, its
 *   state, a chevron), a statement row, a detail list, the round selector
 *   (never a square tick box), the switch, the back link, the map's frame,
 *   the screen's title and a section's;
 * - nothing in capitals but the logo; every word Premium Black.
 *
 * The site outside the portal is unchanged by anything here.
 * ========================================================================== */

/* ---- The page: no tab bar, and nothing scrolled to under the menu -------- */

@media (max-width: 47.99rem) {
	body.bpc-field-portal {
		padding-block-end: 0;
	}

	html:has(> body.bpc-field-portal) {
		scroll-padding-block-end: 0;
	}
}

/* Focus, a key press, an anchor: never under the sticky menu (WCAG 2.4.11). */
html:has(> body.bpc-field-portal .bpc-pmenu) {
	scroll-padding-block-start: 3.5625rem; /* the menu row, 44px, and 13px */
}

@media (min-width: 48rem) {
	html:has(> body.bpc-field-portal .bpc-pmenu) {
		scroll-padding-block-start: 3.8125rem; /* 48px and 13px */
	}
}

/*
 * Figures are lining and proportional across the portal (spec §3.3):
 * Newsreader's default figures are tabular, so a date or an amount in the
 * display serif opened gaps ("202 7", R1 review). Tabular figures stay only
 * where figures line up, each set by its own rule (.bpc-num, the payments'
 * columns), and the boxes of a form keep theirs.
 */
body.bpc-field-portal {
	min-height: 100svh;
	font-variant-numeric: lining-nums proportional-nums;
}

body.bpc-field-portal .bpc-portal-shell > * {
	margin-block: 0;
}

/* The column every screen stands in, under the header's. */
body.bpc-field-portal .bpc-screen {
	box-sizing: border-box;
	width: 100%;
	max-width: calc(var(--bpc-p-col) + 2 * var(--bpc-p-gutter));
	margin: 0 auto;
	padding: 1.375rem max(var(--bpc-p-gutter), env(safe-area-inset-right, 0px)) 2rem max(var(--bpc-p-gutter), env(safe-area-inset-left, 0px));
}

body.bpc-field-portal .bpc-screen > .wp-block-post-content > * {
	margin-block: 0;
}

/*
 * Every screen's block fills the column the header stands in, so the
 * right edge holds from tab to tab (R1 review: at 1280 the header and Home
 * ran 880px while Account was 640 and the rest 608, each on the left). The
 * column caps the width; a paragraph inside keeps its own reading measure.
 */
body.bpc-field-portal .bpc-screen :is(.bpc-portal-pay, .bpc-pay-docs, .bpc-account-screen, .bpc-dayplan-page, .bpc-menu, .bpc-agreement, .bpc-venue, .bpc-tasting) {
	max-width: none;
}

@media (min-width: 48rem) {
	body.bpc-field-portal .bpc-screen {
		padding-block: 2.5rem 3.5rem;
	}
}

@media (min-width: 68.75rem) {
	body.bpc-field-portal .bpc-screen {
		padding-block-start: 3rem;
	}
}

/* ---- The portal's header ----------------------------------------------- */

/*
 * Sticky with no script: the template part's own wrapper sticks, at minus
 * the logo row's height, so as the page moves the logo row slides away and
 * the menu row stays at the top. The sign-in and Register have no menu, and
 * their header simply scrolls.
 */
body.bpc-field-portal .bpc-portal-shell > .wp-block-template-part:has(> .bpc-ptop .bpc-pmenu) {
	position: sticky;
	top: calc(-1 * var(--bpc-p-brand-h));
	z-index: 100;
}

body.bpc-field-portal .bpc-ptop {
	margin: 0;
	padding: env(safe-area-inset-top, 0px) 0 0;
	border-block-end: var(--bpc-hairline) solid var(--bpc-chrome-rule);
	background-color: var(--bpc-chrome);
}

body.bpc-field-portal .bpc-ptop > * {
	margin-block: 0;
}

body.bpc-field-portal .bpc-ptop__bar,
body.bpc-field-portal .bpc-pmenu {
	box-sizing: border-box;
	width: 100%;
	max-width: calc(var(--bpc-p-col) + 2 * var(--bpc-p-gutter));
	margin-inline: auto;
	padding-inline: max(var(--bpc-p-gutter), env(safe-area-inset-left, 0px)) max(var(--bpc-p-gutter), env(safe-area-inset-right, 0px));
}

body.bpc-field-portal .bpc-ptop__bar {
	display: flex;
	align-items: center;
	gap: 0.625rem;
	height: var(--bpc-p-brand-h);
}

/* The logo: a 44px target round a 38px lockup on a phone, 48px from an iPad. */
body.bpc-field-portal .bpc-ptop .bpc-logo {
	width: 2.75rem;
	height: 2.75rem;
	margin-inline-start: -0.1875rem;
	padding: 0.1875rem;
	border-radius: var(--bpc-radius-button);
}

@media (min-width: 48rem) {
	body.bpc-field-portal .bpc-ptop .bpc-logo {
		width: 3.25rem;
		height: 3.25rem;
		padding: 0.125rem;
	}
}

body.bpc-field-portal .bpc-ptop__session {
	display: flex;
	flex: 1 1 auto;
	align-items: center;
	min-width: 0;
	margin: 0;
}

body.bpc-field-portal .bpc-ptop__name {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	margin: 0;
	font-family: var(--bpc-font-sans);
	font-size: 0.9375rem;
	font-weight: 500;
	line-height: 1;
	white-space: nowrap;
	color: var(--bpc-type);
}

@media (min-width: 48rem) {
	body.bpc-field-portal .bpc-ptop__name {
		margin-inline-start: 0.375rem;
	}
}

/* Beta: Black words at 11/500, a 1px Black edge, 4px; never orange, never capitals (Ollie, 21 Oct). */
.bpc-beta {
	display: inline-block;
	padding: 3px 6px;
	border: 1px solid var(--bpc-type);
	border-radius: 4px;
	font-family: var(--bpc-font-sans);
	font-size: 0.6875rem;
	font-weight: 500;
	font-style: normal;
	line-height: 1;
	letter-spacing: 0.02em;
	text-transform: none;
	color: var(--bpc-type);
}

/*
 * Account, at the right: a mark, never the word (Ollie, 22 Oct: "Don't say
 * account have it as icon"). The site header's fine line person, 24px, in
 * a 44px round target whose mark ends on the column's right edge; named
 * "Account" for a screen reader. On its own screen a short orange rule
 * sits under the mark, as the current section's sits under its word.
 */
body.bpc-field-portal .bpc-ptop__account {
	position: relative;
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: 2.75rem;
	margin-inline: auto -0.625rem;
	padding: 0;
	border-radius: var(--bpc-radius-button);
	color: var(--bpc-type);
	text-decoration: none;
	transition: opacity 60ms var(--bpc-ease);
}

body.bpc-field-portal .bpc-ptop__mark {
	display: block;
	flex: 0 0 auto;
	width: 1.5rem;
	height: 1.5rem;
	overflow: visible;
}

body.bpc-field-portal .bpc-ptop__account[aria-current]::after {
	content: "";
	position: absolute;
	inset-inline: 0.625rem;
	bottom: 3px;
	height: 2px;
	border-radius: 2px;
	background-color: var(--bpc-accent);
}

/* The menu at the top: plain words, one line from 320px up, never icons alone. */
body.bpc-field-portal .bpc-pmenu__list {
	display: flex;
	height: var(--bpc-p-menu-h);
	margin: 0 0 0 calc(-1 * var(--bpc-p-item-pad));
	padding: 0;
	list-style: none;
}

body.bpc-field-portal .bpc-pmenu__item {
	margin: 0;
}

body.bpc-field-portal .bpc-pmenu__link {
	position: relative;
	display: flex;
	align-items: center;
	min-width: 2.75rem;
	height: var(--bpc-p-menu-h);
	padding: 0 var(--bpc-p-item-pad);
	font-family: var(--bpc-font-sans);
	font-size: 0.9375rem;
	font-weight: 500;
	line-height: 1;
	letter-spacing: 0.002em;
	white-space: nowrap;
	color: var(--bpc-type);
	text-decoration: none;
	transition: opacity 60ms var(--bpc-ease);
}

/* The one you are in: a 2px orange rule under its word, on the header's hairline. It does not slide; it is simply there. */
body.bpc-field-portal .bpc-pmenu__link[aria-current]::after {
	content: "";
	position: absolute;
	inset-inline: var(--bpc-p-item-pad);
	bottom: -1px;
	height: 2px;
	border-radius: 2px 2px 0 0;
	background-color: var(--bpc-accent);
}

body.bpc-field-portal :is(.bpc-pmenu__link, .bpc-ptop__account):active {
	opacity: 0.75;
}

body.bpc-field-portal :is(.bpc-pmenu__link, .bpc-ptop__account):focus-visible {
	outline-offset: -3px;
}

/*
 * R1's type on a small phone: the menu's words and "Your portal" at 14px
 * below 340px. Only a menu of five goes to 13px to stay on one line, and
 * "Your portal" never does (Ollie wants the type more high end, not
 * smaller).
 */
@media (max-width: 21.24rem) {
	body.bpc-field-portal :is(.bpc-pmenu__link, .bpc-ptop__name) {
		font-size: 0.875rem;
	}
}

@media (max-width: 24.5rem) {
	body.bpc-field-portal .bpc-pmenu__list:has(> .bpc-pmenu__item:nth-child(5)) .bpc-pmenu__link {
		font-size: 0.8125rem;
	}
}

/* ---- Focus, and the skip link -------------------------------------------- */

/* :focus-visible only: 2px Black, 2px off (16.58:1 on the page). */
body.bpc-field-portal :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 2px solid var(--bpc-type);
	outline-offset: 2px;
}

/* WordPress's own skip link, first on the page: "Skip to the page", a pill at the top left when focused. */
body.bpc-field-portal .skip-link.screen-reader-text:focus {
	top: 0.5rem;
	left: 0.75rem;
	padding: 0.75rem 1rem;
	border: 1px solid var(--bpc-type);
	border-radius: var(--bpc-radius-button);
	background-color: var(--bpc-card);
	color: var(--bpc-type);
	font-family: var(--bpc-font-sans);
	font-size: 0.9375rem;
	font-weight: 500;
	line-height: 1;
	outline: 2px solid var(--bpc-type);
	outline-offset: 2px;
}

/* ---- Type ------------------------------------------------------------------ */

/* A screen's title: "Account", "Sarah & James's menu". */
body.bpc-field-portal .bpc-screen-title {
	margin: 0;
	font-family: var(--bpc-font-display);
	font-size: 1.875rem;
	font-style: italic;
	font-weight: 400;
	line-height: 1.12;
	letter-spacing: -0.006em;
	font-variant-numeric: lining-nums proportional-nums;
	color: var(--bpc-type);
}

@media (min-width: 68.75rem) {
	body.bpc-field-portal .bpc-screen-title {
		font-size: 2.25rem;
	}
}

/* A section on a screen: "Sign in faster next time", "Add-ons". */
body.bpc-field-portal .bpc-section-title {
	margin: 1.625rem 0 0.625rem;
	font-family: var(--bpc-font-display);
	font-size: 1.25rem;
	font-style: italic;
	font-weight: 400;
	line-height: 1.2;
	letter-spacing: 0;
	text-transform: none;
	color: var(--bpc-type);
}

/*
 * Nothing in capitals but the logo (Ollie, 21 Oct: the capitals card labels
 * "go"). A label a screen still carries reads as a quiet word, in sentence
 * case, until its screen is redrawn (plan R2 to R4).
 */
body.bpc-field-portal .bpc-eyebrow {
	font-family: var(--bpc-font-sans);
	font-size: 0.9375rem;
	font-weight: 500;
	letter-spacing: 0;
	line-height: 1.4;
	text-transform: none;
}

/* A field's label in the portal (the agreement's "Your full name"): above its box at 15/600, in sentence case (spec §4.8). */
body.bpc-field-portal .bpc-label {
	font-size: 0.9375rem;
	font-weight: 600;
	line-height: 1.35;
	letter-spacing: 0;
	text-transform: none;
	color: var(--bpc-type);
}

/*
 * The day plan's headings on Your day ("The timings", "The venue"): a
 * section's serif title, as on every portal screen, not small tracked
 * capitals. The printed day plan keeps its own look (DayPlan::html()).
 */
body.bpc-field-portal .bpc-dayplan-page .bpc-dayplan__h2 {
	margin: 1.625rem 0 0.625rem;
	font-family: var(--bpc-font-display);
	font-size: 1.25rem;
	font-style: italic;
	font-weight: 400;
	line-height: 1.2;
	letter-spacing: 0;
	text-transform: none;
	color: var(--bpc-type);
}

/* ---- Buttons: every one a full pill -------------------------------------- */

/*
 * The one button: orange, Black words 16/500 in sentence case, 52px, its
 * 1px darker orange edge (Ollie, 26 Sep). Full width on a phone; from an
 * iPad its own width, 240px at least. Pointing warms it towards White;
 * pressed it dims to 75%. No sheen, shadow, lift or glow in the portal.
 */
body.bpc-field-portal .bpc-btn {
	min-height: 3.25rem;
	padding: 0 1.75rem;
	border-radius: var(--bpc-radius-button);
	font-family: var(--bpc-font-sans);
	font-size: 1rem;
	font-weight: 500;
	line-height: 1;
	letter-spacing: 0.004em;
	text-transform: none;
	box-shadow: none;
	transition: background-color var(--bpc-dur-quick) var(--bpc-ease), border-color var(--bpc-dur-quick) var(--bpc-ease), opacity 60ms var(--bpc-ease);
}

body.bpc-field-portal .bpc-btn:hover,
body.bpc-field-portal .bpc-btn:active {
	box-shadow: none;
	transform: none;
}

body.bpc-field-portal .bpc-btn:active {
	opacity: 0.75;
}

body.bpc-field-portal .bpc-btn.is-pressed {
	animation: none;
}

body.bpc-field-portal .bpc-btn.is-pressed::before {
	content: none;
}

/* An outline pill: the card's fill, a 1px Black-60% edge, Black words, 48px; the edge comes to Black under the pointer. */
body.bpc-field-portal .bpc-btn--secondary {
	min-height: 3rem;
	padding: 0 1.5rem;
	background-color: var(--bpc-card);
	border-color: var(--bpc-input-border);
}

body.bpc-field-portal .bpc-btn--secondary:hover {
	background-color: var(--bpc-card);
	border-color: var(--bpc-type);
}

/* A small pill beside a row: Add, Remove, Switch, Change. 44px. */
body.bpc-field-portal .bpc-btn--small {
	min-height: 2.75rem;
	min-width: 5rem;
	padding: 0 1.375rem;
	font-size: 0.9375rem;
}

body.bpc-field-portal .bpc-btn:focus-visible {
	outline-offset: 3px;
}

@media (max-width: 47.99rem) {
	body.bpc-field-portal .bpc-btn--block {
		display: flex;
		width: 100%;
	}
}

@media (min-width: 48rem) {
	body.bpc-field-portal .bpc-btn--block {
		min-width: 15rem;
	}
}

/* ---- Cards and rows ------------------------------------------------------- */

/*
 * A card of rows (.bpc-rowlist; the catering pages' own .bpc-rows is
 * another thing). A row: its name on the left, its state on the right, a chevron; 52px at
 * least. The name wraps (never an ellipsis). Pressed, the quiet fill in
 * 60ms, let go in 160ms. A row that goes nowhere drops the chevron.
 */
body.bpc-field-portal .bpc-rowlist {
	margin: 0;
	padding: 0;
	list-style: none;
}

body.bpc-field-portal .bpc-rowlist.bpc-card {
	padding: 0;
}

body.bpc-field-portal .bpc-rowlist > li {
	position: relative;
	margin: 0;
}

body.bpc-field-portal .bpc-rowlist > li + li::before {
	content: "";
	position: absolute;
	top: 0;
	inset-inline: 1rem 0;
	border-block-start: var(--bpc-hairline) solid var(--bpc-rule);
}

/*
 * The name keeps at least its longest word, and the state takes what is
 * left and wraps (R1 review): with the state's track at `auto` it took all
 * the room it wanted, the name's fell to nothing, and "Quote" stood one
 * letter a line beside "Good until Thursday 5 November 2026".
 */
body.bpc-field-portal .bpc-row {
	display: grid;
	grid-template-columns: minmax(min-content, 1fr) minmax(0, max-content) 1rem;
	align-items: center;
	column-gap: 0.625rem;
	min-height: 3.25rem;
	padding: 0.625rem 0.875rem 0.625rem 1rem;
	border-radius: var(--bpc-radius);
	color: var(--bpc-type);
	text-decoration: none;
	transition: background-color var(--bpc-dur-quick) var(--bpc-ease);
}

/* The chevron, drawn: a 7px corner in a 1.5px Black line, aria-hidden by being CSS. */
body.bpc-field-portal .bpc-row::after {
	content: "";
	justify-self: center;
	width: 0.4375rem;
	height: 0.4375rem;
	margin-inline-start: -0.1875rem;
	border-block-start: 1.5px solid currentColor;
	border-inline-end: 1.5px solid currentColor;
	transform: rotate(45deg);
}

body.bpc-field-portal .bpc-row:not(:has(.bpc-row__state)) {
	grid-template-columns: minmax(0, 1fr) 1rem;
}

body.bpc-field-portal .bpc-row--plain {
	grid-template-columns: minmax(min-content, 1fr) minmax(0, max-content);
}

body.bpc-field-portal .bpc-row--plain::after {
	content: none;
}

body.bpc-field-portal a.bpc-row:active,
body.bpc-field-portal button.bpc-row:active {
	background-color: var(--bpc-fill);
	transition-duration: 60ms;
}

body.bpc-field-portal :is(a, button).bpc-row:focus-visible {
	outline-offset: -2px;
	border-radius: var(--bpc-radius);
}

/* Broken only between words; a single word longer than the whole row breaks rather than spill. */
body.bpc-field-portal .bpc-row__name {
	min-width: 0;
	font-size: 1rem;
	line-height: 1.3;
	overflow-wrap: break-word;
}

body.bpc-field-portal .bpc-row__state {
	min-width: 0;
	font-size: 0.9375rem;
	line-height: 1.3;
	text-align: end;
	overflow-wrap: break-word;
}

body.bpc-field-portal button.bpc-row {
	width: 100%;
	border: 0;
	background: none;
	font: inherit;
	text-align: start;
	cursor: pointer;
}

/* Figures that line up (a statement, a schedule, the choices' figures): tabular. */
.bpc-num {
	font-variant-numeric: lining-nums tabular-nums;
}

/* A statement row: date · what · amount · chevron; the whole row one link. */
body.bpc-field-portal .bpc-srow {
	display: grid;
	grid-template-columns: 7.4em minmax(0, 1fr) auto 1rem;
	align-items: baseline;
	align-content: center;
	column-gap: 0.625rem;
	min-height: 3.125rem;
	padding: 0.625rem 0.875rem 0.625rem 1rem;
	border-radius: var(--bpc-radius);
	color: var(--bpc-type);
	text-decoration: none;
	transition: background-color var(--bpc-dur-quick) var(--bpc-ease);
}

body.bpc-field-portal .bpc-srow::after {
	content: "";
	align-self: center;
	justify-self: center;
	width: 0.4375rem;
	height: 0.4375rem;
	margin-inline-start: -0.1875rem;
	border-block-start: 1.5px solid currentColor;
	border-inline-end: 1.5px solid currentColor;
	transform: rotate(45deg);
}

body.bpc-field-portal a.bpc-srow:active {
	background-color: var(--bpc-fill);
	transition-duration: 60ms;
}

body.bpc-field-portal .bpc-srow__date {
	font-size: 0.9375rem;
	line-height: 1.3;
	white-space: nowrap;
	font-variant-numeric: lining-nums tabular-nums;
}

body.bpc-field-portal .bpc-srow__what {
	min-width: 0;
	font-size: 1rem;
	line-height: 1.3;
	overflow-wrap: anywhere;
}

body.bpc-field-portal .bpc-srow__amount {
	font-size: 1rem;
	line-height: 1.3;
	text-align: end;
	font-variant-numeric: lining-nums tabular-nums;
}

/* A detail list: a label in a 5.4em column, its value, a hairline between. */
body.bpc-field-portal .bpc-dl {
	margin: 0;
	padding: 0;
}

body.bpc-field-portal .bpc-dl > div {
	position: relative;
	display: grid;
	grid-template-columns: 5.4em minmax(0, 1fr);
	align-items: baseline;
	column-gap: 0.75rem;
	padding: 0.875rem 1rem;
}

body.bpc-field-portal .bpc-dl > div + div::before {
	content: "";
	position: absolute;
	top: 0;
	inset-inline: 1rem 0;
	border-block-start: var(--bpc-hairline) solid var(--bpc-rule);
}

body.bpc-field-portal .bpc-dl dt {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.4;
}

body.bpc-field-portal .bpc-dl dd {
	margin: 0;
	font-size: 1rem;
	line-height: 1.4;
	overflow-wrap: anywhere;
}

/* ---- The round selector (single and multi choice) ------------------------ */

/*
 * Ollie, 21 Oct: "menu I do not like tick boxes square also should be at
 * right hand side maybe circle ?". A real radio or checkbox, drawn: a 22px
 * circle with a 1.5px Black-60% edge (4.77:1), on the right of a full-width
 * label row. Chosen, it fills Black with a 2px gap and a fine orange ring
 * round it, the same mark for one-of and any-of. Never a square box.
 */
body.bpc-field-portal .bpc-mark {
	appearance: none;
	-webkit-appearance: none;
	flex: none;
	justify-self: end;
	width: 1.375rem;
	height: 1.375rem;
	margin: 0 1px 0 0;
	border: 1.5px solid var(--bpc-input-border);
	border-radius: 50%;
	background-color: var(--bpc-card);
	cursor: pointer;
	transition: border-color var(--bpc-dur-quick) var(--bpc-ease), background-color var(--bpc-dur-quick) var(--bpc-ease), box-shadow var(--bpc-dur-quick) var(--bpc-ease);
}

body.bpc-field-portal .bpc-mark:checked {
	border-color: var(--bpc-type);
	background-color: var(--bpc-type);
	box-shadow: 0 0 0 2px var(--bpc-card), 0 0 0 3.25px var(--bpc-accent);
}

body.bpc-field-portal .bpc-mark:focus-visible {
	outline-offset: 5px;
	border-radius: 50%;
}

/* A choice: the whole row is its label, 52px at least; the name on the left, a figure before the mark when there is one. */
body.bpc-field-portal .bpc-choice {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto 1.5rem;
	align-items: center;
	column-gap: 0.875rem;
	min-height: 3.25rem;
	padding: 0.75rem 0;
	cursor: pointer;
}

body.bpc-field-portal .bpc-choice:not(:has(.bpc-choice__aside)) {
	grid-template-columns: minmax(0, 1fr) 1.5rem;
}

body.bpc-field-portal .bpc-choice:hover .bpc-mark:not(:checked) {
	border-color: var(--bpc-type);
}

body.bpc-field-portal .bpc-choice__text {
	font-size: 1rem;
	line-height: 1.35;
}

body.bpc-field-portal .bpc-choice__aside {
	font-size: 0.9375rem;
	text-align: end;
	white-space: nowrap;
	font-variant-numeric: lining-nums tabular-nums;
}

/* ---- The switch ----------------------------------------------------------- */

/* A checkbox with role="switch", 46 by 28, a pill; off a ring and a knob at the left, on a Black track with a White knob at the right. */
body.bpc-field-portal .bpc-switch {
	appearance: none;
	-webkit-appearance: none;
	flex: none;
	width: 2.875rem;
	height: 1.75rem;
	margin: 0;
	border: 1.5px solid var(--bpc-input-border);
	border-radius: var(--bpc-radius-button);
	background: var(--bpc-card) radial-gradient(circle, var(--bpc-input-border) 0 8px, transparent 8.6px) no-repeat 2px 50% / 20px 20px;
	cursor: pointer;
	transition: background-color var(--bpc-dur-quick) var(--bpc-ease), background-position var(--bpc-dur-quick) var(--bpc-ease), border-color var(--bpc-dur-quick) var(--bpc-ease);
}

body.bpc-field-portal .bpc-switch:checked {
	border-color: var(--bpc-type);
	background: var(--bpc-type) radial-gradient(circle, var(--bpc-card) 0 8px, transparent 8.6px) no-repeat calc(100% - 2px) 50% / 20px 20px;
}

body.bpc-field-portal .bpc-switch:focus-visible {
	outline-offset: 3px;
	border-radius: var(--bpc-radius-button);
}

/* ---- The back link --------------------------------------------------------- */

/* "‹ Payments": 15/500 Black, a 20px chevron, a 44px target, above a pushed screen's title. */
body.bpc-field-portal .bpc-back {
	display: inline-flex;
	align-items: center;
	gap: 0.375rem;
	min-height: 2.75rem;
	margin: -0.75rem 0 0.125rem -0.4375rem;
	padding: 0 0.625rem 0 0.4375rem;
	border-radius: var(--bpc-radius-button);
	font-family: var(--bpc-font-sans);
	font-size: 0.9375rem;
	font-weight: 500;
	line-height: 1;
	color: var(--bpc-type);
	text-decoration: none;
	transition: opacity 60ms var(--bpc-ease);
}

body.bpc-field-portal .bpc-back::before {
	content: "";
	width: 0.5rem;
	height: 0.5rem;
	margin-inline-start: 0.25rem;
	border-block-end: 1.5px solid currentColor;
	border-inline-start: 1.5px solid currentColor;
	transform: rotate(45deg);
}

body.bpc-field-portal .bpc-back:active {
	opacity: 0.75;
}

/* ---- The map's frame -------------------------------------------------------- */

/* A flat map across the top of the venue's card, 104px tall: the image is the places lookup's, in the palette. */
body.bpc-field-portal .bpc-map {
	display: block;
	overflow: hidden;
	height: 6.5rem;
	margin: 0;
	border-block-end: var(--bpc-hairline) solid var(--bpc-rule);
	border-radius: var(--bpc-radius) var(--bpc-radius) 0 0;
	line-height: 0;
}

body.bpc-field-portal .bpc-map img,
body.bpc-field-portal .bpc-map svg {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* ---- The sign-in and Register's foot -------------------------------------- */

body.bpc-field-portal .bpc-pfoot {
	box-sizing: border-box;
	width: 100%;
	max-width: calc(var(--bpc-p-col) + 2 * var(--bpc-p-gutter));
	margin: 0 auto;
	padding: 0 var(--bpc-p-gutter) 2rem;
}

body.bpc-field-portal .bpc-pfoot__legal {
	margin: 0;
	font-size: 0.875rem;
	line-height: 1.4;
}

body.bpc-field-portal .bpc-pfoot__legal a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.75rem;
	min-height: 2.75rem;
	color: var(--bpc-type);
	text-decoration: none;
	border-radius: var(--bpc-radius-button);
}

@media (min-width: 48rem) {
	body.bpc-field-portal .bpc-pfoot__legal {
		text-align: center;
	}
}

/* ---- With reduced motion nothing travels; the small fades stay quiet ----- */

@media (prefers-reduced-motion: reduce) {
	body.bpc-field-portal :is(.bpc-row, .bpc-srow, .bpc-mark, .bpc-switch, .bpc-back, .bpc-pmenu__link, .bpc-ptop__account) {
		transition: none;
	}
}

/* ---- Fields: a label above a plain box ------------------------------------ */

/*
 * A label above at 15/600 in sentence case (nothing in capitals but the
 * logo); a plain box 48px tall, the card's fill, a 1px Black-60% edge, the
 * 6px radius, 16px words; the edge comes to Black under the pointer and in
 * focus. "· optional" at 400.
 */
body.bpc-field-portal .bpc-flow__label {
	margin-block-end: 0.5rem;
	font-size: 0.9375rem;
	font-weight: 600;
	letter-spacing: 0;
	line-height: 1.35;
	text-transform: none;
}

body.bpc-field-portal .bpc-flow__opt {
	letter-spacing: 0;
	text-transform: none;
}

body.bpc-field-portal .bpc-login input.bpc-flow__box {
	min-height: 3rem;
	padding: 0 0.875rem;
	border-radius: var(--bpc-radius);
	background-color: var(--bpc-card);
	font-size: 1rem;
}
