/* =========================================================================
 * portal.css — the client portal's one shared stylesheet (design v2)
 *
 * Brooklyn Pizza & Co. The portal's frame and every part a screen is drawn
 * with, ported from the design Ollie approved on 27 Oct ("Amazing. … let's
 * get it live asap"): design v2's src/portal.css, sections 1-13, with its
 * values, measures and words; system.md explains every one (go-live plan
 * GL-1). Each screen's own layout (the design's sections 14-21) comes with
 * that screen's rebuild and is added at the foot, under its number.
 *
 * Loaded on the portal's screens, the sign-in, Register and the pay page
 * only (functions.php, brooklyn_style_manifest()), after the site's own
 * sheets, with type.css (the type, one swappable layer) just before it.
 * Every rule is scoped to the portal's body class through :where(), so it
 * weighs what the design wrote and nothing more; the tokens sit on :root
 * because html reads them too. The base resets (links, lists, margins,
 * buttons) apply to the frame's own parts (the header, the bar, a sheet
 * and a screen's .col), so a screen still drawn by plan R1 keeps its
 * spacing until it is rebuilt in this look.
 *
 * Binding: docs/ollie-rules.md (the 22 Oct sections, his notes on the first
 * v2 Home, the 26 Oct asks, and the 18-point checklist).
 *
 * Its colours are Ollie's five of 20 Oct (tokens.css, --bp-*) and mixes of
 * them: the page a tenth of Light Grey into White, the pill's edge orange
 * into Black, its hover orange into White, the quiet fill and the boxes'
 * edges White with Light Grey or Black in it. Never Pearl Grey; orange is
 * never a letter.
 *
 * Sections
 *   1  Tokens           8  Cards, rows, inset rows, statement rows, details, tiles
 *   2  Base             9  Pills, links, back step, sub-menu, switch, filters
 *   3  Focus           10  Choices: round selector, switch, fields, count box
 *   4  Screen frame    11  The arch, the progress line (both ways), the menu card, the map
 *   5  Header          12  Notices, Messages, questions, the sheet
 *   6  (computer) menu 13  Motion (view transitions and in-page screen changes)
 *   7  The phone's bottom bar
 *  13a The frame in WordPress (the template's wrappers, the admin bar)
 * ========================================================================= */

/* ---------- 1. Tokens ------------------------------------------------------ */
:root {
	/* Colour: Ollie's five of 20 Oct (tokens.css, --bp-*), as the portal uses them. Never Pearl Grey. */

	--field: color-mix(in srgb, var(--bp-light-grey) 10%, var(--bp-white));             /* the page: a tenth of Light Grey into White */
	--card: var(--bp-white);      /* cards, the header, the bar, boxes */
	--edge: var(--bp-light-grey); /* card edges and row hairlines */
	--ink: var(--bp-black);       /* every word */
	--rule-strong: var(--bp-black); /* the header's foot, the arch, uprights: drawing lines */
	--accent: var(--bp-orange);   /* fills, rules and dots only; never a letter */
	--btn-edge: color-mix(in srgb, var(--bp-orange) 62%, var(--bp-black));          /* orange 62% into Black */
	--btn-hover: color-mix(in srgb, var(--bp-orange) 82%, var(--bp-white));         /* orange 82% into White; Black on it 6.77:1 */
	--fill: color-mix(in srgb, var(--bp-light-grey) 31%, var(--bp-white));              /* pressed rows and tiles; the chosen filter */
	--box-edge: color-mix(in srgb, var(--bp-black) 60%, var(--bp-white));          /* boxes, selectors, switches off: 4.77:1 on White */
	--disc-foot: color-mix(in srgb, var(--bp-light-grey) 48%, var(--bp-white));         /* the Account disc's gradient foot, on White */
	--disc-edge: color-mix(in srgb, var(--bp-black) 45%, var(--bp-white));
	--map-land: color-mix(in srgb, var(--bp-light-grey) 18%, var(--bp-white));
	--map-water: color-mix(in srgb, var(--bp-light-grey) 57%, var(--bp-white));
	--logo: url("../brand/bridge-lockup.png"); /* the website's lockup, used as a mask (Black on light) */

	/* The one lift: the arch alone. Barely there; the card keeps its 1px edge. */
	--lift: 0 8px 24px rgb(17 17 17 / 0.06), 0 1px 2px rgb(17 17 17 / 0.04);

	/* Space: a 4px base. */
	--g: 24px;                 /* page gutter (the website's) */
	--pad: 20px;               /* inside a card */
	--gap: 12px;               /* between cards */
	--gap-s: 8px;              /* between tiles */
	--radius: 8px;             /* the one small radius: cards, boxes, the map */
	--radius-pill: 999px;      /* every button, chip and selector track */
	--radius-tag: 4px;         /* the Beta tag alone */
	--row-h: 56px;             /* a row's least height */
	--tap: 44px;               /* the least tap target */

	/* The shell. Phone and iPad: the logo row, the website's 1px Black foot, then the
	   back row ("Back to the site") closed by a Light Grey hairline. Computer: one row. */
	--head-h: 76px;            /* the logo row (the website's logo at 56px) */
	--back-h: 36px;            /* the back row (phone and iPad only); its link is still a 44px tap */
	--safe-t: env(safe-area-inset-top, 0px);
	--safe-b: env(safe-area-inset-bottom, 0px);
	--safe-l: env(safe-area-inset-left, 0px);
	--safe-r: env(safe-area-inset-right, 0px);
	--bar-h: 60px;             /* the phone's bottom bar */
	--bar-item: 88px;          /* each bar item's width where the bar is not full */
	--bar-off: max(12px, var(--safe-b)); /* clear of the home indicator */
	--top-clear: calc(var(--head-h) + 1px + var(--back-h) + 1px + var(--safe-t));
	--foot-clear: calc(var(--bar-h) + var(--bar-off) + 16px);

	/* Motion: the law. Two curves, four durations, one rise. */
	--ease: cubic-bezier(0.2, 0.6, 0.2, 1);      /* state changes, hovers, exits */
	--ease-out: cubic-bezier(0.16, 1, 0.3, 1);   /* arrivals: quick, then settling */
	--t-quick: 160ms;
	--t: 260ms;
	--t-slow: 300ms;
	--t-reveal: 640ms;
	--rise: 4px;

	color-scheme: light;
}
/* Renders only: an iPhone added to the Home Screen (34px home indicator) and an iPad (20px). */
html.sim-ios { --safe-b: 34px; }
html.sim-ipad { --safe-b: 20px; }
@media (min-width: 960px) {
	:root { --head-h: 84px; --back-h: 0px; --top-clear: calc(var(--head-h) + 1px + var(--safe-t)); --pad: 24px; --foot-clear: 32px; --g: 32px; }
}
@media (prefers-reduced-motion: reduce) {
	:root { --t-quick: 1ms; --t: 1ms; --t-slow: 1ms; --t-reveal: 1ms; --rise: 0px; }
	:where(.bpc-field-portal) *, :where(.bpc-field-portal) *::before, :where(.bpc-field-portal) *::after { animation-delay: 0ms !important; transition-delay: 0ms !important; }
}

/* ---------- 2. Base -------------------------------------------------------- */
:where(.bpc-field-portal) *, :where(.bpc-field-portal) *::before, :where(.bpc-field-portal) *::after { box-sizing: border-box; }
html {
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
	background: var(--field);
	scroll-padding-top: calc(var(--top-clear) + 12px);
	scroll-padding-bottom: var(--foot-clear);
}
body.bpc-field-portal {
	margin: 0;
	min-height: 100vh;
	min-height: 100dvh;
	background: var(--field);
	color: var(--ink);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	-webkit-tap-highlight-color: transparent;
	overflow-x: hidden;
	font-variant-numeric: lining-nums proportional-nums;
}
:where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) a { color: inherit; text-decoration: none; }
:where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) p, :where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) h1, :where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) h2, :where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) h3, :where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) ul, :where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) ol, :where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) dl, :where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) dd, :where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) figure { margin: 0; padding: 0; }
:where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) ul, :where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) ol { list-style: none; }
:where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) button, :where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) input, :where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) select, :where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) textarea { font: inherit; color: inherit; }
:where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) button { background: none; border: 0; padding: 0; cursor: pointer; }
:where(.bpc-field-portal) :where(.top, .tabs, .col, .sheet, .veil) svg { flex: none; }
:where(.bpc-field-portal) .sr { position: absolute !important; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* Words that must not break ("set-up", "£1,440 by 6 March"). */
:where(.bpc-field-portal) .nw { white-space: nowrap; }

/* Line icons: the website's set, drawn on a 20-unit grid (the bar) or a 16-unit grid (rows). */
:where(.bpc-field-portal) .ic { display: block; width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
:where(.bpc-field-portal) .gl { display: block; width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round; }

/* The arrow, the out-mark and the download mark are drawn, not typed: none of the three
   faces has U+2192, so a typed arrow would fall back to a system face. */
:where(.bpc-field-portal) .arw, :where(.bpc-field-portal) .pill::after, :where(.bpc-field-portal) .row__go, :where(.bpc-field-portal) .tile__go, :where(.bpc-field-portal) .lnk--go::after, :where(.bpc-field-portal) .lnk--out::after, :where(.bpc-field-portal) .lnk--down::after {
	--mk: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 10'%3E%3Cpath d='M1 5h11.2M8.4 1.4 12.2 5 8.4 8.6' fill='none' stroke='%23000' stroke-width='1.3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	display: inline-block;
	flex: none;
	width: 14px;
	height: 10px;
	background: currentColor;
	-webkit-mask: var(--mk) center / contain no-repeat;
	mask: var(--mk) center / contain no-repeat;
}
:where(.bpc-field-portal) .pill::after, :where(.bpc-field-portal) .lnk--go::after, :where(.bpc-field-portal) .lnk--out::after, :where(.bpc-field-portal) .lnk--down::after { content: ""; }
:where(.bpc-field-portal) .lnk--out::after { --mk: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 9.5 9.5 2.5M4 2.5h5.5V8' fill='none' stroke='%23000' stroke-width='1.3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); width: 11px; height: 11px; }
:where(.bpc-field-portal) .lnk--down::after { --mk: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M6 1.5v8M2.6 6.4 6 9.8l3.4-3.4M2 11.2h8' fill='none' stroke='%23000' stroke-width='1.3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); width: 11px; height: 12px; }

/* ---------- 3. Focus ------------------------------------------------------- */
:where(.bpc-field-portal) :focus { outline: none; }
:where(.bpc-field-portal) :focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; border-radius: inherit; }
/* A screen's title takes the focus when the screen changes (so a screen reader starts there);
   it is not a control, so it draws no ring. */
:where(.bpc-field-portal) h1[tabindex="-1"]:focus, :where(.bpc-field-portal) .screen[tabindex="-1"]:focus { outline: none; }
:where(.bpc-field-portal) .skip {
	position: fixed; z-index: 50; top: calc(var(--safe-t) + 8px); left: calc(var(--g) + var(--safe-l));
	display: flex; align-items: center; min-height: var(--tap); padding: 0 18px;
	background: var(--card); border: 1px solid var(--ink); border-radius: var(--radius-pill);
	font: 500 15px/1 var(--sans);
	transform: translateY(-160%); transition: transform var(--t-quick) var(--ease);
}
:where(.bpc-field-portal) .skip:focus-visible { transform: none; }

