/* ===========================================================================
   ARCADIA — design tokens + shell + Home/Top Plays  (sub-gates 12.a / 12.b)
   Owner: P12-B1.

   DESIGN AUTHORITY
     1. docs/design/reference-preview.html — the EXECUTABLE VISUAL SPEC,
        ratified 2026-08-06.  Anatomy, type scale, spacing and component
        structure below are matched to it.
     2. docs/design/UI_BRIEF.md — the binding token table, and the sole
        authority for every state the preview does not depict (§A9).

   No build step.  Vanilla CSS custom properties only — no preprocessor, no
   CDN, no utility framework.  Class prefix `a-`.  No `!important`.

   COLOUR PROVENANCE
     Every hex is copied VERBATIM from UI_BRIEF §COLOR SYSTEM.  Nothing is
     sampled from an image.  The preview introduces five off-table greys
     (#1B2836 #1A2734 #2A3846 #243241 #0A1119); rather than fork the palette
     they are DERIVED here with color-mix() from brief tokens, which keeps
     the app to one colour source and is imperceptibly different.

   TYPE SCALE
     The preview's phone frames are 340px wide with 18px padding (304px of
     content); a real mobile viewport is ~390px with 16px padding (358px).
     Its px values are therefore multiplied by ~1.18 here.  Two floors are
     applied on top, and both are reported as deviations:
       - technical labels never go below 10px (UI_BRIEF §TYPE HIERARCHY says
         10-12px; the preview scales some to 7.7-9px);
       - `--text-muted` is never a text colour (see below).

   ACCESSIBILITY FINDING — the contrast conflict, measured.
     The preview sets its small labels, captions and the held score in
     `--muted` (#7E8995).  Measured against the brief's four backgrounds that
     token is 3.26:1 - 3.86:1: it FAILS WCAG AA 4.5:1 for normal-size text.
     WCAG wins, so every one of those uses is `--text-secondary` (#A7ADB5,
     7.14:1 - 8.46:1) here — very slightly lighter than the preview, AA-clean
     at every size.  `--accent-dark` (3.26:1 - 3.87:1) is treated the same
     way.  The one exception is `--text-dim-large`, an alias for
     `--text-muted` allowed ONLY at >=1.5rem, where AA's 3:1 large-text bar
     applies; a test enforces that every rule using it sets such a size.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   0. SELF-HOSTED HERO FACE  (DECISION 2, operator ruling 2026-08-15)
   ---------------------------------------------------------------------------
   WHY THIS EXISTS.  --font-hero used to be a six-name fallback stack
   (Haettenschweiler / Arial Narrow Bold / DIN Condensed Bold / ... / Impact).
   iOS ships NONE of those six.  Every one resolved on macOS — which is why
   every screenshot taken from this machine looked right — and on the
   operator's iPhone the whole chain fell through to `sans-serif`, so the
   giant condensed numerals that ARE the product's identity rendered in the
   same SF Pro as body copy.  A fallback stack is a lottery, not a typeface.
   One self-hosted file ends it: the judged surface and the served surface
   become the same surface, macOS included.

   WHAT THIS IS.  League Gothic, by Tyler Finck, Caroline Hadilaksono and
   Micah Rich (The League of Moveable Type).  Licensed SIL OPEN FONT LICENSE
   1.1 — redistributable, embeddable, self-hostable, modifiable.  NO Reserved
   Font Name is declared (the copyright line carries no RFN clause), so
   instancing, subsetting and this CSS alias are all permitted.  The licence
   ships beside the file as `arcadia-numerals-OFL.txt`, which is what the OFL
   requires of a redistribution.
     Source:  https://github.com/google/fonts/tree/main/ofl/leaguegothic
     Upstream: https://github.com/theleagueof/league-gothic

   WHY THIS FACE.  Measured against docs/design/mockup.jpg, the binding
   oracle.  The mock's `0` has an ink width-to-cap-height ratio of 0.296;
   Anton is 0.519, Impact 0.563, Bebas Neue 0.463 — all far too wide.  League
   Gothic carries a `wdth` axis (75-100); instanced at **wdth 80** its `0`
   measures 0.293, a 1% error against the mock.  It is the only open-licensed
   candidate tested that reaches the mock's ultra-condensed proportion.

   WHAT SHIPS.  wdth 80 static instance, subset to the 74 codepoints that can
   actually reach a --font-hero rule (see the unicode-range below), hinting
   dropped, WOFF2: 4,840 bytes.  `font-stretch` is declared as a 75%-100%
   RANGE so that every hero rule matches this face unambiguously, whether it
   asks for `condensed` (75%, which all six currently do) or for normal.

   KNOWN, REPORTED: League Gothic ships no `tnum` feature and its digits are
   proportional (the `1` is 480/2000 em against ~700 for the rest), so the
   `font-variant-numeric: tabular-nums` on the six hero rules is INERT.  That
   matches the mock, whose `1` is likewise narrower than its `0` (0.185 vs
   0.296) — but it is a real property of the face, not an oversight here.
   --------------------------------------------------------------------------- */
@font-face {
  font-family: "Arcadia Numerals";
  src: url("arcadia-numerals.woff2") format("woff2");
  font-weight: 400 900;  font-display: swap;
  font-style: normal;
  font-stretch: 75% 100%;
  /* Exactly the subset that ships — digits, +-.,:/%() and the two dashes for
     numerals and absent-value em dashes; A-Z for the hero word ("PLAYS") and
     for team abbreviations, which land in .a-stat-v via stat('BEST EDGE');
     a-z as a cheap guard for any other data-driven value.  A codepoint
     outside this range is served by the fallbacks below, per glyph. */
  unicode-range: U+0020, U+0025, U+0028-002F, U+0030-0039, U+003A,
                 U+0041-005A, U+0061-007A, U+2013, U+2014;
}

/* ---------------------------------------------------------------------------
   1. TOKENS
   --------------------------------------------------------------------------- */
