/* ============================================================================
   chrisfrost.co — "ROUNDED CINEMA" (v2)
   One stylesheet. Implements REDESIGN-BRIEF §2 (design language), §3 (components),
   §6 (motion), §7 (what to keep).

   THE THREE RULES THIS FILE ENFORCES
   1. Nothing draws a line to organise itself. There is no <hr>, no section rule,
      no hairline above a heading, no crop mark, no folio. Structure is carried by
      colour bands, curved shoulders, shared radii and blocks overlapping.
      ONE hairline survives: --hairline, usable ONLY between sibling items inside a
      list (.linked-list). It may never end a section or sit under a heading.
   2. One family (Inter 400/500/600/700). Sentence case with a terminal full stop
      on all display type. UPPERCASE survives only in .eyebrow.
   3. Warm ground, saturated accents, everything rounded. Radii start at 999px and
      only go down when a box has to hold content.

   CONTRAST: every text/background and every filled control pair in here was
   computed. Raw --crimson #E9353E is 4.16:1 on white and NEVER fills a control:
   fills use --crimson-fill #C1121F (white 6.22:1), hover #A50E1A (7.84:1).
   ========================================================================== */

/* ============================================================================
   1. TOKENS
   ========================================================================== */
:root {
  color-scheme: light;

  /* ---- NAVY — the cinematic ground, in both themes ---- */
  --navy-950: #070B16;
  --navy-900: #0B1220;
  --navy-800: #131B2E;
  --navy-700: #1E2740;
  --navy-600: #2B3552;

  /* ---- WARM NEUTRALS — warm, never grey ---- */
  --paper:   #FBF7F1;
  --paper-2: #F3ECE2;
  --paper-3: #E9DFD1;
  --card:    #FFFFFF;

  /* ---- INK — slate navy, never pure black ---- */
  --ink:   #141A2C;
  --ink-2: #5A6178;   /* secondary copy AND the 3:1 UI boundary colour on light */

  /* ---- CRIMSON ---- */
  --crimson: #E9353E;            /* the "light up" red: dots, glyphs, focus ring */
  --crimson-text: #C1121F;       /* red TYPE on paper — 5.83:1 */
  --crimson-fill: #C1121F;       /* every filled pill — white on it 6.22:1 */
  --crimson-fill-hover: #A50E1A; /* 7.84:1 */
  --crimson-deep: #7E0D18;
  --crimson-tint: #FBEDED;
  /* red type that survives a navy ground */
  --crimson-on-dark: #F0555D;    /* 5.49:1 on --navy-900, 5.04:1 on --navy-800 */
  --crimson-on-navy-700: #FF7A80;/* 5.88:1 on --navy-700 */

  /* ---- BRASS — the single warm secondary. ≤3% of pixels, ever. ---- */
  --brass: #F2A33C;
  --brass-tint: #FDF3E4;

  /* ---- UI boundary colours (WCAG 1.4.11 — 3:1 against their own field) ---- */
  --ui-line-light: #5A6178;  /* 5.76:1 on paper, 6.15:1 on white */
  --ui-line-dark:  #6B7590;  /* 4.08:1 on navy-900, 3.22:1 on navy-700 */

  /* ---- TYPE ---- */
  --font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --fs-eyebrow:   clamp(.8125rem, .79rem + .18vw, .9375rem);
  --fs-micro:     clamp(.75rem, .73rem + .12vw, .8125rem);
  --fs-body:      clamp(1rem, .96rem + .2vw, 1.125rem);
  --fs-lead:      clamp(1.1875rem, 1.05rem + .7vw, 1.5rem);
  --fs-h3:        clamp(1.25rem, 1.1rem + .6vw, 1.625rem);
  --fs-h2:        clamp(1.875rem, 1.2rem + 2.6vw, 3.25rem);
  /* CAP MEASURED, not assumed: the defining sentence is 159 characters. At a
     3.5rem cap it ran to twelve lines and pushed the CTA off a 900px screen.
     2.875rem over a 30ch measure gives five or six balanced lines at 1440. */
  --fs-sentence:  clamp(1.625rem, 1.05rem + 2.2vw, 2.875rem);
  /* The hero H1 is no longer the defining sentence — that sentence moved to the
     standfirst directly beneath it, verbatim. A six-word line can therefore be
     set at display scale. CAP MEASURED: 3.25rem over the hero's 34rem measure
     breaks "Your life works. / Your drive doesn’t." to exactly two lines at
     1280, 1440 and 1920, and to two lines at 390. */
  --fs-sentence-short: clamp(2.125rem, 1rem + 3.1vw, 3.25rem);
  --fs-statement: clamp(2rem, 1.4rem + 3.6vw, 4.5rem);
  --fs-numeral:   clamp(2.25rem, 1.5rem + 3.4vw, 4.25rem);

  /* ---- RADII. Fluid: a phone reads tight, a desktop reads generous. ---- */
  --r-pill: 999px;
  --r-card: clamp(.875rem, .7rem + .6vw, 1.5rem);
  --r-hero: clamp(1.25rem, .9rem + 1.4vw, 2rem);
  --r-band: clamp(1.5rem, 1rem + 2.5vw, 3.75rem);
  --r-circle: 50%;
  /* Asymmetric interlock sets — blocks eat each other's corners so a 2×2 grid
     reads as one object. Named for the corner that is squared off. */
  --r-eat-br: var(--r-hero) var(--r-hero) 0 var(--r-hero);
  --r-eat-tr: var(--r-hero) 0 var(--r-hero) var(--r-hero);
  --r-eat-tl: 0 var(--r-hero) var(--r-hero) var(--r-hero);

  /* ---- SHADOW — two registers on light, NONE on dark. Navy-tinted, diffuse. ---- */
  --shadow-ambient: 0 2px 8px rgba(8,13,26,.06), 0 18px 40px rgba(8,13,26,.10);
  --shadow-lift:    0 30px 70px rgba(8,13,26,.18);
  --shadow-nav:     0 8px 28px rgba(8,13,26,.14);
  --ring-focus:     0 0 0 3px rgba(233,53,62,.35);

  /* ---- GRADIENTS — every one is a legibility device dressed as mood ---- */
  --g-dissolve:  linear-gradient(to bottom, transparent 42%, var(--navy-900) 96%);
  --g-bloom:     radial-gradient(62% 54% at 22% 26%, rgba(233,53,62,.30), transparent 72%);
  --g-mesh:      radial-gradient(70% 60% at 12% 10%, rgba(242,163,60,.16), transparent 65%),
                 radial-gradient(60% 70% at 88% 82%, rgba(233,53,62,.20), transparent 68%),
                 linear-gradient(160deg, var(--navy-950), var(--navy-900));
  --g-vignette:  radial-gradient(120% 100% at 50% 42%, transparent 52%, rgba(7,11,22,.34) 100%);

  /* ---- SPACING — six steps. Bands butt at gap 0; colour IS the divider. ---- */
  --s-1: .5rem;
  --s-2: .75rem;
  --s-3: 1.25rem;
  --s-4: 2rem;
  --s-5: 3.25rem;
  --s-6: 5rem;
  --gutter: clamp(1.25rem, 4vw, 2.5rem);
  --band-pad: clamp(3.5rem, 8vw, 7rem);
  --container: 75rem;
  --container-wide: 90rem;
  --measure: 38rem;
  --hero-inset: clamp(.75rem, 2vw, 1.25rem);
  --nav-h: 4.5rem;
  --nav-gap: clamp(.75rem, 2vw, 1.25rem);
  --nav-total: calc(var(--nav-h) + var(--nav-gap) * 2);
  --interlock-gap: clamp(.5rem, 1vw, .75rem);

  /* ---- MOTION — one duration governs the site ---- */
  --t: 500ms;
  --t-fast: 220ms;
  --t-slow: 900ms;
  --ease: cubic-bezier(.22, 1, .36, 1);

  /* ---- TEXTURE assets ----
     THE LOZENGE FIELD IS RETIRED. lozenges-*.svg tiled 14×34 rounded rects at 240px, which read
     at page size as a jittered grid of short vertical dashes — i.e. the registration-tick /
     crop-mark register Chris rejected, returning as texture. Screenshotted and confirmed by eye.
     The replacement is a soft radial bloom of the site's own crimson and brass, with the existing
     grain over it. It has no repeat, no edge and no stroke anywhere in it. */
  --grain: url(/grain.svg);
  --bloom-field:
    radial-gradient(52% 46% at 16% 18%, rgba(233,53,62,.20), transparent 72%),
    radial-gradient(44% 40% at 86% 26%, rgba(242,163,60,.13), transparent 74%),
    radial-gradient(60% 54% at 64% 92%, rgba(233,53,62,.15), transparent 76%);
}