/* ---------- 4. Screen frame ------------------------------------------------
 * One screen per page. The header is fixed at the top; on a phone and an iPad
 * the bar is fixed at the foot. Each screen reserves both, so nothing sits
 * under them. A screen's first view fits the window: what is secondary opens
 * on a tap (a pushed page or a sheet), never below. */
:where(.bpc-field-portal) .screen {
	padding: calc(var(--top-clear) + 12px) max(var(--g), var(--safe-r)) var(--foot-clear) max(var(--g), var(--safe-l));
}
:where(.bpc-field-portal) .col { width: 100%; max-width: 480px; margin: 0 auto; }
@media (min-width: 700px) and (max-width: 959.98px) {
	:root { --g: 40px; }
	:where(.bpc-field-portal) .col { max-width: 560px; }
}
@media (min-width: 960px) {
	:where(.bpc-field-portal) .screen { padding-top: calc(var(--top-clear) + 28px); }
	:where(.bpc-field-portal) .col { max-width: 720px; }
}
/* Titles at the head of a screen: the italic, ending in a full stop. No sub-line. */
:where(.bpc-field-portal) .screen__title { margin: 4px 0 16px; }
@media (min-width: 960px) { :where(.bpc-field-portal) .screen__title { margin: 0 0 24px; } }
/* A pushed screen (a payment, the venue, an email, Notices): one way back, in one place. On a
   phone and an iPad the header's back row carries it ("‹ Payments") in place of "Back to the
   site" (the logo still goes to the site), so the page's own back step steps aside; on a
   computer, where the header has no back row, the page's own back step shows. */
@media (max-width: 959.98px) {
	:where(.bpc-field-portal) .screen--pushed > .col > .back:first-child { display: none; }
}

/* ---------- 5. Header ------------------------------------------------------
 * Of the website's header family, finer: the logo at the site's 56px on a
 * White band, the plain Beta tag beside it, the site's 1px Black foot line.
 * Phone and iPad: the bell at the right, then a 34px back row under the Black
 * line, "‹ Back to the site" with the site's orange chevron, closed by a Light
 * Grey hairline (the site's inner pages carry "‹ Home" the same way).
 * Computer: one 84px row; the logo is the way back (its hover label says so),
 * the menu's words in the centre with the site's uprights, then an upright,
 * the bell and the Account disc. "Your portal" is gone: the logo says whose. */
:where(.bpc-field-portal) .top {
	position: fixed; inset: 0 0 auto 0; z-index: 20;
	padding-top: var(--safe-t);
	background: var(--card);
	view-transition-name: bpc-top;
}
:where(.bpc-field-portal) .top__bar {
	display: flex; align-items: center; gap: 12px;
	height: var(--head-h);
	max-width: 1280px; margin: 0 auto;
	padding: 0 max(var(--g), var(--safe-r)) 0 max(var(--g), var(--safe-l));
	border-bottom: 1px solid var(--rule-strong);
	transition: height var(--t-slow) var(--ease-out);
}
:where(.bpc-field-portal) .top__brand { position: relative; display: flex; align-items: center; gap: 12px; min-width: 0; }
/* The logo is drawn 59 x 56; its link reaches 2px past each side and 3px above and below (taken
   back by the margin), so slimmed to 0.72 it is still a 45 x 45 tap. */
:where(.bpc-field-portal) .logo {
	position: relative; flex: none; display: block; width: 63px; height: 62px; margin: -3px -2px;
	transform-origin: left center;
	transition: transform var(--t-slow) var(--ease-out);
}
:where(.bpc-field-portal) .logo::before {
	content: ""; position: absolute; inset: 3px 2px;
	background: var(--ink);
	-webkit-mask: var(--logo) center / contain no-repeat;
	mask: var(--logo) center / contain no-repeat;
	transition: opacity var(--t) var(--ease);
}
@media (hover: hover) { :where(.bpc-field-portal) .logo:hover::before { opacity: 0.75; } }
/* The logo's label ("Back to the site"), shown under it on hover or focus on a computer only. */
:where(.bpc-field-portal) .logo__hint {
	position: absolute; left: 50%; top: calc(100% + 3px); z-index: 1;
	display: none; padding: 6px 9px 7px; white-space: nowrap;
	background: var(--card); border: 1px solid var(--edge); border-radius: var(--radius-tag);
	font: 500 12px/1 var(--sans); letter-spacing: 0.01em;
	transform: translate(-50%, var(--rise)); opacity: 0;
	transition: opacity var(--t) var(--ease), transform var(--t) var(--ease);
	pointer-events: none;
}
:where(.bpc-field-portal) .beta { display: inline-block; padding: 3px 6px 4px; border: 1px solid var(--ink); border-radius: var(--radius-tag); white-space: nowrap; }
:where(.bpc-field-portal) .top__end { display: flex; align-items: center; margin-left: auto; }
:where(.bpc-field-portal) .top__end .upright, :where(.bpc-field-portal) .top__end .acct { display: none; }
:where(.bpc-field-portal) .nav { display: none; }

/* The back row (phone and iPad): one step back to brooklynpizza.co. */
:where(.bpc-field-portal) .top__back {
	display: flex; align-items: center;
	height: var(--back-h);
	max-width: 1280px; margin: 0 auto;
	padding: 0 max(var(--g), var(--safe-r)) 0 max(var(--g), var(--safe-l));
	border-bottom: 1px solid var(--edge);
	transition: height var(--t-slow) var(--ease-out), opacity var(--t) var(--ease);
}

/* The bell: Notices. A fine line glyph; a small orange dot when something is unread, never a
   number. The glyph's right edge sits on the gutter; its tap area is 44 x 44. */
:where(.bpc-field-portal) .bell {
	position: relative; flex: none; display: grid; place-items: center;
	width: var(--tap); height: var(--tap); margin-right: -11px;
	border-radius: 50%;
	transition: background-color var(--t-quick) var(--ease), transform var(--t) var(--ease);
}
:where(.bpc-field-portal) .bell .ic { transition: transform var(--t) var(--ease); }
@media (hover: hover) { :where(.bpc-field-portal) .bell:hover .ic { transform: translateY(-1px); } }
:where(.bpc-field-portal) .bell:active { background: var(--fill); transform: scale(0.94); }
/* Open (Notices on its own screen, or its panel on a computer): pressed, and its own dot fades
   (260ms) while they are looking at them; it comes back on leaving only if something is still
   unread. The bar keeps the tab Notices was opened from. */
:where(.bpc-field-portal) .bell[aria-current="page"], :where(.bpc-field-portal) .bell.is-open, :where(.bpc-field-portal) .bell[aria-expanded="true"] { background: var(--fill); }
/* "Something new": 7px orange with a 1.5px ring in the ground's colour, on the glyph's shoulder.
   The one unread mark everywhere: the bell, the bar's and the menu's Messages, and each unread
   notice or email row (on its glyph's shoulder, .icw). Never a number. */
:where(.bpc-field-portal) .new { position: absolute; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 1.5px var(--card); pointer-events: none; transition: opacity var(--t) var(--ease); }
:where(.bpc-field-portal) .new.is-gone { opacity: 0; }
:where(.bpc-field-portal) .bell .new { top: 9.5px; right: 11.5px; }
:where(.bpc-field-portal) .bell.is-open .new { opacity: 0; }

/* Slim once the page moves (phone and iPad), as the website's app.js: the logo row to 60px,
   the logo to 0.72, and the back row tucks away. Never on a screen that does not scroll. */
html.is-slim :where(.bpc-field-portal) .top__bar { height: 60px; }
html.is-slim :where(.bpc-field-portal) .logo { transform: scale(0.72); }
html.is-slim :where(.bpc-field-portal) .top__back { height: 0; opacity: 0; border-bottom-width: 0; overflow: hidden; }

