/* Projects RH: the firm's own design language.
   White paper, slate type, one teal accent. Structure is hairlines and space;
   exactly one card shadow is permitted per page. Every colour comes from
   tokens.css, which carries only the brand palette.

   Four palette rules are load-bearing and enforced here rather than left to
   discipline: --meta never sets small text, --accent never sits on the warm
   band, --accent-soft never sets a glyph, and --border never edges a control. */

/* ─────────────────────────────────────────────────────────────────────
   1  base
   ───────────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg-3);
  font: var(--type-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
h1, h2, h3, h4 { margin: 0; color: var(--fg-2); font-weight: inherit; }
h1 { font: var(--type-h1); letter-spacing: var(--track-display); }
h2 { font: var(--type-h2); letter-spacing: var(--track-display); }
h3 { font: var(--type-h3); }
p { margin: 0 0 1.1em; max-width: var(--measure); }
p:last-child { margin-bottom: 0; }
a { color: var(--accent); text-underline-offset: 3px; }
a:hover { color: var(--accent-hover); }
ul, ol { margin: 0 0 1.1em; padding-left: 1.25rem; }
li { margin: 0 0 0.45em; max-width: var(--measure); }
img, svg { max-width: 100%; height: auto; display: block; }
hr { border: 0; border-top: 1px solid var(--border); margin: 0; }
table { border-collapse: collapse; width: 100%; }
strong, b { font-weight: 600; color: var(--fg-2); }
::selection { background: var(--accent-tint); color: var(--fg-2); }

:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-sm); }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--accent); color: var(--accent-on);
  padding: 0.85rem 1.5rem; min-height: 48px;
  display: inline-flex; align-items: center;
  font: var(--type-eyebrow); letter-spacing: var(--track-eyebrow); text-transform: uppercase;
  border-radius: 0 0 var(--radius-sm) 0;
}
.skip:focus { left: 0; }

.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
[hidden] { display: none !important; }

/* ─────────────────────────────────────────────────────────────────────
   2  layout
   ───────────────────────────────────────────────────────────────────── */
.wrap { width: min(100% - var(--gutter) * 2); max-width: var(--container-base); margin-inline: auto; }
.wrap-wide { width: min(100% - var(--gutter) * 2); max-width: var(--container-wide); margin-inline: auto; }
.wrap-narrow { width: min(100% - var(--gutter) * 2); max-width: var(--container-narrow); margin-inline: auto; }

.section { padding-block: var(--section-y); }
.section-tight { padding-block: var(--section-y-tight); }

/* Bands. White is the page; these are the only grounds that interrupt it, and
   the warm tint appears at most once per page. */
.band       { background: var(--surface); }
.band-warm  { background: var(--surface-warm); }
.band-tint  { background: var(--surface-tint); }
.band-slate { background: var(--fg-2); color: var(--bg); }
.band-slate h1, .band-slate h2, .band-slate h3, .band-slate strong { color: var(--bg); }
.band-slate p, .band-slate li { color: var(--bg); }
.band-slate .eyebrow { color: var(--accent-tint); }
.band-slate .meta { color: var(--accent-tint); }
.band-slate a { color: var(--accent-tint); }
/* Figures and basis lines set their own colour, and on a slate band or the hero
   film that colour is the band's own, so they vanished (How we work hero,
   29 Sep 2026: "20-minute" and "USD 1,000" printed slate on slate). On a dark
   ground they inherit the band's text colour, and small print takes the tint
   that .meta already uses there. */
.band-slate .fig, .hero-film .fig, .band-film .fig,
.band-slate strong, .hero-film strong, .band-film strong { color: inherit; }
.band-slate .basis, .hero-film .basis, .band-film .basis,
.band-slate .small, .hero-film .small, .band-film .small { color: var(--accent-tint); }

/* One column below 860px, twelve above. The twelve-column grid used to be the
   base at every width with every item spanning all twelve, which is the same
   layout on a phone but not the same box: eleven 32px gaps are 352px of gap
   before any content, and at 360px that is 32px more than the container. Every
   page scrolled sideways by 12px at 360 on 2026-09-23, measured. */
.grid { display: grid; gap: var(--space-6); grid-template-columns: minmax(0, 1fr); }
.c-3, .c-4, .c-5, .c-6, .c-7, .c-8, .c-9 { grid-column: auto; min-width: 0; }
@media (min-width: 860px) {
  .grid { gap: var(--space-8); grid-template-columns: repeat(12, 1fr); }
  .c-3 { grid-column: span 3 } .c-4 { grid-column: span 4 } .c-5 { grid-column: span 5 }
  .c-6 { grid-column: span 6 } .c-7 { grid-column: span 7 } .c-8 { grid-column: span 8 }
  .c-9 { grid-column: span 9 }
}

.stack   > * + * { margin-top: var(--space-4); }
.stack-l > * + * { margin-top: var(--space-8); }
.row { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; }
.mt-l { margin-top: var(--space-8); }
.mt-m { margin-top: var(--space-6); }

/* ─────────────────────────────────────────────────────────────────────
   3  type helpers
   ───────────────────────────────────────────────────────────────────── */
.eyebrow {
  font: var(--type-eyebrow); letter-spacing: var(--track-eyebrow);
  text-transform: uppercase; color: var(--accent);
  margin: 0 0 var(--space-3); display: block;
}
.lead { font: var(--type-body-lg); color: var(--fg-3); max-width: var(--measure); }
.small { font: var(--type-caption); color: var(--fg-3); }
/* --meta is 4.42:1 and fails AA at body size, so it is only ever used at 24px+
   or as a non-text edge. Small print uses --fg-3, which is 9.64:1. */
.meta { font: var(--type-caption); color: var(--fg-3); }
.meta-lg { font: 400 1.5rem/1.35 var(--font-supporting); color: var(--meta); }

/* Figures are Roboto with tabular numerals so columns of numbers align. */
.fig { font-family: var(--font-supporting); font-variant-numeric: tabular-nums; font-weight: 500; color: var(--fg-2); }
.fig-lg {
  font-family: var(--font-display); font-weight: 700; color: var(--accent);
  font-size: clamp(1.75rem, 3.2vw, 2.75rem); line-height: 1.05;
  font-variant-numeric: tabular-nums; letter-spacing: var(--track-display);
}
.basis { display: block; font: var(--type-caption); color: var(--fg-3); margin-top: var(--space-2); max-width: 40ch; }

.sec-head { max-width: 46rem; margin-bottom: var(--space-12); }
.sec-head .lead { margin-top: var(--space-4); }

/* ─────────────────────────────────────────────────────────────────────
   4  header
   ───────────────────────────────────────────────────────────────────── */
/* Opaque. At 94% the page text ghosted through the header as it scrolled under
   it, and a blur behind type is a cost with no argument for it here: the header
   carries the wordmark and the nav, which have to stay legible over whatever
   band happens to be passing. */
.site-head {
  position: sticky; top: 0; z-index: 50;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.site-head-in { display: flex; align-items: center; gap: var(--space-8); min-height: 72px; position: relative; }
/* The mark is 34px, but the link around it is the way home from every page, so the
   box you can hit is padded to 44. Measured at 390px on 2026-09-21: the mark alone
   gave a 34px target. */
.wordmark { display: inline-flex; align-items: center; flex: 0 0 auto; min-height: 44px; }
.wordmark img { height: 34px; width: auto; }

.nav { display: flex; align-items: center; gap: var(--space-2); margin-left: auto; }
.nav a {
  position: relative; text-decoration: none; color: var(--fg-2);
  font: 500 0.9375rem/1 var(--font-body);
  padding: var(--space-3) var(--space-3);
  transition: color var(--motion-base) var(--ease-standard);
}
.nav a::after {
  content: ""; position: absolute; left: var(--space-3); right: var(--space-3); bottom: 0.4rem;
  height: 2px; background: var(--accent); border-radius: var(--radius-pill);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--motion-base) var(--ease-standard);
}
.nav a:hover { color: var(--accent); }
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }
.nav a[aria-current="page"] { color: var(--accent); }

/* A component rule like `.nav a` (0,1,1) outranks a utility like `.call-primary`
   (0,1,0), which rendered the header call slate-on-teal and illegible. These
   restore the garment inside the nav, and drop its underline, which is for
   navigation links rather than buttons. */
.nav .call-primary, .nav .call-secondary { padding-inline: var(--space-6); margin-left: var(--space-4); }
.nav .call-primary { color: var(--accent-on); }
.nav .call-primary:hover { color: var(--accent-on); }
.nav .call-secondary { color: var(--accent); }
.nav .call-secondary:hover { color: var(--accent-hover); }
.nav .call-primary::after, .nav .call-secondary::after { display: none; }

.nav-toggle {
  display: none; margin-left: auto; cursor: pointer;
  background: transparent; border: 1px solid var(--meta); color: var(--fg-2);
  border-radius: var(--radius-pill); padding: 0.6rem 1rem; min-height: 44px;
  font: 500 0.875rem/1 var(--font-body);
}
@media (max-width: 899px) {
  .nav-toggle { display: inline-flex; align-items: center; }
  .nav {
    position: absolute; top: 100%; left: 0; right: 0; display: none;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--bg); border-bottom: 1px solid var(--border);
    padding: var(--space-2) var(--gutter) var(--space-6);
    box-shadow: var(--elev-card);
  }
  .nav.is-open { display: flex; }
  .nav a { padding: var(--space-4) 0; border-bottom: 1px solid var(--border-soft); min-height: 44px; display: flex; align-items: center; }
  .nav a::after { left: 0; right: 0; bottom: 0; }
  .nav .call-primary { margin-top: var(--space-4); justify-content: center; }
}

/* ─────────────────────────────────────────────────────────────────────
   5  calls to action: one garment per intent
   ───────────────────────────────────────────────────────────────────── */
/* Primary: the brand pill. Teal fill, white label, 44px. One per section. */
.call-primary {
  display: inline-flex; align-items: center; gap: var(--space-3);
  background: var(--accent); color: var(--accent-on); text-decoration: none;
  border: 1px solid var(--accent); border-radius: var(--radius-pill);
  padding: 0 var(--space-8); min-height: 48px;
  font: 600 0.9375rem/1 var(--font-body);
  transition: background var(--motion-base) var(--ease-standard), box-shadow var(--motion-base) var(--ease-standard);
}
.call-primary:hover { background: var(--accent-hover); color: var(--accent-on); }
.call-primary:active { background: var(--accent-active); }