[data-theme="dark"] { color-scheme: dark; }

/* ----------------------------------------------------------------------------
   1.1 THE STANCE MECHANIC
   Every band declares its own stance; the USER theme decides what "light" means.
   A section writes `background:var(--bg); color:var(--fg)` and nothing else.
   Dark stance is the hero stance in BOTH themes.
   -------------------------------------------------------------------------- */
:root,
[data-stance="light"] {
  --bg: var(--paper);
  --fg: var(--ink);
  --fg-2: var(--ink-2);
  --surface: var(--card);
  --surface-2: var(--paper-2);
  --well: var(--paper-3);
  --accent-text: var(--crimson-text);
  --ui: var(--ui-line-light);
  --hairline: rgba(20,26,44,.12);
  --wash: rgba(20,26,44,.05);
  --shadow-card: var(--shadow-ambient);
  --pill-quiet: rgba(20,26,44,.06);
}
[data-stance="sand"] {
  --bg: var(--paper-2);
  --fg: var(--ink);
  --fg-2: var(--ink-2);
  --surface: var(--card);
  --surface-2: var(--paper-3);
  --well: var(--paper-3);
  --accent-text: var(--crimson-text);
  --ui: var(--ui-line-light);
  --hairline: rgba(20,26,44,.12);
  --wash: rgba(20,26,44,.05);
  --shadow-card: var(--shadow-ambient);
  --pill-quiet: rgba(20,26,44,.06);
}
[data-stance="dark"] {
  --bg: var(--navy-900);
  --fg: #FFFFFF;
  --fg-2: #A8B0C4;
  --surface: var(--navy-800);
  --surface-2: var(--navy-700);
  --well: var(--navy-950);
  --accent-text: var(--crimson-on-dark);
  --ui: var(--ui-line-dark);
  --hairline: rgba(255,255,255,.12);
  --wash: rgba(255,255,255,.10);
  --shadow-card: none;
  --pill-quiet: rgba(255,255,255,.08);
}
[data-stance="crimson"] {
  --bg: var(--crimson-fill);
  --fg: #FFFFFF;
  --fg-2: #FFD9DC;
  --surface: rgba(255,255,255,.10);
  --surface-2: rgba(255,255,255,.14);
  --well: rgba(0,0,0,.12);
  --accent-text: #FFFFFF;
  --ui: rgba(255,255,255,.72);
  --hairline: rgba(255,255,255,.20);
  --wash: rgba(255,255,255,.12);
  --shadow-card: none;
  --pill-quiet: rgba(255,255,255,.14);
}

/* In dark theme, "light" and "sand" become raised navies — dark mode still
   ALTERNATES, it does not flatten to one colour. */
[data-theme="dark"] [data-stance="light"],
[data-theme="dark"]:root {
  --bg: var(--navy-800);
  --fg: #FFFFFF;
  --fg-2: #A8B0C4;
  --surface: var(--navy-700);
  --surface-2: var(--navy-800);
  --well: var(--navy-950);
  /* MEASURED: --crimson-on-dark #F0555D on --surface (--navy-700) is 4.34:1 and fails the 4.5:1
     text threshold — and in this theme --surface is what every card, plate and work-card is
     painted with. --crimson-on-navy-700 #FF7A80 is 6.60:1 there and 7.4:1 on --bg. */
  --accent-text: var(--crimson-on-navy-700);
  --ui: var(--ui-line-dark);
  --hairline: rgba(255,255,255,.12);
  --wash: rgba(255,255,255,.10);
  --shadow-card: none;
  --pill-quiet: rgba(255,255,255,.08);
}
[data-theme="dark"] [data-stance="sand"] {
  --bg: var(--navy-700);
  --fg: #FFFFFF;
  --fg-2: #B6BDD0;
  --surface: var(--navy-800);
  --surface-2: var(--navy-900);
  --well: var(--navy-950);
  --accent-text: var(--crimson-on-navy-700);
  --ui: var(--ui-line-dark);
  --hairline: rgba(255,255,255,.12);
  --wash: rgba(255,255,255,.10);
  --shadow-card: none;
  --pill-quiet: rgba(255,255,255,.08);
}
[data-theme="dark"] [data-stance="dark"] {
  --bg: var(--navy-950);
  --surface: var(--navy-800);
  --surface-2: var(--navy-700);
}

/* ============================================================================
   2. RESET (minimal — carried forward from v1)
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
body, h1, h2, h3, h4, p, figure, blockquote, dl, dd, ul, ol { margin: 0; }
/* Nothing on this site wants a list marker. De-marker EVERY list, not only
   classed ones (the footer's columns carry no class). */
ul, ol { padding: 0; list-style: none; }
/* [hidden] must actually hide: the UA rule loses to any author display rule,
   which once left a dead form sitting under its own confirmation. */
[hidden] { display: none !important; }
img, svg, video { max-width: 100%; display: block; }
img, video { height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; }

/* overflow-x is CLIPPED on the root, never hidden on the body: `overflow-x:hidden`
   on <body> turns the body into a scroll container in some engines and quietly
   breaks the sticky nav. `clip` contains a stray full-bleed child without
   creating a scroll container. */
html { -webkit-text-size-adjust: 100%; overflow-x: clip; }

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-optical-sizing: auto;
  font-feature-settings: "cv11", "ss01";
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.7;
  letter-spacing: 0;
  -webkit-font-smoothing: antialiased;
  transition: background-color var(--t-fast) ease, color var(--t-fast) ease;
}
::selection { background: var(--crimson-fill); color: #FFFFFF; }

a { color: inherit; text-decoration: none; }
:focus-visible { outline: 2px solid var(--crimson); outline-offset: 2px; }
/* MEASURED: the crimson ring on the crimson stance is 1.49:1 — invisible. On
   that one band the ring turns white (6.22:1). */
/* Scope is deliberate: a crimson pill on a PAPER band keeps the crimson ring,
   which sits on the paper at 3.90:1. Only a control on a crimson GROUND needs
   the white ring — a white ring on paper would be invisible. */
[data-stance="crimson"] :focus-visible,
.il-mark :focus-visible { outline-color: #FFFFFF; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.skip {
  position: absolute;
  left: -9999px; top: 0;
  z-index: 200;
  background: var(--crimson-fill);
  color: #FFFFFF;
  font-size: var(--fs-micro);
  font-weight: 600;
  padding: .625rem 1.25rem;
  border-radius: 0 0 var(--r-pill) 0;
}
.skip:focus { left: 0; }
.nb { white-space: nowrap; }

/* ============================================================================
   3. BANDS, CONTAINERS, SHOULDERS
   Sections butt directly against one another. The colour change is the divider.
   ========================================================================== */
.band {
  position: relative;
  isolation: isolate;
  background: var(--bg);
  color: var(--fg);
  padding-block: var(--band-pad);
}
.band--tight { padding-block: clamp(2.25rem, 5vw, 3.75rem); }
.band--tall  { padding-block: clamp(4.5rem, 10vw, 9rem); }
.band--flush { padding-block: 0; }

/* The curved shoulder — the replacement for every `.sec-rule` hairline.
   The band rises INTO the one before it, so the join is a curve, not a line. */
.band--shoulder {
  border-start-start-radius: var(--r-band);
  border-start-end-radius: var(--r-band);
  margin-top: calc(-1 * clamp(1.25rem, 3.5vw, 3rem));
  padding-top: calc(var(--band-pad) + clamp(1.25rem, 3.5vw, 3rem));
  z-index: 1;
}
/* …and its mirror, for a band that should curve away at the bottom. */
.band--shoulder-end {
  border-end-start-radius: var(--r-band);
  border-end-end-radius: var(--r-band);
  margin-bottom: calc(-1 * clamp(1.25rem, 3.5vw, 3rem));
  padding-bottom: calc(var(--band-pad) + clamp(1.25rem, 3.5vw, 3rem));
  z-index: 1;
}

/* Photographic beds where no photograph exists. */
.band--mesh { background: var(--g-mesh); }
/* Grain: flat CSS colour reads as film rather than as a div. */
.band--grain::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--grain);
  background-size: 180px 180px;
  opacity: .05;
  mix-blend-mode: overlay;
  pointer-events: none;
  z-index: 0;
  border-radius: inherit;
}
/* The bloom field — the replacement for crop marks, and for the lozenge tile that had quietly
   become crop marks again. Three soft radials, no repeat, no tile edge, nothing with a stroke.
   The class name is kept so no page markup has to change. */
