/* ============================================================================
   HIVEMIND — page styles.
   Mobile first: every unqueried rule below IS the 320-375px layout. Wider
   layouts are layered on top with min-width rem queries, never with max-width
   overrides walking a desktop layout back down.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   1. RESET + BASE
   --------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;   /* no browser text inflation rescaling type */
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  background: var(--bg-page);
}

body {
  margin: 0;
  /* THE ENGINEERED SUBSTRATE. A machined PCB graticule — fine minor grid, a
     heavier major grid every fifth line, and a via-pad at each cell — etched at a
     whisper into the void, mirroring what comb.js paints behind the hero field so
     the whole page reads as one drafting surface. Fixed, so the content slides
     over a stationary substrate rather than dragging a texture with it. */
  background-color: var(--void);
  background-image:
    radial-gradient(circle at center, var(--grid-dot) 0 1px, transparent 1.5px),
    repeating-linear-gradient(90deg, var(--grid-major) 0 1px, transparent 1px calc(var(--substrate-pitch) * 5)),
    repeating-linear-gradient(0deg,  var(--grid-major) 0 1px, transparent 1px calc(var(--substrate-pitch) * 5)),
    repeating-linear-gradient(90deg, var(--grid-minor) 0 1px, transparent 1px var(--substrate-pitch)),
    repeating-linear-gradient(0deg,  var(--grid-minor) 0 1px, transparent 1px var(--substrate-pitch));
  background-size: var(--substrate-pitch) var(--substrate-pitch), auto, auto, auto, auto;
  background-attachment: fixed;
  color: var(--text-body);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  font-weight: var(--w-body);
  line-height: var(--lh-body);
  letter-spacing: var(--track-body);
  font-feature-settings: "ss01" on;   /* the face's alternate set where offered */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* the fixed bar is hidden at the top and overlays content when shown, so nothing
     is reserved up top; the phone's bottom inset is the only reservation */
  padding-block-end: env(safe-area-inset-bottom, 0px);
}

img,
svg,
canvas { display: block; max-width: 100%; }

h1, h2, h3, h4, p, ul, ol, dl, dd, figure, pre, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }

a { color: inherit; text-decoration: none; }

button,
input,
textarea,
select {
  font: inherit;
  color: inherit;
  margin: 0;
}

button { background: none; border: 0; padding: 0; cursor: pointer; }

::selection { background: var(--amber); color: var(--void); }

::placeholder { color: var(--text-muted); opacity: 1; }

/* One focus treatment for the whole page: a 2px amber ring, offset 2px.
   13:1 against the void, so it is never the thing that fails. */
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}
:focus:not(:focus-visible) { outline: none; }

/* ---------------------------------------------------------------------------
   2. TYPOGRAPHY PRIMITIVES
   Weight 400 does every display size; a headline is never bolded.
   Weight 200 belongs to lead copy at 19px and up.
   --------------------------------------------------------------------------- */
h1, h2, h3 {
  color: var(--text-strong);
  font-weight: var(--w-display);
  text-wrap: balance;              /* no widowed word in a display line */
}

.display {
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
}

.h2 {
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--track-h2);
}

.h3 {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--track-h3);
}

p {
  max-width: var(--measure);       /* ~66 characters; never a full-width column */
  text-wrap: pretty;
}

.lead {
  max-width: var(--measure-lead);
  font-size: var(--fs-lead);
  font-weight: var(--w-air);
  line-height: var(--lh-lead);
  color: var(--text-body);
}

.eyebrow,
.label,
.caption {
  font-family: var(--font-mono);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

.eyebrow,
.label {
  display: block;
  font-size: var(--fs-label);
  font-weight: var(--w-mono-strong);
  line-height: var(--lh-label);
  letter-spacing: var(--track-label);
}

/* Amber is the action colour, so emphasis that cannot be acted on takes the
   neutral ramp instead: an eyebrow reads one step above a label, both quiet. */
.eyebrow { color: var(--text-body); }
.label { color: var(--text-muted); }

.caption {
  font-size: var(--fs-caption);
  font-weight: 400;
  line-height: var(--lh-caption);
  letter-spacing: var(--track-caption);
  color: var(--text-muted);
}

/* caption-sized copy that is a sentence rather than a shouted label */
.note {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--text-muted);
}

.lower { text-transform: none; }

.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;   /* digits that update never jitter */
}

.num {
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--track-h2);
}

/* ---------------------------------------------------------------------------
   3. LAYOUT PRIMITIVES
   One container system: every section shares --shell and --gutter, so every
   element on the page shares a left edge with something above it.
   --------------------------------------------------------------------------- */
.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* one rhythm between any two blocks — the footer supplies the gap after the
   last band, so the two never stack into a double-height void */
.band { padding-block-start: var(--rhythm); }

/* anchored sections clear the top of the viewport when jumped to */
[id] { scroll-margin-top: calc(var(--sp-4) + var(--sp-1)); }

.head { max-width: var(--measure-lead); margin-block-end: var(--gap-block); }
.head .h2 { margin-block-start: var(--sp-2); }
.head .lead { margin-block-start: var(--sp-2); }
.head--split { max-width: none; }
.head--split .h2 { max-width: 17ch; }
.head--split .display { max-width: 13ch; }
.head--split .lead { max-width: var(--measure-lead); }