/* Secondary: white with a teal edge. Never competes with the primary. */
.call-secondary {
  display: inline-flex; align-items: center; gap: var(--space-3);
  background: var(--bg); color: var(--accent); text-decoration: none;
  border: 1px solid var(--accent); border-radius: var(--radius-pill);
  padding: 0 var(--space-8); min-height: 48px;
  font: 600 0.9375rem/1 var(--font-body);
  transition: background var(--motion-base) var(--ease-standard);
}
.call-secondary:hover { background: var(--accent-tint); color: var(--accent-hover); }

/* Quiet: a text call with a rule that extends. For in-body cross references. */
.call-quiet {
  display: inline-flex; align-items: center; gap: var(--space-2);
  color: var(--accent); text-decoration: none; font-weight: 500;
  border-bottom: 1px solid var(--accent-tint); padding-bottom: 2px;
  transition: border-color var(--motion-base) var(--ease-standard);
}
.call-quiet::after { content: "\2192"; transition: transform var(--motion-base) var(--ease-standard); }
.call-quiet:hover { border-bottom-color: var(--accent); }
.call-quiet:hover::after { transform: translateX(4px); }

/* Row: the whole ledger row is the control. */
.call-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-4);
  align-items: center; text-decoration: none; color: var(--fg-2);
  padding: var(--space-6) 0; border-bottom: 1px solid var(--border);
  min-height: 48px; position: relative;
  transition: color var(--motion-base) var(--ease-standard);
}
.call-row::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: var(--accent); transform: scaleX(0); transform-origin: left;
  transition: transform var(--motion-base) var(--ease-standard);
}
.call-row .arrow { color: var(--accent); font-size: 1.125rem; transition: transform var(--motion-base) var(--ease-standard); }
.call-row:hover { color: var(--accent); }
.call-row:hover::before { transform: scaleX(1); }
.call-row:hover .arrow { transform: translateX(5px); }

/* Book: a quiet mono-ish call for scheduling. */
.call-book {
  display: inline-flex; align-items: center; gap: var(--space-3);
  font: 500 0.9375rem/1 var(--font-supporting); color: var(--accent);
  text-decoration: none; min-height: 44px;
  border-bottom: 1px dashed var(--meta); padding-bottom: 4px;
  transition: border-color var(--motion-base) var(--ease-standard);
}
.call-book:hover { border-bottom-color: var(--accent); border-bottom-style: solid; }

/* ─────────────────────────────────────────────────────────────────────
   6  cards, ledgers, strips
   ───────────────────────────────────────────────────────────────────── */
.cards { display: grid; gap: var(--space-6); grid-template-columns: 1fr; }
@media (min-width: 720px)  { .cards.two, .cards.four { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .cards.three { grid-template-columns: repeat(3, 1fr); }
                             .cards.four  { grid-template-columns: repeat(4, 1fr); } }
.card {
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: var(--space-8); display: flex; flex-direction: column; gap: var(--space-3);
  transition: border-color var(--motion-base) var(--ease-standard), transform var(--motion-base) var(--ease-standard);
}
.card h3 { margin-bottom: var(--space-1); }
.card p { font: var(--type-caption); font-size: 0.9375rem; color: var(--fg-3); margin-bottom: 0; max-width: none; }
.card .foot { margin-top: auto; padding-top: var(--space-4); }
a.card { text-decoration: none; }
a.card:hover { border-color: var(--accent); transform: translateY(-2px); }
/* The one shadow the brand permits, reserved for a single feature card. */
.card-raised { box-shadow: var(--elev-card); border-color: var(--border-soft); }

.ledger { border-top: 1px solid var(--border); }
.ledger-row {
  display: grid; gap: var(--space-2) var(--space-8); grid-template-columns: 1fr;
  padding: var(--space-6) 0; border-bottom: 1px solid var(--border); align-items: baseline;
}
@media (min-width: 720px) { .ledger-row { grid-template-columns: minmax(0,1fr) minmax(0,14rem); } .ledger-row .v { text-align: right } }
.ledger-row .k { color: var(--fg-2); font-weight: 500; }
.ledger-row .v { font-family: var(--font-supporting); font-variant-numeric: tabular-nums; color: var(--accent); font-weight: 700; font-size: 1.125rem; }

/* KPI strip divided by vertical hairlines. */
.kpis { display: grid; gap: 0; grid-template-columns: 1fr; border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; }
@media (min-width: 640px)  { .kpis { grid-template-columns: repeat(2, 1fr); } }
/* Four cells across only from 1200px. Between 1000 and 1200 a four-up strip
   gave each basis line about 180px, and a three-sentence basis (How we work,
   29 Sep 2026) poured into twelve lines of small print. */
@media (min-width: 1200px) { .kpis { grid-template-columns: repeat(4, 1fr); } }
.kpi { padding: var(--space-8); border-top: 1px solid var(--border); }
.kpi:first-child { border-top: 0; }
@media (min-width: 640px) {
  .kpi { border-top: 0; border-left: 1px solid var(--border); }
  .kpi:nth-child(2n+1) { border-left: 0; }
}
@media (min-width: 1200px) { .kpi:nth-child(2n+1) { border-left: 1px solid var(--border) } .kpi:first-child { border-left: 0 } }

/* Status pill: teal on the tint ground, 4.60:1. */
.pill {
  display: inline-flex; align-items: center; gap: var(--space-2);
  background: var(--accent-tint); color: var(--accent);
  border-radius: var(--radius-pill); padding: 0.3rem 0.75rem;
  font: var(--type-eyebrow); letter-spacing: 0.06em; text-transform: uppercase;
}
.pill-quiet { background: var(--surface-warm); color: var(--fg-3); }

/* ─────────────────────────────────────────────────────────────────────
   7  stepped rail
   ───────────────────────────────────────────────────────────────────── */
.rail { border-top: 1px solid var(--border); }
.rail-step {
  display: grid; gap: var(--space-2) var(--space-6); grid-template-columns: 3rem minmax(0, 1fr);
  padding: var(--space-6) 0; border-bottom: 1px solid var(--border); position: relative;
}
.rail-step .n {
  font: var(--type-eyebrow); letter-spacing: var(--track-eyebrow); color: var(--fg-3);
  font-size: 0.875rem; padding-top: 0.35rem;
}
.rail-step.is-paid .n { color: var(--accent); }
.rail-step p { font-size: 0.9375rem; margin-bottom: 0; }
.rail-step .tag { display: inline-block; margin-top: var(--space-3); }
.rail-step::before {
  content: ""; position: absolute; left: 1.45rem; top: 2.6rem; bottom: 0;
  width: 1px; background: var(--border);
}
.rail-step:last-child::before { display: none; }

/* ─────────────────────────────────────────────────────────────────────
   8  disclosure: the brand's own 0fr to 1fr accordion
   ───────────────────────────────────────────────────────────────────── */
.disclose { border-top: 1px solid var(--border); }
.disclose details { border-bottom: 1px solid var(--border); }
.disclose summary {
  cursor: pointer; list-style: none; position: relative;
  padding: var(--space-6) 2.5rem var(--space-6) 0;
  color: var(--fg-2); font-weight: 600; min-height: 48px;
  display: flex; align-items: center;
}
.disclose summary::-webkit-details-marker { display: none; }
.disclose summary::after {
  content: "+"; position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  color: var(--meta); font-size: 1.375rem; font-weight: 400; line-height: 1;
  transition: color var(--motion-base) var(--ease-standard);
}
.disclose summary:hover { color: var(--accent); }
.disclose summary:hover::after { color: var(--accent); }
.disclose details[open] summary::after { content: "\2212"; color: var(--accent); }
.disclose .body { padding-bottom: var(--space-6); font-size: 0.9375rem; }
.disclose .body p { max-width: 62ch; }

/* ─────────────────────────────────────────────────────────────────────
   9  document / figure surfaces
   ───────────────────────────────────────────────────────────────────── */
.figure-frame { border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; background: var(--bg); }
.figure-cap {
  padding: var(--space-3) var(--space-4); border-top: 1px solid var(--border);
  background: var(--surface); font: var(--type-caption); color: var(--fg-3);
}
.table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-md); }
.data { min-width: 34rem; font-size: 0.9375rem; font-variant-numeric: tabular-nums; }
.data th, .data td { padding: var(--space-4); text-align: left; border-bottom: 1px solid var(--border-soft); }
.data th {
  font: var(--type-eyebrow); letter-spacing: var(--track-eyebrow); text-transform: uppercase;
  color: var(--fg-3); background: var(--surface); border-bottom-color: var(--border);
}
.data td { color: var(--fg-3); }
.data td.num { font-family: var(--font-supporting); font-variant-numeric: tabular-nums; color: var(--fg-2); text-align: right; font-weight: 500; }
.data tr:last-child td { border-bottom: 0; }
.data .state { font: var(--type-eyebrow); letter-spacing: 0.06em; text-transform: uppercase; }
.data .state.on  { color: var(--accent); }
.data .state.off { color: var(--fg-3); }
/* Below 640px a data table stacks: each row is a block, each cell a line, and
   a cell shows its column heading as an eyebrow from data-label (written by
   the build from the table's own thead). Until 2026-09-29 the table scrolled
   sideways inside .table-wrap, which cut the right-hand columns off at the
   viewport edge with nothing to say so. A cell with no data-label still
   stacks; it just carries no heading. */