/* ---------- 6. The computer's menu ----------------------------------------- */
@media (min-width: 960px) {
	:where(.bpc-field-portal) .top__bar { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: 0; }
	/* Each part in its own column, so with no menu (the sign-in, Register) the disc still stands at the right. */
	:where(.bpc-field-portal) .top__brand { grid-column: 1; }
	:where(.bpc-field-portal) .nav { grid-column: 2; }
	:where(.bpc-field-portal) .top__end { grid-column: 3; }
	:where(.bpc-field-portal) .top__back { display: none; }
	html.is-slim :where(.bpc-field-portal) .top__bar { height: var(--head-h); }
	html.is-slim :where(.bpc-field-portal) .logo { transform: none; }
	:where(.bpc-field-portal) .logo__hint { display: block; }
	:where(.bpc-field-portal) .logo:hover .logo__hint, :where(.bpc-field-portal) .logo:focus-visible .logo__hint { opacity: 1; transform: translate(-50%, 0); }
	:where(.bpc-field-portal) .nav { display: flex; align-items: center; justify-content: center; height: 100%; }
	:where(.bpc-field-portal) .nav a {
		position: relative; display: flex; align-items: center;
		height: 48px; padding: 0 2px;
		white-space: nowrap;
	}
	:where(.bpc-field-portal) .nav a + a { margin-left: 44px; }
	/* The website's 1px Black upright, 14px tall, centred in the gap between menu words. */
	:where(.bpc-field-portal) .nav a + a::before { content: ""; position: absolute; left: -22px; top: 50%; width: 1px; height: 14px; margin-top: -7px; background: var(--rule-strong); }
	:where(.bpc-field-portal) .nav .icw { position: relative; display: block; }
	:where(.bpc-field-portal) .nav .new { top: 7px; right: -9px; }
	/* Hover: a 1px orange hairline draws in under the word, from the left (the website's). */
	:where(.bpc-field-portal) .nav a::after { content: ""; position: absolute; left: 2px; right: 2px; bottom: 9px; height: 1px; background: var(--accent); transform: scaleX(0); transform-origin: left; transition: transform var(--t) var(--ease); }
	@media (hover: hover) { :where(.bpc-field-portal) .nav a:hover::after { transform: scaleX(1); } }
	/* Here: a 2px orange rule under the word. It carries a view-transition name, so between
	   screens it glides from the old item to the new (300ms, --ease). */
	:where(.bpc-field-portal) .nav__here { position: absolute; left: 2px; right: 2px; bottom: 8px; height: 2px; background: var(--accent); view-transition-name: bpc-here; }
	/* Where screens change in place (the prototype; a browser without view transitions), one rule
	   serves every word and glides to the one tapped (300ms, --ease); portal.js sets --x, --y, --w. */
	:where(.bpc-field-portal) .nav { position: relative; }
	:where(.bpc-field-portal) .nav__glide { position: absolute; left: 0; top: 0; width: var(--w, 0px); height: 2px; background: var(--accent); transform: translate(var(--x, 0px), var(--y, 0px)); transition: transform var(--t-slow) var(--ease), width var(--t-slow) var(--ease), opacity var(--t) var(--ease); pointer-events: none; }
	:where(.bpc-field-portal) .nav.has-glide .nav__here { display: none; }
	:where(.bpc-field-portal) .nav.is-none .nav__glide { opacity: 0; }
	:where(.bpc-field-portal) .top__end { justify-content: flex-end; gap: 14px; margin-left: 0; }
	:where(.bpc-field-portal) .top__end .upright { display: block; width: 1px; height: 28px; margin-right: 6px; background: var(--rule-strong); }
	:where(.bpc-field-portal) .top__end .acct { display: block; }
	:where(.bpc-field-portal) .bell { margin-right: 0; }
}
/* Account, as an icon (never the word): the website's raised 44px disc, on White. */
:where(.bpc-field-portal) .acct {
	position: relative; display: block; width: var(--tap); height: var(--tap);
	border: 1px solid var(--disc-edge); border-radius: 50%;
	background: linear-gradient(180deg, var(--card) 35%, var(--disc-foot) 100%);
	box-shadow: inset 0 1px 0 var(--card), inset 0 -2px 3px rgb(17 17 17 / 0.12), 0 1px 2px rgb(17 17 17 / 0.16), 0 6px 14px -6px rgb(17 17 17 / 0.34);
	transition: transform var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
:where(.bpc-field-portal) .acct .gl { position: absolute; inset: 0; margin: auto; width: 18px; height: 18px; stroke-width: 1.3; }
@media (hover: hover) { :where(.bpc-field-portal) .acct:hover { transform: translateY(-1px); box-shadow: inset 0 1px 0 var(--card), inset 0 -2px 3px rgb(17 17 17 / 0.12), 0 2px 3px rgb(17 17 17 / 0.16), 0 10px 20px -8px rgb(17 17 17 / 0.4); } }
:where(.bpc-field-portal) .acct:active, :where(.bpc-field-portal) .acct[aria-current] {
	transform: translateY(1px);
	background: linear-gradient(180deg, var(--disc-foot) 0%, var(--card) 70%);
	box-shadow: inset 0 2px 4px rgb(17 17 17 / 0.18), inset 0 -1px 0 var(--card), 0 1px 0 var(--card);
}

/* ---------- 7. The phone's bottom bar --------------------------------------
 * The website's floating app bar, in the portal's White: 12px in from the
 * sides, clear of the home indicator, 60px tall, 22px corners, a 1px Light
 * Grey edge and one soft shadow. A line icon over its word. Here = the bolder
 * word and the website's 4px orange dot under it; the dot glides to the item
 * tapped. Something new = the 7px dot on the icon's shoulder.
 * --n is the number of items (5 for a client, 3 for an enquiry); --i the
 * current item's index from 0. Where the bar is wider than its items need
 * (an iPad, an enquiry), it hugs them, centred. */
:where(.bpc-field-portal) .tabs {
	--n: 5; --i: 0;
	position: fixed; z-index: 20;
	left: 0; right: 0; bottom: var(--bar-off);
	width: min(calc(100% - 24px - var(--safe-l) - var(--safe-r)), calc(var(--n) * var(--bar-item) + 4px));
	height: var(--bar-h);
	margin: 0 auto;
	display: grid; grid-template-columns: repeat(var(--n), minmax(0, 1fr));
	padding: 0 2px;
	background: var(--card);
	border: 1px solid var(--edge);
	border-radius: 22px;
	box-shadow: 0 6px 20px -8px rgb(17 17 17 / 0.16), 0 1px 2px rgb(17 17 17 / 0.05);
	view-transition-name: bpc-tabs;
}
:where(.bpc-field-portal) .tabs a {
	position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
	min-width: 0; padding-bottom: 4px; border-radius: 18px;
	white-space: nowrap;
	transition: transform var(--t) var(--ease);
}
:where(.bpc-field-portal) .tabs a:active { transform: scale(0.94); }
:where(.bpc-field-portal) .tabs .icw { position: relative; display: block; }
:where(.bpc-field-portal) .tabs .new { top: -1px; right: -3px; }
:where(.bpc-field-portal) .tabs__here {
	position: absolute; left: 2px; bottom: 6px;
	width: calc((100% - 4px) / var(--n)); height: 4px;
	transform: translateX(calc(var(--i) * 100%));
	transition: transform var(--t-slow) var(--ease);
	pointer-events: none;
	view-transition-name: bpc-here;
}
:where(.bpc-field-portal) .tabs__here::before { content: ""; position: absolute; left: 50%; top: 0; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: var(--accent); }
:where(.bpc-field-portal) .tabs.is-none .tabs__here { opacity: 0; }
@media (max-width: 359.98px) { :where(.bpc-field-portal) .tabs .ty-bar { font-size: 10px; letter-spacing: 0; } }
@media (min-width: 600px) { :where(.bpc-field-portal) .tabs .ty-bar { font-size: 12px; } :where(.bpc-field-portal) .tabs a { gap: 6px; } }
@media (min-width: 960px) { :where(.bpc-field-portal) .tabs { display: none; } }
/* The bar stays a way out while a stepped form is open (Menu, Venue; UI/UX pass, 2 Nov; Ollie:
   no dead ends). flow.css holds the form's Back, Next and Save on screen: on a phone in a bar
   fixed over this one, so none of its words could be tapped, and on an iPad in a sticky band
   whose foot sat under this bar's pill, on Next. In the frame both ride 8px above the bar: the
   iPad's band as it is, and on a phone the same band in place of the fixed bar, sticky in the
   card, in its White with the Light Grey hairline, at the phone bar's own 10px room. The screen
   already keeps this bar's room, so the body gives back what flow.css kept for its fixed bar,
   and what the browser scrolls to stands clear of both (a band: hairline, room, 52px button). */
@media (max-width: 959.98px) {
	html body.bpc-field-portal .bpc-flow.is-stepped .bpc-flow__actions { inset-block-end: calc(var(--bar-h) + var(--bar-off) + 8px); }
	:root.bpc-flow-open { scroll-padding-bottom: calc(var(--bar-h) + var(--bar-off) + 8px + 1px + 2rem + 3.25rem + 12px); }
}
@media (max-width: 46rem) {
	html body.bpc-field-portal .bpc-flow.is-stepped:not(.is-typing) .bpc-flow__actions,
	html body.bpc-field-portal.bpc-flow-open .bpc-flow.is-stepped:not(.is-typing) .bpc-flow__actions {
		position: sticky; inset-inline: auto; inset-block-end: calc(var(--bar-h) + var(--bar-off) + 8px); z-index: 15;
		min-height: 0; margin: 2.5rem 0 0; padding: 0.625rem 0;
		border-block-start: 1px solid var(--edge); background: var(--card);
	}
	html body.bpc-field-portal.bpc-flow-open { padding-block-end: 0; }
}
/* Renders only: the device's home indicator, so the clearance can be seen. */
:where(.bpc-field-portal) .indicator { display: none; }
html.sim-ios :where(.bpc-field-portal) .indicator, html.sim-ipad :where(.bpc-field-portal) .indicator { display: block; position: fixed; z-index: 30; left: 50%; bottom: 8px; width: 134px; height: 5px; margin-left: -67px; border-radius: 3px; background: var(--ink); }
html.sim-ipad :where(.bpc-field-portal) .indicator { width: 200px; margin-left: -100px; bottom: 7px; }
@media (min-width: 960px) { html.sim-ios :where(.bpc-field-portal) .indicator, html.sim-ipad :where(.bpc-field-portal) .indicator { display: none; } }

/* ---------- 8. Cards, rows, statement rows, details, tiles ---------------- */
/* A card: White with a fine Light Grey edge and the one small radius. Flat: no shadow.
   Only the arch (.invite) lifts. */
:where(.bpc-field-portal) .card {
	position: relative;
	background: var(--card);
	border: 1px solid var(--edge);
	border-radius: var(--radius);
}
/* The website's orange stroke on a card's top edge, inset by the card's padding:
   40 x 2 for a screen's main card, 20 x 2 (-s) for an item card or a pane's head inside a card
   (Messages' two heads; Payments' and Account's pane heads on a computer, in sections 16 and 19).
   Not on the arch (it is centred). */
:where(.bpc-field-portal) .card--stroke::before { content: ""; position: absolute; top: -1px; left: var(--pad); width: 40px; height: 2px; background: var(--accent); }
:where(.bpc-field-portal) .card--stroke-s::before { width: 20px; }
:where(.bpc-field-portal) .card__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 52px; padding: 14px var(--pad) 10px; }
:where(.bpc-field-portal) .card__body { padding: 16px var(--pad) 18px; }
:where(.bpc-field-portal) .stack > * + * { margin-top: var(--gap); }
:where(.bpc-field-portal) .section-h { margin: 22px 0 10px; }

/* A row: the name in the serif on the left, its state or figure on the right, then the arrow.
   The whole row is the tap. Rows inside a card are divided by Light Grey hairlines. */
:where(.bpc-field-portal) .rows > li + li, :where(.bpc-field-portal) .rows > a + a, :where(.bpc-field-portal) .rows > .row + .row { border-top: 1px solid var(--edge); }
:where(.bpc-field-portal) .row {
	display: flex; align-items: center; gap: 12px;
	min-height: var(--row-h); padding: 10px var(--pad);
	transition: background-color var(--t-quick) var(--ease);
}
:where(.bpc-field-portal) .row__ic { width: 18px; height: 18px; }
:where(.bpc-field-portal) .row__name { flex: 1; min-width: 0; overflow-wrap: anywhere; }
:where(.bpc-field-portal) .row__value { text-align: right; }
:where(.bpc-field-portal) .row__go { transition: transform var(--t) var(--ease); }
:where(.bpc-field-portal) a.row:active, :where(.bpc-field-portal) button.row:active { background: var(--fill); }
:where(.bpc-field-portal) button.row, :where(.bpc-field-portal) button.choice, :where(.bpc-field-portal) summary.choice { width: 100%; text-align: left; }
@media (hover: hover) { :where(.bpc-field-portal) a.row:hover .row__go { transform: translateX(4px); } }
:where(.bpc-field-portal) .rows > li:first-child > .row, :where(.bpc-field-portal) .rows > .row:first-child { border-top-left-radius: inherit; border-top-right-radius: inherit; }

/* Inset rows: a card's rows divided by hairlines that stop at the card's padding at both ends
   (a fine app's settings), so a group reads as one piece. Menu's lists (.mlist > .mi) and
   Account's settings (.set__rows) are the same component. */
:where(.bpc-field-portal) .inset > *, :where(.bpc-field-portal) .mlist > .mi, :where(.bpc-field-portal) .set__rows > * { position: relative; }
:where(.bpc-field-portal) .inset > * + *::before, :where(.bpc-field-portal) .mlist > .mi + .mi::before, :where(.bpc-field-portal) .set__rows > * + *::before {
	content: ""; position: absolute; z-index: 1; top: 0; left: var(--pad); right: var(--pad);
	height: 1px; background: var(--edge); pointer-events: none;
}