:root {
  /* --- UI_BRIEF §COLOR SYSTEM, verbatim ---------------------------------- */
  --background-primary: #07101A;
  --background-secondary: #0C1621;
  --surface-primary: #111C27;
  --surface-elevated: #16222D;

  --text-primary: #F4F0E8;
  --text-secondary: #A7ADB5;
  --text-muted: #7E8995;

  --accent-primary: #C8A66A;
  --accent-light: #E0C38E;
  --accent-dark: #8D6A35;

  --positive: #4CCB7F;
  --warning: #E0AF47;
  --negative: #D45C5C;
  --neutral: #73808C;

  /* --- Derived surfaces: mixes of the above, never new hexes ------------- */
  --hairline: color-mix(in srgb, var(--text-muted) 26%, transparent);
  --hairline-strong: color-mix(in srgb, var(--text-muted) 42%, transparent);
  --hairline-gold: color-mix(in srgb, var(--accent-primary) 34%, transparent);
  --track: var(--surface-elevated);
  --shadow-card: 0 18px 38px -22px rgba(0, 0, 0, 0.9);

  /* Allowed as a text colour ONLY at >=1.5rem, where AA's bar is 3:1. */
  --text-dim-large: var(--text-muted);

  /* --- TYPE ROLES (UI_BRIEF §TYPOGRAPHY — three coordinated roles) ------- */

  /* ROLE 1 — BRAND SCRIPT.  Wordmark only.  Never body, buttons, stats, nav.
     The preview's stack; no font file ships (no build step).  OPEN ASK: the
     real cursive Arcadia wordmark needs a font file or traced paths — §A6
     forbids tracing the preview-resolution sketches. */
  --font-script: "Snell Roundhand", "Apple Chancery", "Segoe Script",
                 "Brush Script MT", cursive;

  /* ROLE 2 — HERO NUMERALS.  ===== DECISION 2, TAKEN 2026-08-15 =====
     "Arcadia Numerals" is the self-hosted League Gothic wdth-80 subset
     declared in section 0 above — canonical on EVERY platform, macOS
     included.  The old six-name stack is kept BEHIND it: it is now a
     degradation path (if the .woff2 404s or fails to parse the site returns
     to exactly today's behaviour), never the primary.
       NOTE: the @font-face had to move OUT of :root.  It was prepared inside
       this block, where an at-rule is invalid CSS and would have been
       dropped by the parser the moment it was uncommented. */
  --font-hero: "Arcadia Numerals",
               "Haettenschweiler", "Arial Narrow Bold", "DIN Condensed Bold",
               "DIN Condensed", "Arial Narrow", Impact, sans-serif;

  /* ROLE 3 — INTERFACE TYPE.  Navigation, labels, explanations, buttons. */
  --font-ui: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
             Inter, Roboto, "Helvetica Neue", Arial, sans-serif;

  /* --- TYPE SCALE (preview px x1.18, floored at 10px for labels) -------- */
  --type-hero: clamp(4.5rem, 31vw, 8rem);   /* preview 104px -> 72-128px    */
  --type-hero-detail: clamp(4.5rem, 27vw, 6.5rem); /* preview 88px (phone 3) */
  --type-hero-word: 2.1rem;                 /* preview 31px                 */
  --type-score: 2.75rem;                    /* preview 37px  (board)        */
  --type-route: 2.4rem;                     /* preview 33px  (.rt .n)       */
  --type-rank: 1.9rem;                      /* preview 26px                 */
  --type-stat: 2.1rem;                      /* preview 29px                 */
  --type-health: 1.8rem;                    /* preview 25px                 */
  --type-matchup: 1rem;                     /* preview 12.5px               */
  --type-body: 0.9375rem;
  --type-note: 0.8125rem;                   /* preview 11px   -> 13px       */
  --type-label: 0.6875rem;                  /* preview 9.5px  -> 11px       */
  --type-micro: 0.625rem;                   /* preview 6.5-8.5px -> 10px    */
  --track-label: 0.24em;                    /* preview .24em on .lab        */
  --track-micro: 0.14em;

  /* --- SPACING (UI_BRIEF §LAYOUT scale: 4/8/12/16/24/32/48/64) ---------- */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px;

  /* --- RADIUS (18-24 major, 12-16 compact, pill for status) ------------- */
  --radius-card: 22px;
  --radius-compact: 15px;   /* preview .card 15px */
  --radius-pill: 999px;

  /* --- MOTION (UI_BRIEF §NUMBER ANIMATION 400-700ms, restrained) -------- */
  --dur-number: 550ms;
  --dur-ui: 180ms;
  --ease-instrument: cubic-bezier(0.22, 0.61, 0.36, 1);
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--background-primary);
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: var(--type-body);
  line-height: 1.55;
}

h1, h2, h3, p, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }

:focus-visible {
  outline: 2px solid var(--accent-light);
  outline-offset: 3px;
  border-radius: var(--sp-1);
}

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

.a-skip {
  position: absolute; left: var(--sp-3); top: -100px; z-index: 20;
  padding: var(--sp-2) var(--sp-4); border-radius: var(--radius-pill);
  background: var(--accent-primary); color: var(--background-primary);
  font-size: var(--type-micro); letter-spacing: var(--track-micro);
  text-transform: uppercase;
}
.a-skip:focus { top: var(--sp-3); }

.a-topbar,
.a-main,
.a-nav-list,
.a-footer {
  width: 100%;
  max-width: 27rem;      /* the preview's phone content column */
  margin: 0 auto;
  padding-left: var(--sp-4);
  padding-right: var(--sp-4);
}

.a-topbar { padding-top: var(--sp-5); }
.a-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding-bottom: var(--sp-5);
}
.a-main > .a-ghost { margin-top: auto; }

/* ---------------------------------------------------------------------------
   3. SHARED PRIMITIVES — label, rule, foot note
   --------------------------------------------------------------------------- */
.a-lab {
  font-size: var(--type-label);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-secondary);
}

/* The preview's `.rule`: a hairline fading to nothing, left to right. */
.a-rule {
  height: 1px;
  margin: var(--sp-2) 0 var(--sp-3);
  background: linear-gradient(90deg, var(--hairline-strong), transparent);
}

.a-foot {
  margin-top: var(--sp-2);
  font-size: var(--type-micro);
  line-height: 1.6;
  color: var(--text-secondary);
}
.a-foot--held { margin-top: var(--sp-3); }

.a-block { margin-top: var(--sp-5); }

/* ---------------------------------------------------------------------------
   4. BRAND LOCKUP — script wordmark over the trajectory underline
   §A1: the underline is the probability object, not decoration.
   --------------------------------------------------------------------------- */
.a-lockup { display: grid; justify-items: center; line-height: 1; }

.a-lockup-script {
  font-family: var(--font-script);
  font-size: 2rem;                 /* preview 27px */
  font-weight: 500;
  color: var(--text-primary);
}

/* The box is held to the drawing's own aspect ratio.  A fixed height with
   `meet` letterboxes it, and the swash then renders short and as a sub-pixel
   hairline — which is exactly the defect this replaces. */
.a-lockup-swash {
  display: block;
  width: 8.7rem;                   /* preview 118px */
  aspect-ratio: var(--swash-aspect, 118 / 9);
  margin-top: 1px;
  overflow: visible;
}
.a-swash,
.a-tail-line {
  fill: none; stroke: var(--accent-primary);
  stroke-width: 2.1; stroke-linecap: round;
}
.a-tail-line { stroke-width: 1.4; }
.a-tail-tick { stroke: var(--accent-primary); stroke-width: 1; stroke-linecap: round; }
.a-tail-lace { stroke: var(--accent-primary); stroke-width: 1.2; stroke-linecap: round; }
.a-tail-dot { fill: var(--accent-primary); }

.a-lockup-subline {
  margin-top: var(--sp-1);
  font-size: var(--type-micro);
  letter-spacing: 0.34em;
  text-indent: 0.34em;             /* balance the trailing letter-space */
  text-transform: uppercase;
  color: var(--accent-primary);
}

/* Screen header for non-Home screens: back chevron + screen label. */
.a-crumb {
  display: flex; align-items: center; gap: var(--sp-3);
  min-height: 1.5rem;
}
.a-back {
  font-size: 1.15rem; line-height: 1;
  color: var(--text-secondary);
  padding: var(--sp-1) var(--sp-2);
  margin-left: calc(-1 * var(--sp-2));
}
.a-crumb .a-chip { margin-left: auto; }

/* ---------------------------------------------------------------------------
   5. CHIPS + TAGS — colour ALWAYS paired with a text label
   --------------------------------------------------------------------------- */
.a-chip {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-secondary);
  white-space: nowrap;
}
.a-chip-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--neutral); flex: none;
}
.a-chip--ready { color: var(--positive); }
.a-chip--ready .a-chip-dot { background: var(--positive); }
.a-chip--held,
.a-chip--stale { color: var(--warning); }
.a-chip--held .a-chip-dot,
.a-chip--stale .a-chip-dot { background: var(--warning); }
.a-chip--absent .a-chip-dot,
.a-chip--unknown .a-chip-dot { background: var(--neutral); }

.a-tag {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-secondary);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  padding: 1px var(--sp-2);
  white-space: nowrap;
}
.a-tag--provisional,
.a-tag--flip { border-color: color-mix(in srgb, var(--warning) 52%, transparent); }
.a-tag--degraded { border-color: color-mix(in srgb, var(--warning) 34%, transparent); }
.a-tag--up { color: var(--positive); border-color: color-mix(in srgb, var(--positive) 40%, transparent); }
.a-tag--down { color: var(--negative); border-color: color-mix(in srgb, var(--negative) 40%, transparent); }