@media (max-width: 639px) {
  .table-wrap { position: relative; }
  .data { display: block; min-width: 0; width: 100%; }
  .data thead { display: block; position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .data tbody, .data tr, .data th, .data td { display: block; }
  .data tr { padding: var(--space-4) 0; border-bottom: 1px solid var(--border-soft); }
  .data tbody:last-child tr:last-child { border-bottom: 0; }
  .data th, .data td { padding: 0 var(--space-4); border-bottom: 0; }
  .data th + td, .data td + td { margin-top: var(--space-3); }
  .data th[scope="row"] { font: var(--type-body); font-weight: 600; text-transform: none; letter-spacing: normal; color: var(--fg-2); background: transparent; }
  .data th[scope="colgroup"], .data th[scope="rowgroup"] { padding: var(--space-3) var(--space-4); }
  .data tr:has(> th[scope="colgroup"]), .data tr:has(> th[scope="rowgroup"]) { padding: 0; border-bottom: 1px solid var(--border); }
  .data td[data-label]::before { content: attr(data-label); display: block; font: var(--type-eyebrow); letter-spacing: var(--track-eyebrow); text-transform: uppercase; color: var(--fg-3); margin-bottom: var(--space-1); }
  .data td.num { text-align: left; }
}

/* portraits: circular, graded, on a warm disc */
.portraits { display: grid; gap: var(--space-8); grid-template-columns: 1fr; }
@media (min-width: 720px)  { .portraits { grid-template-columns: repeat(2, 1fr) } }
@media (min-width: 1000px) { .portraits { grid-template-columns: repeat(3, 1fr) } }
.portrait { text-align: left; }
.portrait .shot {
  width: 132px; height: 132px; border-radius: var(--radius-pill); overflow: hidden;
  background: var(--surface-tint); margin-bottom: var(--space-4);
  display: flex; align-items: center; justify-content: center;
}
.portrait .shot img { width: 100%; height: 100%; object-fit: cover; filter: grayscale(1) sepia(0.12) contrast(0.96); }
/* No photograph on file: the person's initials, never a substitute face and
   never a note about what is missing. */
.portrait .shot.is-mono {
  font: 600 1.75rem/1 var(--font-display); letter-spacing: 0.02em; color: var(--fg-2);
}
/* When no approved photograph exists the slot says so rather than inventing a face. */
.portrait .shot.is-empty {
  border: 1px dashed var(--meta); background: var(--surface);
  font: var(--type-eyebrow); letter-spacing: var(--track-eyebrow);
  text-transform: uppercase; color: var(--fg-3); text-align: center; padding: var(--space-4);
}

/* ─────────────────────────────────────────────────────────────────────
   10  forms: control edges use --meta, never --border (1.49:1)
   ───────────────────────────────────────────────────────────────────── */
.field-row { margin-bottom: var(--space-6); }
label, legend {
  display: block; color: var(--fg-2); font-weight: 600;
  font-size: 0.9375rem; margin-bottom: var(--space-2);
}
input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="file"]):not([type="range"]):not([type="color"]):not([type="hidden"]),
select, textarea {
  width: 100%; background: var(--bg); color: var(--fg-3);
  border: 1px solid var(--meta); border-radius: var(--radius-sm);
  padding: 0.75rem var(--space-4); min-height: 48px;
  font: var(--type-body); font-family: var(--font-body);
  transition: border-color var(--motion-base) var(--ease-standard), box-shadow var(--motion-base) var(--ease-standard);
}
textarea { min-height: 8rem; resize: vertical; }
input:hover, select:hover, textarea:hover { border-color: var(--fg-2); }
input:focus, select:focus, textarea:focus { border-color: var(--accent); box-shadow: var(--focus-ring); outline: none; }
fieldset { border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--space-6); margin: 0 0 var(--space-6); min-width: 0; }
.choice { display: flex; gap: var(--space-3); align-items: flex-start; padding: var(--space-2) 0; }
.choice input { width: auto; min-height: 0; margin-top: 0.85rem; accent-color: var(--accent); }
.choice label {
  margin: 0; font-weight: 400; color: var(--fg-3); font-size: 0.9375rem;
  min-height: 44px; display: flex; align-items: center; flex: 1; cursor: pointer;
}
.hint { font: var(--type-caption); color: var(--fg-3); margin-top: var(--space-2); }

.notice {
  border-left: 3px solid var(--accent); background: var(--surface);
  padding: var(--space-6); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: 0.9375rem; color: var(--fg-3); margin-bottom: var(--space-8);
}
.notice strong { color: var(--fg-2); }
.pending {
  border: 1px dashed var(--meta); border-radius: var(--radius-sm);
  padding: var(--space-6); margin: 0 0 var(--space-6);
  color: var(--fg-3); font-size: 0.9375rem; background: var(--surface);
}
.pending .plabel {
  display: block; font: var(--type-eyebrow); letter-spacing: var(--track-eyebrow);
  text-transform: uppercase; color: var(--fg-3); margin-bottom: var(--space-2);
}

/* ─────────────────────────────────────────────────────────────────────
   11  footer: slate with a teal keyline, as the firm's collateral does
   ───────────────────────────────────────────────────────────────────── */
.site-foot { background: var(--fg-2); color: var(--bg); border-top: 3px solid var(--accent); padding-block: var(--space-16) var(--space-8); }
.site-foot .foot-grid { display: grid; gap: var(--space-8); grid-template-columns: 1fr; }
@media (min-width: 720px) { .site-foot .foot-grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; } }
.site-foot h3 {
  font: var(--type-eyebrow); font-size: 0.8125rem; letter-spacing: var(--track-eyebrow);
  text-transform: uppercase; color: var(--accent-tint); margin-bottom: var(--space-3);
}
.site-foot ul { list-style: none; padding: 0; margin: 0; }
.site-foot li { margin-bottom: var(--space-1); }
/* Each link is a block with room around it, so on a phone the target is the
   row and not the eighteen pixels of its text. */
.site-foot a { display: inline-block; padding-block: 0.3rem; color: var(--bg); text-decoration: none; font-size: 0.9375rem; opacity: 0.86; transition: opacity var(--motion-base) var(--ease-standard); }
.site-foot a:hover { opacity: 1; color: var(--accent-tint); }
.site-foot .foot-mark img { height: 30px; filter: brightness(0) invert(1); }
.foot-legal {
  margin-top: var(--space-12); padding-top: var(--space-6);
  border-top: 1px solid color-mix(in srgb, var(--bg) 22%, transparent);
  font: var(--type-caption); color: var(--bg); opacity: 0.78; max-width: 82ch;
}

/* ─────────────────────────────────────────────────────────────────────
   12  motion
   ───────────────────────────────────────────────────────────────────── */
/* Once-only reveal. The element is fully visible before JavaScript runs and
   only becomes animatable when the script marks the document, so a reader with
   no JS, or a failed script, never sees a blank page. */
.js-reveal [data-reveal] { opacity: 0; transform: translateY(14px); }
.js-reveal [data-reveal].is-in {
  opacity: 1; transform: none;
  transition: opacity var(--motion-reveal) var(--ease-out), transform var(--motion-reveal) var(--ease-out);
}
@media (prefers-reduced-motion: reduce) {
  .js-reveal [data-reveal] { opacity: 1; transform: none; }
}

/* The wordmark draws itself once on first load. */
@keyframes mark-in { from { opacity: 0; transform: translateY(-4px) } to { opacity: 1; transform: none } }
.js-reveal .wordmark img { animation: mark-in var(--motion-reveal) var(--ease-out) both; }

/* Section rules that draw in as they arrive. */
.rule-draw { height: 1px; background: var(--border); position: relative; }
.rule-draw::after {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 100%;
  background: var(--accent); transform: scaleX(0); transform-origin: left;
}
.js-reveal .rule-draw.is-in::after { transform: scaleX(1); transition: transform var(--motion-draw) var(--ease-out); }

/* A call that is the only thing in its block is a target, not a word in a
   sentence, so it takes the 44px floor. WCAG 2.5.8 exempts a link inline in a
   sentence, and :only-child is what separates the two cases. */
p > .call-quiet:only-child,
p > .call-book:only-child,
li > .call-quiet:only-child {
  min-height: 44px;
}

/* ─────────────────────────────────────────────────────────────────────
   13  the unified site: new chrome, and the three pages built against
       STRUCTURE.md section 4 (Raise capital, For investors, Partners).
       Appended 2026-09-21. Tokens only, no hex, and no raw font-size
       outside the composite type tokens.
   ───────────────────────────────────────────────────────────────────── */

/* 13.1  the header's quiet sign in link.
   STRUCTURE section 3 puts it right of the persistent call and asks for it to
   be quiet. It is deliberately not a CTA garment. Site chrome is capped at
   three accents (the current-page nav link, the header call, the footer
   keyline) and a teal fourth here would break that cap in chrome.mjs, which
   is where the contract says to fix it. --fg-3 is 9.64:1 on white. */
.nav .nav-quiet { color: var(--fg-3); font-weight: 400; }

/* 14.23  a dropdown under a nav item. The top link is a page; the menu lists
   the pages under it. Desktop: opens on hover, on focus within, or from the
   chevron (a real button, so a keyboard and a touch can open it without
   leaving the page). Phone: the menu is simply open under its item. */
.nav-item { position: relative; display: flex; align-items: center; }
.nav-more {
  display: inline-grid; place-items: center; width: 2.25rem; height: 2.75rem; margin-left: -0.5rem;
  border: 0; background: transparent; color: var(--fg-3); border-radius: var(--radius-sm); cursor: pointer;
  transition: transform var(--motion-base) var(--ease-standard), color var(--motion-base) var(--ease-standard);
}
.nav-more .ico { width: 1rem; height: 1rem; stroke-width: 2; }
.nav-more:hover, .nav-item:hover .nav-more, .nav-item.is-menu-open .nav-more { color: var(--accent); }
.nav-item.is-menu-open .nav-more, .nav-item:hover .nav-more { transform: rotate(180deg); }
.nav-menu {
  display: none; position: absolute; left: 50%; top: calc(100% + 0.5rem); transform: translateX(-50%);
  min-width: 14rem; padding: var(--space-2); z-index: 40;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-md);
  box-shadow: var(--elev-card);
}
.nav-menu::before { content: ""; position: absolute; left: 0; right: 0; top: -0.6rem; height: 0.6rem; }
.nav-item:hover .nav-menu, .nav-item:focus-within .nav-menu, .nav-item.is-menu-open .nav-menu { display: grid; }
.nav-menu a {
  display: block; padding: 0.6rem 0.9rem; border-radius: var(--radius-sm); white-space: nowrap;
  color: var(--fg-2); font-weight: 500;
}
.nav-menu a::after { display: none; }
.nav-menu a:hover, .nav-menu a[aria-current="page"] { background: var(--accent-tint); color: var(--fg-2); }
.has-film .site-head.is-over .nav .nav-more { color: var(--bg); }
/* Inside the menu the links are on white whatever the bar is over; this rule
   has to outrank the over-the-band rule of section 14.16 by one class. */
.has-film .site-head.is-over .nav .nav-menu a { color: var(--fg-2); }
.has-film .site-head.is-over .nav .nav-menu a:hover, .has-film .site-head.is-over .nav .nav-menu a[aria-current="page"] { color: var(--fg-2); background: var(--accent-tint); }
@media (max-width: 959px) {
  .nav-item { flex-direction: column; align-items: stretch; }
  .nav-more { display: none; }
  .nav-menu { display: grid; position: static; transform: none; min-width: 0; padding: 0 0 var(--space-3) var(--space-5); border: 0; box-shadow: none; background: transparent; }
  .nav-menu a { padding: 0.45rem 0; color: var(--fg-3); }
}

/* On phones the nav is a stretched column. The call and the sign in link were
   inheriting the desktop left margin, which read as an accidental indent once
   a second control sat under the first. */