/* THE ZIGZAG COMPOSITION. Every content section is one two-column split: a
   heading side (eyebrow + h2 + lead — display type IS the visual) and a body
   side that carries the content as a spacious vertical sequence. Sections
   alternate which side the heading takes (.split--flip), so the reading rhythm
   zigzags down the page and both 1440 columns always carry something — the real
   fix for the dead right-hand column. Mobile is one column, heading first. */
/* minmax(0,1fr) on the single mobile column so a wide child (the 78px bench
   figure, a long numeral) can never push the track past the shell */
.split { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-4); }
.split__aside > .h2 { margin-block-start: var(--sp-2); }
.split__aside > .lead { margin-block-start: var(--sp-3); max-width: 34rem; }

/* a vertical sequence: one or two elements per viewport, read top to bottom.
   This is what replaces every three-across grid on the page. */
.seq { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); }

/* one item's internal rhythm: a heading sits nearer the copy it introduces than
   the block above it. Shared by every sequence item, whatever its wrapper. */
.item > .h3,
.figure > .h3,
.tier > .h3,
.state > .h3 { margin-block: var(--sp-2) var(--sp-1); }
.item > .label + .h3,
.tier > .label + .h3,
.state > .label + .h3 { margin-block-start: var(--sp-1); }
.item > p + p { margin-block-start: var(--sp-2); }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  z-index: 60;
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;              /* 44 — a real target the moment it appears */
  inset-block-start: var(--sp-1);
  inset-inline-start: var(--sp-1);
  padding: var(--sp-1) var(--sp-2);
  background: var(--interactive);
  color: var(--on-interactive);
  border-radius: var(--radius-pill);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  transform: translateY(calc(-100% - var(--sp-2)));
  transition: transform var(--dur-hint) var(--ease-out);
}
.skip-link:focus { transform: translateY(0); }

.icon {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  stroke: currentColor;
  stroke-width: 1.5;
  fill: none;
  stroke-linecap: square;
  stroke-linejoin: miter;
}

/* ---------------------------------------------------------------------------
   4. BUTTONS + LINKS
   Rest / hover / active / focus-visible / disabled all read differently.
   Primary controls clear 48px; nothing interactive is under 44px.
   --------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-1);
  min-height: 3rem;                 /* 48 — Material comfort band */
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--radius-pill);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: var(--lh-body);      /* 24 — on the 4px grid, like every other */
  text-align: center;
  transition:
    background-color var(--dur-hint) var(--ease-out),
    color var(--dur-hint) var(--ease-out),
    transform var(--dur-press) var(--ease-out);
}

.btn--primary {
  background: var(--interactive);
  color: var(--on-interactive);
}
.btn--primary:hover { background: var(--interactive-hover); }
.btn--primary:active { transform: scale(0.97); }

/* The system allows no borders, so a quiet action's REST affordance is a rule
   under its own label: a hairline in the quietest neutral, which the amber
   picks up on hover. Rest, hover, active and focus all read differently and
   nothing ever grows a box. */
.btn--ghost {
  color: var(--text-body);
  padding-inline: var(--sp-2);
  text-decoration: underline;
  text-decoration-color: var(--line-quiet);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.3em;
  transition: background-color var(--dur-hint) var(--ease-out),
              color var(--dur-hint) var(--ease-out),
              text-decoration-color var(--dur-hint) var(--ease-out),
              transform var(--dur-press) var(--ease-out);
}
.btn--ghost:hover {
  background: var(--wash);
  color: var(--text-strong);
  text-decoration-color: var(--interactive);
}
.btn--ghost:active { transform: scale(0.97); }
.btn--ghost .icon { text-decoration: none; }

.btn:disabled,
.btn[aria-disabled="true"] {
  background: transparent;
  color: var(--text-muted);
  cursor: not-allowed;
  transform: none;
}

.btn .icon { transition: transform var(--dur-hint) var(--ease-out); }
.btn:hover .icon--out { transform: translate(2px, -2px); }
.btn:hover .icon--down { transform: translateY(2px); }

/* ---------------------------------------------------------------------------
   5. NAV — a fixed, frosted-glass bar in front of the page.
   --------------------------------------------------------------------------- */
/* Fixed to the top so the bar stays put as the page scrolls under it. The fill is
   translucent with a blurred backdrop (glassmorphism), full-bleed to both edges;
   the inner row still sits on the shell. */
.nav {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 50;
  /* At the top of the page there is no glass: the bar fades to black across its own
     height, so the wordmark and the action read against black rather than against the
     field behind them. */
  background: linear-gradient(to bottom, var(--void), var(--void) 65%, transparent);
  transition: background var(--dur-panel) var(--ease-out);
}
/* Once the reader scrolls down (ui.js adds .is-shown) the bar becomes frosted glass
   that the content passes under. */
.nav.is-shown {
  background: color-mix(in srgb, var(--raised) 60%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
  border-block-end: 1px solid color-mix(in srgb, var(--bone) 8%, transparent);
}
/* Without backdrop-filter support the scrolled bar goes near-opaque so its contents
   keep contrast over whatever passes beneath. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav.is-shown { background: color-mix(in srgb, var(--raised) 94%, transparent); }
}

.nav__inner {
  position: relative;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  min-height: var(--sp-4);          /* a slim bar — half the former height */
  padding-block: 0;
}