.band--lozenge::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--bloom-field);
  pointer-events: none;
  z-index: 0;
  border-radius: inherit;
  -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,.95), rgba(0,0,0,.35));
  mask-image: linear-gradient(to bottom, rgba(0,0,0,.95), rgba(0,0,0,.35));
}
.band > * { position: relative; z-index: 1; }

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--wide { max-width: var(--container-wide); }
.container--narrow { max-width: 46rem; }
.measure { max-width: var(--measure); }
.measure--tight { max-width: 34rem; }

/* Two-column split used by §3.5 / §3.8 / /contact. Photo-first on mobile is a
   source-order decision; .split--flip re-places it at the breakpoint instead. */
.split { display: grid; gap: var(--s-5); }
/* minmax(0, …) everywhere: `1fr` has an AUTO minimum, so an <img width="800">
   in a track forced the track to 800px and pushed the interlock 121px past a
   900px viewport. Measured, not theoretical. */
@media (min-width: 900px) {
  .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
  .split--wide-left { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); }
  .split--wide-right { grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr); }
  .split--top { align-items: start; }
  .split--flip > :first-child { order: 2; }
}

/* Vertical rhythm inside a band. Six steps, nothing else. */
.stack > * + * { margin-top: var(--s-3); }
.stack--tight > * + * { margin-top: var(--s-2); }
.stack--loose > * + * { margin-top: var(--s-4); }
.stack--wide > * + * { margin-top: var(--s-5); }

/* ============================================================================
   4. TYPE
   Sentence case, terminal full stop, balanced wrap. UPPERCASE only in .eyebrow.
   ========================================================================== */
.eyebrow {
  display: flex;
  /* flex-start, not center: a two-line eyebrow at 390px floated the dot into
     the gap between its lines. */
  align-items: flex-start;
  gap: .5em;
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  letter-spacing: .15em;
  line-height: 1.35;
  text-transform: uppercase;
  color: var(--fg-2);
  margin: 0;
}
/* The 8px crimson dot that replaced the `№ 01 — THE COVER` folio. */
.eyebrow::before {
  content: "";
  flex: 0 0 auto;
  width: 8px; height: 8px;
  border-radius: var(--r-circle);
  background: var(--crimson);
  margin-top: .5em;
}
.eyebrow--plain::before { display: none; }
.eyebrow--centred { justify-content: center; }
.eyebrow--fg { color: var(--fg); }

.micro { font-size: var(--fs-micro); font-weight: 500; line-height: 1.5; color: var(--fg-2); }
.caption { font-size: var(--fs-micro); font-weight: 500; line-height: 1.5; color: var(--fg-2); }
.lead { font-size: var(--fs-lead); font-weight: 400; line-height: 1.45; letter-spacing: -.01em; text-wrap: balance; }
.body { font-size: var(--fs-body); line-height: 1.7; }

.h3 { font-size: var(--fs-h3); font-weight: 600; line-height: 1.2; letter-spacing: -.02em; text-wrap: balance; }
.h2 { font-size: var(--fs-h2); font-weight: 600; line-height: 1.02; letter-spacing: -.035em; text-wrap: balance; }

/* .sentence — the H1. It carries the whole defining sentence, so it is capped
   and measured, not scaled to shout. */
.sentence {
  font-size: var(--fs-sentence);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -.03em;
  max-width: 30ch;
  text-wrap: balance;
}
.sentence .role { color: var(--accent-text); font-weight: 700; }
/* .sentence--short — a headline, not a summary. One clause, sentence case, a
   terminal full stop, and AT MOST ONE crimson phrase. The 25-word H1 that used
   to live here ran to seven lines at 1440 with 56% of its words in crimson; the
   words it carried now sit in .standfirst below, unsplit by any <strong>. */
.sentence--short {
  font-size: var(--fs-sentence-short);
  line-height: 1.04;
  letter-spacing: -.035em;
  max-width: 20ch;
}
/* The defining sentence, at lead size, directly under the H1 — one continuous
   run of text so an extractor gets it byte-for-byte. */
.standfirst { text-wrap: pretty; }

/* .statement — short brand lines only. This is where the cinematic scale lives. */
.statement {
  font-size: var(--fs-statement);
  font-weight: 600;
  line-height: .95;
  letter-spacing: -.04em;
  max-width: 22ch;
  text-wrap: balance;
}
.statement--centred { margin-inline: auto; text-align: center; }
.statement--wide { max-width: 30ch; }

/* Giant year numerals — the timeline's rhythm, with no spine and no dots. */
.numeral {
  font-size: var(--fs-numeral);
  font-weight: 600;
  line-height: .9;
  letter-spacing: -.045em;
  color: var(--accent-text);
  font-variant-numeric: tabular-nums;
}

/* Prose. No drop cap, no serif, no first-line indent. */
.prose { max-width: var(--measure); }
.prose > p + p { margin-top: 1.35em; }
.prose a,
a.prose-link {
  text-decoration: underline;
  text-decoration-color: var(--crimson);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  transition: color var(--t-fast) ease;
}
.prose a:hover, a.prose-link:hover { color: var(--accent-text); }
.prose strong { font-weight: 600; }
.crimson-line { color: var(--accent-text); font-weight: 500; }

/* The highlighter block — the replacement for the crimson pull-quote rule. */
.mark {
  background: var(--crimson-fill);
  color: #FFFFFF;
  border-radius: .2em;
  padding: 0 .18em .06em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* An arrow glyph that leans forward on hover. */
.arrow { display: inline-block; transition: transform var(--t-fast) var(--ease); }
a:hover .arrow, button:hover .arrow, .btn:hover .arrow, li:hover .arrow { transform: translateX(4px); }

/* No hairline. Two footer link columns on every one of six pages meant this rule
   drew 5-12 full-width rules per page at 390px — the ruled-line look the whole
   redesign exists to remove. Spacing separates these items instead. */
.linked-list > li { padding-block: .45rem; }

/* ============================================================================
   5. NAV — a floating pill. (Retires the 3px+1px scotch rule.)
   ========================================================================== */
.nav {
  position: sticky;
  top: 0;
  z-index: 60;
  height: var(--nav-total);
  /* The nav floats OVER the band that follows it. */
  margin-bottom: calc(-1 * var(--nav-total));
  padding: var(--nav-gap) var(--gutter);
  pointer-events: none;
}
.nav__pill {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  max-width: var(--container-wide);
  margin-inline: auto;
  min-height: var(--nav-h);
  padding: .5rem .5rem .5rem clamp(1rem, 2.5vw, 1.5rem);
  border-radius: var(--r-pill);
  background: rgba(255,255,255,.72);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
  box-shadow: var(--shadow-nav);
  color: var(--ink);
}
/* MAJOR 6 — the pill inverts over the dark hero and reverts over the light bands. The class sits
   on <body>, is written into the markup as the no-JS default (correct at scroll top, where every
   dark-hero page starts) and is toggled by the IntersectionObserver in site.js §4. Nothing is
   hard-coded on the <header>, so the pill can no longer be stuck dark for a whole scroll. */
[data-theme="dark"] .nav__pill,
.nav-dark .nav__pill {
  background: rgba(19,27,46,.72);
  color: #FFFFFF;
  box-shadow: 0 8px 28px rgba(0,0,0,.34);
  /* The quiet-pill tokens must invert with the pill, or the theme toggle's
     circle disappears into a dark pill in the light theme. */
  --pill-quiet: rgba(255,255,255,.10);
  --wash: rgba(255,255,255,.14);
}
.nav__wordmark {
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1;
  white-space: nowrap;
}
.nav__links {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  justify-content: center;
  gap: clamp(.75rem, 2vw, 1.5rem);
}
.nav__links a {
  font-size: .9375rem;
  font-weight: 500;
  padding: .35rem 0;
  border-radius: var(--r-pill);
  transition: color var(--t-fast) ease, opacity var(--t-fast) ease;
}
.nav__links a:hover { color: var(--crimson-text); }
[data-theme="dark"] .nav__links a:hover,
.nav-dark .nav__links a:hover { color: var(--crimson-on-dark); }
.nav__links a[aria-current="page"] {
  color: var(--crimson-text);
  font-weight: 600;
}
[data-theme="dark"] .nav__links a[aria-current="page"],
.nav-dark .nav__links a[aria-current="page"] { color: var(--crimson-on-dark); }
.nav__actions { display: flex; align-items: center; gap: .5rem; }

/* Theme toggle — a 32px circle. Chris's signature; it never collapses. */
.theme-toggle {
  display: none;
  width: 2.25rem; height: 2.25rem;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-circle);
  background: var(--pill-quiet);
  color: currentColor;
  cursor: pointer;
  padding: 0;
  transition: background-color var(--t-fast) ease, transform var(--t-fast) var(--ease);
}
.js .theme-toggle { display: inline-flex; }
.theme-toggle:hover { background: rgba(20,26,44,.12); }
[data-theme="dark"] .theme-toggle:hover,
.nav-dark .theme-toggle:hover { background: rgba(255,255,255,.16); }
.theme-toggle svg { width: 1.125rem; height: 1.125rem; }
.theme-toggle .icon-moon { display: none; }
[data-theme="dark"] .theme-toggle .icon-moon { display: block; }
[data-theme="dark"] .theme-toggle .icon-sun { display: none; }