@media (max-width: 899px) {
  .nav .call-secondary { margin-left: 0; margin-top: var(--space-4); justify-content: center; }
  .nav .nav-quiet { justify-content: center; }
}

/* 13.2  footer small print.
   It replaces a `.meta` in the footer, which inherited --fg-3 (#474444) onto
   the slate footer ground (#394a58): about 1.1:1, effectively unreadable.
   `.foot-legal` already solved the same problem with --bg at 78 per cent, and
   this is that treatment for a short note. */
.site-foot .foot-note {
  margin-top: var(--space-4); max-width: 34ch;
  font: var(--type-caption); color: var(--bg); opacity: 0.78;
}

/* 13.3  anchored headings clear the 72px sticky header when jumped to.
   Three page generators had declared this identically in their own scoped
   blocks; it belongs here once. */
h2[id], h3[id] { scroll-margin-top: var(--space-24); }

/* 13.4  .matrix: sibling cards whose labelled rows line up across cards.
   STRUCTURE section 4 requires the Raise capital "what we need from you /
   what Projects RH delivers / typical stage" cards to be siblings carrying
   IDENTICAL labelled rows at IDENTICAL heights. Three independent cards
   cannot do that: each row would size to its own text and the reader would
   have to hunt for the matching row in the next card.

   Row alignment across siblings is what `subgrid` is for. The outer grid owns
   the rows; each card subscribes to them, so row 3 is one height across all
   three cards no matter which card has the longest sentence in it. `--rows`
   is the number of labelled rows the page emits, which is a count rather than
   a measurement, so it is passed inline by the generator.

   Where subgrid is unsupported the declaration is dropped and the cards fall
   back to ordinary full-height cards: still correct, just not row-aligned.
   Below 1000px there is one column and nothing to align. */
.matrix { display: grid; gap: var(--space-6); grid-template-columns: 1fr; }
.matrix .mrow {
  border-top: 1px solid var(--border-soft);
  padding-block: var(--space-4);
}
.matrix .mlabel {
  display: block; font: var(--type-eyebrow); letter-spacing: var(--track-eyebrow);
  text-transform: uppercase; color: var(--fg-3); margin-bottom: var(--space-2);
}
.matrix .mrow p { margin-bottom: 0; }
@media (min-width: 1000px) {
  .matrix { grid-template-columns: repeat(3, 1fr); }
  /* The three cards share row baselines only where subgrid exists (Chrome 117,
     Safari 16, Firefox 71, Samsung Internet 25). The feature query is deliberate:
     without it the browser drops the subgrid line alone and the cards keep a grid
     they no longer use. Inside the query the whole mechanism is skipped, so an
     older browser gets three ordinary cards side by side, each sizing its own
     rows. The comparison still reads; only the shared baselines are lost. */
  @supports (grid-template-rows: subgrid) {
    .matrix { grid-template-rows: auto repeat(var(--rows, 5), auto); }
    .matrix > .card {
      grid-row: 1 / -1;
      display: grid;
      grid-template-rows: subgrid;
      gap: 0;
    }
  }
}

/* 13.5  .lede-cap: a caption under a photographic plate that is not a
   `.figure-cap` because it sits outside the frame. Same treatment as
   `.basis`, without the 40ch clamp that suits a figure beside a number. */
.lede-cap { display: block; font: var(--type-caption); color: var(--fg-3); margin-top: var(--space-3); }

/* 13.6  .stub: the two retired pages.
   `/who-we-help` and `/opportunities` are 301s in Caddy. These files are the
   static mirror's fallback, so they are a real page with a real heading and a
   real link rather than a blank document with a meta refresh in it. */
.stub { min-height: 46vh; display: flex; align-items: center; }


/* ─────────────────────────────────────────────────────────────────────
   11  film bands: the hero, the sector strip, the closing band, and the
       subpage mastheads. Promoted from the homepage on 2026-09-23 so every
       page can carry one. Tokens only.
   ───────────────────────────────────────────────────────────────────── */
:root { --head-h: 73px; }
/* -- hero: a film band, then the colophon on white -----------------------
   The hero was a document masthead: an eyebrow rule, a two-column grid and a
   colophon rail, all on white, with no image anywhere in the first viewport.
   It was accurate and it was inert, and the open Phase 6 warning against it
   (no kinetic brand element above the fold) is closed by this band rather
   than waived.

   The band is the firm's own reception floor at blue hour with its mark on
   the wall, held still under a slate scrim, with the claim over the dark left
   third. The colophon keeps every word it had; it moves below the band and
   runs horizontally, where it reads as the masthead's imprint rather than a
   sidebar. Measured on a reference site, the equivalent band is a
   900px full-bleed autoplaying loop; ours is shorter, because the twenty-one
   steps below it are the reason anyone stays. */
.hero-film {
  position: relative; overflow: clip; background: var(--fg-2);
  min-height: min(86vh, 720px);
  display: flex; align-items: flex-end;
  padding-block: var(--space-24) var(--space-16);
}
.film-media { position: absolute; inset: 0; }
.hero-film-media { position: absolute; inset: 0; }
.hero-film-media img, .hero-film-media video, .film-media img, .film-media video {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: 56% 50%;
}
/* The band is wider than the frame, so cover crops top and bottom here and the
   horizontal value does nothing. Biased low, which puts the table and the
   chairs behind the copy and lifts the photographed sign above it: a second,
   half-legible wordmark reading through three columns of body text is the one
   thing this image can do wrong. */
.band-film .film-media img, .band-film .film-media video { object-position: 50% 78%; }
/* The video sits over the still and is transparent until its first frame, so
   the poster is what shows while it loads and what stays when it never does.
   It carries no src in the markup: assets/site.js sets it only when motion is
   allowed, so a reduced-motion reader and a reader with no JavaScript both get
   the still and neither downloads the file. */
.hero-film-media video, .film-media video { position: absolute; inset: 0; }
/* Two scrims, not one. The diagonal carries the text and is measured against
   the rendered pixels under the headline, not against the token; the flat one
   pulls the whole band into a single slate field, because the lit limestone on
   the right is two stops warmer than the walnut on the left and without it the
   band reads as two photographs stitched together. */
.film-scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(101deg,
      color-mix(in srgb, var(--fg-2) 94%, transparent) 0%,
      color-mix(in srgb, var(--fg-2) 92%, transparent) 34%,
      /* The copy column ends at 46rem, which is 51% of the band at 1440. The
         third call sat just inside that and measured 2.86:1 against the lit
         window behind it, so the scrim holds its strength to 54% and only
         then opens onto the photograph. */
      color-mix(in srgb, var(--fg-2) 88%, transparent) 54%,
      color-mix(in srgb, var(--fg-2) 48%, transparent) 76%,
      color-mix(in srgb, var(--fg-2) 26%, transparent) 100%),
    linear-gradient(to top,
      color-mix(in srgb, var(--fg-2) 72%, transparent) 0%,
      color-mix(in srgb, var(--fg-2) 18%, transparent) 38%,
      transparent 62%);
}
/* Under 961px the copy runs the full width, so the diagonal cannot carry it:
   the scrim goes flat and the frame moves off the sign and onto the dark
   panelling, where a headline has somewhere to sit. */
@media (max-width: 960px) {
  .hero-film-media img, .hero-film-media video { object-position: 24% 50%; }
  .film-scrim {
    background:
      linear-gradient(to bottom,
        color-mix(in srgb, var(--fg-2) 82%, transparent) 0%,
        color-mix(in srgb, var(--fg-2) 90%, transparent) 46%,
        color-mix(in srgb, var(--fg-2) 94%, transparent) 100%);
  }
}
.hero-film-in { position: relative; }
.hero-film .hero-note { font-weight: 400; }
.hero-film-copy { max-width: 46rem; }

.hero-film h1 { color: var(--bg); font: var(--type-display); letter-spacing: var(--track-display); max-width: 17ch; }
/* A short, wide screen (a laptop with the browser's own bars) has less height
   than the display size assumes; the heading steps down so both calls stay on
   the first screen. */
@media (min-width: 960px) and (max-height: 700px) {
  .hero-film h1 { font-size: clamp(2rem, 3.6vw, 3rem); }
  .hero-film .lead { margin-top: var(--space-5); }
  .hero-calls { margin-top: var(--space-6); }
}
.hero-film .lead { color: var(--bg); margin-top: var(--space-6); max-width: 40rem; }
.hero-film .hero-note { color: var(--accent-tint); margin-top: var(--space-5); max-width: 52ch; }
.hero-rule {
  font: var(--type-eyebrow); letter-spacing: var(--track-eyebrow); text-transform: uppercase;
  color: var(--accent-tint); margin: 0 0 var(--space-8); padding-bottom: var(--space-4);
  border-bottom: 1px solid color-mix(in srgb, var(--bg) 30%, transparent);
  /* Not the value none. On white this line ran the full width of the band; over the
     photograph its right end crossed onto lit limestone and measured 2.70:1
     there. It is now the width of the copy it introduces, which is the only
     part of the band the scrim is built to carry. */
  max-width: 46rem;
}
.hero-calls { margin-top: var(--space-8); gap: var(--space-5); }
/* On the dark ground the secondary call's teal-on-tint pairing is 4.34:1 and
   the quiet call's slate is invisible, so both are restated in white here.
   The primary keeps its teal fill: white on teal is 5.56:1 whatever is behind
   the button, and it stays the one filled thing on the screen. */
.hero-film .call-secondary {
  background: transparent; color: var(--bg);
  border: 1px solid color-mix(in srgb, var(--bg) 62%, transparent);
}
.hero-film .call-secondary:hover { background: color-mix(in srgb, var(--bg) 14%, transparent); color: var(--bg); border-color: var(--bg); }
.hero-film .call-quiet { color: var(--bg); border-bottom-color: color-mix(in srgb, var(--bg) 44%, transparent); }
.hero-film .call-quiet:hover { color: var(--accent-tint); border-bottom-color: var(--accent-tint); }
/* A quiet call standing beside another call is a target, not a word in a
   sentence, so it takes the touch floor. site.css gives that only to a quiet
   call that is alone in its paragraph. */
.row > .call-quiet { min-height: 48px; }

/* -- the sector strip ------------------------------------------------------
   Fifteen thousand pixels of type with one photograph in it was the honest
   complaint. This strip introduces the marketplace band with the kind of
   asset the marketplace is actually about, and it carries that band's own
   heading rather than existing as decoration under one. Every listing on the
   register is anonymous, so the picture cannot be a project: it says so in
   the line under it, on the band, not in a caption a reader has to find. */