.brand {
  position: relative;
  z-index: 2;                       /* stays above the menu overlay it sits in */
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  min-height: 2.75rem;
  color: var(--text-strong);
  transition: color var(--dur-hint) var(--ease-out);
}
.brand:hover { color: var(--text-accent); }
.brand__mark { width: 1.75rem; height: 1.75rem; color: currentColor; }
.brand__name {
  font-size: var(--fs-label);
  font-weight: var(--w-mono-strong);
  letter-spacing: 0.02em;
}

/* the single nav action — a quiet text link matching the wordmark opposite it */
.nav__contact {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;              /* a real tap target inside the slim bar */
  color: var(--text-strong);
  font-size: var(--fs-label);
  font-weight: var(--w-mono-strong);
  letter-spacing: 0.02em;
  transition: color var(--dur-hint) var(--ease-out);
}
.nav__contact:hover { color: var(--text-accent); }

.nav__toggle {
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;                   /* 44 x 44 hit area around a 20px glyph */
  height: 2.75rem;
  margin-inline-end: calc(var(--sp-1) * -1);
  border-radius: var(--radius-sm);
  color: var(--text-strong);
  transition: background-color var(--dur-hint) var(--ease-out);
}
.nav__toggle:hover { background: var(--wash); }
.nav__toggle:active { transform: scale(0.94); }
.nav__toggle .icon--close { display: none; }
.nav__toggle[aria-expanded="true"] .icon--menu { display: none; }
.nav__toggle[aria-expanded="true"] .icon--close { display: block; }

.nav__menu { display: none; }
.nav__menu[data-open="true"] {
  display: block;
  position: fixed;
  inset: 0;
  z-index: 1;
  background: var(--bg-raised);
  padding: var(--sp-7) var(--gutter) var(--sp-5);
  overflow-y: auto;
  overscroll-behavior: contain;
  animation: menu-in var(--dur-menu) var(--ease-out) both;
}

.nav__list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

/* Same rest affordance as the ghost actions and the footer links: this page has
   three classes of link and one way of saying "this is a link before you point
   at it" — a rule under the label in the quietest neutral, which picks up amber
   on hover. Rest, hover, active and focus each read differently. */
.nav__link {
  display: flex;
  align-items: center;
  min-height: 3rem;
  padding-inline: var(--sp-1);
  margin-inline: calc(var(--sp-1) * -1);
  border-radius: var(--radius-sm);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);        /* 32 — on the grid, like every other step */
  letter-spacing: var(--track-h3);
  color: var(--text-muted);
  text-decoration: underline;
  text-decoration-color: var(--line-quiet);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.3em;
  transition: color var(--dur-hint) var(--ease-out),
              background-color var(--dur-hint) var(--ease-out),
              text-decoration-color var(--dur-hint) var(--ease-out);
}
.nav__link:hover {
  color: var(--text-strong);
  background: var(--wash);
  text-decoration-color: var(--interactive);
}
.nav__link:active { color: var(--text-accent); }

.nav__cta { margin-block-start: var(--sp-2); }
.nav__cta .btn { width: 100%; }

/* the edge page carries one nav action, so it stays a static row at every
   width — nothing behind a disclosure, nothing lost below 56rem */
.nav__menu--static { display: block; }
.nav__menu--static .nav__list { flex-direction: row; align-items: center; gap: var(--sp-1); }
.nav__menu--static .nav__cta { margin-block-start: 0; }
.nav__menu--static .nav__cta .btn { width: auto; min-height: 2.75rem; }

@keyframes menu-in {
  from { opacity: 0; transform: translate3d(0, -0.75rem, 0); }
  to   { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------------------
   6. HERO — one full-bleed field, the copy rendered over it. The canvas spans
   the whole section; the resolved brain settles right-of-centre, so the two-
   column impression comes from the composition, not from a boxed column.
   --------------------------------------------------------------------------- */
.hero {
  position: relative;
  isolation: isolate;               /* own stacking context so z:-1 stays local */
  overflow: hidden;                 /* the field bleeds to the section edge only */
  display: flex;
  align-items: flex-start;
  min-height: min(42rem, 100svh);
  padding-block: var(--sp-4) var(--sp-6);
}
.hero__canvas {
  position: absolute;               /* out of flow: it can never shift the copy */
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  max-width: none;
  background: var(--bg-page);        /* the reserved box is black before it paints */
}
/* The scrim that guarantees the copy's contrast over the field. It sits between
   the canvas (-2) and the copy (auto), reads as a natural vignette rather than a
   box, and fades out before the brain's mass on the right so the field still
   shows. Vertical on the narrow layout, where the copy leads at the top. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(90deg,
    rgba(0, 0, 0, 0.95) 0%,
    rgba(0, 0, 0, 0.88) 42%,
    rgba(0, 0, 0, 0.24) 64%,
    rgba(0, 0, 0, 0) 82%);
}
/* below the desktop split (56rem) the copy leads full-width at the top, so the
   scrim runs vertical and holds through the copy's whole height before it fades
   into the field below */
@media (max-width: 55.99rem) {
  .hero::after {
    background: linear-gradient(180deg,
      rgba(0, 0, 0, 0.94) 0%,
      rgba(0, 0, 0, 0.9) 58%,
      rgba(0, 0, 0, 0.62) 80%,
      rgba(0, 0, 0, 0.16) 94%,
      rgba(0, 0, 0, 0) 100%);
  }
}
.hero__inner { position: relative; width: 100%; }
/* per-glyph insurance: a tight dark halo so a single lit cell passing directly
   behind a thin 200-weight letter can never take it below its contrast floor.
   The scrim sets the mood; this guarantees the letter. */
.hero__copy .display,
.hero__copy .lead,
.hero__proof,
.hero__secondary,
.hero__micro { text-shadow: 0 0 6px rgba(0, 0, 0, 0.72), 0 1px 2px rgba(0, 0, 0, 0.85); }
.hero__copy { max-width: 34rem; }

.hero__eyebrow { margin-block-end: var(--sp-2); }
.hero__lead { margin-block-start: var(--sp-3); max-width: 30rem; }

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1);
  margin-block-start: var(--sp-4);
}

.hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  margin-block-start: var(--sp-3);
}

/* SHORT VIEWPORTS. With the field behind the copy rather than stacked above it,
   nothing competes with the headline for vertical room; the only job left is to
   keep the primary action reachable when the window is short. Two steps ease the
   display down and tighten the rhythm — nothing is hidden, nothing re-orders. */
@media (max-height: 40rem) and (max-width: 55.99rem) {
  .hero { min-height: 0; padding-block: var(--sp-3) var(--sp-4); }
  .nav__inner { padding-block: 0; }
  .hero .display { font-size: var(--fs-h2); }
  .hero__lead { margin-block-start: var(--sp-2); }
  .hero__actions { margin-block-start: var(--sp-3); }
  .hero__meta { margin-block-start: var(--sp-2); }
}
/* a phone on its side has ~375px of height for eyebrow, headline, deck and an
   action — compress hard so the primary action still lands in the first screen */
@media (max-height: 30rem) and (min-width: 30rem) and (max-width: 55.99rem) {
  .hero { padding-block: var(--sp-1) var(--sp-3); min-height: 0; }
  .hero .display { font-size: var(--fs-subhead); line-height: 1.05; }
  .hero__eyebrow { margin-block-end: var(--sp-1); }
  .hero__lead { max-width: 30rem; margin-block-start: var(--sp-1); }
  .hero__actions { margin-block-start: var(--sp-2); }
  .hero__meta { margin-block-start: var(--sp-1); }
}

/* HERO CTA — the proof-chip strip, the inline early-access capture, and the
   honest microcopy. The email and button share one row on the wide layout and
   stack under 32rem; the field reuses the .field control styling with only its
   top margin reset, so there is one input treatment across the page. */
.hero__proof {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  margin-block-start: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  text-transform: uppercase;
  letter-spacing: var(--track-caption);
  color: var(--text-body);
}
.hero__proof [aria-hidden] { color: var(--text-muted); }

.hero__cta { margin-block-start: var(--sp-4); max-width: 32rem; }

.signup__row {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;         /* the button matches the field's height */
  gap: var(--sp-1);
}
.signup__field {
  margin-block-start: 0;        /* reset .field's top margin inside the row */
  flex: 1 1 15rem;
  display: flex;
  flex-direction: column;
}
.signup__field input { flex: 1; }
.signup__row .btn { flex: 0 0 auto; }
@media (max-width: 32rem) {
  .signup__row { flex-direction: column; }
  .signup__row .btn { width: 100%; justify-content: center; }
}

.signup__done { margin-block-start: var(--sp-2); color: var(--text-body); }

.hero__secondary { margin-block-start: var(--sp-2); }
.hero__secondary a {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  color: var(--text-body);
  text-decoration: underline;
  text-decoration-color: var(--line-quiet);
  text-underline-offset: 3px;
  transition: color var(--dur-hint) var(--ease-out);
}
.hero__secondary a:hover { color: var(--text-strong); text-decoration-color: currentColor; }
.hero__secondary a .icon { width: 1em; height: 1em; }
.hero__secondary a:hover .icon--out { transform: translate(2px, -2px); }

.hero__micro { margin-block-start: var(--sp-2); max-width: 30rem; }

/* The gate's own view onto the same simulation — one field, painted into
   whichever viewport is on screen, so the floor being dragged and the brain it
   re-gates are never on different screenfuls. It is the control's readout, not
   the control: it is held to instrument scale at every width and painted well
   down the ramp (comb.js), so the slider and its verdict read before it does.
   The canvas paints the void as its own background, so a small box shows a small
   brain rather than a hole in the column. */
.comb--gate {
  width: 100%;
  max-width: 20rem;
  aspect-ratio: 16 / 9;             /* box reserved before the canvas paints */
  border-radius: var(--radius-lg);
  background: var(--bg-page);
}
.comb-view__cap { margin-block-start: var(--sp-1); max-width: none; }
.comb-view__cap .num { color: var(--text-body); }

/* ---------------------------------------------------------------------------
   7. THE PROBLEM — a zigzag split; the failures are a .seq. No boxes, ever.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   8. THE GATE — the live proof. The page's one hairline lives here.
   --------------------------------------------------------------------------- */
/* The five blocks are one column in document order — question, comb, floor,
   candidates, verdict — so the floor control sits between the two things it
   gates and both are visible while it is dragged. Nothing here re-orders:
   the wide layout below places the same five by grid area, keeping visual
   order identical to DOM order and to the tab order. */
.gate {
  display: grid;
  gap: var(--sp-3);
}