/* Burger. Without JS it is hidden and the links simply stay inline — a failed
   script can never hide the navigation. */
.nav__burger {
  display: none;
  width: 2.25rem; height: 2.25rem;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-circle);
  background: var(--pill-quiet);
  cursor: pointer;
}
.nav__burger svg { width: 1.125rem; height: 1.125rem; }
.nav__burger .icon-close { display: none; }
.nav__burger[aria-expanded="true"] .icon-close { display: block; }
.nav__burger[aria-expanded="true"] .icon-burger { display: none; }

@media (max-width: 719px) {
  .nav__pill { gap: .5rem; padding-left: 1rem; }
  .nav__wordmark { font-size: 1rem; }
  /* MEASURED, no-JS: wordmark + three inline links + toggle + CTA overflowed a 390px viewport by
     up to 72px and gave every phone a horizontal scrollbar, because the collapse was gated on .js.
     Without JS the pill therefore WRAPS — the links drop to a second row inside the same pill and
     stay reachable. A failed script costs a taller pill, never a hidden navigation and never a
     sideways scroll. */
  html:not(.js) .nav { height: auto; margin-bottom: calc(-1 * var(--nav-total)); }
  html:not(.js) .nav__pill { flex-wrap: wrap; row-gap: .25rem; border-radius: var(--r-card); }
  html:not(.js) .nav__links {
    order: 3;
    flex: 1 0 100%;
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: .25rem 1rem;
    padding-bottom: .25rem;
  }
  html:not(.js) .nav__actions { margin-left: auto; }
  /* The CTA survives the collapse; the navigation doesn't. */
  .js .nav__burger { display: inline-flex; }
  .js .nav__links {
    position: absolute;
    top: calc(100% + .5rem);
    left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: var(--s-2);
    border-radius: var(--r-card);
    background: var(--surface);
    color: var(--fg);
    box-shadow: var(--shadow-lift);
    opacity: 0;
    transform: translateY(-6px);
    visibility: hidden;
    transition: opacity var(--t-fast) var(--ease), transform var(--t-fast) var(--ease), visibility var(--t-fast);
  }
  [data-theme="dark"] .js .nav__links { background: var(--navy-800); }
  .js .nav__links[data-open] { opacity: 1; transform: none; visibility: visible; }
  .js .nav__links a { padding: .7rem 1rem; border-radius: var(--r-pill); }
  .js .nav__links a:hover { background: var(--pill-quiet); }
  .nav__pill { position: relative; }
  .nav__cta { padding: .7rem 1.1rem; font-size: .9375rem; }
  .nav__pill { flex-wrap: nowrap; }
}
@media (max-width: 419px) {
  .nav__cta .nav__cta-long { display: none; }
}

