/* ══════════════════════════════════════════════════════════════════════════
   JOE STOCKER FUNDRAISER — STAKEHOLDER PHOTOGRAPHY REVIEW
   The reviewer's surface. Not the engineering lab.

   THE CAMPAIGN IS THE SUBJECT. It is warm cream, gold and Fraunces, and it is
   the thing being judged — so this page is deliberately its opposite: near
   black, one accent, almost no chrome. Every piece of furniture here is sized to
   get out of the way of a photograph.

   THE SYSTEM, IN FOUR RULES
   1 · ONE LEFT EDGE. Everything on every page starts at the same x. Width
       hierarchy is expressed by how far things END — prose stops at a measure,
       photography runs to the page edge — never by a second, differently
       centred column. An earlier build gave the viewer its own wider column; it
       bought 46px of frame and cost a visible 23px step between the heading and
       the controls under it, at every width.
   2 · ONE SPACING SCALE. A 4px base, used in steps. The values it replaced were
       12 / 10 / 18 / 16 / 6 / 6 / 22 / 30 — eight numbers, no relationship.
   3 · THREE RADII, TWO CONTROL HEIGHTS. A photograph frame is square (0), a
       control is softened (6px), a pill is a pill (999px). Anything a finger
       presses is 44px; navigation chips are 40px.
   4 · TYPE HAS ROLES, NOT SIZES. Each role is declared once and reused, so the
       same thing is never set two ways on two pages.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── ink. Contrast ratios are against --ink. ─────────────────────────── */
  --ink: #0b0b0c;
  --ink-2: #131316;
  --ink-3: #1c1c21;
  --line: #2b2b32;
  --line-soft: #202026;
  --fg: #f4f3f0;            /* 17.4:1                                        */
  --fg-2: #b2b1ac;          /*  8.4:1 — supporting copy                      */
  --fg-3: #8a8983;          /*  5.3:1 — metadata, still AA at small sizes    */
  --gold: #e8b23a;          /*  9.6:1 — the campaign's own accent            */
  --live: #63d69a;          /* 11.2:1 — "this is what is on the site today"  */

  /* ── type ────────────────────────────────────────────────────────────── */
  --ui: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  --display: Fraunces, Georgia, "Times New Roman", serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

  /* ── space: 4px base, used in steps, nothing in between ──────────────── */
  --s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;
  --s-5: 24px;  --s-6: 32px;  --s-7: 48px;  --s-8: 64px;  --s-9: 96px;

  /* ── measure: prose stops, photography does not ──────────────────────── */
  --measure: 62ch;          /* lede, question, locked copy                   */
  --measure-note: 78ch;     /* footer note — smaller type, wider measure     */

  /* ── the single column every page shares ─────────────────────────────── */
  --gutter: clamp(20px, 3.2vw, 56px);
  --page: min(1680px, 100% - var(--gutter) * 2);

  /* ── controls ────────────────────────────────────────────────────────── */
  --h-control: 44px;        /* anything a finger presses                     */
  --h-nav: 40px;            /* step chips in the bar                         */
  --r-frame: 0px;           /* a photograph frame is square                  */
  --r-control: 6px;
  --r-pill: 999px;
  --frame-gap: 20px;        /* between two comparison frames                 */
  --bar-h: 60px;            /* replaced at runtime with the measured value   */
}