/* ---------------------------------------------------------------------------
   6. HOME — hero, CTA, stats, model health
   --------------------------------------------------------------------------- */
.a-hero-block { margin-top: var(--sp-6); }

/* "the number should often become the visual composition" — numeral and word
   share one baseline, as in the ratified sheet. */
.a-hero {
  display: flex;
  align-items: baseline;
  gap: 0.08em;
  margin-top: var(--sp-1);
}
.a-hero-num {
  font-family: var(--font-hero);
  font-size: var(--type-hero);
  font-stretch: condensed;
  line-height: 0.86;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--text-primary);
  animation: a-settle var(--dur-number) var(--ease-instrument) both;
}
.a-hero-word {
  font-family: var(--font-hero);
  font-size: var(--type-hero-word);
  font-stretch: condensed;
  /* THE RATIFIED TARGET'S SPACE, RESTORED (2026-08-11, P12-B22).
     `reference-preview.html` line 79 sets the lockup as
     `2<span style="font-size:31px;letter-spacing:.03em"> PLAYS</span>` — a
     LITERAL LEADING SPACE inside the word span.  The build re-expressed the
     lockup as two adjacent elements and the space went with the rewrite, so
     the hero read `2PLAYS` as one token.  Invisible for the whole of Part 12
     because the only figure ever rendered was the offseason em dash, which
     carries its own side bearings and looked correctly spaced.  A margin
     rather than a markup space so it cannot be lost again to whitespace
     collapsing, and one token wide — the reference's space measures ~8px at
     its 31px size. */
  margin-left: var(--sp-2);
  letter-spacing: 0.03em;
  color: var(--text-primary);
}
.a-hero--none .a-hero-num,
.a-hero--none .a-hero-word,
.a-hero--absent .a-hero-num,
.a-hero--absent .a-hero-word { color: var(--text-secondary); }

/* An absent figure is a dash, and a dash set in a condensed display face at
   120px is a redaction bar, not a punctuation mark.  Every "no value" glyph
   therefore drops to the interface face at a modest size — the composition
   de-emphasises itself exactly when there is nothing to headline. */
.a-hero--absent { gap: 0.3em; }
.a-hero--absent .a-hero-num {
  font-family: var(--font-ui);
  font-size: var(--type-hero-word);
  font-weight: 300;
}

/* An instrument recalibrating, not a slot machine. */
@keyframes a-settle {
  from { opacity: 0; transform: translateY(0.1em); }
  to   { opacity: 1; transform: none; }
}

.a-statusline {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-secondary);
}
.a-ts { font-variant-numeric: tabular-nums; }

/* Exactly one filled gold CTA per screen (UI_BRIEF §A8). */
.a-cta {
  display: block;
  margin: var(--sp-4) 0 var(--sp-5);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-pill);
  background: var(--accent-primary);
  color: var(--background-primary);
  text-align: center;
  font-size: var(--type-label);
  font-weight: 700;
  letter-spacing: 0.15em;
  transition: background-color var(--dur-ui) var(--ease-instrument);
}
.a-cta:hover { background: var(--accent-light); }

.a-ghost {
  display: block;
  margin-top: var(--sp-5);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-pill);
  color: var(--text-secondary);
  text-align: center;
  font-size: var(--type-micro);
  letter-spacing: 0.15em;
  transition: border-color var(--dur-ui) var(--ease-instrument);
}
.a-ghost:hover { border-color: var(--hairline-gold); color: var(--text-primary); }

.a-stats { display: flex; gap: var(--sp-2); }
.a-stat { flex: 1; min-width: 0; }
.a-stat-v {
  display: block;
  font-family: var(--font-hero);
  font-size: var(--type-stat);
  font-stretch: condensed;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}
.a-stat-v--gold { color: var(--accent-primary); }
.a-stat--absent .a-stat-v {
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-weight: 300;
}
.a-stat-k {
  display: block;
  margin-top: var(--sp-1);
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  color: var(--text-secondary);
}

.a-health-v {
  font-family: var(--font-hero);
  font-size: var(--type-health);
  font-stretch: condensed;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.a-health-pc { font-size: 0.55em; }

.a-bar {
  height: 3px; margin-top: var(--sp-2);
  border-radius: 2px; overflow: hidden;
  background: var(--track);
}
.a-bar i {
  display: block; height: 100%;
  background: var(--accent-primary);
  transition: width var(--dur-number) var(--ease-instrument);
}

/* ---------------------------------------------------------------------------
   7. TOP PLAYS BOARD
   --------------------------------------------------------------------------- */
.a-board { margin-top: var(--sp-1); }

.a-row { border-bottom: 1px solid var(--surface-elevated); }

.a-row-link {
  display: grid;
  grid-template-columns: 1.5rem auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) 0;
  transition: opacity var(--dur-ui) var(--ease-instrument);
}
a.a-row-link:hover { opacity: 0.86; }

.a-rank {
  font-family: var(--font-hero);
  font-size: var(--type-rank);
  font-stretch: condensed;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--accent-primary);
}
/* >=1.5rem, so AA's 3:1 large-text bar applies (measured 3.26:1 - 3.86:1).
   The preview's #2A3846 would be ~1.5:1 and is not shippable. */
.a-rank--held {
  font-size: var(--type-rank);
  font-family: var(--font-ui);
  font-weight: 300;
  color: var(--text-dim-large);
}

/* Team mark: the abbreviation, never a licensed logo (UI_BRIEF §TOP PLAYS). */
.a-tm {
  display: flex; align-items: center; justify-content: center;
  width: 2.15rem; height: 2.15rem;
  border-radius: 50%;
  background: var(--surface-elevated);
  color: var(--text-secondary);
  font-size: var(--type-micro);
  font-weight: 800;
  letter-spacing: 0.02em;
}

.a-mu { display: grid; gap: 3px; min-width: 0; }
.a-mu-teams {
  font-size: var(--type-matchup);
  font-weight: 600;
  letter-spacing: 0.01em;
}
.a-team { color: var(--text-primary); }
.a-team--opp { color: var(--text-primary); }
.a-vs { color: var(--text-secondary); font-weight: 400; }
.a-mu-meta {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2);
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-secondary);
}
.a-prob {
  display: inline-flex; align-items: baseline; gap: var(--sp-1);
  font-size: var(--type-micro);
  color: var(--text-secondary);
}
.a-prob b { color: var(--text-primary); font-weight: 700; }
.a-prob-k { letter-spacing: var(--track-micro); }

/* --- The Arcadia Score.  0-1000.  Never a percentage. ------------------- */
.a-sc { text-align: right; }
.a-sc-n {
  display: block;
  font-family: var(--font-hero);
  font-size: var(--type-score);
  font-stretch: condensed;
  line-height: 1;
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--text-primary);
  /* Built for three digits (UI_BRIEF §A6): the mockup's two-digit scores are
     illustrative; the canon is 0-1000. */
  min-width: 3ch;
}
.a-sc--dim .a-sc-n { color: var(--text-secondary); }
.a-sc-n--absent {
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-weight: 300;
}
.a-sc-c {
  display: block;
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  color: var(--text-secondary);
}

/* A held row is greyed, railed in warning, and states its reason. */
.a-row--held { border-left: 2px solid var(--warning); }
.a-row--held .a-row-link { padding-left: var(--sp-2); }
.a-row--held .a-mu-teams { color: var(--text-secondary); }
.a-row--held .a-team--opp { color: var(--text-secondary); }

/* ---------------------------------------------------------------------------
   8. EMPTY / DEGRADED STATES — first-class, never a crash, never a placeholder
   --------------------------------------------------------------------------- */