.strip-film {
  position: relative; overflow: clip; background: var(--fg-2); color: var(--bg);
  padding-block: var(--section-y);
  min-height: min(62vh, 520px); display: flex; align-items: flex-end;
}
/* Its own scrim, lighter than the closing band's. That one carries three
   columns of body copy and has to be nearly opaque; this one carries a
   heading and one paragraph in the left half, so the right half can stay a
   photograph. Set on the diagonal for the same reason the hero's is. */
.strip-film .film-scrim-flat {
  background:
    linear-gradient(99deg,
      color-mix(in srgb, var(--fg-2) 90%, transparent) 0%,
      color-mix(in srgb, var(--fg-2) 82%, transparent) 40%,
      color-mix(in srgb, var(--fg-2) 44%, transparent) 72%,
      color-mix(in srgb, var(--fg-2) 22%, transparent) 100%),
    linear-gradient(to top,
      color-mix(in srgb, var(--fg-2) 62%, transparent) 0%,
      transparent 58%);
}
.strip-film .sec-head { max-width: 40rem; }
/* Same reason as the hero: under 961px the copy runs the full width of the
   band, so a diagonal cannot carry it. Measured at 390 the lead was 3.42:1 and
   the basis line 3.63:1 against the lit sand on the right of the frame. */
@media (max-width: 960px) {
  .strip-film .film-scrim-flat {
    background:
      linear-gradient(to bottom,
        color-mix(in srgb, var(--fg-2) 76%, transparent) 0%,
        color-mix(in srgb, var(--fg-2) 88%, transparent) 40%,
        color-mix(in srgb, var(--fg-2) 93%, transparent) 100%);
  }
}
.strip-film-in { position: relative; }
.strip-film h2, .strip-film .lead { color: var(--bg); }
.strip-film .sec-head { margin-bottom: var(--space-8); }
.strip-film .strip-basis { color: var(--accent-tint); margin: 0; }
.band-film { position: relative; overflow: clip; background: var(--fg-2); }
.band-film-in { position: relative; }
.film-scrim-flat {
  background:
    linear-gradient(to bottom,
      color-mix(in srgb, var(--fg-2) 93%, transparent) 0%,
      color-mix(in srgb, var(--fg-2) 96%, transparent) 55%,
      color-mix(in srgb, var(--fg-2) 97%, transparent) 100%);
}


/* The subpage masthead: the same band, shorter, with the page's H1 at the
   heading size rather than the display size. Which part of the frame shows is
   decided per film, because each was composed with a different quiet side. */
.hero-film.is-masthead { min-height: clamp(420px, 56vh, 600px); padding-block: var(--space-16) var(--space-12); }
.hero-film.is-masthead h1 { font: var(--type-h1); letter-spacing: var(--track-display); max-width: 24ch; }
.hero-film.is-masthead .lead { max-width: 44rem; }
.hero-film[data-film="room"] .film-media img, .hero-film[data-film="room"] .film-media video { object-position: 50% 62%; }
.hero-film[data-film="sector"] .film-media img, .hero-film[data-film="sector"] .film-media video { object-position: 50% 45%; }
.hero-film[data-film="lobby"] .film-media img, .hero-film[data-film="lobby"] .film-media video { object-position: 56% 50%; }
@media (max-width: 960px) {
  .hero-film[data-film="lobby"] .film-media img, .hero-film[data-film="lobby"] .film-media video { object-position: 24% 50%; }
}

/* ── the header over the film ──────────────────────────────────────────
   On a page that opens on a film band the header sits over it: transparent,
   white type, the wordmark knocked out to white, and it turns solid the moment
   the band scrolls out from under it. Only with JavaScript, because the
   switch is what makes it legible over the rest of the page; without it the
   header stays the opaque bar it always was, above the band. */
.js-reveal .has-film .site-head { margin-bottom: calc(-1 * var(--head-h)); }
.js-reveal .has-film .hero-film { padding-top: calc(var(--space-24) + var(--head-h)); }
.js-reveal .has-film .hero-film.is-masthead { padding-top: calc(var(--space-16) + var(--head-h)); }
.has-film .site-head { transition: background var(--motion-base) var(--ease-standard), border-color var(--motion-base) var(--ease-standard); }
.has-film .site-head.is-over { background: transparent; border-bottom-color: transparent; }
.has-film .site-head.is-over .nav a, .has-film .site-head.is-over .nav-toggle { color: var(--bg); }
.has-film .site-head.is-over .nav a::after { background: var(--bg); }
.has-film .site-head.is-over .nav .call-secondary { color: var(--bg); background: transparent; border-color: color-mix(in srgb, var(--bg) 62%, transparent); }
.has-film .site-head.is-over .nav .call-secondary:hover { background: color-mix(in srgb, var(--bg) 14%, transparent); border-color: var(--bg); }
.has-film .site-head.is-over .wordmark img { filter: brightness(0) invert(1); }
.has-film .site-head.is-over .nav-toggle { border-color: color-mix(in srgb, var(--bg) 62%, transparent); }

/* ── the reading-progress hairline ─────────────────────────────────── */
.pgbar { position: absolute; left: 0; top: 0; height: 3px; width: 100%; background: var(--accent); transform: scaleX(0); transform-origin: left; pointer-events: none; }
.has-film .site-head.is-over .pgbar { opacity: 0; }

/* ── the headline rise ─────────────────────────────────────────────────
   The H1 of a film band rises into view through a clip, once, on load. Under
   reduced motion and without JavaScript it is simply there. */
.rise { display: block; overflow: hidden; padding-bottom: 0.08em; margin-bottom: -0.08em; }
.rise > span { display: block; }
.js-reveal .rise > span { transform: translateY(112%); animation: rise 0.95s cubic-bezier(0.16, 1, 0.3, 1) 0.05s forwards; }
@keyframes rise { to { transform: none; } }
@media (prefers-reduced-motion: reduce) { .js-reveal .rise > span { animation: none; transform: none; } }

/* ── planks: the short rule over every section heading draws on arrival ── */
.plank { display: block; width: 48px; height: 2px; background: var(--fg-2); margin: 0 0 var(--space-5); }
.js-reveal .plank { transform: scaleX(0); transform-origin: left; transition: transform var(--motion-draw) var(--ease-out); }
.js-reveal .plank.is-in { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) { .js-reveal .plank { transform: none; transition: none; } }

/* ── images answer the pointer ─────────────────────────────────────── */
.figure-frame img { transition: transform 0.6s var(--ease-out); }
@media (hover: hover) {
  .figure-frame:hover img { transform: scale(1.02); }
  .portrait .shot img { transition: filter 0.35s var(--ease-standard); }
  .portrait:hover .shot img { filter: none; }
}
@media (prefers-reduced-motion: reduce) { .figure-frame img { transition: none; } .figure-frame:hover img { transform: none; } }


/* ─────────────────────────────────────────────────────────────────────
   14  the simplification pass, 30 September 2026
       One idea to a screen. A pane is a section sized to the viewport: its
       heading is larger, its copy is shorter, and its parts arrive one at a
       time. Tokens only. Everything here is additive; no rule above changes,
       because the signed-in workspace shares this file.
   ───────────────────────────────────────────────────────────────────── */

/* 14.1  the pane, its heading and its grounds */
.pane { position: relative; padding-block: var(--section-y); font: var(--type-body-xl); }
@media (min-width: 961px) and (min-height: 700px) {
  .pane.is-screen { min-height: min(calc(100svh - var(--head-h)), 58rem); display: grid; align-content: center; }
}
.pane-head { max-width: 44rem; margin-bottom: var(--space-12); }
.pane-head h1, .pane-head h2 { font: var(--type-h2-xl); letter-spacing: var(--track-display); text-wrap: balance; }
.pane-head .lead { font: var(--type-lead-xl); margin-top: var(--space-5); max-width: 38rem; text-wrap: pretty; }
.pane-head.is-center { margin-inline: auto; text-align: center; }
.pane-head.is-center .lead { margin-inline: auto; }
.pane-head.is-tight { margin-bottom: var(--space-8); }
.pane-row { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--space-6); margin-bottom: var(--space-12); }
.pane-row .pane-head { margin-bottom: 0; }
.pane-foot { margin-top: var(--space-12); }
.pane .row { max-width: none; }
/* A quiet call that stands alone beside a heading or under a note is a target,
   not a word in a sentence, so it takes the touch floor. */
.pane-row > .call-quiet, .read-note > .call-quiet { min-height: 44px; }

/* Neighbouring sections never share a ground. The two dark ones are added to
   .band-slate, which already restates every text colour for a dark field. */
.g-mist  { background: var(--grad-mist); }
.g-wash  { background: var(--grad-wash); }
.g-warm  { background: var(--grad-warm); }
.g-slate { background: var(--grad-slate); }
.g-deep  { background: var(--grad-deep); }

/* Calls on a dark ground. The hero restated these for itself; every other dark
   band needs the same two, so they are named once here. */
.on-dark .call-secondary {
  background: transparent; color: var(--bg);
  border: 1px solid color-mix(in srgb, var(--bg) 62%, transparent);
}
.on-dark .call-secondary:hover { background: color-mix(in srgb, var(--bg) 14%, transparent); color: var(--bg); border-color: var(--bg); }
.on-dark .call-quiet { color: var(--bg); border-bottom-color: color-mix(in srgb, var(--bg) 44%, transparent); }
.on-dark .call-quiet:hover { color: var(--accent-tint); border-bottom-color: var(--accent-tint); }

/* 14.2  icons: one line set, on a tint tile when it carries a step or a service */
.ico {
  width: 1.5rem; height: 1.5rem; flex: none; display: block;
  fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
.ico-tile {
  width: 4rem; height: 4rem; flex: none; display: grid; place-items: center;
  border-radius: var(--radius-lg); background: var(--accent-tint); color: var(--accent-active);
}
.ico-tile .ico { width: 2rem; height: 2rem; }
.ico-tile.is-lg { width: 5rem; height: 5rem; border-radius: 1.25rem; }
.ico-tile.is-lg .ico { width: 2.5rem; height: 2.5rem; stroke-width: 1.4; }
.band-slate .ico-tile { background: color-mix(in srgb, var(--bg) 14%, transparent); color: var(--bg); }

/* 14.3  tick and cross lists */
.ticks { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4); }
.ticks > li {
  display: grid; grid-template-columns: 1.75rem minmax(0, 1fr); gap: var(--space-4); align-items: start;
  margin: 0; max-width: none; font-size: 1.125rem; line-height: 1.45; color: var(--fg-2);
}
.ticks .tk {
  width: 1.75rem; height: 1.75rem; border-radius: var(--radius-pill); display: grid; place-items: center;
  background: var(--accent-tint); color: var(--accent-active); margin-top: 0.05em;
}
.ticks .tk .ico { width: 1rem; height: 1rem; stroke-width: 2.2; }
.ticks > li.is-no { color: var(--fg-3); }
.ticks > li.is-no .tk { background: var(--surface-tint); color: var(--fg-2); }
.ticks .sub { display: block; font-size: 0.9375rem; line-height: 1.5; color: var(--fg-3); margin-top: 2px; }
.band-slate .ticks > li { color: var(--bg); }
.band-slate .ticks .tk { background: color-mix(in srgb, var(--bg) 16%, transparent); color: var(--bg); }
@media (min-width: 720px) { .ticks.two { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--space-8); } }
@media (min-width: 960px) { .ticks.three { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: var(--space-8); } }