.gate__query .label { margin-block-end: var(--sp-1); }
.gate__query-text {
  max-width: none;
  font-size: var(--fs-lead);
  font-weight: var(--w-air);
  line-height: var(--lh-lead);
  color: var(--text-strong);
}

.gate__list { position: relative; }
.cands { display: grid; gap: var(--sp-2); }

/* THE hairline: the absolute serve floor, drawn once across every candidate */
.gate__floor {
  position: absolute;
  inset-block: 0;
  inset-inline-start: calc(var(--tau) * 100%);
  width: 1px;
  background: var(--hairline);
  pointer-events: none;
}

.cand {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  column-gap: var(--sp-2);
  row-gap: var(--sp-1);
}

.cand__text {
  max-width: none;
  font-size: var(--fs-body);
  color: var(--text-muted);
  transition: color var(--dur-hint) var(--ease-out);
}
.cand__meta {
  display: flex;
  align-items: baseline;
  gap: var(--sp-1);
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  letter-spacing: var(--track-caption);
  text-transform: uppercase;
  color: var(--text-muted);
}
.cand__score {
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  transition: color var(--dur-hint) var(--ease-out);
}
/* The score axis. Track and fill are neutral chrome, so they come from the
   neutral ramp and never from the comb ramp, which belongs to the swarm alone.
   Track 3.3:1 on the void and fill 3.3-3.9:1 on the track: both clear the
   non-text bar, so the axis is readable rather than implied. */
.cand__meter {
  grid-column: 1 / -1;
  height: 2px;
  background: var(--line-quiet);
  border-radius: var(--radius-pill);
}
.cand__fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--text-body);
  transition: background-color var(--dur-hint) var(--ease-out);
}

/* Withheld rows recede by taking a quieter token, never by compositing opacity
   onto text: --text-dim measures 4.6:1 on the void, so a row that the gate
   refuses to serve is still a row anyone can read. */
.cand.is-withheld .cand__text,
.cand.is-withheld .cand__meta,
.cand.is-withheld .cand__score { color: var(--text-dim); }

.cand.is-served .cand__text { color: var(--text-strong); }
.cand.is-served .cand__score { color: var(--text-accent); }
.cand.is-served .cand__fill { background: var(--interactive); }

.tau__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-2);
  margin-block-end: var(--sp-1);
}
.tau__value {
  font-family: var(--font-mono);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);        /* 32 */
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--track-h3);
  color: var(--text-accent);
}

.tau__row {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
}

.step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 2.75rem;                   /* 44 — the tap equivalent of dragging */
  height: 2.75rem;
  border-radius: var(--radius-pill);
  color: var(--text-body);
  transition: background-color var(--dur-hint) var(--ease-out),
              color var(--dur-hint) var(--ease-out),
              transform var(--dur-press) var(--ease-out);
}
.step:hover { background: var(--wash); color: var(--text-strong); }
.step:active { transform: scale(0.94); }

.tau__slider {
  flex: 1 1 auto;
  min-width: 0;
  height: 2.75rem;                  /* 44px of draggable track */
  background: none;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
  touch-action: pan-y;
}
.tau__slider::-webkit-slider-runnable-track {
  height: 2px;
  border-radius: var(--radius-pill);
  background: linear-gradient(
    to right,
    var(--interactive) 0 calc(var(--tau-pct) * 1%),
    var(--line-quiet) calc(var(--tau-pct) * 1%) 100%
  );
}
.tau__slider::-moz-range-track {
  height: 2px;
  border-radius: var(--radius-pill);
  background: var(--line-quiet);
}
.tau__slider::-moz-range-progress {
  height: 2px;
  border-radius: var(--radius-pill);
  background: var(--interactive);
}
.tau__slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 1.5rem;
  height: 1.5rem;
  /* centres a 24px thumb on a 2px track: (24 - 2) / 2 */
  margin-block-start: -0.6875rem;
  border-radius: var(--radius-pill);
  background: var(--interactive);
  transition: transform var(--dur-press) var(--ease-out);
}
.tau__slider::-moz-range-thumb {
  width: 1.5rem;
  height: 1.5rem;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--interactive);
}
.tau__slider:hover::-webkit-slider-thumb { transform: scale(1.08); }
.tau__slider:active::-webkit-slider-thumb { transform: scale(0.94); }

.tau__hint { margin-block-start: var(--sp-2); }


.verdict__state {
  max-width: none;
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--track-h3);
  color: var(--text-strong);
}
.verdict.is-abstained .verdict__state { color: var(--text-muted); }

/* row to row is twice term to value, so three pairs read as three pairs */
.verdict__stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-3);
  margin-block-start: var(--sp-2);
}
.verdict__stats div { display: flex; align-items: baseline; gap: var(--sp-1); }
.verdict__stats dt {
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  letter-spacing: var(--track-caption);
  text-transform: uppercase;
  color: var(--text-muted);
}
.verdict__stats dd {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-body);
  font-variant-numeric: tabular-nums;
  color: var(--text-strong);
}
.verdict__note { margin-block-start: var(--sp-2); }

/* ---------------------------------------------------------------------------
   9. KEEPS ITSELF TRUE — the bench figure is this section's visual, in the aside.
   --------------------------------------------------------------------------- */