/* ============================================================================
   6. PILLS — buttons, chips, links. Radius 999px on all three.
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5em;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -.005em;
  text-align: center;
  padding: 1rem 1.75rem;
  border-radius: var(--r-pill);
  border: 0;
  cursor: pointer;
  /* The fill grows from the inside on hover — never a colour swap. */
  transition: box-shadow var(--t) var(--ease), background-color var(--t) var(--ease),
              color var(--t) var(--ease), transform var(--t-fast) var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn--crimson { background: var(--crimson-fill); color: #FFFFFF; }
.btn--crimson:hover { background: var(--crimson-fill-hover); box-shadow: inset 0 0 0 100px rgba(255,255,255,.10); }
.btn--light { background: #FFFFFF; color: var(--ink); }
.btn--light:hover { box-shadow: inset 0 0 0 100px rgba(20,26,44,.08); }
.btn--ink { background: var(--ink); color: var(--paper); }
.btn--ink:hover { box-shadow: inset 0 0 0 100px rgba(255,255,255,.12); }
/* In the dark theme an ink pill would fill with the same navy as the band it
   sits on (the sand stance IS --navy-700), so it inverts to the light pill. */
[data-theme="dark"] .btn--ink { background: #FFFFFF; color: var(--navy-900); }
[data-theme="dark"] .btn--ink:hover { box-shadow: inset 0 0 0 100px rgba(20,26,44,.10); }
.btn--quiet {
  background: var(--pill-quiet);
  color: var(--fg);
  box-shadow: inset 0 0 0 1px var(--ui);
}
.btn--quiet:hover { box-shadow: inset 0 0 0 1px var(--ui), inset 0 0 0 100px var(--wash); }
/* Frosted — for a control sitting on top of a photograph or film.
   MEASURED: white on rgba(255,255,255,.18) over an unknown photograph has NO contrast floor — over
   a bright frame it was 1.1:1. The fill is therefore navy at 62%, which is the site's own scrim:
   worst case (a pure-white frame underneath) composites to #686C75 and white on it is 5.1:1; over
   anything darker it only improves. The blur stays, so it still reads as frosted glass. */
.btn--frost {
  background: rgba(11,18,32,.62);
  color: #FFFFFF;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.34);
  -webkit-backdrop-filter: blur(12px) saturate(1.2);
  backdrop-filter: blur(12px) saturate(1.2);
}
.btn--frost:hover { background: rgba(11,18,32,.76); }
.btn--sm { padding: .625rem 1.125rem; font-size: .9375rem; }
/* The one label that must never wrap: it is the pill the mobile nav keeps.
   inline-block, not flex: the flex `gap` would otherwise double the space in
   `<span class="nav__cta-long">The </span>Stand-To`. */
.nav__cta { white-space: nowrap; display: inline-block; }
/* COUNTED, then cut: the first screen carried FOUR competing crimson objects —
   the H1's crimson words, this nav pill, the edge tab and the hero CTA. The
   benchmark carries one quiet nav pill and one saturated action. So the nav pill
   goes neutral (ink on paper, white on navy — both far past AA) and the hero CTA
   becomes the only filled crimson on the screen. The markup keeps btn--crimson
   so a future light-nav page inherits the same neutral treatment. */
.nav__cta.btn--crimson { background: var(--ink); color: var(--paper); }
.nav__cta.btn--crimson:hover { box-shadow: inset 0 0 0 100px rgba(255,255,255,.14); }
[data-theme="dark"] .nav__cta.btn--crimson,
.nav-dark .nav__cta.btn--crimson { background: #FFFFFF; color: var(--navy-900); }
[data-theme="dark"] .nav__cta.btn--crimson:hover,
.nav-dark .nav__cta.btn--crimson:hover { box-shadow: inset 0 0 0 100px rgba(20,26,44,.10); }
.btn--wide { width: 100%; }
/* Ratio discipline: the sentence and the photograph do the selling, so the
   hero button is deliberately quiet. */
.btn--hero { padding: 1.0625rem 2rem; }

/* Three full-width stacked pills — the replacement for the `.doors` hairline list. */
.pill-stack { display: grid; gap: var(--s-1); }
.pill-stack .pill-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
  min-height: 3.5rem;
  padding: .875rem 1.375rem;
  border-radius: var(--r-pill);
  background: var(--pill-quiet);
  color: var(--fg);
  font-weight: 500;
  transition: background-color var(--t) var(--ease), color var(--t) var(--ease);
}
.pill-stack .pill-row:hover { background: var(--crimson-fill); color: #FFFFFF; }
.pill-stack .pill-row:hover .arrow { transform: translateX(4px); }

/* Chips, pill links, the dateline pill. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  font-size: var(--fs-micro);
  font-weight: 600;
  line-height: 1.2;
  padding: .375rem .75rem;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--fg);
}
[data-stance="dark"] .chip, [data-theme="dark"] .chip { background: var(--pill-quiet); }
.chip--crimson { background: var(--crimson-tint); color: var(--crimson-text); }
/* MEASURED: --crimson-on-dark on the 16% crimson tint is 4.43:1 and FAILS.
   --crimson-on-navy-700 clears 4.5:1 over every navy in the set (5.23–6.92:1). */
[data-theme="dark"] .chip--crimson,
[data-stance="dark"] .chip--crimson { background: rgba(233,53,62,.16); color: var(--crimson-on-navy-700); }
.chip--outline { background: transparent; box-shadow: inset 0 0 0 1px var(--ui); }
/* The numeral slot of a row whose year is not confirmed. It used to hold a display-size em dash,
   which rendered as a long horizontal stroke — a rule by another name. A quiet chip says the same
   thing, keeps the slot occupied so the grid does not collapse, and draws no line. */
.chip--undated { background: var(--pill-quiet); color: var(--fg-2); font-weight: 500; }
.chip--btn {
  cursor: pointer;
  box-shadow: inset 0 0 0 1px var(--ui);
  transition: background-color var(--t-fast) ease, opacity 150ms ease;
}
.chip--btn.is-swapping { opacity: 0; }
.chip--btn:hover { background: var(--wash); }
.dateline {
  display: inline-flex;
  align-items: center;
  gap: .5em;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: .02em;
  padding: .5rem 1rem;
  border-radius: var(--r-pill);
  background: var(--pill-quiet);
  color: var(--fg);
}
.pill-link {
  display: inline-flex;
  align-items: center;
  gap: .5em;
  padding: .625rem 1.125rem;
  border-radius: var(--r-pill);
  background: var(--pill-quiet);
  color: var(--fg);
  font-size: .9375rem;
  font-weight: 500;
  transition: background-color var(--t-fast) ease, color var(--t-fast) ease;
}
.pill-link:hover { background: var(--crimson-fill); color: #FFFFFF; }
.pill-row-list { display: flex; flex-wrap: wrap; gap: var(--s-1); }
/* A large pill carrying an address — /contact's email. */
.pill-address {
  display: inline-flex;
  align-items: center;
  gap: .6em;
  max-width: 100%;
  padding: .875rem 1.5rem;
  border-radius: var(--r-pill);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  font-size: var(--fs-h3);
  font-weight: 600;
  letter-spacing: -.02em;
  word-break: break-word;
}
[data-stance="dark"] .pill-address, [data-theme="dark"] .pill-address { box-shadow: inset 0 0 0 1px var(--hairline); }
.pill-address:hover { color: var(--accent-text); }

/* Icon button — a circle. Video controls, carousel arrows, the letter submit. */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem; height: 2.75rem;
  flex: 0 0 auto;
  border-radius: var(--r-circle);
  cursor: pointer;
  transition: background-color var(--t-fast) ease, transform var(--t-fast) var(--ease);
}
.icon-btn svg { width: 1.125rem; height: 1.125rem; }
.icon-btn--crimson { background: var(--crimson-fill); color: #FFFFFF; }
.icon-btn--crimson:hover { background: var(--crimson-fill-hover); }
.icon-btn--frost {
  background: rgba(11,18,32,.55);
  color: #FFFFFF;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.34);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.icon-btn--frost:hover { background: rgba(11,18,32,.72); }
.icon-btn--quiet { background: var(--pill-quiet); color: var(--fg); }
.icon-btn--quiet:hover { background: var(--wash); }

/* ============================================================================
   7. CARDS, PLATES, WELLS — depth from radius and overlap, not from rules.
   ========================================================================== */
.card {
  min-width: 0;
  background: var(--surface);
  color: var(--fg);
  border-radius: var(--r-card);
  padding: clamp(1.25rem, 3vw, 2rem);
  box-shadow: var(--shadow-card);
}
.card--hero-r { border-radius: var(--r-hero); }
.card--raised { background: var(--surface-2); }
.card--well { background: var(--well); box-shadow: none; }
.card--flush { padding: 0; overflow: hidden; overflow: clip; }
/* Tinted rounded plate — replaces the left-border bio block and mission aside. */
.plate {
  min-width: 0;
  background: var(--surface);
  border-radius: var(--r-card);
  padding: clamp(1.5rem, 4vw, 2.75rem);
  box-shadow: var(--shadow-card);
}
.plate--tint { background: var(--surface-2); box-shadow: none; }
.plate--crimson { background: var(--crimson-tint); box-shadow: none; }
[data-theme="dark"] .plate--crimson { background: rgba(233,53,62,.12); }
.plate--brass { background: var(--brass-tint); box-shadow: none; }
[data-theme="dark"] .plate--brass { background: rgba(242,163,60,.12); }

/* A card that is a link: lifts, and its media grows. */
a.card, .card--link { display: block; transition: transform var(--t) var(--ease), box-shadow var(--t) var(--ease); }
a.card:hover, .card--link:hover { transform: translateY(-2px); }
[data-stance="light"] a.card:hover, [data-stance="sand"] a.card:hover { box-shadow: var(--shadow-lift); }
a.card:hover .media img, .card--link:hover .media img { transform: scale(1.03); }

.grid-3 { display: grid; gap: var(--s-3); }
.grid-2 { display: grid; gap: var(--s-3); }
@media (min-width: 760px) { .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px) { .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-4); } }

/* Fact rows — numbers and dates only, never adjectives, never a count-up. */
.facts { display: flex; flex-wrap: wrap; gap: var(--s-4); }
.fact__n { font-size: clamp(1.5rem, 1.2rem + 1vw, 2.125rem); font-weight: 700; letter-spacing: -.03em; line-height: 1.1; display: block; }
.fact__l { font-size: var(--fs-micro); font-weight: 500; color: var(--fg-2); display: block; margin-top: .25rem; }

/* §3.2 the sourced-proof triad */
.proof__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem; height: 3rem;
  border-radius: var(--r-circle);
  background: var(--crimson-tint);
  color: var(--crimson-text);
  margin-bottom: var(--s-3);
}
[data-theme="dark"] .proof__icon { background: rgba(233,53,62,.16); color: var(--crimson-on-dark); }
[data-stance="dark"] .proof__icon { background: rgba(233,53,62,.16); color: var(--crimson-on-dark); }
.proof__icon svg { width: 1.375rem; height: 1.375rem; }
.proof__fact { font-size: var(--fs-h3); font-weight: 600; letter-spacing: -.02em; line-height: 1.2; }
/* A 26-character URL token pushed the proof card 13px past a 320px viewport
   and gave the phone a horizontal scrollbar. Sourced facts name URLs, so this
   has to break. */
.proof__source { margin-top: .5rem; color: var(--fg-2); font-size: var(--fs-body); line-height: 1.6; overflow-wrap: anywhere; }
@media (max-width: 899px) {
  .proof .card { display: grid; grid-template-columns: 3rem minmax(0, 1fr); gap: var(--s-3); align-items: start; }
  .proof .proof__icon { margin-bottom: 0; }
  .proof .proof__body { grid-column: 2; }
}

/* ============================================================================
   8. MEDIA — every image lives inside a rounded container.
   ========================================================================== */
.media {
  min-width: 0;
  position: relative;
  overflow: hidden;
  overflow: clip;
  border-radius: var(--r-card);
  background: var(--well);
  aspect-ratio: 16 / 9;
  isolation: isolate;
}
.media--hero-r { border-radius: var(--r-hero); }
.media--4-3 { aspect-ratio: 4 / 3; }
.media--3-4 { aspect-ratio: 3 / 4; }
.media--4-5 { aspect-ratio: 4 / 5; }
.media--1-1 { aspect-ratio: 1 / 1; }
.media > img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--t) var(--ease);
}
/* One locked photographic grade: warm skin, cool surroundings. */
.media > img.graded { filter: saturate(1.08) contrast(1.06); }
.media--vignette::after {
  content: "";
  position: absolute; inset: 0;
  background: var(--g-vignette);
  pointer-events: none;
  z-index: 1;
}
/* Treatment C — the duotone tile. Costs one blend mode. */
.media--duotone { background: var(--navy-800); }
.media--duotone > img { filter: grayscale(1) contrast(1.1); mix-blend-mode: screen; }
.media--duotone-crimson { background: var(--crimson-fill); }
.media__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
  pointer-events: none;
}
.media__overlay > * { pointer-events: auto; }
.media__label {
  position: absolute;
  left: var(--s-2); top: var(--s-2);
  z-index: 2;
}
/* NOTE: the video-control block (.media__controls, the play/pause and mute/unmute icon swaps) was
   deleted with the video subsystem in site.js §5 — no page in this build contains a <video>. The
   rules in REDESIGN-BRIEF §6 stand and come back with the markup, not before it. */