/* A statement row (Payments): date, what it was, amount in tabular figures, arrow. */
:where(.bpc-field-portal) .srow {
	display: grid; grid-template-columns: 6.6em minmax(0, 1fr) auto auto; align-items: baseline; column-gap: 12px;
	min-height: 52px; padding: 15px var(--pad) 14px;
	transition: background-color var(--t-quick) var(--ease);
}
:where(.bpc-field-portal) .srow .row__go { align-self: center; }
:where(.bpc-field-portal) a.srow:active { background: var(--fill); }
:where(.bpc-field-portal) .caption { padding: 12px var(--pad) 2px; }

/* A detail list (a payment's page, an opened email's head): label over value, hairlines between. */
:where(.bpc-field-portal) .dl > div { display: grid; grid-template-columns: 7.2em minmax(0, 1fr); column-gap: 12px; align-items: baseline; padding: 13px var(--pad); }
:where(.bpc-field-portal) .dl > div + div { border-top: 1px solid var(--edge); }

/* Tiles: the small live tiles under the arch. A name and where it stands, nothing else; the
   whole tile is the tap. --n tiles across. The arrow shows from the iPad up, at the foot's right. */
:where(.bpc-field-portal) .tiles { display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); gap: var(--gap-s); }
:where(.bpc-field-portal) .tile {
	position: relative; display: flex; flex-direction: column; justify-content: flex-start;
	height: 100%; min-height: 84px; padding: 12px 12px 12px;
	transition: background-color var(--t-quick) var(--ease), transform var(--t) var(--ease);
}
:where(.bpc-field-portal) .tile:active { background: var(--fill); transform: scale(0.98); }
:where(.bpc-field-portal) .tile__name { white-space: nowrap; }
:where(.bpc-field-portal) .tile__state { margin-top: 5px; text-wrap: balance; }
:where(.bpc-field-portal) .tile__go { display: none; position: absolute; right: 16px; bottom: 19px; transition: transform var(--t) var(--ease); }
/* The narrowest phones: three tiles cannot hold their words, so they stack as rows: the name
   on the left, where it stands on the right. */
@media (max-width: 359.98px) {
	:where(.bpc-field-portal) .tiles { grid-template-columns: minmax(0, 1fr); gap: 6px; }
	:where(.bpc-field-portal) .tile { flex-direction: row; align-items: baseline; justify-content: space-between; gap: 12px; min-height: 48px; padding: 12px 14px; }
	:where(.bpc-field-portal) .tile__state { margin: 0; text-align: right; }
	:where(.bpc-field-portal) .tile__state br { display: none; }
}
/* From the iPad up the state still sits right under the name (so the three read alike whether
   a state takes one line or two); the arrow sits alone at the foot's right. */
@media (min-width: 700px) {
	:where(.bpc-field-portal) .tile { min-height: 96px; padding: 14px 16px 15px; }
	:where(.bpc-field-portal) .tile__state { padding-right: 22px; }
	:where(.bpc-field-portal) .tile__go { display: inline-block; }
}
@media (min-width: 960px) {
	:where(.bpc-field-portal) .tiles { gap: var(--gap); }
	:where(.bpc-field-portal) .tile { min-height: 92px; padding: 16px 20px 15px; }
	:where(.bpc-field-portal) .tile__state { margin-top: 6px; }
	:where(.bpc-field-portal) .tile__go { right: 18px; bottom: 18px; }
}
@media (hover: hover) { :where(.bpc-field-portal) .tile:hover .tile__go { transform: translateX(3px); } }

/* ---------- 9. Pills, links, back step, sub-menu, filters ----------------- */
/* The one pill per view: the website's button material (orange fill, the 1px darker edge, the
   White sheen, the warm shadow, the drawn arrow that moves 4px on hover) with the portal's
   words: sentence case, no letter-spacing. */
:where(.bpc-field-portal) .pill {
	position: relative;
	display: inline-flex; align-items: center; justify-content: center; gap: 10px;
	min-height: 52px; padding: 0 28px;
	border: 1px solid var(--btn-edge); border-radius: var(--radius-pill);
	background: var(--accent); color: var(--ink);
	box-shadow: inset 0 1px 0 rgb(246 244 239 / 0.32), 0 0.6rem 1.2rem -0.75rem color-mix(in srgb, var(--accent) 70%, var(--ink));
	white-space: nowrap;
	transition: background-color var(--t) var(--ease), box-shadow var(--t) var(--ease), transform var(--t) var(--ease);
}
:where(.bpc-field-portal) .pill::after { content: ""; transition: transform var(--t) var(--ease); }
:where(.bpc-field-portal) .pill--block { display: flex; width: 100%; }
@media (hover: hover) {
	:where(.bpc-field-portal) .pill:hover { background-color: var(--btn-hover); transform: translateY(-1px); }
	:where(.bpc-field-portal) .pill:hover::after { transform: translateX(4px); }
}
:where(.bpc-field-portal) .pill:active { background-color: var(--btn-hover); transform: translateY(1px) scale(0.985); box-shadow: inset 0 1px 0 rgb(246 244 239 / 0.32); transition-duration: var(--t-quick); }
/* The outline pill: same words, a fine Black-60% edge, no fill, no lift. Never the one that asks. */
:where(.bpc-field-portal) .pill--line {
	min-height: 48px; padding: 0 22px;
	background: var(--card); border-color: var(--box-edge); box-shadow: none;
}
:where(.bpc-field-portal) .pill--line::after { display: none; }
:where(.bpc-field-portal) .pill--line.lnk--out::after, :where(.bpc-field-portal) .pill--line.lnk--down::after { display: inline-block; }
@media (hover: hover) { :where(.bpc-field-portal) .pill--line:hover { background: var(--card); border-color: var(--ink); transform: none; } }
:where(.bpc-field-portal) .pill--line:active { background: var(--fill); transform: scale(0.985); }
:where(.bpc-field-portal) .pill--s { min-height: var(--tap); padding: 0 18px; font-size: 13.5px; }

/* A quiet link in a line: underlined 1px, offset 0.3em (the website's link). */
:where(.bpc-field-portal) .lnk {
	display: inline-flex; align-items: center; gap: 6px; min-height: var(--tap);
	text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.3em;
	transition: text-underline-offset var(--t) var(--ease);
}
@media (hover: hover) { :where(.bpc-field-portal) .lnk:hover { text-underline-offset: 0.18em; } }
/* A quiet way somewhere, with the drawn arrow after the words: no underline, no box. */
:where(.bpc-field-portal) .lnk--go { text-decoration: none; }
:where(.bpc-field-portal) .lnk--go::after { width: 12px; height: 9px; transition: transform var(--t) var(--ease); }
@media (hover: hover) { :where(.bpc-field-portal) .lnk--go:hover::after { transform: translateX(4px); } }

/* The back step: "‹ Payments" at the top of a pushed screen, or "‹ Back to the site" in the
   header's back row. The website's orange chevron (an 8px square of 1.5px border, turned 45°),
   nudging 3px left on press. */
:where(.bpc-field-portal) .back { display: inline-flex; align-items: center; gap: 12px; min-height: var(--tap); padding-right: 8px; margin: -4px 0 4px -2px; }
:where(.bpc-field-portal) .back::before { content: ""; width: 8px; height: 8px; margin-left: 4px; border-left: 1.5px solid var(--accent); border-bottom: 1.5px solid var(--accent); transform: rotate(45deg); transition: transform var(--t) var(--ease); }
:where(.bpc-field-portal) .back:active::before { transform: translateX(-3px) rotate(45deg); }
/* In the 36px back row the link keeps a 44px tap: it reaches 4px above and below the row
   (over the lines, which are not taps), so the row stays fine and the thumb still has 44. */
:where(.bpc-field-portal) .top__back .back { min-height: var(--tap); margin: calc((var(--back-h) - var(--tap)) / 2) 0 calc((var(--back-h) - var(--tap)) / 2) -2px; }

/* The sub-menu (Menu's sections): a quiet row of words under the screen's title, on the page's
   own ground over a Light Grey hairline (never a second White header band), the website's Black
   uprights between the words, the current one bolder with a 2px orange rule that slides to it. */
:where(.bpc-field-portal) .sub {
	position: sticky; top: var(--top-clear); z-index: 15;
	display: flex; overflow-x: auto; scrollbar-width: none;
	margin: 0 calc(-1 * var(--g)); padding: 0 calc(var(--g) - 12px);
	background: var(--field); border-bottom: 1px solid var(--edge);
}
:where(.bpc-field-portal) .sub::-webkit-scrollbar { display: none; }
:where(.bpc-field-portal) .sub a { position: relative; display: flex; align-items: center; height: 46px; padding: 0 12px; white-space: nowrap; }
:where(.bpc-field-portal) .sub a + a::before { content: ""; position: absolute; left: 0; top: 15px; width: 1px; height: 16px; background: var(--rule-strong); }
:where(.bpc-field-portal) .sub a[aria-current] { font-weight: 600; }
:where(.bpc-field-portal) .sub a[aria-current]::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: -1px; height: 2px; background: var(--accent); view-transition-name: bpc-sub-here; }
/* Where the sections change in place, one rule glides between the words (300ms, --ease). */
:where(.bpc-field-portal) .sub__glide { position: absolute; left: 0; bottom: -1px; z-index: 1; width: var(--w, 0px); height: 2px; background: var(--accent); transform: translateX(var(--x, 0px)); transition: transform var(--t-slow) var(--ease), width var(--t-slow) var(--ease); pointer-events: none; }
:where(.bpc-field-portal) .sub.has-glide a[aria-current]::after { display: none; }
/* The two-way switch at the head of a card (Payments · Documents): the sub-menu's words and
   rule, in two equal halves, the upright on the centre line, the rule on the head's hairline. */
:where(.bpc-field-portal) .sub--switch {
	position: relative; top: auto; z-index: auto;
	display: grid; grid-template-columns: 1fr 1fr; justify-items: center;
	margin: 0; padding: 0; overflow: visible;
	background: none; border-bottom: 1px solid var(--edge);
	border-radius: var(--radius) var(--radius) 0 0;
}
:where(.bpc-field-portal) .sub--switch::before { content: ""; position: absolute; left: 50%; top: 16px; width: 1px; height: 16px; background: var(--rule-strong); }
:where(.bpc-field-portal) .sub--switch a { height: 48px; }
:where(.bpc-field-portal) .sub--switch a + a::before { display: none; }

/* A place named inside a sentence ("in Messages", "under Add-ons"): the site's 1px underline, in
   the line. Its tap is 44px tall (10px above and below, taken back by the margin), so the line's
   spacing never changes. */
:where(.bpc-field-portal) .inl {
	display: inline-block; padding: 10px 3px; margin: -10px -3px;
	text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.3em;
	transition: text-underline-offset var(--t) var(--ease);
	border-radius: var(--radius-tag);
}
@media (hover: hover) { :where(.bpc-field-portal) .inl:hover { text-underline-offset: 0.18em; } }
:where(.bpc-field-portal) .inl:active { background: var(--fill); }