.bench { margin-block-start: var(--sp-4); }
.bench__figure {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-2);
  /* fluid so "0.92 -> 0.00" fits a 320px column and reaches the h2-lg step wide */
  font-size: clamp(2.25rem, 7vw + 0.6rem, var(--fs-h2-lg));
  font-weight: var(--w-air);
  line-height: 1.05;
  letter-spacing: var(--track-h2);
  color: var(--text-strong);
}
/* the figure earns its emphasis by the before receding, not by the after
   shouting: 0.92 sits two ramp steps down and 0.00 keeps the strong token */
.bench__figure { color: var(--text-dim); }
.bench__arrow { color: var(--text-dim); }
.bench__after { color: var(--text-strong); }
.bench__caption { margin-block-start: var(--sp-2); }
.bench__label { margin-block-end: var(--sp-1); }

/* ---------------------------------------------------------------------------
   10. THE TRUST LIFECYCLE — a real sequence, so ordinals are earned here.
   --------------------------------------------------------------------------- */
.lifecycle { display: grid; gap: var(--sp-5); }
.state__no { color: var(--text-body); }
.state > .state__served { margin-block-start: var(--sp-2); }

/* ---------------------------------------------------------------------------
   11. SOLVE IT ONCE — three figures as a .seq, a comparison of numerals.
   --------------------------------------------------------------------------- */
.figure__value {
  font-size: var(--fs-h2-lg);
  font-weight: var(--w-air);
  line-height: 1.05;
  letter-spacing: var(--track-h2);
  font-variant-numeric: tabular-nums;
  color: var(--text-strong);
}
.figure__unit { margin-block: var(--sp-1) var(--sp-1); }

/* ---------------------------------------------------------------------------
   12. GET IT
   --------------------------------------------------------------------------- */
.terminal {
  position: relative;
  max-width: var(--measure-lead);
  padding: var(--sp-2);
  /* radius nesting: the copy pill sits --sp-2 in from a --radius-lg corner,
     which is larger than the corner, so no concentric collision to correct */
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
}
.terminal__cmd {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  line-height: var(--lh-body);      /* 20 here, 24 once it steps up to 16px */
  color: var(--text-body);
  white-space: pre-wrap;            /* wraps instead of scrolling at 320px */
  overflow-wrap: anywhere;
}
.terminal__cmd .prompt { color: var(--text-muted); user-select: none; }
.terminal__copy {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  min-height: 2.75rem;
  margin-block-start: var(--sp-1);
  padding-inline: var(--sp-2);
  margin-inline-start: calc(var(--sp-2) * -1);
  border-radius: var(--radius-pill);
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  letter-spacing: var(--track-caption);
  text-transform: uppercase;
  color: var(--text-muted);
  transition: color var(--dur-hint) var(--ease-out),
              background-color var(--dur-hint) var(--ease-out),
              transform var(--dur-press) var(--ease-out);
}
.terminal__copy:hover { color: var(--text-strong); background: var(--wash); }
.terminal__copy:active { transform: scale(0.96); }
.terminal__copy.is-copied { color: var(--text-accent); }
.terminal__copy .icon--check { display: none; }
.terminal__copy.is-copied .icon--copy { display: none; }
.terminal__copy.is-copied .icon--check { display: block; }

.cta__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1);
  margin-block-start: var(--sp-4);
}

/* ---------------------------------------------------------------------------
   13. ENTERPRISE + WAITLIST DIALOG — tiers are a .seq; the waitlist follows.
   --------------------------------------------------------------------------- */
.tiers__cta { margin-block-start: var(--sp-1); }
/* a ghost button's padding must not push its label off the container's edge */
.tiers__cta .btn--ghost { margin-inline-start: calc(var(--sp-2) * -1); }

.dialog {
  width: min(32rem, 100% - var(--sp-3));
  max-height: min(88svh, 100% - var(--sp-3));
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: var(--radius-lg);
  background: var(--bg-raised);     /* elevation by surface lightness, not shadow */
  color: var(--text-body);
  overflow: auto;
  overscroll-behavior: contain;
}
/* Entrance and exit are different motions, not one played backwards: the panel
   settles in over --dur-panel on --ease-out and leaves in --dur-exit (~2/3) on
   --ease-in, accelerating away. Transform + opacity only; `allow-discrete`
   keeps the element painted for the length of its exit. */
.dialog {
  opacity: 0;
  transform: scale(0.96);
  /* the centre is only the fallback: ui.js points the origin at the control
     that opened the panel before it is shown, so it grows out of its trigger */
  transform-origin: 50% 50%;
  transition: opacity var(--dur-exit) var(--ease-in),
              transform var(--dur-exit) var(--ease-in),
              overlay var(--dur-exit) allow-discrete,
              display var(--dur-exit) allow-discrete;
}
.dialog[open] {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-panel) var(--ease-out),
              transform var(--dur-panel) var(--ease-out),
              overlay var(--dur-panel) allow-discrete,
              display var(--dur-panel) allow-discrete;
}
@starting-style {
  .dialog[open] { opacity: 0; transform: scale(0.96); }
}

.dialog::backdrop {
  background: var(--veil);
  opacity: 0;
  transition: opacity var(--dur-exit) var(--ease-in),
              overlay var(--dur-exit) allow-discrete,
              display var(--dur-exit) allow-discrete;
}
.dialog[open]::backdrop {
  opacity: 1;
  transition: opacity var(--dur-panel) var(--ease-out),
              overlay var(--dur-panel) allow-discrete,
              display var(--dur-panel) allow-discrete;
}
@starting-style {
  .dialog[open]::backdrop { opacity: 0; }
}