.a-empty {
  display: grid; gap: var(--sp-2);
  margin-top: var(--sp-4);
  padding: var(--sp-4);
  border: 1px solid var(--hairline);
  border-left: 2px solid var(--hairline-gold);
  border-radius: var(--radius-compact);
  background: var(--surface-primary);
}
.a-empty-title {
  font-size: var(--type-label);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-primary);
}
.a-empty-body { font-size: var(--type-body); color: var(--text-secondary); }
.a-empty-detail { font-size: var(--type-micro); color: var(--text-secondary); }

/* A SYSTEM-INTEGRITY state, visually distinct from an empty PRODUCT state
   (operator ruling, 2026-08-11).  "The model looked and found nothing" and
   "nothing ever ran" must not read the same, so the gold rail — which the
   whole sheet uses to mean an Arcadia verdict — is replaced by the warning
   rail.  Colour REINFORCES here and never carries: the branch that uses this
   class also states the condition in words and carries role="status". */
.a-empty--system {
  border-left-color: var(--warning);
  background: var(--background-secondary);
}

/* ---------------------------------------------------------------------------
   9. NAVIGATION — PLAYS · ROUTES · GAMES · MODEL
   The preview's nav is the last row of the screen, above a top hairline.  It
   is made sticky so it stays reachable on a long board without changing the
   ratified appearance or the DOM order (content precedes nav for keyboard
   and screen-reader users).
   --------------------------------------------------------------------------- */
.a-nav {
  position: sticky;
  bottom: 0;
  margin-top: auto;
  padding-top: var(--sp-3);
  padding-bottom: calc(var(--sp-2) + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--surface-elevated);
  background: var(--background-primary);
}
.a-nav-list { display: flex; justify-content: space-between; }
.a-nav-item { flex: 1; }
.a-nav-link {
  display: grid; justify-items: center; gap: 3px;
  padding: var(--sp-1) 0;
  color: var(--text-secondary);
  transition: color var(--dur-ui) var(--ease-instrument);
}
.a-nav-icon {
  width: 17px; height: 17px;
  fill: none; stroke: currentColor; stroke-width: 1.5;
}
.a-nav-label {
  font-size: var(--type-micro);
  letter-spacing: 0.1em;
}
.a-nav-link.is-active { color: var(--accent-primary); }
/* Selection is not colour alone: the active item is also gold-weighted and
   carries aria-current, and the label text is always present. */
.a-nav-link.is-active .a-nav-label { font-weight: 700; }

.a-footer { padding-top: var(--sp-4); padding-bottom: var(--sp-5); }
.a-notice {
  font-size: var(--type-micro);
  letter-spacing: 0.06em;
  color: var(--text-secondary);
  text-align: center;
}

/* ===========================================================================
   SCREENS — GAME DETAIL / ROUTES / MODEL   (sub-gates 12.c / 12.d / 12.f)
   Owner: P12-E4.  Templates: game.html, routes.html, model.html (NOT owned
   here — this file only dresses the markup those templates already emit).

   SAME AUTHORITIES, SAME RULES AS SECTIONS 1-11 ABOVE
     reference-preview.html phones 3/4/5 are the anatomy; UI_BRIEF is the sole
     authority for every state those three crops do not depict (§A9); no hex
     outside the brief's table; WCAG AA beats the reference and every departure
     is named in the block that makes it.

   THE REFERENCE MAPPING, LITERALLY
     .a-sig / -nm / -tr / -fill / -vl   <-  .sig .nm .tr i .vl
     .a-pill                            <-  .pill
     .a-card / --f / --ineligible       <-  .card / .card.f / opacity:.45
     .a-legs / .a-leg-mark              <-  .legs span
     .a-rt / -body                      <-  .rt
     .a-hero-num--route                 <-  .rt .n            (33px, gold)
     .a-verdict--held                   <-  .hold             (warning rail)

   FOUR MEASURED DEVIATIONS, ALL FORCED BY WCAG AA
     D1  Reference `--muted` (#7E8995) as small-text colour -> --text-secondary
         (#A7ADB5).  #7E8995 clears AA on --background-primary (4.51:1) after
         the operator's 2026-08-10 nudge, but only there: it measures 4.06:1 on
         --surface-primary and 3.80:1 on --surface-elevated, and cards and
         table rows sit on both.  --text-secondary is 7.14:1 - 8.46:1 on all
         four.  It is also what sections 1-11 already ship, and what
         test_muted_tokens_are_never_used_as_a_text_colour enforces.
     D2  Reference `.card{opacity:.45}` for an ineligible route CANNOT ship:
         measured on --surface-primary it takes --text-secondary to 2.57:1 and
         even --text-primary to 4.03:1 — both fail, and this is the one card
         whose whole job is to NAME the gate its leg failed.  Replaced by a
         value recession (recede the surface, fade the border, secondary the
         furniture) that reads as "greyed" while every string stays >= 4.5:1.
     D3  Reference label sizes of 7-9px are floored at 10px, as in section 1.
     D4  Rail notches and low-magnitude signal fills fall under WCAG 1.4.11's
         exception (their value is printed as text beside them); measured
         ratios are stated at each rule.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   12. SCREEN SCAFFOLD
   `.a-screen` is the <article> the three templates open with.  Nothing else in
   the app uses it, so every `.a-screen ...` rule below is scoped away from
   Home and Top Plays by construction.
   --------------------------------------------------------------------------- */
.a-screen {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;            /* long codes/table cells never widen the page */
}

/* Block separation, measured off each phone in the ratified sheet. */
.a-screen--game { gap: var(--sp-4); }     /* phone 3: 11-17px  -> 13-20px */
.a-screen--routes { gap: var(--sp-3); }   /* phone 4: cards carry their own
                                             padding; .card margin is 10px  */
/* phone 5 is the only screen whose section count grew well past its crop —
   nine disclosure blocks instead of four — so it takes the next step up the
   brief's scale to stay scannable.  Reported as a judgement call. */
.a-screen--model { gap: var(--sp-5); }

/* Inside a screen the label/rule rhythm is carried by each section's own grid
   gap, so the shared rule drops its margins rather than double-spacing. */
.a-screen .a-rule { margin: 0; }

/* Every ruled disclosure block: a label, a hairline, then its content. */
.a-detail-head,
.a-screen-head,
.a-verdict,
.a-loading,
.a-why,
.a-signals,
.a-risks,
.a-data-quality,
.a-history,
.a-accuracy,
.a-provenance-list,
.a-disclosures,
.a-composition,
.a-score-explainer,
.a-tables,
.a-freshness-card {
  display: grid;
  /* One column, capped at the container.  An `auto` grid track is sized to
     MAX-CONTENT and is never shrunk below it, so a wide table inside a plain
     `display:grid` section pushes the whole page sideways — measured at 390px:
     the provenance table took the document to 930px.  `minmax(0, 1fr)` is what
     makes the table's own `max-width:100%` resolve against the viewport, and
     therefore what makes its `overflow-x:auto` do anything at all. */
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  gap: var(--sp-2);
  min-width: 0;
}

.a-screen-foot {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-2);
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--surface-elevated);
}

/* The reference's standfirst: one quiet line under the screen label. */
.a-standfirst {
  font-size: var(--type-label);
  line-height: 1.5;
  color: var(--text-secondary);   /* D1 */
}

/* ---------------------------------------------------------------------------
   13. GAME DETAIL — header, verdict, hold
   --------------------------------------------------------------------------- */
.a-back-link {
  display: inline-block;
  padding-right: var(--sp-2);
  color: var(--text-secondary);
  transition: color var(--dur-ui) var(--ease-instrument);
}
.a-back-link:hover { color: var(--text-primary); }

.a-matchup {
  font-size: var(--type-matchup);
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text-primary);
}