* { box-sizing: border-box; }
html { color-scheme: dark; -webkit-text-size-adjust: 100%; }
body.sr {
  margin: 0; background: var(--ink); color: var(--fg);
  font: 400 16px/1.6 var(--ui);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* ONE LEFT EDGE. `.reviewcol` is kept as an alias of `.col` rather than removed,
   so the generated markup and the client modules need no coordinated change. */
.col, .reviewcol { width: var(--page); margin-inline: auto; }
img { max-width: 100%; }
a { color: inherit; }

.skip { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.skip:focus {
  width: auto; height: auto; clip-path: none; position: fixed; left: var(--s-3); top: var(--s-3); z-index: 999;
  background: var(--gold); color: #17140c; padding: var(--s-3) var(--s-5);
  border-radius: var(--r-control); font-weight: 700;
}
:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: var(--r-control); }

/* ── TYPE ROLES ───────────────────────────────────────────────────────────
   `--t-display-l` is shared by the four section headings AND the summary
   heading, so the last page of the review is set like the four before it rather
   than like the landing page. */
.hero-l h1 {
  margin: 0; font: 400 clamp(38px, 5.6vw, 76px)/1.04 var(--display);
  letter-spacing: -0.025em;
}
.head h1, .done-h h1 {
  margin: 0; font: 400 clamp(30px, 3.9vw, 54px)/1.08 var(--display);
  letter-spacing: -0.02em;
}
/* ONE EYEBROW. It was 11.5/650/0.2em on the landing page and 13/500/0.12em on
   the review pages — the same role, set two ways, two pages apart. */
.kicker, .head__n, .journey h2, .strip__lab, .locked__k, .toolset > span {
  margin: 0; font: 650 11px/1.5 var(--ui); letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--fg-3);
}
.kicker, .head__n { color: var(--gold); }
.lede, .head__d {
  margin: 0; max-width: var(--measure); color: var(--fg-2);
  font-size: clamp(16px, 1.15vw, 18px); line-height: 1.62;
}
.lede strong, .head__d strong { color: var(--fg); font-weight: 600; }

/* ── CONTROLS ─────────────────────────────────────────────────────────────
   Three roles, never the same size by accident:
     .btn--go  primary   — the one thing to do on this page
     .btn      secondary — an alternative route
     .btn--sm  utility   — present, subordinate, never competing with a decision */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: var(--h-control); padding: 0 var(--s-6); border-radius: var(--r-pill);
  font: 600 15px/1 var(--ui); letter-spacing: 0.005em; text-decoration: none; white-space: nowrap;
  border: 1px solid var(--line); background: transparent; color: var(--fg);
  cursor: pointer; transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.btn:hover { border-color: var(--fg-3); background: var(--ink-3); }