.dialog__body { padding: var(--sp-3); }
.dialog__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-2);
}
.dialog__title {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--track-h3);
}
.dialog__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  margin: calc(var(--sp-1) * -1) calc(var(--sp-1) * -1) 0 0;
  border-radius: var(--radius-pill);
  color: var(--text-muted);
  transition: color var(--dur-hint) var(--ease-out),
              background-color var(--dur-hint) var(--ease-out),
              transform var(--dur-press) var(--ease-out);
}
.dialog__close:hover { color: var(--text-strong); background: var(--wash); }
.dialog__close:active { transform: scale(0.94); }
.dialog__lead { margin-block-start: var(--sp-1); font-size: var(--fs-body); }

.field { margin-block-start: var(--sp-2); }
.field > label {
  display: block;
  margin-block-end: var(--sp-1);    /* label sits nearer its input than the field above */
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  letter-spacing: var(--track-caption);
  text-transform: uppercase;
  color: var(--text-muted);
}
/* The one place the page draws a box. Everywhere else a surface delta is enough,
   but a field is a control: SC 1.4.11 asks for 3:1 on the visual boundary that
   identifies it, and on a near-black page no fill can be 3:1 from its panel and
   still look like a dark field. So the boundary is a hairline in the neutral
   ramp — 5.2:1 on the panel, 4.5:1 on the fill, and still clear of 3:1 against
   the lighter hover and invalid fills — and the fill itself stays sunken. */
.field input,
.field textarea {
  display: block;
  width: 100%;
  min-height: 2.75rem;
  padding: var(--sp-1) var(--sp-2);
  border: 1px solid var(--line-control);
  border-radius: var(--radius-sm);
  background: var(--bg-field);
  color: var(--text-strong);
  font-size: var(--fs-body);        /* >= 16px, so iOS Safari never force-zooms */
  font-weight: var(--w-body);
  line-height: var(--lh-body);
  transition: background-color var(--dur-hint) var(--ease-out);
}
.field textarea { resize: vertical; }
.field input:hover,
.field textarea:hover { background: color-mix(in oklab, var(--sunken) 88%, var(--bone) 12%); }
.field .req { color: var(--text-body); }

/* a field that failed validation says so programmatically (aria-invalid) and
   visually (its label steps up to the strong token and names the fault). Its
   boundary steps up with the label: the lighter invalid fill leaves the resting
   hairline at 2.9:1 against it, under the bar, and an error is the one state
   that should be the loudest thing in the panel anyway. */
.field [aria-invalid="true"] {
  background: color-mix(in oklab, var(--sunken) 80%, var(--amber) 20%);
  border-color: var(--text-strong);
}
.field:has([aria-invalid="true"]) > label { color: var(--text-strong); }
.field__error {
  display: block;
  margin-block-start: var(--sp-1);
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  letter-spacing: var(--track-caption);
  color: var(--text-strong);
}
.field__error:empty { display: none; }

.hp {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}
/* the trap is never seen, but its UA padding is the only value on the page that
   is not on the spacing scale, so it goes too */
.hp input { padding: 0; }

.form__status {
  margin-block-start: var(--sp-2);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--text-strong);
}
.form__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--sp-1);
  margin-block-start: var(--sp-3);
}

.done { padding: var(--sp-3); text-align: center; }
.done__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem; height: 3rem;
  margin-block-end: var(--sp-2);
  border-radius: var(--radius-pill);
  background: var(--interactive);
  color: var(--on-interactive);
}
.done__mark .icon { width: 1.5rem; height: 1.5rem; }
.done p { margin-inline: auto; margin-block-start: var(--sp-1); }
.done .form__actions { justify-content: center; }

/* ---------------------------------------------------------------------------
   14. FOOTER
   --------------------------------------------------------------------------- */
.foot { padding-block-start: var(--rhythm); }
.foot__grid { display: grid; gap: var(--gap-block); }
.foot__blurb { margin-block-start: var(--sp-2); max-width: 24rem; }
.foot__col .label { margin-block-end: var(--sp-1); }
.foot__col ul { display: grid; gap: var(--sp-1); }
/* Same rest affordance as a ghost action, so a link is legible as a link before
   anyone points at it — the footer's copy and its links no longer read alike. */
.foot__link {
  display: flex;
  align-items: center;
  min-height: 2.75rem;
  color: var(--text-muted);
  text-decoration: underline;
  text-decoration-color: var(--line-quiet);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.3em;
  transition: color var(--dur-hint) var(--ease-out),
              text-decoration-color var(--dur-hint) var(--ease-out);
}
.foot__link:hover {
  color: var(--text-strong);
  text-decoration-color: var(--interactive);
}
.foot__link:active { color: var(--text-accent); }
.foot__base {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-3);
  margin-block-start: var(--sp-5);
  padding-block-end: var(--sp-4);
}

/* ---------------------------------------------------------------------------
   15. SCROLL REVEAL — one job: tie a block together as it arrives.
   Deliberately a rise, not a fade: nothing on this page is ever hidden waiting
   for a scroll event, so the whole document is legible in a static render, with
   or without JavaScript.
   --------------------------------------------------------------------------- */