/* 14.3b  tiles: an icon, a heading and one sentence, two to four across */
.tiles { display: grid; gap: var(--space-8); grid-template-columns: 1fr; }
@media (min-width: 720px) { .tiles.two, .tiles.four { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px) { .tiles.three { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-12); } }
@media (min-width: 1080px) { .tiles.four { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.tile { display: grid; gap: var(--space-4); align-content: start; }
.tile h3 { font: var(--type-h3-xl); margin: 0; }
.tile p { margin: 0; color: var(--fg-3); max-width: 36ch; }
.tile-rule { margin-top: var(--space-12); padding-top: var(--space-8); border-top: 1px solid var(--border); }
.fine { font: var(--type-caption); font-weight: 400; color: var(--fg-3); margin: var(--space-6) 0 0; max-width: 62ch; }
.band-slate .fine, .on-dark .fine { color: var(--accent-tint); }

/* 14.4  the audience switch: three doors, one room at a time.
   Without JavaScript the tabs are links to three panels that all show. */
.aud-tabs { display: grid; gap: var(--space-4); grid-template-columns: 1fr; }
@media (min-width: 860px) { .aud-tabs { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-6); } }
.aud-tab {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-5); align-items: center;
  text-decoration: none; text-align: left; cursor: pointer;
  background: var(--bg); color: var(--fg-2);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-6); min-height: 6rem;
  transition: border-color var(--motion-base) var(--ease-standard), background var(--motion-base) var(--ease-standard), box-shadow var(--motion-base) var(--ease-standard);
}
.aud-tab .k { display: block; font: var(--type-h3-xl); color: var(--fg-2); }
.aud-tab .v { display: block; font: var(--type-caption); font-size: 0.875rem; color: var(--fg-3); margin-top: 2px; }
.aud-tab .ico-tile { transition: background var(--motion-base) var(--ease-standard), color var(--motion-base) var(--ease-standard); }
.aud-tab:hover { border-color: var(--meta); color: var(--fg-2); }
.aud-tab[aria-selected="true"] {
  border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent);
  background: color-mix(in srgb, var(--accent-tint) 38%, var(--bg));
}
.aud-tab[aria-selected="true"] .ico-tile { background: var(--accent); color: var(--accent-on); }
.aud-panel { margin-top: var(--space-12); scroll-margin-top: calc(var(--head-h) + var(--space-8)); }
.aud-body { display: grid; gap: var(--space-8); grid-template-columns: 1fr; align-items: center; }
@media (min-width: 960px) { .aud-body { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-16); } }
.aud-body h3 { font: 600 clamp(1.5rem, 2.4vw, 2rem)/1.2 var(--font-display); letter-spacing: var(--track-display); margin-bottom: var(--space-6); text-wrap: balance; }
.aud-body .row { margin-top: var(--space-8); }
.aud-photo { border-radius: var(--radius-lg); overflow: hidden; aspect-ratio: 3 / 2; background: var(--fg-2); }
.aud-photo img { width: 100%; height: 100%; object-fit: cover; }
@keyframes panel-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.js-tabs .aud-panel:not([hidden]) { animation: panel-in var(--motion-reveal) var(--ease-out) both; }
@media (prefers-reduced-motion: reduce) { .js-tabs .aud-panel:not([hidden]) { animation: none; } }

/* 14.5  numbered steps, for a real sequence and nothing else */
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-8); grid-template-columns: 1fr; }
.steps > li {
  margin: 0; max-width: none; position: relative;
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-5); align-items: start;
}
.steps .n { display: block; font: 500 0.875rem/1 var(--font-supporting); font-variant-numeric: tabular-nums; letter-spacing: 0.04em; color: var(--fg-3); margin-bottom: var(--space-2); }
.steps h3 { font: var(--type-h3-xl); margin-bottom: var(--space-2); }
.steps p { margin: 0; font-size: 1rem; line-height: 1.5; color: var(--fg-3); max-width: 34ch; }
.steps > li:not(:last-child)::before {
  content: ""; position: absolute; left: 2.5rem; top: 5rem; bottom: calc(-1 * var(--space-8));
  width: 1px; background: var(--border);
}
@media (min-width: 1000px) {
  .steps { grid-template-columns: repeat(var(--steps, 5), minmax(0, 1fr)); gap: var(--space-6); }
  /* The row of steps is one grid, so every item is as tall as the tallest. A
     shorter item must not stretch its own rows to fill that height, or its
     tile row grows and its heading sits lower than its neighbours'. */
  .steps > li { grid-template-columns: 1fr; grid-template-rows: 5rem auto; align-content: start; }
  .steps > li:not(:last-child)::before {
    left: 5rem; right: calc(-1 * var(--space-6)); top: 2.5rem; bottom: auto; width: auto; height: 1px;
  }
}
.steps.is-four { --steps: 4; }
.steps.is-three { --steps: 3; }

/* 14.6  one at a time. A `step` reveal is the ordinary once-only reveal with
   a delay by position, so a row of five arrives left to right. */
.js-reveal [data-reveal="step"][data-i="1"] { transition-delay: 110ms; }
.js-reveal [data-reveal="step"][data-i="2"] { transition-delay: 220ms; }
.js-reveal [data-reveal="step"][data-i="3"] { transition-delay: 330ms; }
.js-reveal [data-reveal="step"][data-i="4"] { transition-delay: 440ms; }
.js-reveal [data-reveal="step"][data-i="5"] { transition-delay: 550ms; }
@media (max-width: 999px) { .js-reveal [data-reveal="step"][data-i] { transition-delay: 0ms; } }

/* 14.7  the rail: a row of cards that scrolls sideways and snaps. It is a
   list with native scrolling, so touch, trackpad and keyboard all work before
   any script runs; the two buttons appear only when a script can drive them. */
.rail-x { position: relative; }
.rail-list {
  list-style: none; margin: 0 calc(-1 * var(--space-1)); padding: var(--space-1);
  display: grid; grid-auto-flow: column; grid-auto-columns: min(78vw, 17.5rem); gap: var(--space-6);
  overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--space-1); scrollbar-width: none;
}
.rail-list::-webkit-scrollbar { display: none; }
.rail-list > li { margin: 0; max-width: none; scroll-snap-align: start; }
.rail-list:focus-visible { box-shadow: var(--focus-ring); border-radius: var(--radius-lg); outline: none; }
.rail-ctrl { display: none; gap: var(--space-3); }
.js-rail .rail-ctrl { display: flex; }
.rail-btn {
  width: 48px; height: 48px; border-radius: var(--radius-pill); display: grid; place-items: center;
  border: 1px solid var(--meta); background: var(--bg); color: var(--fg-2); cursor: pointer; padding: 0;
  transition: border-color var(--motion-base) var(--ease-standard), color var(--motion-base) var(--ease-standard), opacity var(--motion-base) var(--ease-standard);
}
.rail-btn:hover { border-color: var(--accent); color: var(--accent); }
.rail-btn[disabled] { opacity: 0.38; cursor: default; border-color: var(--meta); color: var(--fg-2); }

/* 14.8  a person, in a square card. Portraits are the circle crops the firm
   publishes; they are graded to one value so a row of them reads as one
   set, and take their colour back under the pointer. */