/* Filter pills (All · Meat · Veggie): a radio in a 44px label; the pill 32px; only marks a dish carries. */
:where(.bpc-field-portal) .chips { display: flex; flex-wrap: wrap; gap: 0 4px; }
:where(.bpc-field-portal) .chip { position: relative; display: flex; align-items: center; min-height: var(--tap); cursor: pointer; }
:where(.bpc-field-portal) .chip input { position: absolute; opacity: 0; pointer-events: none; }
:where(.bpc-field-portal) .chip span { display: flex; align-items: center; height: 32px; padding: 0 14px; border: 1px solid var(--edge); border-radius: var(--radius-pill); background: var(--card); transition: background-color var(--t-quick) var(--ease), border-color var(--t-quick) var(--ease); }
:where(.bpc-field-portal) .chip input:checked + span { border-color: var(--ink); background: var(--fill); }
:where(.bpc-field-portal) .chip input:focus-visible + span { outline: 2px solid var(--ink); outline-offset: 3px; }

/* ---------- 10. Choices: round selector, switch, fields -------------------- */
/* The round selector, on the right of a full-width row. Never a square. Chosen: it fills Black,
   with a 2px gap in the card's colour and a fine orange ring. One-of and any-of alike. */
:where(.bpc-field-portal) .sel {
	appearance: none; -webkit-appearance: none; flex: none;
	width: 24px; height: 24px; margin: 0;
	border: 1.25px solid var(--box-edge); border-radius: 50%;
	background: var(--card);
	transition: background-color var(--t-quick) var(--ease), border-color var(--t-quick) var(--ease), box-shadow var(--t-quick) var(--ease);
	cursor: pointer;
}
/* .is-on: the same mark drawn on a span that is not an input (an add-on that is Added), so
   nothing can look chosen that is not. */
:where(.bpc-field-portal) .sel:checked, :where(.bpc-field-portal) .sel.is-on { background: var(--ink); border-color: var(--ink); box-shadow: 0 0 0 2px var(--card), 0 0 0 3.25px var(--accent); }
:where(.bpc-field-portal) span.sel { display: block; }
:where(.bpc-field-portal) .sel:focus-visible { outline: 2px solid var(--ink); outline-offset: 5px; border-radius: 50%; }
:where(.bpc-field-portal) .choice {
	display: flex; align-items: center; gap: 14px;
	min-height: var(--row-h); padding: 10px var(--pad);
	cursor: pointer; transition: background-color var(--t-quick) var(--ease);
}
:where(.bpc-field-portal) .choice:active { background: var(--fill); }
:where(.bpc-field-portal) .choice__name { flex: 1; min-width: 0; }
:where(.bpc-field-portal) .choice__fig { margin-left: auto; }
:where(.bpc-field-portal) .choice__art { flex: none; width: 88px; height: 88px; }
:where(.bpc-field-portal) .choice .sel { margin-left: auto; }
:where(.bpc-field-portal) .choice__fig + .sel { margin-left: 0; }
/* A choice's own sub-choices open under its row only (add-ons): indented, divided by hairlines. */
:where(.bpc-field-portal) .choice-more { padding: 0 0 6px; border-top: 1px solid var(--edge); background: var(--field); }
:where(.bpc-field-portal) .choice-more .choice { padding-left: calc(var(--pad) + 14px); min-height: 52px; }

/* The switch (Account: what the planner sees). 46 x 28; off: White with the box edge and a grey
   knob; on: Black track, White knob at the right. The whole row is the label. */
:where(.bpc-field-portal) .switch {
	appearance: none; -webkit-appearance: none; flex: none; position: relative;
	width: 46px; height: 28px; margin: 0 0 0 auto;
	border: 1.5px solid var(--box-edge); border-radius: var(--radius-pill);
	background: var(--card); cursor: pointer;
	transition: background-color var(--t-quick) var(--ease), border-color var(--t-quick) var(--ease);
}
:where(.bpc-field-portal) .switch::before { content: ""; position: absolute; top: 3.5px; left: 3.5px; width: 18px; height: 18px; border-radius: 50%; background: var(--box-edge); transition: transform var(--t-quick) var(--ease), background-color var(--t-quick) var(--ease); }
:where(.bpc-field-portal) .switch:checked { background: var(--ink); border-color: var(--ink); }
:where(.bpc-field-portal) .switch:checked::before { transform: translateX(18px); background: var(--card); }
:where(.bpc-field-portal) .switch:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; border-radius: var(--radius-pill); }

/* Fields: the label above a plain box, in a card; one button. No red: an error doubles the
   edge to 2px Black and says what is wrong under the box. */
:where(.bpc-field-portal) .field + .field { margin-top: 16px; }
:where(.bpc-field-portal) .field__label { display: block; margin-bottom: 7px; }
:where(.bpc-field-portal) .field__label .opt { font-weight: 400; }
:where(.bpc-field-portal) .box {
	display: block; width: 100%; min-height: 48px; padding: 12px 14px;
	background: var(--card); border: 1px solid var(--box-edge); border-radius: var(--radius);
	transition: border-color var(--t-quick) var(--ease);
}
:where(.bpc-field-portal) textarea.box { min-height: 104px; resize: vertical; }
:where(.bpc-field-portal) .box:hover, :where(.bpc-field-portal) .box:focus { border-color: var(--ink); }
:where(.bpc-field-portal) .box:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
:where(.bpc-field-portal) .box::placeholder { color: color-mix(in srgb, var(--bp-black) 65%, var(--bp-white)); }
:where(.bpc-field-portal) .box[aria-invalid="true"] { border-width: 2px; border-color: var(--ink); padding: 11px 13px; }
:where(.bpc-field-portal) .field__error { margin-top: 6px; font: 500 13px/1.3 var(--sans); }
/* A box that grows with what is written (Messages): one line at rest, up to six, then it scrolls
   inside itself. */
:where(.bpc-field-portal) textarea.box--grow { min-height: 48px; max-height: calc(6 * 1.4em + 26px); resize: none; field-sizing: content; overflow-y: auto; }
/* The search box (their venue): a pill, like every control that is tapped, with the site's pin in
   its slot at the left. */
:where(.bpc-field-portal) .box--search { min-height: 52px; padding: 13px 20px 13px 46px; border-radius: var(--radius-pill); -webkit-appearance: none; appearance: none; }
:where(.bpc-field-portal) .box--search::-webkit-search-decoration, :where(.bpc-field-portal) .box--search::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
:where(.bpc-field-portal) .box--search:focus-visible { border-radius: var(--radius-pill); }
/* The count box (how many guests a dietary need is for): a 36px drawn box inside the input's 44px
   tap, its unit inside it, shown in its row once the row is ticked. */
:where(.bpc-field-portal) .count { position: relative; flex: none; width: 104px; }
:where(.bpc-field-portal) .count__in { position: relative; z-index: 1; display: block; width: 100%; height: var(--tap); padding: 0 58px 0 12px; background: none; border: 0; font-variant-numeric: lining-nums tabular-nums; }
:where(.bpc-field-portal) .count::before { content: ""; position: absolute; inset: 4px 0; border: 1px solid var(--box-edge); border-radius: var(--radius); background: var(--card); transition: border-color var(--t-quick) var(--ease); }
:where(.bpc-field-portal) .count:hover::before, :where(.bpc-field-portal) .count:focus-within::before { border-color: var(--ink); }
:where(.bpc-field-portal) .count__in:focus-visible { outline: none; }
:where(.bpc-field-portal) .count:has(.count__in:focus-visible)::before { outline: 2px solid var(--ink); outline-offset: 2px; }
:where(.bpc-field-portal) .count__unit { position: absolute; z-index: 1; right: 12px; top: 50%; transform: translateY(-50%); pointer-events: none; }

/* ---------- 11. The arch, the progress line, the menu card, the map -------- */
/* The arch: their invitation, set in our mark. The logo's arch drawn large with its double
   rule; the bridge in its crown, faint; their names under the deck; the date between the
   logo's double hairlines; the venue and guests; a short hairline; the days to go.
   The card is the one that lifts: the soft shadow with its 1px Light Grey edge kept.
   --bs scales the bridge (1; 0.82 when the names take two lines or the card must be shorter). */
:where(.bpc-field-portal) .invite { padding: 10px; container-type: inline-size; box-shadow: var(--lift); }
/* The whole arch opens Your day details (UI/UX pass, 2 Nov; it was an empty 0 x 0 link): the link
   lies over the card, so a tap anywhere on it opens them, and reached by Tab the house ring rings
   the card. */