.figure { margin: 0; }
.figure figcaption { margin-top: var(--s-2); font-size: var(--fs-micro); color: var(--fg-2); }

/* ============================================================================
   9. THE HERO CARD — the hero is a card, not a bleed.
   ========================================================================== */
.hero { padding-block: 0; }
.hero-card {
  position: relative;
  isolation: isolate;
  /* Capped, then centred. MEASURED: the portrait's native width is 932px, so an
     uncapped full-bleed card enlarges it — 1.502x at 1440, worse above. The cap
     holds the card at 110rem (1760px) so the photographic bed below it never
     exceeds 58rem (928px) and the asset is DOWNSCALED at every width we ship. */
  width: calc(100% - var(--hero-inset) * 2);
  max-width: 110rem;
  margin-inline: auto;
  margin-top: var(--hero-inset);
  border-radius: var(--r-hero);
  overflow: hidden;
  overflow: clip;
  box-shadow: none;
  background: var(--navy-900);
  /* Capped as well as fluid. `cover` on a very tall window becomes HEIGHT-driven
     and starts enlarging the 932×1400 asset — MEASURED 2.46x at a 3600px-tall
     viewport. Holding the card at 58rem keeps the vertical term at 928/1400 =
     0.663, so the bed is width-driven and downscaled at every viewport size. */
  min-height: min(calc(100svh - var(--nav-total) - var(--hero-inset) * 2), 58rem);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--nav-total) clamp(1.25rem, 4vw, 3.5rem) clamp(1.75rem, 4vw, 3.5rem);
  color: #FFFFFF;
}
.hero-card--half { min-height: min(62svh, 40rem); }
.hero-card--short { min-height: min(46svh, 30rem); }

/* ---- THE PHOTOGRAPHIC BED -------------------------------------------------
   ONE grade, and it is BAKED into portrait-hero-*.webp: a chroma-keyed pass
   that lifts him (face sat 0.396 → 0.489, teeth p95 0.706 → 0.837) and lets the
   neutral studio wall recede. Nothing in this stylesheet darkens him a second
   time. The retired portrait-graded-*.webp carried a navy multiply AND took
   --g-halfscrim on top of it, which measured his face at 0.026 mean / 0.052 p95
   against the benchmark's 0.155 / 0.513 — his teeth rendered #3A3A3A grey.
   The only layers over the photograph now are two feathers, and BOTH are fully
   transparent across his face. */
.hero-media {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: var(--hero-img);
  background-size: cover;
  background-position: var(--hero-pos, 50% 12%);
  background-repeat: no-repeat;
  background-color: var(--navy-900);
}
.hero-bloom {
  position: absolute; inset: 0; z-index: -1;
  /* Held to the type side and quieted: on the first screen the crimson budget
     belongs to the CTA. */
  background: radial-gradient(46% 44% at 10% 46%, rgba(233,53,62,.16), transparent 72%);
  pointer-events: none;
}
/* NOTE: Treatment A (.hero-card--flood + .hero-cutout + .ghost-word) was deleted with the parallax
   in site.js §6 — no page in this build contains a cut-out. It returns with its markup. */