.js .reveal {
  transform: translate3d(0, 0.75rem, 0);
  transition: transform var(--dur-panel) var(--ease-out) var(--reveal-delay, 0ms);
}
.js .reveal.is-in { transform: none; }

/* ============================================================================
   16. WIDER LAYOUTS — layered on, never walked back
   ============================================================================ */
@media (min-width: 40rem) {
  .comb--gate { max-width: 20rem; aspect-ratio: 16 / 9; }
  .cand { grid-template-columns: 1fr auto; }
  .foot__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 56rem) {
  /* the hero owns the first screenful: the copy centred in it, the field behind */
  .hero {
    align-items: center;
    min-height: 100svh;
    padding-block: 0;
  }

  /* THE ZIGZAG. Heading side 5fr, body side 7fr; .split--flip swaps which side
     each takes. Both columns always carry something, so the recurring dead
     right-hand column at 1440 cannot form. The heading top-aligns with the first
     item of its sequence; the air under a short heading is the composition's,
     and it alternates sides down the page. */
  .split {
    grid-template-columns: 5fr 7fr;
    column-gap: var(--sp-8);
    row-gap: var(--sp-5);
    align-items: start;
  }
  .split__aside { grid-column: 1; grid-row: 1; }
  .split__body  { grid-column: 2; grid-row: 1; }
  .split--flip .split__aside { grid-column: 2; }
  .split--flip .split__body  { grid-column: 1; }

  /* Gate: two columns, five areas, read exactly as they are written — the
     question and the field share the top line, the floor sits directly above the
     candidates it gates, the verdict answers from beside the list. Nothing is
     re-ordered to get here; DOM, tab and visual order stay one list. */
  .gate {
    grid-template-columns: minmax(0, 1fr) minmax(19rem, 24rem);
    grid-template-areas:
      "query comb"
      "tau   comb"
      "list  verdict";
    column-gap: var(--sp-5);
    row-gap: var(--gap-block);
    align-items: start;
  }
  .gate__query { grid-area: query; }
  .comb-view   { grid-area: comb; }
  .tau         { grid-area: tau; }
  .gate__list  { grid-area: list; }
  .verdict     { grid-area: verdict; }

  .verdict__stats { flex-direction: column; gap: var(--sp-2); }
  .comb--gate { max-width: 20rem; aspect-ratio: 3 / 2; }

  .nav__menu,
  .nav__menu[data-open="false"] {
    display: block;
    position: static;
    padding: 0;
    background: none;
    animation: none;
    overflow: visible;
  }
  .nav__toggle { display: none; }
  .nav__list {
    flex-direction: row;
    align-items: center;
    gap: var(--sp-1);            /* >= 8px between adjacent targets */
  }
  .nav__link {
    min-height: 2.75rem;
    padding-inline: var(--sp-2);
    margin-inline: 0;
    font-size: var(--fs-body);
    line-height: var(--lh-body);
    letter-spacing: var(--track-body);
  }
  .nav__cta { margin-block-start: 0; margin-inline-start: var(--sp-1); }
  .nav__cta .btn { width: auto; min-height: 2.75rem; }
}

@media (min-width: 64rem) {
  /* a touch more room between the two halves at the widest column */
  .split { column-gap: var(--sp-8); }

  /* the four-column footer only once there is room for it; 896-1023 keeps the
     two-column footer so the links never collide */
  .foot__grid { grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr)); gap: var(--sp-5); }

  /* The gate head still composes as two columns: eyebrow and headline hold the
     left, the lead sits in the right and hangs from the headline's last
     baseline, so the band reads as one object rather than a stranded paragraph. */
  .head--split {
    display: grid;
    grid-template-columns: 7fr 5fr;
    column-gap: var(--sp-4);
    align-items: end;
  }
  .head--split > .eyebrow,
  .head--split > .h2,
  .head--split > .display { grid-column: 1; }
  .head--split > .lead {
    grid-column: 2;
    grid-row: 1 / span 2;
    align-self: end;
    max-width: none;
    margin-block-start: 0;
  }

  .terminal { padding: var(--sp-3); }
  .terminal__cmd { font-size: var(--fs-body); }
}

/* ============================================================================
   17. REDUCED MOTION — spatial motion is removed, nothing is hidden by it.
   Colour and opacity acknowledgements stay: they are feedback, not motion.
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  /* the bar still hides and reveals, it just snaps instead of sliding */
  .nav { transition: none; }

  .js .reveal {
    transform: none;
    transition: none;
  }

  .nav__menu[data-open="true"] { animation: none; }

  /* the panel still fades, it just never moves or scales */
  .dialog,
  .dialog[open] {
    transform: none;
    transition: opacity var(--dur-hint) linear,
                overlay var(--dur-hint) allow-discrete,
                display var(--dur-hint) allow-discrete;
  }
  @starting-style {
    .dialog[open] { transform: none; }
  }

  .skip-link { transition: none; }

  .btn:active,
  .btn--ghost:active,
  .nav__toggle:active,
  .step:active,
  .dialog__close:active,
  .terminal__copy:active { transform: none; }

  .btn .icon,
  .btn:hover .icon--out,
  .btn:hover .icon--down { transition: none; transform: none; }

  .tau__slider:hover::-webkit-slider-thumb,
  .tau__slider:active::-webkit-slider-thumb { transform: none; }
}