:where(.bpc-field-portal) .invite--go { position: relative; }
:where(.bpc-field-portal) .invite__go { position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
:where(.bpc-field-portal) .arch {
	--bs: 1;
	--bw: calc(100cqw - 10px);
	--cw: calc(var(--bw) * var(--bs));
	--crown: calc(var(--cw) * 0.54375);
	--clear: 8px;
	position: relative; isolation: isolate;
	display: flex; flex-direction: column; align-items: center;
	padding: calc(5px + var(--crown) + var(--clear)) 16px 16px;
	text-align: center;
}
:where(.bpc-field-portal) .arch__rule { position: absolute; inset: 0; z-index: -1; border: 1px solid var(--rule-strong); border-radius: 999px 999px 0 0; pointer-events: none; }
:where(.bpc-field-portal) .arch__rule::before { content: ""; position: absolute; inset: 3px; border: 0.5px solid var(--rule-strong); border-radius: 999px 999px 0 0; }
:where(.bpc-field-portal) .arch__crown { position: absolute; top: 5px; left: 50%; width: var(--bw); height: var(--crown); margin-left: calc(var(--bw) / -2); z-index: -2; border-radius: 999px 999px 0 0; overflow: hidden; display: flex; align-items: flex-end; justify-content: center; }
:where(.bpc-field-portal) .arch__crown svg {
	display: block; width: var(--cw); height: var(--crown); opacity: 0.42;
	/* Below full size the cables fade at their ends, so the bridge never stops short of the
	   arch's walls with a hard edge. At --bs 1 the fade is nil. */
	--fade: calc((1 - var(--bs)) * 90%);
	-webkit-mask: linear-gradient(90deg, transparent 0, #111 var(--fade), #111 calc(100% - var(--fade)), transparent 100%);
	mask: linear-gradient(90deg, transparent 0, #111 var(--fade), #111 calc(100% - var(--fade)), transparent 100%);
}
/* The smaller arch (two-line names, a Home that holds more, a short phone): the bridge at 0.82. */
:where(.bpc-field-portal) .arch--s { --bs: 0.82; }
/* Their names fill the arch but never wrap for an ordinary pair: the size follows the card's
   width (15.6% of it), from 28px up to the role's size (46 / 58 / 64). Long names wrap, bound
   "& Second" together, and take the smaller arch (.arch--s). */
:where(.bpc-field-portal) .arch__names { max-width: 100%; text-wrap: balance; }
:where(.bpc-field-portal) .arch .arch__names { font-size: clamp(28px, 15.6cqi, 46px); }
:where(.bpc-field-portal) .arch .arch__date { font-size: min(17px, 6.6cqi); }
:where(.bpc-field-portal) .arch__names .pair { white-space: nowrap; }
:where(.bpc-field-portal) .arch__date { display: flex; align-items: center; justify-content: center; gap: clamp(8px, 3.6cqi, 12px); width: 100%; margin-top: 14px; white-space: nowrap; }
:where(.bpc-field-portal) .arch__date::before, :where(.bpc-field-portal) .arch__date::after { content: ""; flex: 0 1 28px; min-width: 10px; height: 3px; border-top: 1px solid var(--rule-strong); border-bottom: 0.5px solid var(--rule-strong); }
/* Where the arch is too narrow for the hairlines to keep their length (a 320 phone), they step
   aside rather than shrink into "=" signs. */
@container (max-width: 290px) { :where(.bpc-field-portal) .arch__date::before, :where(.bpc-field-portal) .arch__date::after { display: none; } }
:where(.bpc-field-portal) .arch__where { margin-top: 9px; }
:where(.bpc-field-portal) .arch__foot { margin-top: 12px; padding-top: 11px; min-width: 128px; border-top: 1px solid var(--edge); }
:where(.bpc-field-portal) .arch__foot.ty-venue { padding-top: 10px; }
@media (min-width: 700px) {
	:where(.bpc-field-portal) .invite { padding: 12px; }
	:where(.bpc-field-portal) .arch { --clear: 10px; padding-bottom: 22px; }
	:where(.bpc-field-portal) .arch .arch__names { font-size: min(58px, 15.6cqi); }
	:where(.bpc-field-portal) .arch .arch__date { font-size: 19px; font-variation-settings: "opsz" 18; }
	:where(.bpc-field-portal) .arch .ty-venue { font-size: 17px; font-variation-settings: "opsz" 16; }
	:where(.bpc-field-portal) .arch__date { margin-top: 16px; }
	:where(.bpc-field-portal) .arch__date::before, :where(.bpc-field-portal) .arch__date::after { flex-basis: 36px; }
	:where(.bpc-field-portal) .arch__where { margin-top: 10px; }
	:where(.bpc-field-portal) .arch__foot { margin-top: 16px; padding-top: 13px; }
}
@media (min-width: 960px) {
	:where(.bpc-field-portal) .invite { padding: 14px; }
	:where(.bpc-field-portal) .arch { --clear: 12px; padding-bottom: 24px; }
	:where(.bpc-field-portal) .arch .arch__names { font-size: min(58px, 15.6cqi); }
	:where(.bpc-field-portal) .arch .arch__date { font-size: 21px; font-variation-settings: "opsz" 20; }
	:where(.bpc-field-portal) .arch .ty-venue { font-size: 18px; font-variation-settings: "opsz" 18; }
	:where(.bpc-field-portal) .arch__date { margin-top: 16px; }
	:where(.bpc-field-portal) .arch__date::before, :where(.bpc-field-portal) .arch__date::after { flex-basis: 40px; }
	:where(.bpc-field-portal) .arch__where { margin-top: 10px; }
	:where(.bpc-field-portal) .arch__foot { margin-top: 16px; padding-top: 13px; }
}
/* The line weights of the drawings: the website's engraving rules (flow.css), non-scaling. */
:where(.bpc-field-portal) .bpc-art * { fill: none; stroke: var(--ink); stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; stroke-width: 0.6px; }
:where(.bpc-field-portal) .bpc-art .a-rim, :where(.bpc-field-portal) .bpc-art .a-line { stroke-width: 1.1px; }
:where(.bpc-field-portal) .bpc-art .a-fine, :where(.bpc-field-portal) .bpc-art .a-cut { stroke-width: 0.75px; }
:where(.bpc-field-portal) .bpc-art .a-hatch, :where(.bpc-field-portal) .bpc-art .a-grain, :where(.bpc-field-portal) .bpc-art .a-back { stroke-width: 0.5px; }
:where(.bpc-field-portal) .bpc-art .a-back, :where(.bpc-field-portal) .bpc-art .a-char { stroke: var(--edge); }
:where(.bpc-field-portal) .bpc-art .a-stip { stroke-width: 1.4px; }
:where(.bpc-field-portal) .bpc-art .a-paper { fill: var(--card); }
:where(.bpc-field-portal) .bpc-art .a-accent { stroke-width: 0.9px; transition: stroke var(--t) var(--ease); }
:where(.bpc-field-portal) .bpc-art .a-seal, :where(.bpc-field-portal) .bpc-art .a-fire { stroke: var(--accent); }
:where(.bpc-field-portal) .bpc-art .a-seal { fill: var(--card); stroke-width: 1px; }
/* A chosen row's drawing: its toppings turn orange (260ms), wherever the tick sits in the row. */
:where(.bpc-field-portal) :checked ~ * .bpc-art .a-accent, :where(.bpc-field-portal) :checked + * .bpc-art .a-accent, :where(.bpc-field-portal) .is-chosen .bpc-art .a-accent, :where(.bpc-field-portal) .choice:has(.sel:checked) .bpc-art .a-accent { stroke: var(--accent); }

/* The progress line: where the booking stands, in words. Done: a Black dot on a Black line.
   Here: an orange dot in a fine Black ring, the word in 600. To come: an open dot on a Light
   Grey line. Never a number, "3 of 7" or a percentage. --n stages across. */
:where(.bpc-field-portal) .steps { display: grid; grid-template-columns: repeat(var(--n, 6), minmax(0, 1fr)); margin: 0 -10px; }
:where(.bpc-field-portal) .steps li { position: relative; display: flex; flex-direction: column; align-items: center; padding-top: 17px; text-align: center; white-space: nowrap; }
:where(.bpc-field-portal) .steps li::before { content: ""; position: absolute; z-index: 1; top: 4px; left: 50%; width: 7px; height: 7px; margin-left: -3.5px; border-radius: 50%; background: var(--card); box-shadow: inset 0 0 0 1px var(--ink); }
:where(.bpc-field-portal) .steps li:not(:last-child)::after { content: ""; position: absolute; top: 7px; left: 50%; width: 100%; height: 1px; background: var(--edge); }
:where(.bpc-field-portal) .steps li.is-done::before { background: var(--ink); box-shadow: none; }
:where(.bpc-field-portal) .steps li.is-done:not(:last-child)::after { background: var(--ink); }
:where(.bpc-field-portal) .steps li.is-now { font-weight: 600; }
:where(.bpc-field-portal) .steps li.is-now::before { top: 1px; width: 13px; height: 13px; margin-left: -6.5px; background: var(--accent); box-shadow: 0 0 0 2px var(--field), 0 0 0 3px var(--ink); }
:where(.bpc-field-portal) .steps--card li.is-now::before { box-shadow: 0 0 0 2px var(--card), 0 0 0 3px var(--ink); }
/* Under 360px six words cannot sit side by side ("Agreement" would touch "Deposit"), so every
   second word drops to a second row and each word has two columns of room. Never smaller type,
   never fewer words. */
@media (max-width: 359.98px) {
	:where(.bpc-field-portal) .steps:not([style*="--n: 3"]):not([style*="--n: 4"]) li:nth-child(even) { padding-top: 31px; }
}
/* The line opens where things stand (the journey): the whole line is one link, its tap 44px tall
   (7px of air above and below, taken back by the margin); pressed, the quiet fill. */
:where(.bpc-field-portal) .steps-link { display: block; margin: -7px -4px; padding: 7px 4px; border-radius: var(--radius); transition: background-color var(--t-quick) var(--ease); }
:where(.bpc-field-portal) .steps-link:active { background: var(--fill); }
:where(.bpc-field-portal) .steps-link:active .steps li.is-now::before { box-shadow: 0 0 0 2px var(--fill), 0 0 0 3px var(--ink); }

/* The progress line on its side (where things stand): each stage a row, its dot on the line, its
   name in the roman and its plain state in the sans on one baseline, the arrow where it opens
   something. Done: Black on a Black line; Here: the orange dot in its fine Black ring; To come:
   an open dot on a Light Grey line. Hairlines between stages start where the words do. */
:where(.bpc-field-portal) .journey__line { position: relative; }
:where(.bpc-field-portal) .journey__line > li { position: relative; }
:where(.bpc-field-portal) .journey__line > li + li::before,
:where(.bpc-field-portal) .journey__line > li:not(:last-child)::after {
	content: ""; position: absolute; z-index: 1; left: calc(var(--pad) + 6.5px); width: 1px; background: var(--edge); pointer-events: none;
}
:where(.bpc-field-portal) .journey__line > li + li::before { top: 0; height: 50%; }
:where(.bpc-field-portal) .journey__line > li:not(:last-child)::after { top: 50%; bottom: 0; }
:where(.bpc-field-portal) .journey__line > li.is-done + li::before, :where(.bpc-field-portal) .journey__line > li.is-done:not(:last-child)::after { background: var(--rule-strong); }
:where(.bpc-field-portal) .jrow {
	position: relative; display: grid; grid-template-columns: 14px auto minmax(0, 1fr) 14px; column-gap: 12px;
	align-content: center; align-items: baseline;
	min-height: 60px; padding: 10px var(--pad);
	transition: background-color var(--t-quick) var(--ease);
}
:where(.bpc-field-portal) .jrow__dot, :where(.bpc-field-portal) .jrow .row__go, :where(.bpc-field-portal) .jrow__nogo { align-self: center; }
:where(.bpc-field-portal) a.jrow:active { background: var(--fill); }
@media (hover: hover) { :where(.bpc-field-portal) a.jrow:hover .row__go { transform: translateX(4px); } }
:where(.bpc-field-portal) .journey__line > li:first-child > .jrow { border-top-left-radius: calc(var(--radius) - 1px); border-top-right-radius: calc(var(--radius) - 1px); }
:where(.bpc-field-portal) .journey__line > li:last-child > .jrow { border-bottom-left-radius: calc(var(--radius) - 1px); border-bottom-right-radius: calc(var(--radius) - 1px); }
:where(.bpc-field-portal) .journey__line > li + li > .jrow::before { content: ""; position: absolute; top: 0; left: calc(var(--pad) + 26px); right: var(--pad); height: 1px; background: var(--edge); }
:where(.bpc-field-portal) .jrow__name { white-space: nowrap; }
:where(.bpc-field-portal) .jrow__state { text-align: right; text-wrap: balance; }
@media (min-width: 360px) { :where(.bpc-field-portal) .jrow__state { white-space: nowrap; } }
:where(.bpc-field-portal) .jrow__nogo { width: 14px; }
:where(.bpc-field-portal) .jrow__dot { position: relative; z-index: 2; width: 14px; height: 14px; }
:where(.bpc-field-portal) .jrow__dot::before { content: ""; position: absolute; left: 50%; top: 50%; width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; border-radius: 50%; background: var(--card); box-shadow: inset 0 0 0 1px var(--ink); }
:where(.bpc-field-portal) .is-done .jrow__dot::before { background: var(--ink); box-shadow: none; }
:where(.bpc-field-portal) .is-now .jrow__dot::before { width: 13px; height: 13px; margin: -6.5px 0 0 -6.5px; background: var(--accent); box-shadow: 0 0 0 2px var(--card), 0 0 0 3px var(--ink); }
:where(.bpc-field-portal) .is-now > a.jrow:active .jrow__dot::before { box-shadow: 0 0 0 2px var(--fill), 0 0 0 3px var(--ink); }
/* The narrowest phones: a long state steps under the stage's name rather than squeeze it. */
@media (max-width: 359.98px) {
	:where(.bpc-field-portal) .jrow { grid-template-columns: 14px minmax(0, 1fr) 14px; row-gap: 2px; }
	:where(.bpc-field-portal) .jrow__dot { grid-row: 1 / 3; }
	:where(.bpc-field-portal) .jrow__name { grid-column: 2; }
	:where(.bpc-field-portal) .jrow__state { grid-column: 2; text-align: left; }
	:where(.bpc-field-portal) .jrow .row__go, :where(.bpc-field-portal) .jrow__nogo { grid-column: 3; grid-row: 1 / 3; }
}

/* The menu card: their confirmed menu, laid out like a fine printed menu, in the logo's double
   rule (a 1px line, a 0.5px line 3px inside it). Centred; their pizzas drawn at its head; their
   names in the italic; the date between the logo's double hairlines; short 40 x 1 orange rules
   between courses; course names in the display italic; dishes in the roman; a dish's own line
   in the sans. The small after-the-day card (section 14) uses the same parts without the frame. */
:where(.bpc-field-portal) .menucard { padding: 12px; text-align: center; }
:where(.bpc-field-portal) .menucard__frame { position: relative; padding: 24px 18px 26px; border: 1px solid var(--rule-strong); border-radius: var(--radius-tag); }
:where(.bpc-field-portal) .menucard__frame::before { content: ""; position: absolute; inset: 3px; border: 0.5px solid var(--rule-strong); border-radius: 2px; pointer-events: none; }
:where(.bpc-field-portal) .menucard__names { margin-top: 16px; font-size: 40px; }
:where(.bpc-field-portal) .menucard__names .pair { white-space: nowrap; }
:where(.bpc-field-portal) .menucard__date { margin-top: 10px; }
:where(.bpc-field-portal) .menucard__rule { display: block; width: 40px; height: 1px; margin: 20px auto 18px; background: var(--accent); }
:where(.bpc-field-portal) .menucard__course + .menucard__dish { margin-top: 8px; }
:where(.bpc-field-portal) .menucard__dish + .menucard__dish { margin-top: 4px; }
:where(.bpc-field-portal) .menucard__line { margin-top: 4px; }
:where(.bpc-field-portal) .menucard__pies { display: flex; justify-content: center; gap: 12px; }
:where(.bpc-field-portal) .menucard__pies .bpc-art { width: 60px; height: 60px; }
:where(.bpc-field-portal) .menucard__frame .menucard__pies .bpc-art .a-accent { stroke: var(--accent); }
@media (min-width: 700px) {
	:where(.bpc-field-portal) .menucard { padding: 14px; }
	:where(.bpc-field-portal) .menucard__frame { padding: 30px 28px 32px; }
	:where(.bpc-field-portal) .menucard__names { font-size: 46px; }
}

/* The map: a flat drawing in the palette (OpenStreetMap's data), the credit at its foot. */
:where(.bpc-field-portal) .map { position: relative; height: 132px; overflow: hidden; border-radius: var(--radius); background: var(--map-land); }
:where(.bpc-field-portal) .map svg { display: block; width: 100%; height: 100%; }
:where(.bpc-field-portal) .map figcaption { position: absolute; right: 0; bottom: 0; padding: 3px 7px 3px 8px; border-top-left-radius: 4px; background: var(--map-land); font: 400 11px/1.2 var(--sans); }
@media (min-width: 700px) { :where(.bpc-field-portal) .map { height: 180px; } }

/* ---------- 12. Notices, Messages, questions ------------------------------- */
/* Notices (the bell): newest first, grouped by day. A notice is one row: the small line glyph,
   the plain line, the time at the right on the line's first baseline; unread is the system's
   "something new" dot on the glyph's shoulder (.icw .new), as on the bell and the bar's icons;
   the whole row goes to its place. Messages' email rows (below) take the same glyph, the same
   shoulder dot and the same quiet column, so an unread row reads alike everywhere. */
:where(.bpc-field-portal) .ngroup { padding: 14px var(--pad) 4px; }
:where(.bpc-field-portal) .ngroup:not(:first-child) { border-top: 1px solid var(--edge); }
:where(.bpc-field-portal) .notice {
	display: grid; grid-template-columns: 18px minmax(0, 1fr) auto; column-gap: 14px; align-items: baseline;
	min-height: 46px; padding: 12px var(--pad) 11px;
	transition: background-color var(--t-quick) var(--ease);
}
:where(.bpc-field-portal) .notice + .notice { border-top: 1px solid var(--edge); }
:where(.bpc-field-portal) .notice .gl, :where(.bpc-field-portal) .mrow .gl { margin: 0; }
:where(.bpc-field-portal) .notice > .icw, :where(.bpc-field-portal) .mrow > .icw { position: relative; display: block; align-self: start; width: 18px; height: 18px; margin-top: 2px; }
:where(.bpc-field-portal) .notice > .icw .new, :where(.bpc-field-portal) .mrow > .icw .new { top: -2px; right: -3px; }
:where(.bpc-field-portal) .notice__line { display: block; text-wrap: pretty; overflow-wrap: break-word; }
:where(.bpc-field-portal) .notice__time { margin: 0; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* After a time, where there is no glyph (a message in the conversation): the same dot, in line. */
:where(.bpc-field-portal) .unread { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); transition: opacity var(--t) var(--ease); }
:where(.bpc-field-portal) .unread.is-gone { opacity: 0; }
:where(.bpc-field-portal) a.notice:active { background: var(--fill); }
:where(.bpc-field-portal) .empty { padding: 40px var(--pad) 44px; text-align: center; }
:where(.bpc-field-portal) .empty .bpc-art { width: 120px; height: auto; margin: 0 auto 18px; }

/* Messages: every email we have sent, in full and in order, and the conversation with the team.
   A list row: the envelope (with the shoulder dot while unread), the subject (a row name), then
   when it was sent and what came with it. Opened, an email is shown as it was sent. */
:where(.bpc-field-portal) .mrow {
	display: grid; grid-template-columns: 18px minmax(0, 1fr); column-gap: 14px; align-items: start;
	padding: 13px var(--pad) 14px;
	transition: background-color var(--t-quick) var(--ease);
}
:where(.bpc-field-portal) .mrow + .mrow { border-top: 1px solid var(--edge); }
:where(.bpc-field-portal) .mrow > .icw { margin-top: 3px; }
:where(.bpc-field-portal) .mrow__when { display: block; margin-top: 3px; }
:where(.bpc-field-portal) a.mrow:active { background: var(--fill); }
/* The document that came with an email: a small hairline pill on a computer; in the line, with
   its folded page, where a row must stay short (.att--inline, phones and iPads). */
:where(.bpc-field-portal) .att { display: inline-flex; align-items: center; gap: 7px; height: 30px; margin-top: 9px; padding: 0 12px 0 10px; border: 1px solid var(--edge); border-radius: var(--radius-pill); background: var(--card); white-space: nowrap; font: 500 12.5px/1 var(--sans); letter-spacing: 0.01em; }
:where(.bpc-field-portal) .att .gl { width: 14px; height: 14px; margin: 0; stroke-width: 1.1; }
@media (max-width: 959.98px) {
	:where(.bpc-field-portal) .att--inline { height: auto; margin: 0; padding: 0; border: 0; border-radius: 0; background: none; }
}
/* A message in the conversation: who and when in the sans, the words as body text. Theirs and
   ours alike, full width, divided by hairlines: a private bank's secure messages, not a chat. */
:where(.bpc-field-portal) .msg { padding: 14px var(--pad) 16px; }
:where(.bpc-field-portal) .msg + .msg { border-top: 1px solid var(--edge); }
:where(.bpc-field-portal) .msg__who { display: flex; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
:where(.bpc-field-portal) .msg--ours { box-shadow: inset 2px 0 0 var(--accent); }
:where(.bpc-field-portal) .mail__head { padding: 18px var(--pad) 14px; border-bottom: 1px solid var(--edge); }
:where(.bpc-field-portal) .mail__head .ty-meta { display: block; margin-top: 6px; }
:where(.bpc-field-portal) .mail__body { padding: 16px var(--pad) 6px; }
:where(.bpc-field-portal) .mail__body > * + * { margin-top: 12px; }

/* An example figure in a drawing (an add-on's price before the office sets it, a card's last
   four digits): a dashed hairline tag, so no stand-in is ever read as a fact. Prototypes only. */
:where(.bpc-field-portal) .tag { display: inline-block; padding: 2px 6px 3px; border: 1px dashed var(--ink); border-radius: var(--radius-tag); font: 500 11px/1 var(--sans); letter-spacing: 0.01em; vertical-align: 2px; white-space: nowrap; }

/* Questions about their day: each a row that opens its answer under it. */
:where(.bpc-field-portal) .qa > details + details { border-top: 1px solid var(--edge); }
:where(.bpc-field-portal) .qa summary {
	display: grid; grid-template-columns: minmax(0, 1fr) 16px; align-items: center; column-gap: 12px;
	min-height: var(--row-h); padding: 12px var(--pad); cursor: pointer; list-style: none;
}
:where(.bpc-field-portal) .qa summary::-webkit-details-marker { display: none; }
:where(.bpc-field-portal) .qa summary::after { content: ""; width: 11px; height: 11px; margin: -6px 0 0 2px; border-right: 1.3px solid var(--ink); border-bottom: 1.3px solid var(--ink); transform: rotate(45deg); transition: transform var(--t) var(--ease), margin var(--t) var(--ease); }
:where(.bpc-field-portal) .qa details[open] summary::after { transform: rotate(225deg); margin-top: 6px; }
:where(.bpc-field-portal) .qa details > div { padding: 0 var(--pad) 18px; }
:where(.bpc-field-portal) .qa details[open] > div { animation: bpc-arrive var(--t-slow) var(--ease-out) both; }
:where(.bpc-field-portal) .qa summary { transition: background-color var(--t-quick) var(--ease); }
:where(.bpc-field-portal) .qa summary:active { background: var(--fill); }
:where(.bpc-field-portal) .qa > details:first-child > summary { border-top-left-radius: calc(var(--radius) - 1px); border-top-right-radius: calc(var(--radius) - 1px); }
:where(.bpc-field-portal) .qa > details:last-child:not([open]) > summary { border-bottom-left-radius: calc(var(--radius) - 1px); border-bottom-right-radius: calc(var(--radius) - 1px); }
/* A calm opening: the answer's room opens with it, so the rows below glide down rather than
   jump, and glide back on closing (300ms; --ease-out opening, --ease closing). Where the browser
   lacks ::details-content the answer simply rises in. */
:where(.bpc-field-portal) .qa { interpolate-size: allow-keywords; }
:where(.bpc-field-portal) .qa details::details-content {
	block-size: 0; overflow-y: clip;
	transition: block-size var(--t-slow) var(--ease), content-visibility var(--t-slow) var(--ease) allow-discrete;
}
:where(.bpc-field-portal) .qa details[open]::details-content { block-size: auto; transition-timing-function: var(--ease-out); }

/* A sheet: what is secondary on a phone opens over the screen from the foot (a payment's
   details, an add-on's confirm). White, the top corners at the one radius, a hairline grab
   mark, the veil behind at Black 40%. It rises 4px and fades in (300ms); the veil fades (260ms). */
:where(.bpc-field-portal) .veil { position: fixed; inset: 0; z-index: 40; background: rgb(17 17 17 / 0.4); animation: bpc-fade var(--t) var(--ease) both; }
:where(.bpc-field-portal) .sheet {
	position: fixed; z-index: 41; left: 0; right: 0; bottom: 0;
	max-height: calc(100% - var(--top-clear) - 12px); overflow: auto;
	padding: 0 var(--g) calc(var(--bar-off) + 8px);
	background: var(--card); border: 1px solid var(--edge); border-bottom: 0;
	border-radius: var(--radius) var(--radius) 0 0;
	animation: bpc-arrive var(--t-slow) var(--ease-out) both;
}
:where(.bpc-field-portal) .sheet::before { content: ""; display: block; width: 36px; height: 4px; margin: 10px auto 14px; border-radius: 2px; background: var(--edge); }
/* Inside a sheet: its title (a card heading), boxes 14px apart, rows that reach its edges, and
   the one pill (Done) 18px under what it closes. */
:where(.bpc-field-portal) .sheet__title { margin: 0 0 6px; }
:where(.bpc-field-portal) .sheet .field { margin-top: 14px; }
:where(.bpc-field-portal) .sheet .set__rows { margin: 0 calc(-1 * var(--g)); }
:where(.bpc-field-portal) .sheet .set__rows > * + *::before { left: var(--g); right: var(--g); }
:where(.bpc-field-portal) .sheet .row, :where(.bpc-field-portal) .sheet .choice { padding-left: var(--g); padding-right: var(--g); }
:where(.bpc-field-portal) .sheet__done { margin-top: 18px; }
@media (min-width: 960px) {
	:where(.bpc-field-portal) .sheet { left: 50%; right: auto; bottom: auto; top: 50%; width: min(560px, calc(100% - 64px)); max-height: calc(100% - 64px); padding: 0 var(--pad) var(--pad); border-bottom: 1px solid var(--edge); border-radius: var(--radius); transform: translate(-50%, -50%); }
	:where(.bpc-field-portal) .sheet::before { display: none; }
	:where(.bpc-field-portal) .sheet__title { padding-top: var(--pad); }
	:where(.bpc-field-portal) .sheet .set__rows { margin: 0 calc(-1 * var(--pad)); }
	:where(.bpc-field-portal) .sheet .set__rows > * + *::before { left: var(--pad); right: var(--pad); }
	:where(.bpc-field-portal) .sheet .row, :where(.bpc-field-portal) .sheet .choice { padding-left: var(--pad); padding-right: var(--pad); }
}
/* Closing: the sheet and the veil fade (160ms --ease). */
:where(.bpc-field-portal) .sheet.is-closing, :where(.bpc-field-portal) .veil.is-closing { animation: bpc-out var(--t-quick) var(--ease) both; }

/* The light veil: behind a panel that drops from the header on a computer (Notices), the screen
   recedes into the page's own White with a slight softening instead of darkening, so the portal
   stays light and the panel reads as the one layer. */
:where(.bpc-field-portal) .veil--light {
	position: fixed; inset: var(--top-clear) 0 0 0; z-index: 18;
	background: color-mix(in srgb, var(--field) 76%, transparent);
	-webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
	animation: bpc-fade var(--t) var(--ease) both;
}

/* ---------- 13. Motion ----------------------------------------------------
 * Two curves, 160 / 260 / 300 / 640ms, a 4px rise, no bounce, overshoot, loops,
 * spinners or count-ups. Reduced motion: every duration 1ms, nothing travels.
 * Between screens (each a real page) the browser's view transition runs; the
 * header and the bar hold still, the "here" marks glide. Inside the portal a
 * screen rises 4px; an arrival from outside (an email link, Stripe, a reload)
 * only fades. direction.js labels html: is-tab, is-push, is-back, is-cold. */
@keyframes bpc-arrive { from { opacity: 0; transform: translateY(var(--rise)); } }
@keyframes bpc-fade { from { opacity: 0; } }
@keyframes bpc-out { to { opacity: 0; } }
@keyframes bpc-in-right { from { opacity: 0; transform: translateX(var(--rise)); } }
@keyframes bpc-in-left { from { opacity: 0; transform: translateX(calc(-1 * var(--rise))); } }
@keyframes bpc-draw { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }

@view-transition { navigation: auto; }
/* Between tabs: the old screen fades out (160ms), the new one rises 4px and fades in (300ms, from
   60ms). A pushed screen comes 4px from the right, going back 4px from the left: the way is the
   view transition's type, which assets/js/direction.js names as the new page is revealed
   (forward, back, tab). Written on html, so it outranks the site's phone moves (components.css,
   "Moving between pages"), which push 3rem. */
html::view-transition-old(root) { animation: bpc-out var(--t-quick) var(--ease) both; }
html::view-transition-new(root) { animation: bpc-arrive var(--t-slow) var(--ease-out) 60ms both; }
html:active-view-transition-type(forward)::view-transition-old(root),
html:active-view-transition-type(back)::view-transition-old(root),
html:active-view-transition-type(tab)::view-transition-old(root) { animation: bpc-out var(--t-quick) var(--ease) both; }
html:active-view-transition-type(forward)::view-transition-new(root) { animation: bpc-in-right var(--t-slow) var(--ease-out) 60ms both; }
html:active-view-transition-type(back)::view-transition-new(root) { animation: bpc-in-left var(--t-slow) var(--ease-out) 60ms both; }
html:active-view-transition-type(tab)::view-transition-new(root) { animation: bpc-arrive var(--t-slow) var(--ease-out) 60ms both; }
html::view-transition-group(bpc-here), html::view-transition-group(bpc-sub-here) { animation-duration: var(--t-slow); animation-timing-function: var(--ease); }
html::view-transition-old(bpc-top), html::view-transition-new(bpc-top), html::view-transition-old(bpc-tabs), html::view-transition-new(bpc-tabs) { animation: none; }
@media (prefers-reduced-motion: reduce) {
	@view-transition { navigation: none; }
}
/* Without view transitions (or on a cold arrival), the screen itself fades in once. Backwards,
   never forwards: an opacity animation still filling once it has played keeps the screen a
   stacking context of its own, and a sheet inside it would sit under the header and the bar. */
html.bpc-cold :where(.bpc-field-portal) .screen { animation: bpc-fade var(--t-slow) var(--ease-out) backwards; }

/* In-page screen changes: the same moves where screens change inside one document (the
   prototype; a browser without cross-document view transitions). portal.js marks the screen
   leaving (.is-leaving: held where it was, above the page, fading out in 160ms) and the one
   arriving (.k-tab rises 4px and fades in, 300ms --ease-out after 60ms; .k-push comes in 4px
   from the right; .k-back 4px from the left; .k-cold only fades). The header and the bar hold
   still; the bar's dot and the menu's rule glide on their own. */
:where(.bpc-field-portal) .screen.is-leaving { position: fixed; z-index: 2; left: 0; right: 0; top: 0; pointer-events: none; animation: bpc-out var(--t-quick) var(--ease) both; }
:where(.bpc-field-portal) .screen.k-tab { animation: bpc-arrive var(--t-slow) var(--ease-out) 60ms both; }
:where(.bpc-field-portal) .screen.k-push { animation: bpc-in-right var(--t-slow) var(--ease-out) 60ms both; }
:where(.bpc-field-portal) .screen.k-back { animation: bpc-in-left var(--t-slow) var(--ease-out) 60ms both; }
:where(.bpc-field-portal) .screen.k-cold { animation: bpc-fade var(--t-slow) var(--ease-out) both; }
/* A part that changes in place (a Menu section, a Payments pane, the menu card): rises 4px. */
:where(.bpc-field-portal) .k-rise { animation: bpc-arrive var(--t-slow) var(--ease-out) both; }
/* The header's back row, when its words change (a tab's "Back to the site", a pushed screen's
   "‹ Payments"): the words fade across (300ms). */
:where(.bpc-field-portal) .top__back .back.k-swap { animation: bpc-fade var(--t-slow) var(--ease-out) both; }
/* Signing in: the bell, the menu and the bar arrive with the arch (300ms, from 120ms). */
html.is-arriving :where(.bpc-field-portal) .tabs, html.is-arriving :where(.bpc-field-portal) .nav, html.is-arriving :where(.bpc-field-portal) .bell { animation: bpc-fade var(--t-slow) var(--ease-out) 120ms both; }

/* The arch's arrival (once, after signing in): the double rule draws down from the crown,
   the parts fade in after it, the rest rises 4px; all settled by about 0.7s. */
html.is-arriving :where(.bpc-field-portal) .invite { animation: bpc-arrive var(--t-reveal) var(--ease-out) both; }
html.is-arriving :where(.bpc-field-portal) .arch__rule { animation: bpc-draw var(--t-reveal) var(--ease-out) 40ms both; }
html.is-arriving :where(.bpc-field-portal) .arch__crown { animation: bpc-fade var(--t-reveal) var(--ease) 80ms both; }
html.is-arriving :where(.bpc-field-portal) .arch__names { animation: bpc-fade var(--t-slow) var(--ease-out) 60ms both; }
html.is-arriving :where(.bpc-field-portal) .arch__date, html.is-arriving :where(.bpc-field-portal) .arch__where { animation: bpc-fade var(--t-slow) var(--ease-out) 120ms both; }
html.is-arriving :where(.bpc-field-portal) .arch__foot { animation: bpc-fade var(--t) var(--ease) 160ms both; }
html.is-arriving :where(.bpc-field-portal) .steps { animation: bpc-arrive var(--t-slow) var(--ease-out) 160ms both; }
html.is-arriving :where(.bpc-field-portal) .home__next { animation: bpc-arrive var(--t-slow) var(--ease-out) 180ms both; }
html.is-arriving :where(.bpc-field-portal) .tiles, html.is-arriving :where(.bpc-field-portal) .home__more, html.is-arriving :where(.bpc-field-portal) .home__faq { animation: bpc-arrive var(--t-slow) var(--ease-out) 210ms both; }


/* ---------- 13a. The frame in WordPress -----------------------------------
 * The header is a template part (parts/header-portal.html): groups around
 * the blocks that draw its parts. A group lays its children out with the
 * block gap between them; inside the header they are the row's own parts,
 * so they keep none. The bar is printed after the page, on wp_footer
 * (functions.php, brooklyn_tab_bar()). Signed in with the admin bar (the
 * team looking on), the header sits under it. */
body.bpc-field-portal :is(.top, .top__bar) > * { margin-block: 0; }
body.bpc-field-portal.admin-bar .top { top: var(--wp-admin--admin-bar--height, 0px); }
@media (max-width: 600px) {
	body.bpc-field-portal.admin-bar .top { position: absolute; }
}