.hero__type { position: relative; z-index: 2; max-width: 34rem; }
.hero__type .sentence { margin-top: var(--s-3); }
.hero__type .lead { margin-top: var(--s-3); color: rgba(255,255,255,.88); max-width: 34ch; }
.hero__type .standfirst { color: rgba(255,255,255,.90); max-width: 44ch; }
.hero__type .micro { margin-top: var(--s-2); color: #A8B0C4; }
.hero__cta { margin-top: var(--s-4); }
/* The risk-reversal caption sits BELOW the button, not inside it. */
.hero__reassure { margin-top: var(--s-2); font-size: var(--fs-micro); color: #A8B0C4; max-width: 46ch; }

/* Bottom-right inset card: the first screen offers exactly two actions. */
.hero__aside {
  position: absolute;
  right: clamp(1.25rem, 4vw, 3.5rem);
  bottom: clamp(1.75rem, 4vw, 3.5rem);
  width: min(17.5rem, 25vw);
  z-index: 2;
}
.hero__aside .media { margin-top: var(--s-2); }
/* The film card is the SECOND thing on the screen. At --fs-h3 its title matched
   the H1 for weight and pulled the eye off him; it is a label, so it is set as
   one. This also shortens the card enough to clear his jaw on a short window. */
.hero__aside .h3 { font-size: 1.0625rem; letter-spacing: -.01em; }

/* ---- ≥900px: the type and the photograph occupy DIFFERENT COLUMNS -----------
   The old hero laid the type over the picture and relied on --g-halfscrim,
   which ran flat navy to 34% of the card while the type block ran to ~50% — so
   the lower H1 lines sat on his cheek and jaw at 1280 and 1440. Splitting the
   card makes the collision structurally impossible: the type's measure is capped
   below the bed's left edge, so type-vs-face overlap is zero at EVERY width. */
@media (min-width: 900px) {
  /* 48% of the card, never wider than the asset's native 932px, and never so
     wide on a SHORT window that his jaw drops into the film card below him —
     MEASURED: at 1920×900 an unbounded 48% put 8,500px² of the film card over
     his face. The svh term is what keeps that at zero. */
  .hero-card { --bed: clamp(22rem, min(48%, 84svh), 58rem); }
  .hero-media { left: auto; width: var(--bed); }
  /* The bed's one interior edge dissolves into the card's navy. No straight line. */
  .hero-media::before {
    content: "";
    position: absolute; inset: 0;
    background: linear-gradient(to right,
      var(--navy-900) 0,
      rgba(11,18,32,.94) 7%,
      rgba(11,18,32,.62) 20%,
      rgba(11,18,32,.24) 34%,
      rgba(11,18,32,0) 50%);
  }
  /* A spotlight, not a scrim: transparent across his face, navy at the corners,
     so the photograph joins the card on every side and the eye lands on him. */
  .hero-media::after {
    content: "";
    position: absolute; inset: 0;
    /* Centred on where his face actually renders (~76%/38% of the bed), not on
       the bed's centre — otherwise the clear core sits on empty studio wall and
       the neutral grey backdrop never joins the navy card. The core is kept tight
       so only the face stays clear; the top fade catches the wall, which is
       brightest above his head. Measured: wall 124,117,112 -> navy before this. */
    background:
      linear-gradient(to bottom, rgba(11,18,32,.72) 0, rgba(11,18,32,.18) 15%, rgba(11,18,32,0) 30%),
      radial-gradient(56% 58% at 76% 38%,
        rgba(11,18,32,0) 0 24%,
        rgba(11,18,32,.30) 52%,
        rgba(11,18,32,.93) 100%);
  }
  /* MEASURED: 42% of the card keeps the last word of the type at least 50px
     clear of the bed's left edge at 900, 1280, 1440 and 1920. */
  .hero__type { max-width: min(34rem, 42%); }
}
@media (min-width: 1500px) {
  .hero__type { max-width: min(38rem, 42%); }
}

/* ---- <900px: a photographic BAND at the top, dissolving into the type -------
   A full-bleed bed cannot work here. MEASURED at 390×844: the card is 366 wide
   and ~720 tall, so `cover` on any portrait crop zooms ~2x and drops his chin
   straight onto the H1 — which is exactly what the first build shipped.
   Instead the photograph takes a band of its own at the top and dissolves into
   the navy the type sits on. The card's PADDING-TOP is the band's height, so the
   type can never enter the band at ANY phone size: if the copy needs more room
   the card grows, it does not climb over his face. */
@media (max-width: 899px) {
  .hero__aside { display: none; }        /* Robbins' `hidden lg:block`, exactly */
  .hero-card {
    /* The band's height must never fall below 62% of its WIDTH. `cover` on a wide,
       short band is width-driven, and MEASURED at 899×900 a purely svh-capped band
       ran the crop 786px tall inside a 374px band — it cut his face in half and put
       1,800px² of type on what was left. The 62vw floor is what stops that. */
    --band: clamp(15rem, max(min(82vw, 46svh), 62vw), 34rem);
    padding-top: calc(var(--band) + var(--s-3));
    justify-content: flex-end;
    text-align: left;
  }
  .hero-media {
    inset: 0 0 auto 0;
    height: var(--band);
    background-position: var(--hero-pos-m, 56% 10%);
  }
  /* The photograph does not end — it becomes the brand colour. MEASURED: the
     stock --g-dissolve starts at 42% of the band and put a 44%–68% navy wash
     across his jaw and chin at 768 (rendered face mean 0.075 against the
     benchmark's 0.200). The feather therefore starts at 82%, which is below his
     chin at EVERY width in this range — his face is never touched. */
  .hero-media::after {
    content: "";
    position: absolute; inset: 0;
    background:
      linear-gradient(to bottom,
        rgba(11,18,32,0) 0 82%,
        rgba(11,18,32,.72) 93%,
        var(--navy-900) 100%),
      /* a side vignette so the studio wall recedes; its transparent core is
         wide enough that it never reaches him */
      radial-gradient(120% 100% at 50% 30%,
        rgba(11,18,32,0) 0 56%,
        rgba(11,18,32,.40) 100%);
  }
  .hero-bloom { display: none; }
  .hero__type { max-width: none; }
  /* Full-width, but never a 676px-wide button on a tablet. */
  .hero__cta .btn { width: 100%; max-width: 24rem; }
}

/* ============================================================================
   10. THE INTERLOCKING GRID — five jobs in one screen, zero straight lines.
   ========================================================================== */
.interlock { display: grid; gap: var(--interlock-gap); }
@media (min-width: 900px) {
  .interlock { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
}
.il-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 16 / 9;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  border-radius: var(--r-eat-br);
  background: var(--crimson-fill);
}
/* The mark is a 100×72 viewBox tightened to the cap-height bounds of the glyph pair, so the
   tile is filled by type instead of by ~90% empty space. Height-driven, width-capped. */
.il-mark img, .il-mark svg { width: auto; height: 100%; max-width: 72%; max-height: 100%; }
.il-say { min-width: 0; display: flex; align-items: center; padding: clamp(1rem, 3vw, 2rem) clamp(0rem, 2vw, 1.5rem); }
.il-panel {
  min-width: 0;
  border-radius: var(--r-eat-tr);
  background: var(--surface);
  padding: clamp(1.5rem, 3.5vw, 3.25rem);
}
/* 16:9 — the same ratio the <img> declares and the same ratio the asset is. A 4:3 box around a
   16:9 still cropped a quarter of the frame away and made the width/height attributes a lie. */
.il-media { min-width: 0; border-radius: var(--r-hero); aspect-ratio: 16 / 9; }
@media (max-width: 899px) {
  /* Radii drop a step; the interlock relaxes into a stack. */
  .il-mark, .il-panel { border-radius: var(--r-card); }
  .il-mark { aspect-ratio: 2 / 1; }
  .il-media { border-radius: var(--r-card); }
}

/* Corner-eating utilities, for any 2×2 that should read as one object. */
.eat-br { border-radius: var(--r-eat-br); }
.eat-tr { border-radius: var(--r-eat-tr); }
.eat-tl { border-radius: var(--r-eat-tl); }

/* ============================================================================
   11. THE WORD STACK — a navigation block disguised as a manifesto.
   ========================================================================== */
.wordstack { display: grid; gap: .25rem; margin-top: var(--s-4); }
.wordstack a, .wordstack span {
  display: inline-block;
  width: fit-content;
  font-size: var(--fs-statement);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -.04em;
  transition: color var(--t) var(--ease), transform var(--t) var(--ease);
}
.wordstack a:hover { color: var(--accent-text); transform: translateX(6px); }

/* ============================================================================
   12. RAILS — films, the work, any row of like cards.
   ========================================================================== */
.rail { display: grid; gap: var(--s-3); }
@media (min-width: 780px) { .rail { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-4); } }
.rail--2 { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 780px) { .rail--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.film-card .media { border-radius: var(--r-card); }
.film-card__meta { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-2); margin-top: var(--s-3); }
.film-card__title { font-size: var(--fs-h3); font-weight: 600; letter-spacing: -.02em; line-height: 1.2; margin-top: .35rem; }
/* NOTE: .film-card__still was deleted with the three identical captions it styled — each image's
   alt text already says it is a film still from the series, so the caption said it twice. */

/* §3.10 the work — one title, one subordinate clause, no prices. */
.work-card {
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  flex-wrap: wrap;
  background: var(--surface);
  border-radius: var(--r-card);
  padding: clamp(1.125rem, 2.5vw, 1.5rem) clamp(1.25rem, 3vw, 1.75rem);
  box-shadow: var(--shadow-card);
  transition: transform var(--t) var(--ease), box-shadow var(--t) var(--ease), background-color var(--t) var(--ease);
}
.work-card:hover { transform: translateY(-2px); }
[data-stance="light"] .work-card:hover, [data-stance="sand"] .work-card:hover { box-shadow: var(--shadow-lift); }
[data-stance="dark"] .work-card:hover, [data-theme="dark"] .work-card:hover { background: var(--surface-2); }
.work-card__title { font-size: var(--fs-h3); font-weight: 600; letter-spacing: -.02em; }
.work-card__clause { color: var(--fg-2); }
/* The one crimson glyph that sits alone on a card. It inherits --accent-text, which now clears
   4.5:1 on --surface in BOTH themes (light 5.83:1 on #FFF, dark 6.60:1 on --navy-700), and it is
   emboldened so a 1px-stem arrowhead is not the thing carrying the contrast. */
.work-card .arrow { margin-left: auto; color: var(--accent-text); font-weight: 700; }
.pill-stack .pill-row .arrow { font-weight: 700; }

/* ============================================================================
   13. THE YEARS — giant crimson numerals, no spine, no dots, no rules.
   ========================================================================== */
.years { display: grid; gap: var(--s-5); margin-top: var(--s-5); }
.year { display: grid; gap: var(--s-2); align-content: start; }
.year__head { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.year__title { font-size: var(--fs-h3); font-weight: 600; letter-spacing: -.02em; line-height: 1.2; }
.year__body { color: var(--fg-2); max-width: 42ch; }
@media (min-width: 900px) {
  .years { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(2rem, 6vw, 5rem); row-gap: var(--s-5); }
  .year:nth-child(odd) { grid-column: 1; }
  .year:nth-child(even) { grid-column: 2; padding-top: var(--s-6); }
}

/* ============================================================================
   14. THE LETTER — The Stand-To
   ========================================================================== */
.letter { text-align: center; }
.letter__inner { max-width: 40rem; margin-inline: auto; }
.letter__inner .eyebrow { justify-content: center; }
.letter__payload { margin-top: var(--s-3); color: var(--fg-2); }
.letter__honesty { margin-top: var(--s-3); font-size: var(--fs-micro); color: var(--fg-2); }

/* One pill input, 56px, with a 44px circular crimson submit inset 6px from its
   right edge. The word "Subscribe" appears nowhere. */
.letter-form { max-width: 30rem; margin: var(--s-4) auto 0; text-align: left; }
.field-pill { position: relative; display: block; }
.field-pill .field { padding-right: 3.75rem; }
.field-pill .icon-btn { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); }
.field-pill .icon-btn:active { transform: translateY(-50%) scale(.96); }

.consents { display: grid; gap: var(--s-2); margin-top: var(--s-3); }
.consent {
  display: grid;
  grid-template-columns: 1.125rem 1fr;
  gap: .75rem;
  align-items: start;
  font-size: var(--fs-micro);
  line-height: 1.6;
  color: var(--fg-2);
  text-align: left;
}
.consent input[type="checkbox"] {
  width: 1.125rem; height: 1.125rem;
  margin: .2rem 0 0;
  accent-color: var(--crimson-fill);
}

/* The edge tab and its drawer — ≥1024px only, JS only. Never a modal, never on mobile.
   BOTH need a base display:none. Every .letter-drawer rule used to live inside the 1024px query,
   so under 1024px the <aside> fell back to a normal in-flow block and painted a 419px duplicate
   letter panel AFTER the footer, with a dead Close button and a second email form that filed its
   signups as page=edge-tab. The base rule below is what makes the component exist at all, and the
   .js gate means a failed script leaves it hidden rather than loose on the page. */
.letter-tab { display: none; }
.letter-drawer { display: none; }
@media (min-width: 1024px) {
  .js .letter-tab {
    display: block;
    position: fixed;
    right: 0; top: 50%;
    transform: translateY(-50%);
    z-index: 55;
    writing-mode: vertical-rl;
    padding: 1.125rem .75rem;
    border-radius: var(--r-pill) 0 0 var(--r-pill);
    /* Neutral, not crimson: see the note on .nav__cta. White on --navy-800 is
       15.0:1, and the tab keeps a single crimson dot as its only accent. */
    background: var(--navy-800);
    color: #FFFFFF;
    box-shadow: var(--shadow-nav), inset 0 0 0 1px rgba(255,255,255,.14);
    font-size: .875rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    cursor: pointer;
    box-shadow: var(--shadow-nav);
    transition: background-color var(--t-fast) ease;
  }
  .js .letter-tab:hover { background: var(--navy-700); }
  .js .letter-drawer {
    display: block;
    position: fixed;
    top: 0; right: 0; bottom: 0;
    width: min(28rem, 92vw);
    /* Above the nav (60), not under it: the drawer is a panel over the page, and
       its Close button sat beneath the nav band at 56. Pad past the nav too. */
    z-index: 70;
    padding: calc(var(--nav-total) + var(--s-3)) var(--s-4) var(--s-5);
    background: var(--navy-900);
    color: #FFFFFF;
    border-radius: var(--r-band) 0 0 var(--r-band);
    box-shadow: var(--shadow-lift);
    overflow-y: auto;
    transform: translateX(102%);
    /* visibility, not just transform: an off-screen panel that keeps its focus
       order is a keyboard trap. */
    visibility: hidden;
    transition: transform 320ms var(--ease), visibility 320ms;
  }
  .js .letter-drawer[data-open] { transform: none; visibility: visible; }
  .letter-drawer__close { position: absolute; top: var(--s-3); right: var(--s-3); }
}

/* ============================================================================
   15. FORMS
   ========================================================================== */
.field {
  width: 100%;
  min-height: 3.5rem;
  background: var(--surface);
  color: var(--fg);
  /* A real 3:1 UI boundary (WCAG 1.4.11) — a 12%-alpha rule was 1.4:1 and failed. */
  border: 1px solid var(--ui);
  border-radius: var(--r-pill);
  padding: .875rem 1.25rem;
  font-size: 1rem;
  font-weight: 400;
  transition: border-color var(--t-fast) ease, box-shadow var(--t-fast) ease;
}
/* In dark mode --surface and a tinted plate are the same navy, so a field inside
   a plate had zero separation. Drop the field to page navy instead. */
[data-theme="dark"] .field,
[data-stance="dark"] .field { background: var(--navy-900); }
[data-theme="dark"] [data-stance="sand"] .field { background: var(--navy-950); }
.field--area { border-radius: var(--r-card); min-height: 8rem; padding: 1rem 1.25rem; resize: vertical; }
.field::placeholder { color: var(--fg-2); opacity: 1; }
.field:focus { border-color: var(--crimson-text); box-shadow: var(--ring-focus); outline: none; }
[data-theme="dark"] .field:focus, [data-stance="dark"] .field:focus { border-color: var(--crimson); }
.field:focus-visible { outline: 2px solid var(--crimson); outline-offset: 2px; }
.field-label { display: block; margin-bottom: .4rem; font-size: var(--fs-micro); font-weight: 600; }
.form-grid { display: grid; gap: var(--s-3); margin-top: var(--s-4); }

/* Live regions stay in the accessibility tree while empty — collapsed, never
   display:none, or the first message can go unannounced. */
.form-status { margin-top: var(--s-3); font-size: var(--fs-lead); line-height: 1.45; }
.form-status:empty { height: 0; margin-top: 0; overflow: hidden; }
.form-status:focus { outline: none; }
.form-status:focus-visible { outline: 2px solid var(--crimson); outline-offset: 2px; }
.form-success { font-weight: 500; }
.form-error { margin-top: .5rem; font-size: var(--fs-micro); font-weight: 600; color: var(--accent-text); }
.copy-status { margin-top: .6rem; font-size: var(--fs-micro); color: var(--fg-2); }
.copy-status:empty { height: 0; margin-top: 0; overflow: hidden; }

/* ============================================================================
   16. NOW / ABOUT / CONTACT / 404 specifics
   ========================================================================== */
.now-entry { }
.now-entry__title { font-size: var(--fs-h3); font-weight: 600; letter-spacing: -.02em; line-height: 1.2; margin-top: .5rem; }
.now-list { display: grid; gap: var(--s-3); margin-top: var(--s-4); }

.bio-copy { font-size: var(--fs-body); line-height: 1.7; }
.bio-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); margin-top: var(--s-3); }