/* The preview sets the two marks side by side.  `.a-tm` is itself a flex box
   (it centres its abbreviation), which makes it block-level and stacks the
   pair unless the container says otherwise — this is that rule. */
.a-team-marks {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}
.a-team-marks .a-tm { flex: none; }

/* Loading: §A3's dot -> line -> curve, at rest.  12.g animates it. */
.a-loading-stages { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-2); }
.a-loading-stage {
  font-size: var(--type-label);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-secondary);
}
.a-loading-stage::before {
  content: "";
  display: inline-block;
  width: 5px; height: 5px;
  margin-right: var(--sp-2);
  border-radius: 50%;
  background: var(--accent-dark);   /* graphical, 3.87:1 on --background-primary */
  vertical-align: middle;
}

/* §DATA STATES: a muted warning treatment, and always a text label beside it. */
.a-banner {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-compact);
  border-left: 2px solid var(--hairline-strong);
  background: var(--surface-primary);
  font-size: var(--type-note);
  line-height: 1.6;
  color: var(--text-secondary);
}
.a-banner--stale { border-left-color: var(--warning); }
.a-banner--inert { border-left: 2px solid var(--accent-dark); }

.a-freshness-card { margin-top: 0; }
.a-freshness-list { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-2); }
.a-freshness {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-1) var(--sp-2);
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  color: var(--text-secondary);
}
.a-freshness-name { color: var(--text-primary); font-weight: 700; }
.a-freshness-age,
.a-freshness-at { font-variant-numeric: tabular-nums; }
/* Colour REINFORCES the words WITHIN THRESHOLD / PAST THRESHOLD / AGE UNKNOWN;
   it never carries the state on its own (UI_BRIEF §ACCESSIBILITY). */
.a-freshness-state { letter-spacing: var(--track-micro); }
.a-freshness--ok .a-freshness-state { color: var(--positive); }   /* 7.81:1+ */
.a-freshness--stale .a-freshness-state,
.a-freshness--stale .a-freshness-age { color: var(--warning); }   /* 7.99:1+ */
.a-freshness--unknown .a-freshness-state { color: var(--text-secondary); }

/* The verdict: hero numeral, caption, confidence pill, rail. */
.a-verdict { justify-items: start; }

/* The preview's `.hold`: a warning rail down the left, reason stated. */
.a-verdict--held {
  padding-left: var(--sp-3);
  border-left: 2px solid var(--warning);
}
.a-hold-kicker { color: var(--warning); }
.a-hold-body {
  font-size: var(--type-note);
  line-height: 1.6;
  color: var(--text-primary);
}
.a-hold-reasons { margin-top: var(--sp-1); }
.a-hold-retry {
  font-size: var(--type-label);
  line-height: 1.5;
  color: var(--text-secondary);
}
/* Where the withheld record still lives (operator ruling, 2026-08-11: "full
   record in the archive").  Set at label size and --text-secondary, the same
   register as .a-hold-retry above it: both are notes about the hold rather
   than the explanation the reader came for, and the sp-2 gap is what separates
   the provenance beat from the retry beat.

   IT IS NOT --text-muted, and that is UI_BRIEF's D1 rather than a preference:
   the reference's muted grey is deprecated as a SMALL-TEXT colour, and the one
   sanctioned use of it in this stylesheet (.a-hero-num--route--absent) is at
   >=24px, where AA's 3:1 large-text allowance applies.  This line is 11px.

   It also does NOT read `var(--text-tertiary, ...)`.  There is no
   --text-tertiary in the brief's token table; written that way the rule
   resolves through its fallback today and silently adopts whatever value a
   future --text-tertiary carries, on a line the contrast registry in
   tests/web/test_screen_styles.py::INTRODUCED_PAIRS cannot follow.  The token
   the rule actually uses is the token it names. */
.a-hold-archive {
  margin-top: var(--sp-2);
  font-size: var(--type-label);
  line-height: 1.5;
  color: var(--text-secondary);
}

.a-score-block {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: start;
  gap: var(--sp-1);
  width: 100%;
}

/* Phone 3 sets its hero at 88px, not the 104px of the Home screen. */
.a-screen--game .a-hero-num { font-size: var(--type-hero-detail); }
.a-hero-label { margin-top: var(--sp-1); }

/* The confidence chip.  Preview `.pill`: gold-bordered, gold-light text. */
.a-pill {
  display: inline-block;
  margin-top: var(--sp-2);
  padding: var(--sp-1) var(--sp-3);
  border: 1px solid var(--accent-dark);      /* 3.48:1 on --surface-primary */
  border-radius: var(--radius-pill);
  color: var(--accent-light);                /* 10.14:1 - 11.26:1 */
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  white-space: nowrap;
}

/* The score rail: the tier ladder the number sits on.  No preview counterpart
   (phone 3 prints the pill alone), so UI_BRIEF §SURFACES governs: a fine
   divider, one accent, no chart furniture. */
.a-score-rail {
  display: block;
  width: 100%;
  height: auto;
  margin-top: var(--sp-2);
  color: var(--accent-primary);
}
.a-rail-track { fill: var(--surface-elevated); opacity: 1; }
.a-rail-fill { fill: var(--accent-primary); }   /* 7.01:1 on the track */
/* D4: notches read as ticks cut out of the gold fill (8.06:1 there).  Over the
   unfilled track they disappear (1.16:1) — a boundary the score has not
   reached carries no information, and every boundary is printed as text in the
   Model screen's tier table. */
.a-rail-notch { fill: var(--background-primary); opacity: 1; }

/* Probability is its own line with its own units (§ARCADIA SCORE). */
.a-screen--game .a-prob {
  flex-wrap: wrap;
  font-size: var(--type-note);
  color: var(--text-secondary);
}
.a-prob-v { color: var(--text-primary); font-weight: 700; font-variant-numeric: tabular-nums; }
.a-prob-pm { color: var(--text-secondary); font-variant-numeric: tabular-nums; }