.person {
  display: flex; flex-direction: column; aspect-ratio: 1 / 1; min-height: 100%;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: var(--space-6); text-decoration: none; color: inherit;
  transition: border-color var(--motion-base) var(--ease-standard);
}
.person-photo {
  width: 6rem; height: 6rem; flex: none; border-radius: var(--radius-pill); overflow: hidden;
  background: var(--surface-tint); display: grid; place-items: center; margin-bottom: var(--space-4);
  font: 600 1.5rem/1 var(--font-display); letter-spacing: 0.02em; color: var(--fg-2);
}
.person-photo img { width: 100%; height: 100%; object-fit: cover; transform: scale(1.06); filter: grayscale(1) contrast(0.97); transition: filter 0.35s var(--ease-standard); }
.person-photo.is-inset img { transform: scale(1.36); }
.person h3, .person .name { font: 600 1.25rem/1.25 var(--font-display); color: var(--fg-2); margin: 0 0 var(--space-1); }
.person .role { font: var(--type-caption); color: var(--fg-3); margin: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.person .more { margin-top: auto; padding-top: var(--space-3); display: inline-flex; align-items: center; gap: var(--space-2); font: 600 0.9375rem/1 var(--font-body); color: var(--fg-2); }
.person .more .ico { width: 1rem; height: 1rem; stroke-width: 2; transition: transform var(--motion-base) var(--ease-standard); }
a.person:hover { border-color: var(--accent); }
a.person:hover .more { color: var(--accent); }
a.person:hover .more .ico { transform: translateX(3px); }
@media (hover: hover) { .person:hover .person-photo img { filter: none; } }
.person:focus-visible .person-photo img { filter: none; }

/* 14.9  questions. The brand's own disclosure, set at reading size, beside a
   heading that stays put while the answers are read. */
.faq { display: grid; gap: var(--space-8); grid-template-columns: 1fr; }
@media (min-width: 960px) {
  .faq { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: var(--space-16); align-items: start; }
  .faq > .pane-head { position: sticky; top: calc(var(--head-h) + var(--space-8)); margin-bottom: 0; }
}
.faq .disclose summary { font: var(--type-h3-xl); padding-block: var(--space-6); min-height: 4.5rem; }
.faq .disclose summary::after { font-size: 1.75rem; color: var(--fg-2); }
.faq .disclose .body { font: var(--type-body-xl); padding-bottom: var(--space-8); }
.faq .disclose .body p { max-width: 60ch; }

/* 14.10  the validation ribbon, and a listing as a card */
/* A gilt ribbon over the photograph (Matthew, 30 September: "a colored gold
   ribbon ... an icon with the badge"): a satin band with a highlight along
   its top edge and a deeper gold along its foot, a swallowtail end, and a
   folded corner under its root where it turns the frame. The icon sits in a
   dark medallion, a seal on the ribbon, so the glyph reads on gold. Two
   states, told apart by the ground as well as the glyph: validated is the
   full gold with a shield; pending is pale gold with a clock. The lettering is
   dark on both, because no white reads on gold. Same shape both times, so a
   reader learns one thing. */
.badge-valid {
  position: relative; display: inline-flex; align-items: center; gap: 0.55rem;
  padding: 0.4rem 1.5rem 0.4rem 0.45rem; border-radius: 0 3px 3px 0;
  background: linear-gradient(180deg, color-mix(in srgb, var(--gold) 68%, var(--bg)) 0%, var(--gold) 38%, var(--gold) 62%, var(--gold-deep) 100%);
  color: var(--fg);
  font: 700 0.8125rem/1 var(--font-supporting); letter-spacing: 0.02em; white-space: nowrap;
  clip-path: polygon(0 0, 100% 0, calc(100% - 0.75rem) 50%, 100% 100%, 0 100%);
  filter: drop-shadow(0 2px 3px color-mix(in srgb, var(--fg) 32%, transparent));
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--bg) 55%, transparent);
}
.badge-valid .badge-ico {
  display: inline-grid; place-items: center; flex: none; width: 1.55rem; height: 1.55rem; border-radius: 50%;
  background: color-mix(in srgb, var(--fg) 78%, var(--gold-deep)); color: var(--gold);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--gold-deep) 60%, transparent), inset 0 1px 0 color-mix(in srgb, var(--bg) 18%, transparent);
}
.badge-valid .ico { width: 0.95rem; height: 0.95rem; stroke-width: 2.4; flex: none; }
.badge-valid .badge-text { padding-top: 1px; }
.badge-valid.is-pending {
  background: linear-gradient(180deg, var(--bg) 0%, var(--gold-pale) 40%, var(--gold-pale) 62%, color-mix(in srgb, var(--gold-pale) 62%, var(--gold)) 100%);
  color: var(--fg-2);
}
.badge-valid.is-pending .badge-ico { background: var(--fg-2); color: var(--gold-pale); box-shadow: 0 0 0 1px color-mix(in srgb, var(--gold-deep) 35%, transparent); }
.badge-valid.is-lg { padding: 0.5rem 1.8rem 0.5rem 0.55rem; font-size: 0.9375rem; gap: 0.65rem; }
.badge-valid.is-lg .badge-ico { width: 1.85rem; height: 1.85rem; }
.badge-valid.is-lg .ico { width: 1.1rem; height: 1.1rem; }
/* Over a photograph the ribbon starts outside the frame and shows its fold:
   a small darker triangle under the root, as if the band turned the corner. */
.deal-img .badge-valid, .mk-d-photo .badge-valid {
  position: absolute; left: 0; top: var(--space-5); z-index: 1;
}
.deal-img .badge-valid::before, .mk-d-photo .badge-valid::before {
  content: ""; position: absolute; left: 0; bottom: -0.45rem; width: 0.45rem; height: 0.45rem;
  background: var(--gold-deep); clip-path: polygon(0 0, 100% 0, 100% 100%);
}
.deal-img .badge-valid.is-pending::before, .mk-d-photo .badge-valid.is-pending::before { background: color-mix(in srgb, var(--gold-deep) 55%, var(--gold-pale)); }
.deal-grid { display: grid; gap: var(--space-6); grid-template-columns: 1fr; }
@media (min-width: 720px)  { .deal-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1040px) { .deal-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.deal {
  display: flex; flex-direction: column; overflow: hidden; text-decoration: none; color: inherit;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-lg);
  transition: border-color var(--motion-base) var(--ease-standard), transform var(--motion-base) var(--ease-standard);
}
a.deal:hover { border-color: var(--accent); transform: translateY(-2px); color: inherit; }
.deal-img { position: relative; aspect-ratio: 3 / 2; overflow: hidden; background: var(--surface-tint); }
.deal-img img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s var(--ease-out); }
a.deal:hover .deal-img img { transform: scale(1.03); }
.deal-img .badge-valid { position: absolute; left: var(--space-4); top: var(--space-4); }
.deal-body { display: flex; flex-direction: column; gap: var(--space-2); flex: 1; padding: var(--space-6); }
/* The card is one link. Where it is drawn from spans inside an anchor, as the
   marketplace draws it, each part still has to be a block. */
.deal-img, .deal-sector, .deal-title, .deal-desc { display: block; }
.deal-sector { font: var(--type-caption); color: var(--fg-3); margin: 0; }
.deal h3, .deal-title { font: var(--type-h3-xl); color: var(--fg-2); margin: 0; }
.deal-title { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden; }
.deal-desc { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; font-size: 1rem; line-height: 1.5; color: var(--fg-3); }
.deal-foot {
  margin-top: auto; padding-top: var(--space-4); border-top: 1px solid var(--border-soft);
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4);
}
.deal-ticket { font: 700 1.25rem/1.1 var(--font-supporting); font-variant-numeric: tabular-nums; color: var(--fg-2); }
.deal-region { font: var(--type-caption); color: var(--fg-3); text-align: right; }
@media (prefers-reduced-motion: reduce) { a.deal:hover { transform: none; } a.deal:hover .deal-img img { transform: none; } }

/* 14.11  the closing call, over a photograph */
.cta-band { position: relative; overflow: clip; background: var(--fg-2); color: var(--bg); text-align: center; }
.cta-band .film-media img { object-position: 50% 58%; }
.cta-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--accent-active) 90%, transparent) 0%,
    color-mix(in srgb, var(--fg-2) 88%, transparent) 70%);
}
.cta-band-in { position: relative; }
.cta-band h2 { font: var(--type-display); letter-spacing: var(--track-display); color: var(--bg); max-width: 18ch; margin-inline: auto; text-wrap: balance; }
.cta-band .lead { font: var(--type-lead-xl); color: var(--bg); margin: var(--space-5) auto 0; max-width: 34rem; }
.cta-band .row { justify-content: center; margin-top: var(--space-8); gap: var(--space-5); max-width: none; }
.cta-band .fine { margin-inline: auto; }

/* 14.12  the homepage hero fills the first screen, and a film pane fills one too */
.hero-film.is-home { min-height: min(100svh, 56rem); }
@media (min-width: 961px) and (min-height: 700px) {
  .strip-film.is-screen { min-height: min(calc(100svh - var(--head-h)), 58rem); }
}
.strip-film { contain: layout paint; }
.strip-film .pane-head h2, .strip-film .pane-head .lead { color: var(--bg); }

/* 14.13  a page with two sides. The switch is the audience switch at page
   level; each side is a run of panes inside one [data-panel]. */
@media (min-width: 720px) { .aud-tabs.is-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); } }
.js-tabs [data-panel]:not([hidden]) { animation: panel-in var(--motion-reveal) var(--ease-out) both; }
@media (prefers-reduced-motion: reduce) { .js-tabs [data-panel]:not([hidden]) { animation: none; } }
.switch-bar { padding-block: var(--space-12) 0; }
[data-panel] > .pane:first-child { padding-top: var(--space-16); }
[data-panel] { scroll-margin-top: calc(var(--head-h) + var(--space-8)); }

/* 14.14  text beside a photograph */
.split { display: grid; gap: var(--space-8); grid-template-columns: 1fr; align-items: center; }
@media (min-width: 960px) { .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-16); } .split.is-flip > :first-child { order: 2; } }
.split .pane-head { margin-bottom: var(--space-8); }
.photo { border-radius: var(--radius-lg); overflow: hidden; aspect-ratio: 3 / 2; background: var(--fg-2); }
.photo img { width: 100%; height: 100%; object-fit: cover; }

/* 14.15  a figure that is a fact: one number, one line under it */
.stats { display: grid; gap: var(--space-6); grid-template-columns: 1fr; }
@media (min-width: 720px) { .stats { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-8); } }
@media (min-width: 1080px) { .stats.is-five { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-6); } .stats.is-five .fig-xl { font-size: clamp(1.5rem, 2.1vw, 2rem); } }
.stat { border-top: 2px solid var(--fg-2); padding-top: var(--space-5); }
.stat .fig-xl { display: block; font: 700 clamp(1.75rem, 3vw, 2.5rem)/1.05 var(--font-supporting); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; color: var(--fg-2); }
.stat p { margin: var(--space-3) 0 0; color: var(--fg-3); max-width: 28ch; }

/* 14.16  a package, as a card: who it is for, the fee, what is done */
.pkgs { display: grid; gap: var(--space-6); grid-template-columns: 1fr; }
@media (min-width: 1000px) { .pkgs { grid-template-columns: repeat(3, minmax(0, 1fr)); } .pkgs.is-two { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.pkg {
  display: flex; flex-direction: column; gap: var(--space-4);
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-8);
}
.pkg .k { font: 600 0.875rem/1 var(--font-supporting); letter-spacing: 0.04em; color: var(--fg-3); }
.pkg h3 { font: var(--type-h3-xl); margin: 0; }
.pkg .for { margin: 0; color: var(--fg-3); font-size: 1rem; }
/* Three cards side by side keep their fees on one line: the name and the
   description each reserve two lines, so a one-line name does not pull its
   fee up past its neighbours'. */
@media (min-width: 1000px) {
  .pkgs:not(.is-two) .pkg h3 { min-height: 2.5em; }
  .pkgs:not(.is-two) .pkg .for { min-height: 3.2em; }
}
.pkg .fee { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--space-2) var(--space-4); padding-block: var(--space-4); border-block: 1px solid var(--border-soft); }
.pkg .fee .fig-xl { font: 700 1.75rem/1 var(--font-supporting); font-variant-numeric: tabular-nums; color: var(--fg-2); }
.pkg .fee .when { font: var(--type-caption); color: var(--fg-3); }
.pkg .ticks > li { font-size: 1rem; }
/* The package cards print no fee: the link that asks for it sits at the foot
   of each card, level across the three. */