.btn:active { background: var(--ink-2); }
.btn--go { background: var(--gold); border-color: var(--gold); color: #17140c; font-weight: 700; }
.btn--go:hover { background: #f2c055; border-color: #f2c055; color: #17140c; }
.btn--sm { min-height: var(--h-nav); padding: 0 var(--s-5); font-size: 13.5px; color: var(--fg-2); }
.btn--sm:hover { color: var(--fg); }
.btn[disabled] { opacity: .36; pointer-events: none; }

.actions { display: flex; flex-wrap: wrap; gap: var(--s-3); }

/* ── LANDING — three bands, one rhythm ────────────────────────────────── */
.hero-l { padding: var(--s-9) 0 var(--s-8); }
.hero-l h1 { margin-bottom: var(--s-5); max-width: 15ch; }
.hero-l h1 em { font-style: italic; color: var(--gold); }
.hero-l .lede + .lede { margin-top: var(--s-4); }
.hero-l .actions { margin-top: var(--s-7); }
.hero-l .fineprint { margin: var(--s-4) 0 0; font-size: 13.5px; color: var(--fg-3); }

.journey { padding: var(--s-8) 0; border-top: 1px solid var(--line-soft); }
.journey p.sub { margin: var(--s-2) 0 var(--s-6); color: var(--fg-2); font-size: 15px; }
.journey h2 { margin-bottom: var(--s-6); }
/* FOUR, THEN TWO BY TWO, THEN ONE — an explicit count, never `auto-fit`.
   This rule has now been wrong in both directions. Fitting wrapped 3 + 1 back
   when there were four decisions; hard-coding three fixed that and then broke
   the moment the thank-you decision made it four again, wrapping 3 + 1 once
   more. The count is therefore tied to the number of decisions and the middle
   state is 2 x 2, which has no orphan at any width. */
.steps {
  display: grid; gap: var(--s-4) var(--s-5); grid-template-columns: repeat(4, minmax(0, 1fr));
  list-style: none; margin: 0; padding: 0;
}
@media (max-width: 1100px) { .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .steps { grid-template-columns: minmax(0, 1fr); } }
/* The status line is pinned to a shared bottom row, so a one-line blurb and a
   two-line blurb do not put "NOT YET REVIEWED" on two different baselines.
   The <li> has to stretch too — the grid item is the list item, and an anchor
   inside one that does not fill it cannot align anything to the row's bottom. */
.steps > li { display: grid; }
.step { height: 100%; }
.step {
  display: grid; grid-template-rows: auto auto 1fr auto; gap: var(--s-2);
  border-top: 2px solid var(--line); padding: var(--s-4) 0 var(--s-5);
  text-decoration: none; transition: border-color .12s ease;
}
a.step:hover { border-top-color: var(--gold); }
.step__n { font: 500 14px/1 var(--mono); color: var(--gold); letter-spacing: .04em; }
.step__t { font: 400 clamp(20px, 1.7vw, 25px)/1.15 var(--display); letter-spacing: -0.012em; }
.step__b { margin: 0; color: var(--fg-2); font-size: 14.5px; line-height: 1.55; }
.step__tag {
  align-self: end; font: 650 10px/1.5 var(--ui); letter-spacing: .14em;
  text-transform: uppercase; color: var(--fg-3);
}

.more {
  border-top: 1px solid var(--line-soft); padding: var(--s-6) 0 var(--s-8);
  display: flex; flex-wrap: wrap; gap: var(--s-4) var(--s-6); align-items: center;
}
.more p { margin: 0; color: var(--fg-3); font-size: 13.5px; max-width: 52ch; }
.more .spacer { flex: 1 1 auto; }

/* ── THE BAR ──────────────────────────────────────────────────────────────
   One row down to 600px. It used to wrap to two rows at 768 and back to one at
   1024, so everything below it jumped 30px between two adjacent widths. */
.bar {
  position: sticky; top: 0; z-index: 70;
  background: color-mix(in srgb, var(--ink) 94%, transparent);
  backdrop-filter: blur(12px); border-bottom: 1px solid var(--line-soft);
}
.bar__in {
  width: var(--page); margin-inline: auto; min-width: 0;
  display: flex; align-items: center; gap: var(--s-4); padding: var(--s-2) 0;
}
.bar__home {
  flex: none; font: 650 11px/1.5 var(--ui); letter-spacing: .14em;
  text-transform: uppercase; color: var(--fg-3); text-decoration: none;
  display: inline-flex; align-items: center; min-height: var(--h-nav);
}
.bar__home:hover { color: var(--fg); }

/* The stepper answers "where am I" with names, not a percentage: a name also
   tells you what is left. It scrolls rather than wraps, so the bar height — and
   therefore the top of every page — is constant. */
.stepper {
  display: flex; gap: var(--s-1); margin-left: auto; list-style: none; padding: 0;
  min-width: 0; overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none;
  /* Below ~900px the four names do not fit and the list scrolls. The fade is
     the only thing that says so — without it the last label is simply chopped
     at the gutter and reads as clipping rather than as more content. */
  mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
}
@media (min-width: 1100px) { .stepper { mask-image: none; -webkit-mask-image: none; } }
.stepper::-webkit-scrollbar { display: none; }
.stepper li { flex: none; }
.stepper a, .stepper span {
  display: inline-flex; align-items: center; gap: var(--s-2);
  min-height: var(--h-nav); padding: 0 var(--s-4); border-radius: var(--r-pill);
  font: 500 13.5px/1 var(--ui); text-decoration: none; white-space: nowrap;
  color: var(--fg-3); border: 1px solid transparent; transition: color .12s ease, border-color .12s ease;
}
.stepper a:hover { color: var(--fg); border-color: var(--line); }
.stepper b { font: 600 11px/1 var(--mono); opacity: .75; }
.stepper [aria-current] { background: var(--fg); color: var(--ink); font-weight: 650; }
.stepper [aria-current] b { opacity: .55; }
/* Completion is never signalled by colour alone. */
.stepper .done { color: var(--fg-2); }
.stepper .done::after { content: "✓"; font-size: 12px; color: var(--live); }

/* ── SECTION HEAD ─────────────────────────────────────────────────────── */
.head { padding: var(--s-6) 0 var(--s-4); }
.head h1 { margin: var(--s-3) 0 var(--s-3); }
/* ── THE QUESTION ────────────────────────────────────────────────────────
   One line, one gold rule, and it is the last thing on the screen before the
   photography. It used to share a two-column brief with a bulleted watch-list —
   "is there room for the headline", "does it still work on a phone" — which
   asked a reviewer to perform our responsive QA before looking at anything. The
   list still exists in sections.mjs and still prints in the technical lab; it is
   our checklist, and it was never leadership's job. */
.ask {
  margin: var(--s-5) 0 0; border-left: 2px solid var(--gold); padding-left: var(--s-4);
  max-width: var(--measure);
  font: 400 clamp(17px, 1.35vw, 20px)/1.42 var(--display); color: var(--fg);
}

/* ── THE VIEWER ───────────────────────────────────────────────────────────
   Controls, preview and options as one pinned block. Its height is its CONTENT,
   not 100svh: a fixed-height panel left a ~105px dead band above the frame at
   768, where the preview is bound by width and cannot grow to fill it. The
   preview's ceiling is measured in JS from what the bar, the controls and the
   deck actually occupy. */
.viewer {
  position: sticky; top: var(--bar-h);
  display: grid; grid-template-rows: auto auto auto; gap: var(--s-3);
  padding-bottom: var(--s-3); background: var(--ink);
}
.tools { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-5); align-items: center; }
.toolset { display: flex; align-items: center; gap: var(--s-2); }

.seg { display: flex; border: 1px solid var(--line); border-radius: var(--r-pill); overflow: hidden; }
.seg button {
  appearance: none; background: none; border: 0; color: var(--fg-2);
  font: 600 13.5px/1 var(--ui); padding: 0 var(--s-5); min-height: var(--h-control);
  cursor: pointer; transition: background .12s ease, color .12s ease;
}
.seg button + button { border-left: 1px solid var(--line); }
.seg button:hover { color: var(--fg); background: var(--ink-3); }
.seg button[aria-pressed="true"] { background: var(--fg); color: var(--ink); }

/* LEFT-ALIGNED, NOT CENTRED. A centred single frame sat at x=269 on one section
   and x=288 on the next, so the photograph slid sideways every time the
   reviewer pressed Next. */
.stages {
  display: flex; flex-wrap: wrap; gap: var(--frame-gap);
  align-items: flex-start; justify-content: flex-start;
  /* `min-width: 0` is load-bearing. As a grid item its default is `auto`, i.e.
     the min-content of its children — so an over-wide frame widened the very
     container the next measurement sized that frame from, and the two fed each
     other until the page overflowed by 442px at 390. */
  min-height: 0; min-width: 0;
}
.stage { display: grid; gap: 0; min-width: 0; align-content: start; }
.stage[hidden] { display: none !important; }

/* Both captions are exactly one line high, always, so the two frames beneath
   them share a baseline and neither is optically favoured. */
.stage__cap {
  display: flex; align-items: center; gap: var(--s-3); flex-wrap: nowrap;
  min-height: 26px; margin: 0 0 var(--s-2); overflow: hidden;
}
.tag {
  display: inline-flex; align-items: center; flex: none;
  font: 700 10.5px/1 var(--ui); letter-spacing: .14em; text-transform: uppercase;
  padding: 6px var(--s-3); border-radius: var(--r-control);
  border: 1px solid var(--line); color: var(--fg-2); white-space: nowrap;
}
.tag--live { border-color: var(--live); color: var(--live); }
.tag--opt { border-color: var(--gold); color: var(--gold); }
.stage__note {
  font-size: 12.5px; color: var(--fg-3); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.stages--compare .stage__note { display: none; }

.screen {
  position: relative; overflow: hidden; background: #000;
  border: 1px solid var(--line); border-radius: var(--r-frame);
}
/* EQUAL WEIGHT. The option frame is marked by an accent colour, not a heavier
   border: a thicker rule on one side of a comparison is a thumb on the scale. */
.screen--opt { border-color: var(--gold); }
.screen iframe { border: 0; display: block; transform-origin: top left; background: #fdfbf5; }
.screen__wait {
  position: absolute; inset: 0; display: grid; place-items: center; color: var(--fg-3);
  font: 650 10.5px/1 var(--ui); letter-spacing: .16em; text-transform: uppercase;
}

/* ── THE DECK: options + choice, always within reach ──────────────────── */
.deck {
  display: grid; gap: var(--s-2) var(--s-5);
  grid-template-columns: minmax(0, 1fr) minmax(0, auto); align-items: center;
  border-top: 1px solid var(--line-soft); padding-top: var(--s-3);
}
.strip { min-width: 0; }
.strip__lab { margin-bottom: var(--s-2); }
.strip__wrap { position: relative; min-width: 0; }
.strip__wrap::after {
  content: ""; position: absolute; inset: 0 0 10px auto; width: 48px; pointer-events: none;
  background: linear-gradient(to right, transparent, var(--ink) 78%);
}
.strip__rail {
  display: flex; gap: var(--s-2); overflow-x: auto; padding: 2px 2px 10px;
  scroll-snap-type: x proximity; scrollbar-width: thin;
}
.strip__rail::-webkit-scrollbar { height: 6px; }
.strip__rail::-webkit-scrollbar-thumb { background: var(--line); border-radius: 3px; }

.chip {
  flex: 0 0 auto; width: 104px; scroll-snap-align: start; padding: 0;
  background: var(--ink-2); border: 1px solid var(--line); border-radius: var(--r-control);
  cursor: pointer; color: inherit; text-align: left; overflow: hidden;
  transition: border-color .12s ease;
}
.chip:hover { border-color: var(--fg-3); }
.chip img { display: block; width: 100%; aspect-ratio: 3/2; object-fit: cover; background: #000; }
.chip__l {
  display: flex; align-items: center; gap: var(--s-1); padding: 7px var(--s-2);
  font: 650 11px/1.2 var(--ui); letter-spacing: .02em; min-height: 28px;
}
.chip__l .k { font: 700 12px/1 var(--mono); color: var(--fg); }
/* Selected is a ring, a filled label AND a dot — never colour alone. The ring is
   an inset shadow rather than a thicker border so the chip does not change size
   when it is chosen. */
.chip[aria-pressed="true"] { border-color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold); }
.chip[aria-pressed="true"] .chip__l { background: var(--gold); color: #17140c; }
.chip[aria-pressed="true"] .chip__l .k { color: #17140c; }
.chip[aria-pressed="true"] .chip__l::after { content: "●"; margin-left: auto; font-size: 9px; }
.chip--live[aria-pressed="true"] { border-color: var(--live); box-shadow: inset 0 0 0 1px var(--live); }
.chip--live[aria-pressed="true"] .chip__l { background: var(--live); }
.chip--live .chip__l .k { font-size: 9.5px; letter-spacing: .1em; color: var(--live); }
.chip--live[aria-pressed="true"] .chip__l .k { color: #06170e; }
.chip--pref .chip__l::before { content: "★"; color: var(--gold); }
.chip[aria-pressed="true"].chip--pref .chip__l::before { color: #17140c; }

.choose { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); align-items: center; justify-content: flex-end; }
.choose__state { margin: 0; font-size: 13px; color: var(--fg-2); max-width: 24ch; }
.choose__state b { color: var(--fg); font-weight: 600; }
.btn--pref[aria-pressed="true"] { background: var(--live); border-color: var(--live); color: #06170e; font-weight: 700; }
.btn--pref[disabled] { opacity: .55; cursor: default; }

/* ── VOTING ───────────────────────────────────────────────────────────────
   RESTRAINED ON PURPOSE. This row shares the deck with twelve thumbnails and
   sits under a photograph that is the actual content of the page; a voting
   panel here would win an argument it should not be having. So: one primary
   action in the existing button, one line of state in the existing type, and
   the counts smaller again beneath it.

   THE COUNTS ARE DELIBERATELY DULL. No bar, no percentage, no ordering by
   score, no colour that reads as winning — a leader board would turn a design
   review into a popularity contest and the totals are decision support, not a
   decision. They also only appear once this reviewer has voted; see the
   herding note in review.mjs. */
.choose__say { display: grid; gap: 3px; justify-items: end; }
.choose__tally {
  margin: 0; display: flex; flex-wrap: wrap; gap: 0 7px; align-items: baseline;
  font: 500 11.5px/1.5 var(--ui); color: var(--fg-3); letter-spacing: .02em;
}
.choose__dot { color: var(--line); }
/* SIMULATED DATA IS NEVER QUIET. Wherever a number could be mistaken for team
   input, the simulation says so at the number, not only in a footnote. */
.choose__sim, .team__sim {
  font: 700 9.5px/1.6 var(--ui); letter-spacing: .14em; text-transform: uppercase;
  color: var(--warn, #e8b23a); border: 1px solid currentColor; border-radius: 3px; padding: 0 5px;
}
.choose__err { margin: 0; font-size: 12.5px; color: #ff9d8a; max-width: 34ch; text-align: right; }
.btn--rm { color: var(--fg-3); }
.btn--rm:hover { color: var(--fg); }

/* The identity step. One field, inline, and only when someone tries to vote. */
.vote-id { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-3); align-items: center; justify-content: flex-end; }
.vote-id__l, .rv-id__l {
  font: 650 10px/1.6 var(--ui); letter-spacing: .14em; text-transform: uppercase; color: var(--fg-3);
}
.vote-id__i, .rv-id__i {
  background: transparent; border: 1px solid var(--line); border-radius: var(--r-sm, 6px);
  color: var(--fg); font: 400 14px/1 var(--ui); padding: 0 var(--s-3);
  min-height: var(--h-nav); min-width: 190px;
}
.vote-id__i:focus-visible, .rv-id__i:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }
.vote-id__n { margin: 0; flex: 1 1 100%; text-align: right; font-size: 11.5px; color: var(--fg-3); }

/* ── STARTING THE REVIEW ──────────────────────────────────────────────────
   ONE ROW, ONE ACTION. The name field and the primary button are a single
   affordance: the field used to sit above its own Save button with Start review
   beside it, which read as two steps and made the name look compulsory. It is
   not — an empty submit starts the review, and the section screen asks for a
   name when a vote is actually cast.

   The field is deliberately quiet and the button is the only gold thing in the
   viewport, so the eye lands on the action rather than on the input. */
.start {
  display: flex; flex-wrap: wrap; align-items: end; gap: var(--s-3);
  margin: var(--s-7) 0 0;
}
.start__l {
  display: block; margin-bottom: 7px;
  font: 650 10px/1.6 var(--ui); letter-spacing: .14em; text-transform: uppercase; color: var(--fg-3);
}
.start__i {
  background: transparent; border: 0; border-bottom: 1px solid var(--line);
  border-radius: 0; color: var(--fg); font: 400 16px/1 var(--ui);
  padding: 0 2px var(--s-2); min-height: var(--h-nav); min-width: 260px;
  transition: border-color .12s ease;
}
.start__i::placeholder { color: var(--fg-3); }
.start__i:hover { border-bottom-color: var(--fg-3); }
.start__i:focus-visible { outline: 0; border-bottom-color: var(--gold); }
.start__go { flex: none; }
@media (max-width: 560px) {
  .start { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-4); }
  .start__i { min-width: 0; width: 100%; }
  .start__go { width: 100%; justify-content: center; }
}

.rv-who { margin: var(--s-4) 0 0; font-size: 13.5px; color: var(--fg-2); }
.rv-who b { color: var(--fg); }
.linkish {
  background: none; border: 0; padding: 0; font: inherit; color: var(--gold);
  text-decoration: underline; cursor: pointer;
}

/* ── THE LANDING FOOTER ───────────────────────────────────────────────────
   One line, and it is for us rather than for the reviewer. The rights position,
   the donor-journey audit and the voting architecture all still exist — in
   docs/design/ and on the technical lab's hub — they are simply not what
   somebody opening this link came to read. */
.foot--thin { padding: var(--s-6) 0 var(--s-9); }
.foot__note { margin: 0; font-size: 12.5px; color: var(--fg-3); }
.foot__tools {
  margin: 0; display: flex; flex-wrap: wrap; gap: 4px var(--s-2); align-items: baseline;
  font: 500 12px/1.6 var(--ui); color: var(--fg-3);
}
.foot__tools a { color: var(--fg-3); text-decoration: none; border-bottom: 1px solid var(--line); }
.foot__tools a:hover { color: var(--fg-2); border-bottom-color: var(--fg-3); }
.foot__tools span {
  font: 650 9.5px/1.6 var(--ui); letter-spacing: .14em; text-transform: uppercase;
  color: var(--line); margin-left: var(--s-2);
}

/* ── TEAM INPUT ───────────────────────────────────────────────────────────
   Below the reviewer's own four rows, and visibly quieter than them: the
   summary is first a statement of what YOU think. Counts in presentation order,
   never sorted — sorting by count is the same as declaring a winner. */
.team { border-top: 1px solid var(--line-soft); margin-top: var(--s-7); padding-top: var(--s-6); max-width: 84ch; }
.team h2 { margin: 0 0 var(--s-3); font: 400 clamp(19px, 1.6vw, 23px)/1.2 var(--display); }
.team__note { margin: var(--s-3) 0 0; font-size: 13px; color: var(--fg-3); max-width: var(--measure-note, 62ch); line-height: 1.6; }
.team__sim { display: inline-block; margin: 0 0 var(--s-3); padding: 4px 7px; line-height: 1.5; max-width: 62ch; letter-spacing: .08em; }
.team__l { display: grid; gap: var(--s-5); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 680px) { .team__l { grid-template-columns: minmax(0, 1fr); } }
.team__s { display: grid; gap: var(--s-2); align-content: start; }
.team__h { margin: 0; font: 650 10.5px/1.6 var(--ui); letter-spacing: .13em; text-transform: uppercase; color: var(--fg-3); }
.team__rows { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.team__rows li {
  display: flex; gap: var(--s-3); align-items: baseline; justify-content: space-between;
  border-bottom: 1px solid var(--line-soft); padding: 5px 0;
}
.team__o { font-size: 13.5px; color: var(--fg-2); }
.team__n { font: 500 12.5px/1.4 var(--mono); color: var(--fg); white-space: nowrap; }

/* ── TECHNICAL DETAIL: present, subordinate ───────────────────────────── */
/* details.tech is deliberately absent: the technical disclosure no longer
   renders on the stakeholder review. Its content is the technical lab's slot
   pages. */

/* ── PAGER ────────────────────────────────────────────────────────────── */
.pager {
  display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center;
  border-top: 1px solid var(--line-soft); margin-top: var(--s-6); padding: var(--s-5) 0 var(--s-9);
}
.pager .spacer { flex: 1 1 auto; }

/* ── WHAT ELSE WE CHECKED ─────────────────────────────────────────────────
   The audited-and-settled surfaces: Joe's film, Stripe, the thank-you page,
   Follow, Share. Deliberately quieter than a review step — this is the review
   showing its work, not asking for a decision, and it must never read as a
   fourth thing to do. Hence no gold, no number, no status tag, and a smaller
   measure than the steps above it. */
.checked { border-top: 1px solid var(--line-soft); padding: var(--s-7) 0 var(--s-8); }
.checked h2 { margin: 0; }
.checked p.sub { margin: var(--s-2) 0 var(--s-5); color: var(--fg-2); font-size: 15px; max-width: var(--measure); }
.checked__l { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-4); max-width: var(--measure); }
.checked__i { display: grid; gap: 6px; border-left: 2px solid var(--line); padding-left: var(--s-4); }
.checked__h { display: flex; flex-wrap: wrap; gap: 4px var(--s-3); align-items: baseline; }
.checked__s { font: 650 11px/1.5 var(--ui); letter-spacing: .12em; text-transform: uppercase; color: var(--fg-2); }
.checked__a { font: 400 12px/1.5 var(--mono); color: var(--fg-3); }
.checked__w { margin: 0; color: var(--fg-3); font-size: 14px; line-height: 1.6; }

/* ── JOE'S STORY (technical lab only) ─────────────────────────────────── */
.locked { display: grid; gap: var(--s-4); max-width: var(--measure); margin-top: var(--s-5); }
.locked__box { border-left: 2px solid var(--line); padding-left: var(--s-4); display: grid; gap: var(--s-2); }
.locked__box--dir { border-left-color: var(--gold); }
.locked__v { margin: 0; font: 400 clamp(20px, 2.1vw, 28px)/1.2 var(--display); color: var(--gold); }
.locked__w { margin: 0; color: var(--fg-2); font-size: 15px; line-height: 1.66; }

/* ── SUMMARY ──────────────────────────────────────────────────────────────
   The rows used to span the full 1324px column while the prose above them
   stopped at 730 — the eye had to cross the whole page to pair a section with
   its answer. They now share a reading measure, and the utility action is
   grouped away from the two routes forward. */
.done-h { padding: var(--s-9) 0 0; }
.done-h h1 { margin: var(--s-4) 0 var(--s-5); }
.rows { list-style: none; margin: var(--s-7) 0 0; padding: 0; max-width: 84ch; }
/* Fixed value and action columns, not `auto`: each row is its own grid, so
   `auto` sized every row independently and the answers stepped in and out by
   ~45px down the list. Joe's row has no Change link and still keeps the column,
   so the rhythm holds where the content does not. */
.row {
  display: grid; grid-template-columns: 34px minmax(0, 1fr) 210px 62px;
  gap: var(--s-2) var(--s-4); align-items: baseline;
  border-top: 1px solid var(--line-soft); padding: var(--s-4) 0;
}
.row:last-child { border-bottom: 1px solid var(--line-soft); }
.row__n { font: 500 13px/1.4 var(--mono); color: var(--gold); }
.row__t { font: 400 clamp(18px, 1.5vw, 22px)/1.25 var(--display); }
.row__v { font: 600 14px/1.4 var(--ui); text-align: right; }
.row__v .none { color: var(--fg-3); font-weight: 400; font-style: italic; }
.row a { color: var(--fg-3); font-size: 13px; text-underline-offset: 3px; }
.row a:hover { color: var(--fg); }
/* Same right edge as the list above it — applied to an inner element, never to
   the `.col` itself: a `.col` is centred by its own auto margins, so capping its
   width there centres the whole action row instead of aligning it. */
.summary-actions { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; margin-top: var(--s-6); max-width: 84ch; }
.summary-actions .util { margin-left: auto; display: flex; align-items: center; gap: var(--s-3); }
.copied { color: var(--live); font-size: 13.5px; font-weight: 600; }

/* ── FOOT ─────────────────────────────────────────────────────────────── */
.foot {
  border-top: 1px solid var(--line-soft); margin-top: var(--s-8);
  padding: var(--s-6) 0 var(--s-8); color: var(--fg-3); font-size: 13px;
}
.foot p { margin: 0 0 var(--s-2); max-width: var(--measure-note); line-height: 1.65; }
.foot p:last-child { margin-bottom: 0; }
.foot strong { color: var(--fg-2); }

/* ══ TABLET ════════════════════════════════════════════════════════════════
   1024 and 768 are not "small desktop". Side-by-side switches off below 900 in
   JS (two frames there would be ~165px each), so these widths get one large
   frame — and the brief collapses to a single column rather than setting the
   question in two narrow measures. */
@media (max-width: 1080px) {
  .brief { grid-template-columns: minmax(0, 1fr); gap: var(--s-4); }
  .deck { grid-template-columns: minmax(0, 1fr); }
  .choose { justify-content: flex-start; }
  .choose__state { max-width: none; }
}

/* ══ MOBILE — ITS OWN COMPOSITION ══════════════════════════════════════════
   Not the desktop layout stacked. Every pixel the furniture gives up here goes
   to the photograph, which at this width is shown at life size and cropped. */
@media (max-width: 760px) {
  :root { --gutter: 18px; --frame-gap: 14px; }
  .hero-l { padding: var(--s-7) 0 var(--s-6); }
  .journey { padding: var(--s-7) 0; }
  .more { padding: var(--s-5) 0 var(--s-7); }

  .bar__in { gap: var(--s-3); padding: var(--s-1) 0; }
  .bar__home { font-size: 10px; letter-spacing: .12em; }
  .stepper a, .stepper span { padding: 0 var(--s-3); font-size: 12.5px; }

  .head { padding: var(--s-4) 0 var(--s-2); }
  .head h1 { margin: var(--s-2) 0 var(--s-2); }
  .brief { margin-top: var(--s-4); }
  .viewer { gap: var(--s-2); }
  .tools { gap: var(--s-2) var(--s-3); }
  .toolset > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .tools__hint { font-size: 12px; flex-basis: 100%; }
  .seg button { padding: 0 var(--s-4); font-size: 13px; }
  /* The pill already says CURRENT LIVE IMAGE; the sentence repeating it costs
     two lines of a phone screen that the photograph needs more. */
  .stage__note { display: none; }
  .chip { width: 92px; }
  .chip--live .chip__l .k { display: none; }
  .strip__lab { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .deck { padding-top: var(--s-2); }
  .pager { padding: var(--s-4) 0 var(--s-7); }
  .pager .spacer { display: none; }
  .pager .btn, .actions .btn { flex: 1 1 auto; }
  .row { grid-template-columns: 30px minmax(0, 1fr); }
  .summary-actions { max-width: none; }
  .row__v { grid-column: 2; text-align: left; }
  .row a { grid-column: 2; justify-self: start; }
  .summary-actions .util { margin-left: 0; width: 100%; }
  .done-h { padding: var(--s-7) 0 0; }
  details.tech dl div { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}