.a-market-line {
  letter-spacing: var(--track-micro);
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
   14. SIGNAL MEASURES — the preview's `.sig` row, label / track / value
   Used by BOTH Game Detail ("why X has the edge") and Model ("accuracy vs
   baselines"), which is why it is one component and not two.
   --------------------------------------------------------------------------- */
.a-signal-list { display: grid; grid-template-columns: minmax(0, 1fr); }

.a-sig {
  display: flex;
  align-items: center;
  /* WRAP, so a full-width annotation (`.a-sig-note`) drops to its own line
     instead of widening the row. Without it the note's `flex-basis: 100%` was
     added to the row's intrinsic width and the Model screen scrolled
     HORIZONTALLY at 390px — caught by measuring documentElement.scrollWidth in
     a real emulated viewport, not by reading the stylesheet. The measured rows
     already fit, so nothing else wraps. */
  flex-wrap: wrap;
  gap: var(--sp-3);              /* preview 9px -> 10.6px */
  margin: var(--sp-2) 0;         /* preview 9px 0        */
}
.a-sig-nm {
  flex: 0 1 8.7rem;              /* preview 118px -> 139px */
  min-width: 5.5rem;
  overflow-wrap: anywhere;
  font-size: var(--type-label);
  color: var(--text-secondary);
}
.a-sig-tr {
  flex: 1 1 3rem;
  height: 5px;
  border-radius: 3px;
  background: var(--track);
  overflow: hidden;
}
/* One accent at varying widths (UI_BRIEF §GAME DETAIL: "one accent color with
   varied opacity, no rainbow charts").  The template supplies width and
   opacity inline from the artifact; this rule supplies only the colour.
   D4: the fill runs from opacity .35 to 1, so the weakest bar measures about
   2.2:1 against its own track.  Every bar prints its value as text in
   `.a-sig-vl` beside it, so no information is carried by the bar alone. */
.a-sig-fill { display: block; height: 100%; background: var(--accent-primary); }
.a-sig-vl {
  flex: 0 0 auto;
  min-width: 3.5rem;             /* fits "+12.3 pts" without wrapping */
  text-align: right;
  white-space: nowrap;
  font-size: var(--type-label);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

/* A contribution that pushes AGAINST the verdict has no counterpart in the
   preview (phone 3 shows only the winning side), so §A9 hands it to the
   brief: status colour, restrained, never the only signal.  The sign is in the
   printed value and the direction is in the row's screen-reader text; the
   neutral fill is reinforcement.  3.99:1 on the track. */
.a-sig--against .a-sig-fill { background: var(--neutral); }
.a-sig--for .a-sig-fill { background: var(--accent-primary); }
.a-sig--none .a-sig-vl { color: var(--text-secondary); }

/* A RULED-INERT family: "n/a" over an EMPTY track, never a zero-length bar.
   The empty track is the template's doing (it emits no <i> at all); this rule
   is what stops the row reading as a measured zero. */
.a-sig--na .a-sig-nm,
.a-sig--na .a-sig-vl {
  color: var(--text-secondary);   /* D1 — preview uses --muted here */
  font-size: var(--type-micro);   /* D3 — preview 8px */
}
.a-sig--na .a-sig-tr { background: color-mix(in srgb, var(--surface-elevated) 60%, transparent); }

/* The annotation on a COLLAPSED baseline row — two registered artifacts that
   are the same probability function render as one bar, and the note is where
   that says so.  Full width beneath the row rather than beside it: it is a
   sentence, and squeezing a sentence into the value column is how a
   disclosure becomes unreadable and then gets deleted. */
.a-sig-note {
  flex: 1 0 100%;
  min-width: 0;                  /* a flex item's min-width:auto is its content */
  font-size: var(--type-micro);
  line-height: 1.5;
  /* --text-secondary, not --text-muted: this is body text at the brief's
     smallest size and the muted token does not clear AA there. Caught by
     tests/web/test_tokens_and_shell.py, which is the point of that test. */
  color: var(--text-secondary);
}

.a-why-note,
.a-inert-caption,
.a-contradiction-caption,
.a-accuracy-caption {
  font-size: var(--type-micro);
  line-height: 1.6;
  color: var(--text-secondary);   /* D1 */
}
.a-inert-caption { margin-top: var(--sp-1); }
.a-accuracy-caption { margin-top: var(--sp-2); }
/* The ruling and the artifact disagree: railed like any other contradiction
   the app reports rather than resolves. */
.a-contradiction-caption {
  margin-top: var(--sp-2);
  padding-left: var(--sp-3);
  border-left: 2px solid var(--warning);
}
.a-why-note { margin-top: var(--sp-2); text-transform: uppercase; }

/* ---------------------------------------------------------------------------
   15. REASON CODES — key signals, risk factors, hold reasons
   Phone 3 renders these as plain prose, so the rails below are the only thing
   added: three different kinds of statement should not look identical.
   --------------------------------------------------------------------------- */
.a-reason-list { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-2); }
.a-reason {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2px;
  font-size: var(--type-note);
  line-height: 1.6;
  color: var(--text-secondary);
}
.a-reason-text { color: var(--text-primary); }
.a-reason-meta {
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-secondary);
}
/* Evidence for the verdict: gold rail. */
.a-reason--signal { padding-left: var(--sp-3); border-left: 2px solid var(--accent-dark); }
/* A listed risk is information, not an alarm — "do not flood cards with status
   colors" (UI_BRIEF §COLOR SYSTEM). */
.a-reason--risk { padding-left: var(--sp-3); border-left: 2px solid var(--neutral); }
/* A hold is the one that IS a warning, and the preview rails it in --warn. */
.a-reason--hold { padding-left: var(--sp-3); border-left: 2px solid var(--warning); }

/* Standalone status chips (`.a-chip` supplies the type; these supply state). */
.a-chip--ok { color: var(--positive); }
.a-chip--degraded { color: var(--warning); }
.a-chip--flag,
.a-chip--inert,
.a-chip--correlation {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  padding: 1px var(--sp-2);
}
.a-chip--flag { border-color: var(--hairline-strong); }
.a-chip--inert { border: 1px solid var(--accent-dark); color: var(--accent-light); }
.a-chip--correlation {
  border-color: color-mix(in srgb, var(--warning) 40%, transparent);
  color: var(--warning);
}

/* ---------------------------------------------------------------------------
   16. PREDICTION HISTORY — the append-only table, rendered
   --------------------------------------------------------------------------- */
.a-history-list { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-1); }
.a-history-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-1) var(--sp-2);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--surface-elevated);
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  color: var(--text-secondary);
}
.a-history-score {
  font-size: var(--type-label);
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.a-history-tier { text-transform: uppercase; }
.a-history-pick { color: var(--text-primary); font-weight: 600; }
.a-history-version { margin-left: auto; font-variant-numeric: tabular-nums; }

.a-sparkline {
  display: block;
  width: 100%;
  height: auto;
  margin: var(--sp-1) 0 var(--sp-2);
  color: var(--accent-primary);
}
.a-spark-line { stroke-width: 1.5; }
.a-spark-head { fill: var(--accent-light); }

/* ---------------------------------------------------------------------------
   17. ROUTES — the card stack from phone 4
   --------------------------------------------------------------------------- */
.a-card {
  padding: var(--sp-4);                       /* preview 13px -> 15.3px */
  border: 1px solid var(--hairline);          /* preview #1A2734, derived */
  border-radius: var(--radius-compact);       /* preview 15px            */
  background: var(--surface-primary);
}
/* The featured card is gold-bordered (§A8, and phone 4's `.card.f`). */
.a-card--f { border: 1px solid var(--accent-dark); }   /* 3.48:1 on the surface */

/* D2 — the preview greys this card with `opacity:.45`.  Measured on
   --surface-primary that is 2.57:1 for --text-secondary and 4.03:1 even for
   --text-primary: both fail AA, on the one card whose entire purpose is to
   NAME the gate its leg failed.  Recede the surface instead of the ink. */
.a-card--ineligible {
  background: var(--background-secondary);
  border-color: color-mix(in srgb, var(--text-muted) 16%, transparent);
}
.a-card--ineligible .a-leg-mark { background: var(--surface-primary); }

/* R4 (operator, 2026-08-15) — the brief's three band headings, ALL of them,
   sparse or empty.  A heading only, with the section rule the rest of the
   product uses: the cards below it are the existing stack, so the band is a
   label on the page rather than a container that would re-draw them.  An empty
   band carries its `.a-empty-body` sentence in the same box, which is why the
   spacing is on the section and not on the label. */
.a-band { margin: var(--sp-4) 0 var(--sp-2); }
.a-band:first-of-type { margin-top: 0; }

.a-route-card { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-2); }
.a-route-kicker { font-size: var(--type-micro); }   /* D3 — preview 8px */

/* Overlapping circular team marks, exactly as `.legs span`. */
.a-legs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  row-gap: var(--sp-1);
  margin: var(--sp-1) 0;
}
.a-leg-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  /* The preview sets a 21px circle around 7px type — a 3.0 ratio.  D3 floors
     that type at 10px, so the circle is scaled to KEEP the ratio rather than
     the raw 21px: a three-letter abbreviation needs the same share of its
     circle at 10px as it had at 7px, and at 24.8px the overlap ate the third
     letter (measured at 390px: "BUF KC" rendered as "BUI KC"). */
  width: 1.85rem; height: 1.85rem;            /* preview 21px, ratio-scaled  */
  /* …and the overlap comes back from 24% of the circle to one spacing step,
     which is what stops the mark on top from clipping a glyph rather than a
     ring.  Reported as a consequence of the 10px floor, not a taste call. */
  margin-right: calc(-1 * var(--sp-1));
  border-radius: 50%;
  border: 1.5px solid var(--surface-primary); /* the ring that separates them */
  background: var(--surface-elevated);
  color: var(--text-secondary);               /* 7.14:1 */
  font-size: var(--type-micro);               /* D3 — preview 7px */
  font-weight: 700;
  letter-spacing: 0;
  line-height: 1;
}
/* The leg that failed the gate.  The "?" glyph and the named gate below carry
   the meaning; the border is reinforcement.  --warning is 7.99:1 here. */