.pkg .pkg-ask { margin: auto 0 0; padding-top: var(--space-2); }
.tag {
  display: inline-flex; align-items: center; padding: 0.35rem 0.7rem; border-radius: var(--radius-pill);
  background: var(--surface); border: 1px solid var(--border);
  font: 500 0.875rem/1 var(--font-supporting); font-variant-numeric: tabular-nums; color: var(--fg-2); white-space: nowrap;
}
.ticks > li.is-give .tk { background: var(--surface-tint); color: var(--fg-2); }
@media (min-width: 1080px) { .tiles.five { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-8); } }
@media (min-width: 720px) and (max-width: 1079px) { .tiles.five { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* 14.16b  the flow: a process set out as rows, one step to a row, each with
   what the client does and what the client gets. Rows arrive one at a time. */
.flow { list-style: none; margin: 0; padding: 0; }
.flow > li {
  position: relative; margin: 0; max-width: none;
  display: grid; grid-template-columns: 5rem minmax(0, 1fr); gap: var(--space-5) var(--space-8);
  padding-block: var(--space-8); border-top: 1px solid var(--border);
}
.flow > li:last-child { border-bottom: 1px solid var(--border); }
.flow .n { display: block; font: 500 0.875rem/1 var(--font-supporting); font-variant-numeric: tabular-nums; letter-spacing: 0.04em; color: var(--fg-3); margin-bottom: var(--space-2); }
.flow h3 { font: var(--type-h2-xl); font-size: clamp(1.5rem, 2.2vw, 2rem); letter-spacing: var(--track-display); margin: 0 0 var(--space-3); }
.flow-main p { margin: 0; font: var(--type-lead-xl); font-size: 1.125rem; color: var(--fg-3); max-width: 34rem; }
.flow-main .flow-tags { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: var(--space-5) 0 0; max-width: none; }
.flow-io { margin: 0; display: grid; gap: var(--space-4); align-content: start; grid-column: 2; }
.flow-io dt { font: 600 0.875rem/1.2 var(--font-supporting); letter-spacing: 0.04em; color: var(--fg-3); margin-bottom: var(--space-1); }
.flow-io dd { margin: 0; color: var(--fg-2); }
/* On a phone each step would otherwise stack six blocks of text. The label
   sits beside its line instead, so a step is its heading, a sentence, and two
   short rows. */
@media (max-width: 959px) {
  .flow-io > div { display: grid; grid-template-columns: 5rem minmax(0, 1fr); column-gap: var(--space-4); align-items: baseline; }
  .flow-io dt { margin-bottom: 0; padding-top: 0.2em; }
}
@media (max-width: 639px) {
  .flow > li { grid-template-columns: 3.5rem minmax(0, 1fr); column-gap: var(--space-5); }
  .flow .ico-tile.is-lg { width: 3.5rem; height: 3.5rem; border-radius: var(--radius-lg); }
  .flow .ico-tile.is-lg .ico { width: 1.75rem; height: 1.75rem; }
  /* A long fee label wraps inside its pill rather than pushing the page wide. */
  .tag { white-space: normal; line-height: 1.3; border-radius: var(--radius-md); }
}
@media (min-width: 960px) {
  .flow > li { grid-template-columns: 5rem minmax(0, 6fr) minmax(0, 5fr); gap: var(--space-8) var(--space-12); align-items: start; }
  .flow-io { grid-column: auto; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-8); padding-top: 1.35rem; }
}

/* 14.17  a short list of pairs, set at reading size */
.kv { margin: 0; border-top: 1px solid var(--border); }
.kv > div { display: grid; gap: var(--space-1) var(--space-8); grid-template-columns: 1fr; padding: var(--space-4) 0; border-bottom: 1px solid var(--border); }
@media (min-width: 640px) { .kv > div { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); align-items: baseline; } }
.kv dt { font-weight: 600; color: var(--fg-2); }
.kv dd { margin: 0; color: var(--fg-3); }

/* 14.18  the team page: a person with a biography, and a region of names */
.profiles { display: grid; gap: var(--space-6); grid-template-columns: 1fr; }
@media (min-width: 900px) { .profiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.profile {
  display: grid; grid-template-columns: 6rem minmax(0, 1fr); gap: var(--space-6); align-items: start;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-8);
  scroll-margin-top: calc(var(--head-h) + var(--space-8));
  transition: border-color var(--motion-base) var(--ease-standard), box-shadow var(--motion-base) var(--ease-standard);
}
.profile:target { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.profile h3 { font: var(--type-h3-xl); margin: 0; }
.profile .role { font: var(--type-caption); color: var(--fg-3); margin: var(--space-1) 0 var(--space-4); }
.profile p { margin: 0 0 var(--space-3); color: var(--fg-3); font-size: 1rem; }
.profile p:last-child { margin-bottom: 0; }
.profile .person-photo { margin: 0; }
@media (hover: hover) { .profile:hover .person-photo img { filter: none; } }
@media (max-width: 480px) { .profile { grid-template-columns: 1fr; } }
.regions { display: grid; gap: var(--space-8) var(--space-12); grid-template-columns: 1fr; }
@media (min-width: 720px) { .regions { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1080px) { .regions { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.region h3 { font: 600 1rem/1.3 var(--font-display); color: var(--fg-2); margin: 0 0 var(--space-3); padding-bottom: var(--space-3); border-bottom: 2px solid var(--fg-2); }
.region ul { list-style: none; margin: 0; padding: 0; }
.region li { margin: 0; padding: var(--space-3) 0; border-bottom: 1px solid var(--border-soft); max-width: none; }
.region .who { display: block; font-weight: 600; color: var(--fg-2); }
.region .what { display: block; font: var(--type-caption); font-weight: 400; color: var(--fg-3); margin-top: 2px; }

/* 14.19  an office, an ally: a plain card with one fact under a name */
.places { display: grid; gap: var(--space-6); grid-template-columns: 1fr; }
@media (min-width: 860px) { .places { grid-template-columns: repeat(3, minmax(0, 1fr)); } .places.is-four { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 560px) and (max-width: 859px) { .places.is-four { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.place { display: grid; gap: var(--space-3); align-content: start; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-6); }
.place h3 { font: 600 1.125rem/1.3 var(--font-display); margin: 0; }
.place p { margin: 0; color: var(--fg-3); font-size: 0.9375rem; }
.place .city { font: var(--type-h3-xl); color: var(--fg-2); }
.plate { border-radius: var(--radius-lg); overflow: hidden; aspect-ratio: 21 / 9; background: var(--fg-2); margin-bottom: var(--space-12); }
.plate img { width: 100%; height: 100%; object-fit: cover; }
.tags { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0; padding: 0; list-style: none; max-width: none; }
.tags li { margin: 0; max-width: none; }
@media (min-width: 900px) { .kv.two { columns: 2; column-gap: var(--space-16); border-top: 0; } .kv.two > div { break-inside: avoid; border-top: 1px solid var(--border); border-bottom: 0; } }

/* A list of route rows paints one arrow a row. They rest in slate and take the
   accent under the pointer, so four rows do not spend four accents. */
#routes .call-row .arrow { color: var(--fg-3); }
#routes .call-row:hover .arrow { color: var(--accent); }
#routes .call-row .meta { font-weight: 400; }

/* a contact: a name, a role, an address to write to, a time to book */
.contacts { display: grid; gap: var(--space-6); grid-template-columns: 1fr; }
@media (min-width: 720px) { .contacts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1080px) { .contacts { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.contact { display: grid; gap: var(--space-2); align-content: start; border-top: 2px solid var(--fg-2); padding-top: var(--space-4); }
.contact .name { font: 600 1.125rem/1.3 var(--font-display); color: var(--fg-2); margin: 0; }
.contact .role { font: var(--type-caption); font-weight: 400; color: var(--fg-3); margin: 0 0 var(--space-2); }
.contact a { color: var(--fg-2); overflow-wrap: anywhere; min-height: 44px; display: inline-flex; align-items: center; }
.contact a:hover { color: var(--accent); }

/* an answer may carry a short list or a small table */
.faq .disclose .body ul { margin: 0; padding-left: 1.2rem; }
.faq .disclose .body li { max-width: 60ch; }
.faq .disclose .body .kv { margin-top: var(--space-2); }
.faq .disclose .body p + p, .faq .disclose .body p + ul, .faq .disclose .body ul + p, .faq .disclose .body p + .kv { margin-top: var(--space-4); }

/* 14.22  a choice as a pill, and a consent box a thumb can hit.
   A pick is a real radio or checkbox laid invisibly over a pill, so the control
   is the target, a keyboard reaches it, and choosing several is a tap on each.
   The consent box is drawn rather than native so the box itself is 48px; there
   is no background image in it, because the app's pages allow none. */
.picks { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.pick { position: relative; display: inline-flex; margin: 0; font-weight: 400; }
.pick input {
  position: absolute; inset: 0; width: 100%; height: 100%; min-height: 0; margin: 0; padding: 0;
  opacity: 0; cursor: pointer; -webkit-appearance: none; appearance: none;
}
.pick span {
  display: inline-flex; align-items: center; min-height: 48px; padding: 0 var(--space-5);
  border: 1px solid var(--meta); border-radius: var(--radius-pill); background: var(--bg);
  font-size: 0.9375rem; font-weight: 500; line-height: 1.25; color: var(--fg-2);
  transition: background-color var(--motion-base) var(--ease-standard), border-color var(--motion-base) var(--ease-standard);
}
.pick:hover span { border-color: var(--fg-2); }
.pick input:checked + span { background: var(--accent-tint); border-color: var(--accent); font-weight: 600; }
.pick input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

.consent { display: flex; gap: var(--space-4); align-items: flex-start; padding: var(--space-3) 0; }
.consent input[type="checkbox"] {
  -webkit-appearance: none; appearance: none;
  flex: 0 0 auto; width: 48px; height: 48px; min-height: 48px; margin: 0;
  border: 1px solid var(--meta); border-radius: var(--radius-sm); background: var(--bg); cursor: pointer;
  transition: box-shadow var(--motion-base) var(--ease-standard), border-color var(--motion-base) var(--ease-standard);
}
.consent input[type="checkbox"]:hover { border-color: var(--fg-2); }
.consent input[type="checkbox"]:checked { border-color: var(--accent); box-shadow: inset 0 0 0 12px var(--accent); }
.consent input[type="checkbox"]:focus-visible { border-color: var(--accent); box-shadow: var(--focus-ring); outline: none; }
.consent input[type="checkbox"]:checked:focus-visible { box-shadow: inset 0 0 0 12px var(--accent), var(--focus-ring); }
.consent label { margin: 0; font-weight: 400; color: var(--fg-3); font-size: 1rem; min-height: 48px; display: flex; align-items: center; flex: 1; cursor: pointer; }

/* A field a person never sees or reaches. A script that fills it has said what it is. */
.hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