.contact-aside { display: grid; gap: var(--s-1); }

.page-404 { display: grid; place-items: center; min-height: 72svh; text-align: center; }
.page-404 .actions { display: flex; flex-wrap: wrap; gap: var(--s-2); justify-content: center; margin-top: var(--s-4); }

/* ============================================================================
   17. FOOTER
   ========================================================================== */
.footer { padding-block: var(--band-pad) var(--s-4); }
.footer__cols { display: grid; gap: var(--s-4); }
@media (min-width: 760px) { .footer__cols { grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr)); gap: var(--s-4); } }
.footer__h { font-size: var(--fs-micro); font-weight: 700; letter-spacing: .15em; text-transform: uppercase; color: var(--fg-2); margin-bottom: var(--s-2); }
.footer__bio { margin-top: var(--s-2); color: var(--fg-2); font-size: .9375rem; line-height: 1.65; max-width: 34ch; }
.footer__wordmark { font-size: 1.0625rem; font-weight: 700; letter-spacing: -.02em; }
.footer__cols a { transition: color var(--t-fast) ease; }
.footer__cols a:hover { color: var(--accent-text); }
.footer__legal { margin-top: var(--s-5); display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); align-items: center; font-size: var(--fs-micro); color: var(--fg-2); }

/* ============================================================================
   18. MOTION — band entry only. No hero entrance, no count-ups, ever.
   ========================================================================== */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity var(--t) var(--ease), transform var(--t) var(--ease);
  transition-delay: var(--d, 0ms);
}
.js [data-reveal].in { opacity: 1; transform: none; }
/* The H1 fades only — slow reads as expensive. Nothing about it slides. */
.js [data-reveal="fade"] { transform: none; transition-duration: var(--t-slow); }
.js [data-reveal].in .stagger > *,
.js .stagger > * { }
/* Max three staggered children per band. */
.js [data-reveal][data-d="1"] { --d: 80ms; }
.js [data-reveal][data-d="2"] { --d: 160ms; }
.js [data-reveal][data-d="3"] { --d: 240ms; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
  .js [data-reveal] { opacity: 1; transform: none; }
}
@media (prefers-reduced-transparency: reduce) {
  .nav__pill { background: var(--paper); -webkit-backdrop-filter: none; backdrop-filter: none; }
  [data-theme="dark"] .nav__pill, .nav-dark .nav__pill { background: var(--navy-800); }
  .btn--frost { background: rgba(11,18,32,.86); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .icon-btn--frost { background: rgba(11,18,32,.86); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@media (prefers-contrast: more) {
  /* Cards gain the one legitimate border. */
  .card, .plate, .work-card, .media, .il-panel, .nav__pill, .pill-stack .pill-row, .chip, .dateline, .pill-link {
    border: 1px solid var(--fg-2);
  }
  .hero__reassure, .caption, .micro, .footer__bio, .year__body, .proof__source { color: var(--fg); }
}

/* ============================================================================
   19. PRINT — no line furniture here either.
   ========================================================================== */
@media print {
  .nav, .letter-tab, .letter-drawer, .theme-toggle { display: none !important; }
  body { background: #FFFFFF; color: #000000; }
  .band { padding-block: 1.5rem; background: #FFFFFF !important; color: #000000 !important; }
}