.a-leg-mark--failed { border-color: var(--warning); color: var(--warning); }

.a-rt {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-3);
}
.a-rt-body { display: grid; grid-template-columns: minmax(0, 1fr); gap: 3px; min-width: 0; }

/* `.rt .n` — a large gold numeral, NOT the hero size. */
.a-hero-num--route {
  flex: none;
  font-size: var(--type-route);
  color: var(--accent-primary);               /* 7.48:1 on the surface */
  line-height: 1;
}
.a-hero-num--absent {
  font-family: var(--font-ui);
  font-weight: 300;
  color: var(--text-secondary);
}
/* An unpublished route score is an em dash.  At 1.625rem (26px) WCAG's 3:1
   large-text bar applies, which is the one size --text-muted is cleared for,
   so the preview's muted dash survives verbatim here. */
.a-hero-num--route.a-hero-num--absent {
  font-size: 1.625rem;
  color: var(--text-dim-large);
}

.a-route-category {
  font-size: var(--type-label);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--accent-primary);
}
.a-route-category--ineligible { color: var(--text-secondary); }   /* D1 */
.a-route-joint {
  font-size: var(--type-label);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.a-route-correlation,
.a-route-gate {
  font-size: var(--type-micro);
  line-height: 1.55;
  color: var(--text-secondary);
}
.a-route-score-note { font-size: var(--type-micro); letter-spacing: var(--track-micro); }
.a-gate-reasons { margin-top: var(--sp-1); }

/* The arithmetic, printed: independent product, haircut, compounded failure. */
.a-joint {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-1);
  margin: 0;
  padding-top: var(--sp-2);
  border-top: 1px solid var(--hairline);
}
.a-joint-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  color: var(--text-secondary);
}
.a-joint-row dt,
.a-joint-row dd { margin: 0; }
.a-joint-row dd { color: var(--text-primary); font-variant-numeric: tabular-nums; }
/* The compounded loss is the number a reader is most likely to skip. */
.a-joint-row--failure dd { color: var(--warning); }

.a-correlation-list { display: flex; flex-wrap: wrap; gap: var(--sp-1); }
.a-correlation-warning {
  font-size: var(--type-micro);
  line-height: 1.6;
  color: var(--text-secondary);
}
/* The closing responsible-use notice is a sentence, not a caption: it reads
   left-aligned even though `.a-notice` centres the shell's one-liner. */
.a-notice--compounding {
  text-align: left;
  font-size: var(--type-micro);
  line-height: 1.6;
  letter-spacing: 0;
}

/* ---------------------------------------------------------------------------
   18. MODEL — the trust screen
   --------------------------------------------------------------------------- */
.a-model-version {
  letter-spacing: var(--track-micro);   /* a version string at .24em is unreadable */
  font-variant-numeric: tabular-nums;
}
.a-stat-note {
  display: block;
  margin-top: var(--sp-1);
  font-size: var(--type-micro);
  line-height: 1.5;
  color: var(--text-secondary);
}
.a-subsection { margin-top: var(--sp-3); }

/* A figure that could not be measured is not a headline number.  `.a-stat-v`
   is the condensed hero face; "NOT MEASURED" set in it at 33px wrapped to two
   lines and broke the triplet.  The template already publishes the state as
   `data-available="false"`, so no markup change is needed — this is the same
   treatment `.a-stat--absent` gives an absent figure on Home. */
.a-screen--model .a-stat[data-available="false"] .a-stat-v {
  font-family: var(--font-ui);
  font-size: var(--type-label);
  font-weight: 600;
  letter-spacing: var(--track-micro);
  line-height: 1.4;
  color: var(--text-secondary);
}

.a-calibration {
  display: block;
  max-width: 100%;
  height: auto;
  margin: var(--sp-1) 0;
  color: var(--accent-primary);
}
.a-cal-ideal { stroke: var(--accent-dark); stroke-opacity: 1; }   /* 3.48:1 */
.a-cal-dot { fill: var(--accent-primary); }

/* Every figure states the query that produced it. */
.a-provenance {
  font-size: var(--type-micro);
  line-height: 1.5;
  color: var(--text-secondary);
}
.a-provenance-key { font-weight: 700; letter-spacing: var(--track-micro); }
.a-provenance code { font-size: 0.95em; overflow-wrap: anywhere; }

.a-disclosure-list { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-2); }
.a-disclosure {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2px;
  padding-left: var(--sp-3);
  font-size: var(--type-note);
  line-height: 1.7;
  color: var(--text-secondary);
}
/* Phone 5 sets the disclosures as "· " bullets. */
.a-disclosure::before {
  content: "";
  position: absolute;
  left: 0; top: 0.7em;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--accent-primary);
}
.a-disclosure-text { color: var(--text-primary); }
/* The measured evidence under a disclosure that carries any. Secondary to the
   sentence above it, ahead of the provenance line below it — the grid already
   stacks all three, so this only sets the weight. */
.a-disclosure-detail { color: var(--text-secondary); }

.a-family-list { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-2); }
.a-family {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-1) var(--sp-2);
  font-size: var(--type-label);
}
.a-family-label { color: var(--text-primary); font-weight: 600; }
.a-family-count {
  margin-left: auto;
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.a-family--inert .a-family-label { color: var(--text-secondary); font-weight: 500; }
.a-family-ruling {
  flex-basis: 100%;
  font-size: var(--type-micro);
  line-height: 1.6;
  color: var(--text-secondary);
}

.a-scale-headline {
  font-size: var(--type-label);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--accent-light);
}
.a-explainer-body {
  font-size: var(--type-note);
  line-height: 1.65;
  color: var(--text-secondary);
}

.a-secondary-figure {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-1) var(--sp-2);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--surface-elevated);
}
.a-secondary-label {
  font-size: var(--type-label);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-secondary);
}
.a-secondary-value {
  margin-left: auto;
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.a-secondary-note {
  flex-basis: 100%;
  font-size: var(--type-micro);
  line-height: 1.5;
  color: var(--text-secondary);
}

/* --- Wide tables scroll INSIDE themselves ------------------------------------
   The provenance and tier tables carry file paths and SQL, so they are wider
   than a 390px viewport no matter how the type is set.  `display:block` turns
   the table itself into the scroll container (its rows still lay out as a
   table, in an anonymous table box), which is what keeps the PAGE body from
   ever scrolling horizontally.  No wrapper element exists to put this on, and
   the templates are not ours to change. */
.a-count-table,
.a-tier-table {
  display: block;
  width: max-content;
  max-width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  color: var(--text-secondary);
}
.a-count-table caption,
.a-tier-table caption {
  display: block;
  margin-bottom: var(--sp-2);
  text-align: left;
}
.a-count-table th,
.a-count-table td,
.a-tier-table th,
.a-tier-table td {
  padding: var(--sp-2) var(--sp-3) var(--sp-2) 0;
  border-bottom: 1px solid var(--surface-elevated);
  text-align: left;
  vertical-align: top;
  white-space: nowrap;
  font-weight: 400;
}
.a-count-table thead th,
.a-tier-table thead th {
  color: var(--text-secondary);
  font-weight: 700;
  text-transform: uppercase;
}
.a-count-table tbody th,
.a-tier-table tbody th { color: var(--text-primary); font-weight: 600; }
.a-tier-table td { color: var(--text-primary); font-variant-numeric: tabular-nums; }
.a-count { color: var(--text-primary); font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------------------
   19. RESPONSIVE — preserve the large-number hierarchy; split panels, never
   mobile cards stretched into horizontal slabs (UI_BRIEF §RESPONSIVE).
   The ratified preview is mobile-only, so this section follows the brief.
   --------------------------------------------------------------------------- */
@media (min-width: 62rem) {
  .a-topbar, .a-main, .a-nav-list, .a-footer { max-width: 62rem; }

  /* Split panels are for Home, where the hero and its supporting readouts sit
     side by side.  A ranked board is a LIST — putting it in a two-column grid
     strands the held summary in an empty second column, so it stays a single
     column and simply breathes wider. */
  body[data-view="home"] .a-main {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: start;
    column-gap: var(--sp-7);
  }
  body[data-view="home"] .a-hero-block { grid-row: 1 / span 2; align-self: center; }
  body[data-view="plays"] .a-ghost { align-self: center; min-width: 22rem; }

  .a-row-link { grid-template-columns: 2rem auto minmax(0, 1fr) auto; gap: var(--sp-4); }
  .a-nav-list { justify-content: flex-start; gap: var(--sp-6); }
  .a-nav-item { flex: 0 0 auto; }
  .a-nav-link { grid-auto-flow: column; align-items: center; gap: var(--sp-2); }

  /* The three screens simply breathe wider: the measure grows, the hierarchy
     does not change, and nothing becomes a horizontal slab. */
  .a-sig-nm { flex-basis: 11rem; }
  .a-count-table th, .a-count-table td,
  .a-tier-table th, .a-tier-table td { padding-right: var(--sp-5); }
}

/* ---------------------------------------------------------------------------
   20. MOTION PREFERENCES
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms;
    animation-iteration-count: 1;
    transition-duration: 1ms;
  }
}

/* ---------------------------------------------------------------------------
   21. THE DESIGN-PREVIEW BANNER  (P12-B22)
   Rendered ONLY by `arcadia.web.design_preview`; `arcadia serve` has no way to
   emit it (the block in base.html keys on a context value the view layer never
   produces, and a test asserts that on all seven screens).

   IT IS DELIBERATELY NOT IN THE PRODUCT REGISTER.  Navy-and-gold is the
   product; a banner in the product's own palette is a banner a reader learns
   to stop seeing.  This one is warning-toned, full-bleed, first in the body
   and hazard-striped — the one surface in the app allowed to look like it does
   not belong, because the fact it states is that this page is not the product.
   `position: sticky` keeps it on screen through a long scroll, so a crop taken
   anywhere down the page still carries it.
   --------------------------------------------------------------------------- */
.a-preview-banner {
  position: sticky;
  top: 0;
  z-index: 30;
  width: 100%;
  box-sizing: border-box;
  margin: 0 0 var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 2px solid var(--warning);
  background:
    repeating-linear-gradient(
      135deg,
      color-mix(in srgb, var(--warning) 20%, var(--background-primary)) 0 10px,
      color-mix(in srgb, var(--warning) 10%, var(--background-primary)) 10px 20px);
  color: var(--text-primary);
}
.a-preview-title {
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--type-label);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--warning);
}
.a-preview-detail {
  margin: var(--sp-1) 0 0;
  font-size: var(--type-micro);
  line-height: 1.5;
  color: var(--text-primary);
}
.a-preview-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-3);
  margin: var(--sp-2) 0 0;
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-secondary);
}
.a-preview-meta > span::before { content: "· "; color: var(--warning); }
.a-preview-meta > span:first-child::before { content: none; }

/* ---------------------------------------------------------------------------
   22. TEAM-MARK OPTIONS — the EXIT 12 comparison surface  (P12-B22)
   Preview-only, like §21.  Two treatments of the SAME Top Plays rows, side by
   side at mobile width, so the decision is made on the layout rather than on a
   description of it.  `--tm-*` are local to this surface: nothing here changes
   `.a-tm`, which is what the product renders today.
   --------------------------------------------------------------------------- */
.a-optcols { display: grid; gap: var(--sp-5); }
.a-optlabel {
  margin: var(--sp-3) 0 var(--sp-1);
  font-size: var(--type-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--accent-primary);
}
/* The comparison surface is the ONE place the shell's 27rem phone column is
   widened, and only far enough for TWO phone-width columns to sit beside each
   other.  Scoped to `body[data-view="team-marks"]`, a view name no shipped
   screen sets — so no product screen changes measure. */
@media (min-width: 56rem) {
  body[data-view="team-marks"] .a-topbar,
  body[data-view="team-marks"] .a-main,
  body[data-view="team-marks"] .a-nav-list,
  body[data-view="team-marks"] .a-footer { max-width: 58rem; }
  body[data-view="team-marks"] .a-optcols {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--sp-6);
    align-items: start;
  }
  body[data-view="team-marks"] .a-optcol + .a-optcol {
    padding-left: var(--sp-6);
    border-left: 1px solid var(--hairline);
  }
}
.a-optcol { min-width: 0; }
.a-opthead { margin: 0 0 var(--sp-1); }
.a-optnote {
  margin: 0 0 var(--sp-3);
  font-size: var(--type-micro);
  line-height: 1.55;
  color: var(--text-secondary);
}
.a-optquote {
  margin: 0 0 var(--sp-3);
  padding-left: var(--sp-3);
  border-left: 2px solid var(--hairline-gold);
  font-size: var(--type-micro);
  line-height: 1.6;
  color: var(--text-primary);
}
.a-optquote cite {
  display: block;
  margin-top: var(--sp-1);
  font-style: normal;
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-secondary);
}
.a-optflag {
  margin: var(--sp-3) 0 0;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid color-mix(in srgb, var(--negative) 55%, transparent);
  border-radius: var(--radius-compact);
  font-size: var(--type-micro);
  line-height: 1.6;
  color: var(--text-primary);
}
.a-optflag b {
  display: block;
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--negative);
}

/* OPTION A — the styled abbreviation chip.  A restatement of `.a-tm` with the
   brief's own restraint applied: mono numerals-and-caps, hairline, no team
   colour, no image, three characters max. */
.a-tm--chip {
  display: inline-grid;
  place-items: center;
  min-width: 2.5rem;
  height: 2.5rem;
  padding: 0 var(--sp-1);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-compact);
  background: var(--surface-elevated);
  font-family: var(--font-ui);
  font-size: var(--type-label);
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-primary);
}
.a-row--f .a-tm--chip { border-color: var(--hairline-gold); color: var(--accent-light); }

/* OPTION B — the SOURCED-LOGO layout, mocked with a NEUTRAL PLACEHOLDER.
   No trademarked mark is downloaded, drawn or committed anywhere in this repo;
   what is being judged here is the 40px raster slot and what sits around it. */
.a-tm--logo {
  display: inline-grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-pill);
  background:
    radial-gradient(circle at 50% 40%,
      color-mix(in srgb, var(--text-muted) 45%, transparent) 0 42%,
      transparent 43%),
    var(--surface-elevated);
  border: 1px dashed var(--hairline-strong);
  color: var(--text-secondary);
  font-size: var(--type-micro);
  letter-spacing: 0;
}
/* The fallback problem, drawn rather than described: this is what the slot
   renders when a mark is missing, blocked or fails to load. */
.a-tm--logo-missing {
  border-style: solid;
  border-color: color-mix(in srgb, var(--negative) 55%, transparent);
  background: var(--surface-elevated);
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: var(--type-label);
  color: var(--text-secondary);
}
