/* ============================================================================
   site-theme.css — THE site theme: "Pro Tour" (theme A, approved by Adam 2026-09-26 — "roll out option A").
   The refined CURRENT design, not a redesign: same layouts, same brand hexes (#2191d2 / #fce81e / #19171a,
   Poppins headings / Roboto body), tightened:
     • radius 6–10px everywhere (pill shapes → 6px, cards 16–26px → 8–10px); avatars stay round
     • UI icons are monochrome line icons from profiles/icons.svg (<svg class="ico"><use href="icons.svg#name">,
       JS: FPT.ico(name) from icons.js) — §0 below sizes them; the emoji they replace are gone from the source
       (_archive/tools/check_ui_emoji.py fails the build if one comes back on a public page)
     • yellow reserved for #1 / title-holder · live · the one key CTA; secondary badges go ink / neutral
     • one quiet shadow family, no dot-grid / wave decoration, no gradient text, no olive hero haze
     • no off-palette purple / teal / green / orange / red; medal tints only on small icons
     • WCAG AA on small text (white-on-blue and blue-on-light step to #1a76ad / #155f8c)

   HOW IT IS LOADED: _archive/tools/sync_site_nav.py stamps ONE <link rel="stylesheet" href="site-theme.css">
   as the LAST stylesheet in every stamped page's <head>, and data-page="<file stem>" on <html> (used by the
   page-scoped rules below where class names collide: .dots is a dot grid on move but carousel dots on watch).
   Its --check fails a build if either is missing, duplicated, or another stylesheet follows this one.

   SPECIFICITY: ~86% of the site's CSS is inline per page, so every rule is prefixed html:root (0,1,1):
   html:root .a (0,2,1) beats a page's .a.b (0,2,0). Same weight as the preview's html:root,
   so the shipped look is the approved one. Do not drop the prefix when editing.
   NEVER touches the site header (site-nav.css owns its geometry AND colour) — this file does not style .nav.

   ORIGIN + DEBT: promoted from the review-only preview profiles/themes/pro-tour.css (commit e04bebf).
   §8 and §9 are page-defect STOPGAPS; each names its real fix in the page — fold them into their owners
   and delete them here (the rollout plan's L5 list). A FUTURE theme previews on top of this file: see
   profiles/themes/README.md.
   ============================================================================ */

html:root{
  --fpt-r-sm:4px; --fpt-r:6px; --fpt-r-lg:8px; --fpt-r-pill:6px;
  --fpt-line:#d8dfe7;                                    /* the card hairline (Crisp, §10) */
  --fpt-shadow:0 1px 2px rgba(20,19,22,.05),0 14px 28px -24px rgba(20,19,22,.4);
  --fpt-muted:#4d5660;                                   /* 7.6:1 on white, 6.6:1 on the backdrop's darkest (#edf1f5); the brand's #6b7280 is 4.3:1 there */
  --fpt-shadow-blue:0 1px 2px rgba(20,19,22,.08),0 12px 26px -18px rgba(20,19,22,.50);   /* hover depth: neutral, no glow */
  /* brand "secondary fade" = blue → yellow (the page-level #6fc36b green midpoint is not in the guide) */
  --fpt-fade:linear-gradient(100deg,#2191d2 0%,#2191d2 45%,#fce81e 100%);
  /* shared tokens for this file (all derived from the brand hexes) */
  --pt-ink:#141316;
  --pt-glass:rgba(20,19,22,.74);
  --pt-glass-line:rgba(255,255,255,.18);
  --pt-neutral:#eef1f4;
  --pt-neutral-ink:#2b2f35;          /* 11.9:1 on --pt-neutral */
  --pt-link:#155f8c;                 /* Crisp's one blue for links and fills: 6.9:1 on white, 6.0:1 on the backdrop (was #1a76ad, 4.3:1 there) */
  --pt-link-deep:#155f8c;            /* 6.0:1 on --fpt-blue-100, 6.9:1 on white */
  --pt-muted-2:#5b6570;              /* 5.9:1 on white, 5.2:1 on --fpt-blue-100 */
  --pt-dark-muted:#8a94a3;           /* 6.0–6.5:1 on the ink surfaces */
  --pt-shadow-dark:0 1px 2px rgba(0,0,0,.25),0 14px 34px -24px rgba(0,0,0,.7);
}

/* ── 0. Line icons (profiles/icons.svg). One markup shape everywhere:
      <svg class="ico" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="icons.svg#NAME"/></svg>
   (JS: FPT.ico("NAME"[, "ico-gold"])). 1em square, sits on the text baseline, colour = currentColor; medals add a
   tint class. Same box as the preview's theme-kit icons, so swapping an emoji for an icon does not move layout. ── */
.ico{display:inline-block;width:1em;height:1em;vertical-align:-.14em;flex:0 0 auto;overflow:visible}
.ico-gold{color:#c9a227}
.ico-silver{color:#9aa3ad}
.ico-bronze{color:#b07a4a}

/* ── 1. Shape: pills → 6px chips; oversized card radii → 8–10px. The site header is excluded. ── */
html:root :is(.chip,.tag,.badge,.pill,.pl,.tchip,.rchip,.mchip,.hchip,.vr-chip,.famchip,.techchip,
  .sigchip,.span-chip,.sponsor-chip,.src-pill,.rankpill,.ce-pl,.jd,.lbadge,.nev-badge,.lyr,.typ,.rtag,.fc-badge,
  .jumbo-ctx,.jumbo-tag,.champ-x,.vc-rank,.aotd-ribbon,.fpta-lab,.reel-hint,.b-src,.b-tour,.bc-flag,
  .preview-tag,.tut-badge,.tile-badge,.tier,.bt,.sb,.rcard-type,.nad-flag,.hero-titles,.gt,.dtab,.btab,.lbtab,
  .tt-tab,.tabs,.tabs button,.fptds,.fpt-btn,.p-btn,.slide-cta,.loadbtn,.all-more,.lgo,.hero-imgmenu-btn,.btn-danger,
  .fpt-userbar,.hsearch,.wsearch,.tb-search,.tb-sort,.search,.heat,.pc-tier,
  .hs-tog button,.rkchip,.v2c .rk,.vcard-img .rating,.fc-play,.rcat .ic,.reel-ctl,.rbox-ic):not(.nav *){
  border-radius:6px;
}
/* ids kept in their own rule: an id inside :is() lifts EVERY selector in the list to (1,x,x) and blocks later tweaks */
html:root :is(#dirSearch,#ysel,#talkSignin){border-radius:6px}
html:root :is(.hfeat,.aotd-face,.hstrip,.jumbo,.reel-shell,.fpta,.lrow,.nev-face,
  article.neon,.bcast,.geo-map,.geo-panel,.pc-photo-wrap,.pc-photo,.stage,.p-video,.dir-ac){
  border-radius:10px;
}
html:root :is(.reel-chase,.of-cell,.minilist .mli,.sig-sug,.sig-card,.hyc){border-radius:8px}
html:root .wp{border-radius:0 8px 8px 0}
html:root :is(.vthumb,.tut-slot){border-radius:8px}
html:root .champ-card .champ-x:not(.nav *){border-radius:3px}   /* tiny count chip: 6px still reads as a pill; (0,4,1) to beat the §1 list */
html:root .neon-in{border-radius:9px}
/* the reel stays full-bleed and square-cornered on phones (its own ≤700px rule) */
@media (max-width:700px){ html:root .reel-shell{border-radius:0} }

/* ── 2. Depth: one quiet shadow family instead of big coloured glows ── */
html:root :is(.hfeat,.aotd-face,.hstrip,.reel-shell,.stage,.p-video){box-shadow:var(--pt-shadow-dark)}
html:root :is(.hero-titles,.vc-rank,.vcard-img .rating,.fc-pic,.nev-badge){box-shadow:none}
html:root .champ-card.latest{box-shadow:none}
/* hover lifts: 2px, not 3–4px */
html:root :is(.fcard,.rbox,.vcard):is(:hover,:focus-visible){transform:translateY(-2px)}

/* ── 3. Decoration off: dot grids, the wave divider, gradient text, the olive hero haze ── */
html:root :is(.hero-dots,.tt-hero-dots,.dotgrid),
html:root[data-page="move"] .dots{background-image:none}
html:root .hero-wave{display:none}
/* athlete: the diagonal hatch sits behind every dark module (UI background, not a hero texture) */
html:root[data-page="athlete"] .hatch{display:none}
/* the home hero kept 78px of bottom padding for the wave — close most of that gap now it is gone */
html:root[data-page="home"] .hero .wrap{padding-bottom:44px}
@media (max-width:560px){ html:root[data-page="home"] .hero .wrap{padding-bottom:32px} }
/* hero glows: keep the brand-blue light, drop the yellow radial that reads as olive/brown haze on ink */
html:root[data-page="home"] .hero::before{
  background:radial-gradient(900px 420px at 78% -8%,rgba(33,144,210,.46),transparent 62%)}
html:root :is(.nhero,.ehero,.tt-hero)::before{
  background:radial-gradient(900px 400px at 82% -10%,rgba(33,144,210,.44),transparent 60%)}
/* The fill FOLLOWS the colour (currentColor), never a value of its own: a later rule that re-colours the title
   (§10 puts the card titles on white cards, in ink) then shows. Pinned to #fff, the fill out-ranked the colour and
   the move names on the hub's clip cards were white on white from the Crisp roll-out until 12 Nov 2026. */
html:root .neon-move{
  background:none;-webkit-background-clip:border-box;background-clip:border-box;color:#fff;-webkit-text-fill-color:currentColor;
}
html:root .tt-hero h1 .ac{
  background:none;-webkit-background-clip:border-box;background-clip:border-box;color:var(--fpt-blue-300);-webkit-text-fill-color:currentColor;
}
html:root .fade-rule{background:var(--fpt-blue);height:3px}

/* ── 4. Colour discipline: yellow = #1 / title · live · key CTA. Everything else goes ink / neutral. ── */
/* on photos / dark modules → ink glass */
html:root :is(.fc-badge.show,.fc-badge.comp,.tile-badge,.typ,.b-src.b-yt,.jumbo-ctx,.hf-kick .badge,
  .vc-rank,.lbadge){
  background:var(--pt-glass);color:#fff;border:1px solid var(--pt-glass-line);
}
html:root .fc-play{background:#fff;color:var(--pt-ink)}
html:root .fc-play.pend{background:rgba(255,255,255,.16);color:#e3ebf3}
html:root .jumbo-tag{background:rgba(255,255,255,.12);color:#fff}
/* "Featured athlete" is a label, not a title: white text on glass; only the leading ★ keeps the yellow
   (★ is a text glyph the kit deliberately leaves alone, so ::first-letter is the one handle on it) */
html:root .aotd-ribbon{background:var(--pt-glass);color:#fff;border:1px solid var(--pt-glass-line)}
html:root .aotd-ribbon::first-letter{color:var(--fpt-yellow)}
html:root .bc-flag{background:transparent;color:var(--fpt-blue-300);border:1px solid rgba(126,195,232,.5)}
html:root .bcast-live{background:rgba(255,255,255,.1);color:#fff}   /* "Latest" is not live */
/* directory cards: the rating box is data, not a highlight */
html:root .vcard-img .rating{background:var(--pt-glass);color:#fff;border:1px solid var(--pt-glass-line)}
html:root .vcard-img .rating span{font-size:9.5px;letter-spacing:.06em;color:#d7dee6}
/* selected leaderboard box: selection is blue (interactive), not yellow */
html:root .rbox.on .rbox-ic{background:var(--pt-link);color:#fff}
/* "Recent moves" is a feed, not a live signal: no red pulsing dot */
html:root .live-dot{background:var(--fpt-blue);animation:none;box-shadow:none;width:8px;height:8px}
/* carousel position indicators are navigation, not a highlight: white on dark (ad slides keep a hollow ring) */
html:root :is(.hf-dots i.on,.nh-dots i.on,.jumbo-dots i.on){background:#fff}
html:root .jumbo-dots i.ad{box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.8)}
html:root .jumbo-dots i.ad.on{background:#fff}
html:root[data-page="watch"] .dot.on{background:#fff}
/* Stories Reel: yellow stays on the #1 value and the "#1 · leads" tag; ranks 2–5 and the link go neutral / blue */
html:root .reel-chase .crk{color:rgba(255,255,255,.72)}
html:root .reel-more{color:var(--fpt-blue-300)}
/* the gesture hint: a quiet right-aligned caption, no bounce (it sat on top of "Open full board") */
html:root .reel-hint{left:auto;right:14px;transform:none;animation:none;background:none;border:0;padding:0;
  backdrop-filter:none;-webkit-backdrop-filter:none;font-size:9.5px;letter-spacing:.12em;color:rgba(255,255,255,.62)}
html:root .reel-hint .ar{color:rgba(255,255,255,.62)}
/* events: Open Fleet figures are facts, not #1s */
html:root .of-cell .v{color:#fff}
html:root .lrow .lgo.results{background:var(--pt-ink);color:#fff}   /* (0,4,1): beats the small-blue-text rule */
/* events: season scrubber selection is interactive (blue); card year chips → glass; status pills off the green / yellow */
html:root .scrub-yr.on::after{background:var(--fpt-blue);box-shadow:0 0 0 4px rgba(33,145,210,.24)}
html:root .ecard-yr{background:var(--pt-glass);color:#fff;border:1px solid var(--pt-glass-line)}
html:root .ecard-live.on{background:var(--pt-link);color:#fff;border-color:var(--pt-link)}
html:root .ecard-live.up{background:#fff;color:var(--pt-ink);border-color:#fff}
html:root .livepill.up{background:#fff;color:var(--pt-ink);border-color:#c9cfd6}
html:root .nev-facts a{color:var(--fpt-blue-300)}
html:root .nev-cu{border-radius:6px}
/* standings ticker: the men / women key was brand-blue vs off-palette pink → light blue vs white (key dots follow) */
html:root .tick-item b.m{color:var(--fpt-blue-300)}
html:root .tick-item b.f{color:#fff}
html:root .ticker-key .km{background:var(--fpt-blue-300)}
html:root .ticker-key .kf{background:#fff}
/* Roll of Honour: every card is a champion, so the ×N count is data (neutral); the latest card keeps its yellow edge */
html:root .champ-x{background:var(--pt-neutral);color:var(--pt-neutral-ink)}
html:root .champ-card.latest .champ-yr{color:var(--fpt-ink)}
/* featured-athlete rating sits on a light photo: the grey "RATING" label vanished → white + a soft shadow */
html:root .aotd-rating :is(b,span){text-shadow:0 1px 8px rgba(0,0,0,.55)}
html:root .aotd-rating span{color:rgba(255,255,255,.9);font-weight:700}
/* admin edit affordance: interactive blue, not a yellow sticker */
html:root .fpt-edit{background:var(--pt-link);color:#fff}
/* move: the "preview: saved on this device" note is a caveat, not an accent */
html:root .preview-tag{color:#aab4bf;background:rgba(255,255,255,.05);border-color:rgba(255,255,255,.16)}
/* moves ticker: one signal per item — move names white, the NEW flag a quiet blue outline */
html:root .bc-txt .mv{color:#fff}
/* athlete move standings (dark box): green / amber / salmon rank colours → brand blue tint + white + neutral.
   The two sub-heads colour themselves with inline style="color:…", so only !important can reach them. */
/* athlete: "top" source flags and podium placements are achievements, not #1s → ink chips (yellow stays on #1) */
html:root :is(.src-pill.top,.ce-pl.pod){background:var(--pt-ink);color:#fff;border-color:var(--pt-ink)}
/* moves hub: board ranks / counts on dark go blue-tint / white; discipline tag + like count lose green / red;
   the move-bag "success" key goes to the brand blue tint */
html:root .brk{color:var(--fpt-blue-300)}
html:root :is(#geoChips .chip.on,.m-chip.on){background:var(--pt-link);border-color:var(--pt-link);color:#fff}
html:root[data-page="moves"] .av{background:linear-gradient(135deg,#1a76ad,#155f8c)}   /* was blue→purple */
/* moves hub "neon" cards: the blue→yellow frame + blue glow → one blue edge that fades out, neutral depth;
   gradient-filled play / CTA buttons → solid (white play disc like the home "Watch" buttons; blue CTAs) */
html:root .neon{background:linear-gradient(160deg,#2191d2 0%,rgba(33,145,210,.24) 55%,rgba(255,255,255,.08) 100%);
  box-shadow:var(--pt-shadow-dark)}
html:root .neon:hover{transform:translateY(-2px)}
html:root[data-page="moves"] .play{background:#fff;color:#0a0f18}
html:root :is(.m-deepdive,.gp-cta){background:var(--pt-link);color:#fff;box-shadow:0 10px 24px -14px rgba(0,0,0,.6)}
html:root .gp-n{color:#fff}
html:root .tag.disc{background:var(--pt-neutral);color:var(--pt-neutral-ink)}
html:root .mstatline .lk{color:var(--fpt-ink-2)}
html:root :is(.mb-succ,.mb-key){color:var(--fpt-blue-300)}
html:root .mb-legend i.succ{background:var(--fpt-blue-300)}
/* the same lists on a light surface */
html:root .minilist .mli.good .rk{color:var(--pt-link-deep)}
html:root .minilist .mli.bad .rk{color:var(--pt-muted-2)}
html:root .sig-sug .rk{color:var(--pt-muted-2)}
html:root .wp{border-left-color:var(--fpt-blue-300)}
html:root .wp .rk{color:var(--pt-ink)}
/* on light surfaces → neutral chips */
html:root :is(.lyr,.b-tour.b-on,.techchip,.tut-badge){background:var(--pt-neutral);color:var(--pt-neutral-ink)}
html:root .lrow .lyr{background:rgba(255,255,255,.94);color:var(--pt-ink);border:0}
html:root[data-page="move"] .techchip{background:rgba(255,255,255,.08);color:#fff;border:1px solid var(--pt-glass-line)}
/* events: "Live-scored" was off-palette green; "Upcoming" was yellow */
html:root .lrow .lbadge.on{background:var(--pt-link);color:#fff;border-color:var(--pt-link)}
html:root .lrow .lbadge.up{background:#fff;color:var(--pt-ink);border-color:#fff}
html:root .openfleet .badge{background:transparent;color:var(--fpt-yellow);border:1px solid rgba(252,232,30,.55)}
/* the athlete rating-tier chip: medal fills → one neutral chip; ELITE keeps a yellow edge */
html:root .pc-tier{background:transparent;color:#dfe5ec;border:1px solid rgba(255,255,255,.28)}
html:root .pc-tier.gold{color:var(--fpt-yellow);border-color:rgba(252,232,30,.6)}

/* athlete honours: one chip family; the title mark is a yellow edge + yellow icon, not a rainbow fill */
html:root .hero-titles{
  background:rgba(255,255,255,.07);color:#fff;border:1px solid rgba(255,255,255,.2);font-weight:700;
}
html:root .hero-titles:not(.vice){border-color:rgba(252,232,30,.55)}
html:root .hero-titles:not(.vice) .ico{color:var(--fpt-yellow)}
html:root .hero-titles.vice{color:#d9dee3}

/* news type chips: purple (feature) and olive (announcement) are off-palette */
html:root .tchip{background:var(--fpt-blue-100);color:var(--pt-link-deep)}
html:root .tchip.t-feature{background:var(--fpt-black);color:#fff}
html:root .tchip.t-announcement{background:#fff;color:var(--pt-neutral-ink);box-shadow:inset 0 0 0 1px #c9cfd6}
html:root .tchip.t-digest{background:var(--pt-neutral);color:var(--pt-neutral-ink)}
html:root .tchip.t-event{background:var(--pt-link);color:#fff}
/* news placeholder covers: the purple / olive fills are off-palette → ink with a blue wash */
html:root .ncover-ph{background:linear-gradient(135deg,#19171a,#1c3f5a) !important}   /* !important: page sets per-type fills with inline style */
/* watch: no-thumbnail tiles get a per-kind rainbow hue (inline style) → the same ink/blue placeholder as news */
html:root .tile .grad-art{background:linear-gradient(135deg,#19171a,#1c3f5a) !important}

/* ── 5. AA contrast. White on brand blue #2191d2 is 3.47:1 and blue text on white is 3.47:1 — both FAIL AA
   for small text (the site uses both at 9–14px). Small white-on-blue fills step to #1a76ad (4.95:1); small blue
   text on white does the same; small blue text on the blue-100 tint steps to #155f8c (6.0:1). Large numerals,
   rules, fills behind ink text and anything on the ink surfaces keep the exact brand blue. ── */
html:root :is(.chip.on,.gt.on,.dtab.on,.btab.on,.lbtab.on,.tt-tab.on,.fpt-btn--blue,.p-btn-primary,.slide-cta,
  .fpt-cbar button.on,.hs-tog button.on,.thbtn.on,.fptds .fpt.on,.tabs button[aria-selected="true"],.g-btn,.talk-signin button,
  .vthumb-now,.nad-flag,.ticker-lab,.lb-sub button.on,.mchip.t-report,.mb-veil span):where(:not(.nav *)){background-color:var(--pt-link);border-color:var(--pt-link)}
/* small blue text on LIGHT surfaces only. The dark-surface exclusions sit in  so they add no specificity
   (a :not() chain here reached 0,8,2 and repainted text on dark modules / locked-video overlays). */
html:root :is(.rbox-full,.sec-link,.fpt-lb-row .vl,.fpt-prem,.vcard-go,.champ-yr,.rbox-val,.live-tag,
  .lrow .lgo,td.c-pts,.era-split .col h4,.fpt-btn--ghost,.fpt-eyebrow,.debut .l,.sec-head .kick,.fpt-ulink
  ):where(:not(.nav *):not(.hero *):not(.tt-hero *):not(.aotd-back *):not(.pcard .flip-front *):not(.ctlbar *):not(.mv-locked *):not(.vbig-locked *)){color:var(--pt-link)}
/* the rating card's flip side is white although the card sits in the dark hero */
html:root .pcard .flip-back :is(.era-split .col h4,.fpt-btn--ghost){color:var(--pt-link);border-color:var(--pt-link)}
/* ⚠ keep each :where(:not()…:not()) chain on ONE line — whitespace between two :not()s is a descendant combinator */
html:root .fpt-btn--ghost:where(:not(.nav *):not(.hero *)){border-color:var(--pt-link)}
html:root .champ-card.gap .champ-yr{color:#6b7280}                   /* the COVID gap year stays muted */
/* dark modules: small blue text uses the light tint (#7ec3e8 ≈ 8.9:1 on #19171a) */
html:root .heatbest .big .v span{color:var(--fpt-blue-300)}
html:root .nbox.active .im .typ{background:var(--pt-link);border-color:var(--pt-link)}   /* the active news box keeps its blue state */
html:root :is(.fpt-i,.rankpill:not(.one),.vr-chip.has,.vr-ct,.vthumb-meta b .vt-mv,.v2c .rk,.pc-rankrow .rr .v,.heat .tot){color:var(--pt-link-deep)}
html:root .vr-ct{opacity:1}
html:root .heat .tot.score-lock{color:var(--pt-muted-2)}
html:root :is(.vt-ct,.vt-when,.pc-rankrow .rr .l){color:var(--pt-muted-2)}
html:root .pc-rankrow .rr .l{font-size:10px}
/* !important on opacity only: the unit span carries an inline style="opacity:.6" (2.6:1 at 11px) */
html:root .fpt-lb-row .vl :is(span,.bn){opacity:1 !important;color:var(--pt-muted-2)}
html:root :is(.lmeta .tag,.rbox-ic){color:var(--pt-link-deep)}
/* moves hub: dim slate captions on the ink panels (3.8:1) → #8a94a3; chip counts drop the .7 opacity; the off-tour tag text darkens */
html:root :is(.neon-sub,.geo-note,.rail-count){color:var(--pt-dark-muted)}
html:root .chip .n{opacity:1}
html:root .tag.tour-off{color:var(--pt-muted-2)}
html:root .mchips .tag:not(.tour-off):not(.disc):not(.code){color:var(--pt-link-deep)}   /* the plain "On tour" tag (blue-100) */
/* move-bag squares: landed = blue-700 so the white micro-codes reach 4.95:1; the unlanded codes lift to #8a94a3 */
html:root .mb-sq.on{background:var(--pt-link)}
html:root .mb-sq-c{color:var(--pt-dark-muted)}
html:root .mb-sq.on .mb-sq-c{color:#fff}
html:root .mb-veil span{box-shadow:0 10px 24px -12px rgba(0,0,0,.6)}
/* article hero type chips: same type → colour map as the news grid (feature was purple, announcement yellow) */
html:root .mchip.t-feature{background:#fff;border-color:var(--mv-edge);color:var(--pt-ink)}
html:root .mchip.t-announcement{background:var(--pt-ink);border-color:var(--pt-ink);color:#fff}   /* the head is light since §10: an ink chip */
html:root .hs-tack{color:#6b7280;font-size:10px}
html:root .champ-av.ph{color:var(--pt-muted-2)}
html:root .stars button:not(.on){color:var(--mv-star-off,#5e6a78)}   /* move page: follows its skin token (move.html THE CARD SKIN) */
html:root .lrow.done .lbody{opacity:1}

/* ── 6. Type discipline: labels Poppins 700 (not 800), no text under ~9.5px, tabular figures on data ── */
html:root :is(.chip,.tag,.badge,.pill,.tchip,.rchip,.lbadge,.lyr,.typ,.rtag,.fc-badge,.jumbo-tag,.aotd-ribbon,
  .vc-rank,.bc-flag,.tile-badge,.nad-flag,.rankpill,.pc-tier,.fc-play):not(.nav *){font-weight:700}
html:root :is(.typ,.vthumb-now,.fc-badge,.nad-flag){font-size:10px}
html:root .pc-mini .m .l{font-size:9.5px}
html:root .evpts{font-size:10px;opacity:1;color:var(--pt-muted-2)}
html:root :is(table,.rbox-val,.reel-big,.reel-chase .cval,.pc-rate,.pc-mini .v,.hs-athl .pt,.aotd-stat b,
  .aotd-rating b,.vcard-img .rating b,.champ-yr,.num,.cd b){font-variant-numeric:tabular-nums}

/* ── 7. Floating CTAs (pitch-lib.js .p-float — home only). The round 96px stickers sat top-right over the hero
   ("All news →", the featured athlete's rating / name) and over news titles. Now: ONE docked ink unit, bottom-right,
   two segments (yellow icon on "Host an event" = the one yellow; blue-300 on "Become a partner"), revealed only
   once the hero is half scrolled away. pitch-lib's own .gone (footer in view) still hides it: the reveal animates
   visibility + translate only, never the opacity / transform that .gone sets.
   pitch-lib injects its <style> late, but .p-float a (0,1,1) / .p-float .host (0,2,0) lose to these (0,2,2)+. ── */
html:root .p-float{top:auto;bottom:20px;right:20px;flex-direction:row;gap:0;align-items:stretch;
  background:rgba(20,19,22,.94);border:1px solid rgba(255,255,255,.14);border-radius:8px;overflow:hidden;
  box-shadow:0 14px 32px -16px rgba(0,0,0,.7)}
html:root .p-float a{
  display:block;position:relative;width:auto;height:auto;padding:8px 14px 8px 36px;border:0;border-radius:0;
  background:transparent;color:#fff;font-weight:700;font-size:11.5px;line-height:1.22;text-align:left;box-shadow:none;
}
html:root .p-float a + a{border-left:1px solid rgba(255,255,255,.14)}
html:root .p-float a:hover{transform:none;background:rgba(255,255,255,.07)}
html:root .p-float a:focus-visible{outline:2px solid var(--fpt-blue-300);outline-offset:-3px}
html:root .p-float .ic{position:absolute;left:12px;top:50%;transform:translateY(-50%);font-size:16px;line-height:0;margin:0}
html:root .p-float .host .ic{color:var(--fpt-yellow)}
html:root .p-float .partner .ic{color:var(--fpt-blue-300)}
@media (max-width:900px){
  html:root .p-float{bottom:14px;right:14px}
  html:root .p-float a{padding:7px 11px 7px 31px;font-size:10.5px}
  html:root .p-float .ic{left:10px;font-size:15px}
}
/* reveal after the hero: a view timeline on the home hero, hoisted to <body> so the fixed .p-float can use it.
   No support (Safari / Firefox today) or no .hero → no animation → the unit simply sits docked bottom-right. */
@supports (animation-timeline: view()) and (timeline-scope: --pt-hero){
  html:root[data-page="home"] body{timeline-scope:--pt-hero}
  html:root[data-page="home"] .hero{view-timeline:--pt-hero block}
  html:root[data-page="home"] .p-float{animation:pt-float-in linear both;animation-timeline:--pt-hero;animation-range:exit 50% exit 80%}
  @media (prefers-reduced-motion:reduce){
    html:root[data-page="home"] .p-float{animation-name:pt-float-show}
  }
}
@keyframes pt-float-in{from{visibility:hidden;translate:0 calc(100% + 30px)}to{visibility:visible;translate:0 0}}
@keyframes pt-float-show{from{visibility:hidden}to{visibility:visible}}

/* ── 8. Page fixes that are purely colour ── */
/* move: the now-playing caption sits inside the page's navy player card since 2026-11-10 (move.html THE CARD SKIN),
   so it is light text again (it was dark while the caption sat on the light page) */
html:root[data-page="move"] .vnow-t{color:var(--mv-strong,#fff)}
html:root[data-page="move"] .vnow-m{color:var(--mv-ink-3,#93a9c3)}
html:root[data-page="move"] .vnow-m b{color:var(--mv-ink,#e6eef7)}

/* rankings: cream / peach podium rows + gold-gradient discs → white rows, flat squares; yellow only for #1 */
html:root .rrow.pod1,
html:root .rrow.pod2,
html:root .rrow.pod3{--rowbg:#fff}
html:root .rrow.pod1 td.c-rank{box-shadow:inset 3px 0 0 var(--fpt-yellow)}
html:root .rrow:hover{--rowbg:#f1f6fa}
html:root .rkchip{min-width:30px;height:30px;font-weight:700;box-shadow:none;background:var(--pt-neutral);color:var(--pt-neutral-ink)}
html:root .rkchip.rk1{background:var(--fpt-yellow);color:var(--fpt-black);box-shadow:none}
html:root :is(.rkchip.rk2,.rkchip.rk3){background:#e4e8ec;color:var(--fpt-black);box-shadow:none}
html:root .rkchip.rk0{background:transparent;color:var(--pt-muted-2)}
html:root .pl1{background:var(--fpt-yellow);color:var(--fpt-black)}
html:root :is(.pl2,.pl3){background:#e4e8ec;color:var(--fpt-black)}
html:root .plnr{color:#4b5563}

/* ── 9. Refinement pass (art-director review, 2026-09-25). Theme-only stopgaps for page defects: each block names
   the page-level real fix so the owner can move it into the page and delete the block here. ── */

/* 9a. Home gutter. Every home section is `.wrap.sec`, and home.html's `.sec{padding:64px 0}` (declared after
   `.wrap{padding:0 20px}`) zeroes the gutter, as does `.hero .wrap{padding:20px 0 78px}` — so below the 1180px
   column everything touched the glass (375: kicker, cards and tabs at x=0). Put it back: 20px, 16px on phones.
   Real fix (home.html): `.sec{padding-block:64px}` + `.hero .wrap{padding-block:…}`. */
@media (max-width:1219px){
  html:root[data-page="home"] :is(.hero .wrap,.wrap.sec){padding-left:20px;padding-right:20px}
}
@media (max-width:700px){
  html:root[data-page="home"] :is(.hero .wrap,.wrap.sec,.jumbo-band .wrap){padding-left:16px;padding-right:16px}
  /* the leaderboard reel and the athlete rails stay full-bleed; their bleed matches the restored gutter
     (home.html's own note at the reel rule: "If the section gutter is ever restored, set the negative margin to match it") */
  html:root[data-page="home"] .reel-shell{width:calc(100% + 32px);margin:0 -16px}
  html:root[data-page="home"] .dir-rail{margin-left:-16px;margin-right:-16px;padding-left:16px;padding-right:16px;scroll-padding-inline:16px}
  /* featured athlete: one column, gutter to gutter (it was 340px pinned to the right edge: 35–375) */
  html:root[data-page="home"] .hero-aotd{max-width:none;justify-self:stretch}
}
html:root[data-page="home"] .hero-links a{white-space:nowrap}   /* "All news →" broke onto 3 lines at 375 */

/* 9b. Home "Recent moves": the four small tiles need ~175px of height (avatar + label + title + meta + Watch).
   At 1180px they are 285×160 — fine; at 1024 they were 246×138 and at 375 just 181×102, so the title rode up
   under the avatar and was clipped at the top. Below the full column: big card full width, 2×2 below it
   (tiles ≥323px wide); on phones one column (343×193 at 375). Title max 2 lines, meta 1 line, at every width. */
html:root[data-page="home"] .fc-move{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
html:root[data-page="home"] .fc-who{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@media (max-width:1219px){
  html:root[data-page="home"] .feed{grid-template-columns:minmax(0,1fr)}
  html:root[data-page="home"] .fcard.fc-big{aspect-ratio:21/9;min-height:0}
}
@media (max-width:700px){
  html:root[data-page="home"] .fcard.fc-big{aspect-ratio:auto;min-height:230px}
  html:root[data-page="home"] .fc-right{grid-template-columns:minmax(0,1fr);grid-template-rows:none}
  html:root[data-page="home"] .fc-right .fcard{max-height:240px}
}

/* 9c. Home first view: at most one yellow fill. The spotlight "Watch" matches every other Watch (white);
   a sail number is data, not a #1. (The float unit's yellow is an icon only — §7.) */
html:root .jumbo-watch{background:#fff;color:var(--pt-ink)}
html:root .jumbo-who .sail{color:rgba(255,255,255,.72)}
html:root .jumbo-icon{border-color:#fff}
/* the spotlight banner's dot overlay is the same dot-grid decoration §3 turns off elsewhere */
html:root .jumbo::after{background-image:none}
/* the round ‹ sat on the headline's first letter ("‹ow-In Spock"): inset the copy past both arrows (≥641px,
   where the arrows show). Real fix (home.html): `.jumbo-in{padding-inline:62px}` or arrows beside the dots. */
@media (min-width:641px){
  html:root[data-page="home"] .jumbo-in{padding-left:62px;padding-right:62px}
}
/* featured athlete with no nation on file: FPT.flag('') renders a white 🏳️ + an empty sail span. In the roster
   nation_code is set exactly when the nation NAME is (106/106, 2026-09-25), so "no ·nation span after the sail"
   = no flag. Real fix (home.html): render no .fl / .sail when the value is empty. */
html:root[data-page="home"] .aotd-sub:not(:has(> .sail + span)) > .fl,
html:root[data-page="home"] .aotd-sub > .sail:empty{display:none}

/* 9d. Leaderboard #1 card (app.css .fpt-lb-one — every board app.js builds: move page, home / athlete full-board modals): the blue→yellow
   fade read as an olive wash with dark text across it. Ink card, white type, a yellow edge + yellow trophy. */
html:root .fpt-lb-one{background:var(--pt-ink);color:#fff;box-shadow:inset 3px 0 0 var(--fpt-yellow)}
html:root .fpt-lb-one :is(.fpt-lb-1name,.fpt-lb-1val){color:#fff}
html:root .fpt-lb-one .fpt-lb-1val span{opacity:1;color:#c3cad2}          /* unit label: 11.6:1 on ink */
html:root .fpt-lb-one .fpt-lb-pct{color:var(--pt-dark-muted)}
html:root .fpt-lb-one .fpt-lb-medal{color:var(--fpt-yellow)}
html:root .fpt-lb-one img{border-width:2px}
html:root .fpt-lb-one .fpt-lb-ph{background:#2a282d;border:2px solid #fff}

/* 9e. (removed 2026-11-11) the move page's old .rate-acts / .heart / .rate-note markup is gone: RATE · LIKE · SICK is styled in move.html */

/* (9f, the text-shadow stopgap that flattened the colour emoji left in the events next-event meta and the move
   page's tutorial slot, is gone: both now draw line icons from icons.svg in the markup — its named real fix.) */

/* 9g. Athlete page, the yellow rule: points ranges, discipline win-rates and "View full … →" links are data /
   navigation, not #1s. All three sit on ink. */
html:root .disc .top .pct{color:rgba(255,255,255,.78)}
html:root .pos .cta{color:var(--fpt-blue-300)}
/* "Where it began": kicker · value · caption are three inline spans, so they ran together
   ("CAREER START2010 · EFPT overall #50European…"). Stack them. Real fix: the same three lines in athlete.html's .debut CSS. */
html:root .debut{text-align:left}
html:root .debut > span:not(.ic) > :is(.l,.v,.d){display:block}
html:root .debut .d{margin-top:2px}
/* move bag: the animated wave (off-palette #22c8e8 cyan) under "68 / 251 landed" read as a stray blue sliver */
html:root .tl-wavehead .wv{display:none}
html:root .tl-wavehead{padding:0;border-radius:0}

/* 9h. Events list thumbnails: the scrapbook look (torn-paper edge, halftone strip, cropped poster lettering) is
   BAKED INTO the cover art — tour posters, not photos: logo panel + torn edge on the left, the photo on the right
   inside a coloured frame with a star badge and a series label (and "Event confirmed!" on the 16:9 one). Frame just
   the photo: each template gets a crop window (x0–x1, y0–y1 as fractions of the poster, r = height / width) and the
   poster is scaled so that window covers the thumbnail box, at 230×172 and at the full-width phone layout alike.
   Real photos (surf-festival, Podersdorf banner) are untouched. Real fix: event PHOTOS as covers in the data. */
html:root[data-page="events"] .lrow .limg > img:is([src*="FPT-Event-Header"],[src*="brouwersdam-2026-cover"]){
  --pt-pw:max(calc(100cqw / (var(--x1) - var(--x0))),calc(100cqh / ((var(--y1) - var(--y0)) * var(--r))));   /* rendered poster width */
  inset:auto;width:var(--pt-pw);height:auto;max-width:none;object-fit:fill;
  left:calc(50% - var(--pt-pw) * (var(--x0) + var(--x1)) / 2);
  top:calc(50% - var(--pt-pw) * var(--r) * (var(--y0) + var(--y1)) / 2);
  /* offsets use % (the abs-pos containing block is always sized): on the phone layout the box height comes from
     min-height alone and Chrome resolves cqh to 0 there — harmless, the width term decides on phones */
}
html:root[data-page="events"] .lrow .limg:has(> img:is([src*="FPT-Event-Header"],[src*="brouwersdam-2026-cover"])){container-type:size;overflow:hidden}
/* 2026 event headers, 1440×556 (8 cards) */
html:root[data-page="events"] .lrow .limg > img[src*="FPT-Event-Header"]{--x0:.47;--x1:.90;--y0:.05;--y1:.86;--r:.3861}
/* ONE-OFF: the Brouwersdam "Event confirmed!" post, 2000×1125 — the only hand-placed cover (public/assets/img/events/) */
html:root[data-page="events"] .lrow .limg > img[src*="brouwersdam-2026-cover"]{--x0:.48;--x1:.97;--y0:.27;--y1:.87;--r:.5625}
/* next-event card: with no e.cover the page draws an SVG placeholder with the venue name baked in, under the badge
   and repeated right beside it. Show a flat ink cover with the FPT mark instead; the badge moves bottom-left.
   Real fix (events.html + data): a real event photo as the cover (ED[id].cover is the poster above today). */
html:root[data-page="events"] .nev-cov > img[src^="data:"]{display:none}
html:root[data-page="events"] .nev-cov:has(> img[src^="data:"]){
  background:url("../_brand/logos/web/fpt-logo-white-480.png") center/auto 42px no-repeat,
    radial-gradient(420px 220px at 88% -10%,rgba(33,144,210,.32),transparent 62%),var(--pt-ink)}
html:root .nev-badge{top:auto;bottom:12px;left:12px}

/* 9i. (Footer word-mark rule folded into site-footer.js 2026-11-12, when the IWA logo arrived.) */

/* ── 10. CRISP DAYLIGHT — the site's look since 2026-11-11 (Adam: "4b 4 - crisp is the one, roll this out across the
   whole site, all parts of it"). Chosen on the real move page and landing page from five rounds of review skins
   (git: ef436e3, cd354c3, 653b38e); this section is that look, shipped. What it is:
     • one pale, cool backdrop behind every page (it stays put while the page scrolls), white at the foot
     • every panel a solid white card: a hairline, 10px corners, one quiet shadow. No dark data panels.
     • no dark title bands: a page's head sits on the backdrop in ink. Pictures, video and the header / footer stay dark.
     • deep brand blue #155f8c for links, kickers and buttons (yellow on hover); yellow as a marker under section
       headlines and for #1 / live, never as text on white
     • READABLE BY RULE: dark text on light, every piece of text at least 4.5:1 against the lightest and darkest
       background it can sit on, nothing under 11px. Measured on the rendered pages (docs/CRISP-ROLLOUT-2026-11-11.md).
   The --mv-* tokens began as the move page's card skin and are now the look's tokens for every page (the name is
   history; renaming them is a mechanical follow-up). Sections 1–9 above still apply; where this section disagrees
   with them, it is later in the file and wins. ── */
html:root{
  --mv-page:linear-gradient(180deg,#edf1f5 0%,#f6f8fa 40%,#fff 100%);
  --mv-bg:#fff; --mv-line:#d8dfe7; --mv-r:10px; --mv-band:rgba(255,255,255,.7);
  --mv-shadow:0 1px 2px rgba(20,19,22,.05),0 14px 28px -24px rgba(20,19,22,.4);
  --mv-shadow-sm:0 1px 2px rgba(16,40,60,.1),0 10px 20px -14px rgba(16,40,60,.5);   /* a small card: the big shadow's spread hides it */
  --mv-bar-h:0px; --mv-glow:none;

  --mv-strong:#141316; --mv-ink:#24272c; --mv-ink-2:#343a42; --mv-ink-3:#4d5660; --mv-ink-4:#5f6872;
  --mv-link:#155f8c; --mv-link-sky:#0e4668; --mv-kick:#155f8c;            /* -sky: a link straight on the backdrop, not on a card */
  --mv-edge:#c3ced9;                                                      /* the line round a control */
  --mv-line-2:#e3e7ec; --mv-well:#f4f6f9; --mv-well-2:#eceff3;
  --mv-field:#fff; --mv-field-ink:#141316; --mv-scroll:#b9c1ca;
  --mv-chip:#fff; --mv-chip-on:#e3f1fb; --mv-chip-on-ink:#114f75;
  --mv-av:#141316; --mv-av-ink:#fff;
  --mv-btn:#155f8c; --mv-btn-ink:#fff; --mv-btn-hover:var(--fpt-yellow); --mv-btn-hover-ink:#141316; --mv-on-acc:#fff;
  --mv-star-off:#fff; --mv-star-on:#fce81e; --mv-star-edge:#141316;       /* outlined stars, yellow when lit */
  --mv-like:#b8123a; --mv-sick:#141316; --mv-down:#141316; --mv-money:#141316;
  --mv-gold:#5c4700; --mv-gold-line:#d9c043; --mv-gold-well:#fff8cc;       /* a funded bounty: amber ink on a pale yellow well */
  --mv-track:rgba(20,19,22,.1); --mv-track-2:rgba(20,19,22,.17); --mv-tick:rgba(20,19,22,.36); --mv-mark:#141316;
  --mv-dot:#fff; --mv-wick:#4d5660;
  --mv-marker:linear-gradient(transparent 58%,#fce81e 58%,#fce81e 92%,transparent 92%);   /* the yellow stroke under a section headline (also pitch.css) */
  --mv-one:#141316; --mv-one-line:#141316; --mv-one-ink:#fff;             /* the #1 row: an ink card */
  /* the head: a page's title block, the landing page's hero. It is just the backdrop, in ink. */
  --mv-head:transparent; --mv-head-ink:#141316; --mv-head-ink-2:#3d4650;
  --mv-head-kick:#155f8c; --mv-head-unit:#155f8c; --mv-head-link:#155f8c;
}
html:root body{background:var(--mv-page);background-attachment:fixed}
/* the yellow marker under section headlines (ink on yellow, ink on white: both read) */
html:root :is(.mv-sh h2,.sec-head h2){
  display:inline;padding:0 .14em;-webkit-box-decoration-break:clone;box-decoration-break:clone;
  background:var(--mv-marker)}

/* 10c · title bands: every page's head sits on the backdrop, in ink (no dark band, no glow). A head that is a
   picture keeps its own surface and is handled with its page below. */
html:root :is(.ehero,.nhero,.ahero,.tt-hero){background:var(--mv-head);color:var(--mv-head-ink)}
html:root :is(.ehero,.nhero,.ahero,.tt-hero)::before{display:none}
html:root :is(.ehero,.nhero,.ahero,.tt-hero) .eb{color:var(--mv-head-kick)}
html:root :is(.ehero,.nhero,.ahero,.tt-hero) :is(p,.cnt,.sub){color:var(--mv-head-ink-2)}

/* 10d · what stood on those dark heads: chips, crumbs, toggles become white chips with ink text */
html:root :is(.hchip,.mchip:not([class*="t-"]),.ahero .rchip,.chips button:not([aria-pressed="true"]):not(.on)){
  background:#fff;border-color:var(--mv-edge);color:var(--mv-ink-2)}
html:root .chips button[aria-pressed="true"]{background:var(--mv-btn);border-color:var(--mv-btn);color:var(--mv-btn-ink)}
html:root .chips .n{opacity:1}
html:root :is(.hchip b,.ahero .rchip .fpt-name){color:var(--mv-strong)}
html:root .crumb{color:var(--mv-link-sky)}
html:root .crumb:hover{color:var(--mv-strong)}
html:root .ahero::after{display:none}
html:root .ahero-bg{display:none}                        /* the blurred cover behind an article's title */
html:root .slab{color:var(--mv-ink-2)}
html:root .hsearch{background:var(--mv-field);border-color:var(--mv-edge);color:var(--mv-ink-3)}   /* the search field in a head (news) */
html:root .hsearch:focus-within{background:var(--mv-field);border-color:var(--mv-link)}
html:root .hsearch input{color:var(--mv-field-ink)}
html:root .hsearch input::placeholder{color:var(--mv-ink-3)}
html:root .fptds{background:#fff;border-color:var(--mv-edge)}
html:root .fptds button:not(.on){color:var(--mv-ink-2)}

/* 10e · text links and labels that were brand blue #2191d2 (3.3:1 on this backdrop) or a pale grey */
html:root :is(.nad-cta){color:var(--mv-link)}
html:root[data-page="rankings"] .evq{opacity:1;color:var(--mv-ink-3)}
html:root[data-page="rankings"] .c-ev .dot{color:var(--mv-ink-4)}
html:root[data-page="rankings"] .ctrl-row input::placeholder{color:var(--mv-ink-3);opacity:1}

/* 10f · nothing under 11px (labels that were 9.5–10.5px) */
html:root :is(.thbtn,.thbtn .arr,th.plain,.evq,.evpts,.tchip,.nad-flag,.rcard-type,.prv .lab,
  .nev-cu i,.badge,.lbadge,.lmeta .tag,.lnums .l):not(.nav *){font-size:11px}

/* 10h · the world map (map-lib.js, on events and the moves hub; its CSS is injected at runtime, after this file, so
   these rules carry html:root to outweigh it): drawn in deep blue on the backdrop, pins in yellow with an ink edge,
   no neon glow */
html:root .emap{background:transparent}
html:root .emap-land .wl-glow{display:none}
html:root .emap-land .wl-line{stroke:#155f8c;opacity:.6}
html:root .emap-routes polyline{stroke:#141316;opacity:.28;filter:none}
html:root .emap-evt .evt-halo{opacity:.55;filter:none}
html:root .emap-evt .evt-dot{stroke:#141316;stroke-width:.9}
html:root .emap-evt:is(:hover,.on) .evt-dot{fill:#141316}
html:root .spot-ring{stroke:#141316;filter:none}
html:root .emap-callout text{fill:#141316;stroke:#fff}
html:root .emap-callout .co-date{fill:#343a42}
html:root .emap-tag{color:var(--mv-head-ink-2)}

/* 10g · events: the standings ticker, the timeline, the next-event card's back and the Open Fleet panel were dark
   data panels. They are white cards now; yellow and pale-blue figures become ink / deep blue. */
html:root[data-page="events"]{
  .ticker{background:#fff;border-bottom-color:var(--mv-line)}
  .ticker-key{background:linear-gradient(90deg,transparent,#fff 26%)}
  .ticker-key span{color:var(--mv-ink-2);font-size:11px}
  .tick-item{color:var(--mv-ink)}
  .tick-item b{color:var(--mv-strong)} .tick-item b.m{color:#155f8c} .tick-item b.f{color:#b01561}
  .ticker-key .km{background:#155f8c} .ticker-key .kf{background:#b01561}
  .scrub{background:#fff;border:1px solid var(--mv-line);box-shadow:var(--mv-shadow);color:var(--mv-strong)}
  .scrub-yr{color:var(--mv-ink-3)}
  .scrub-yr:hover,.scrub-yr.on{color:var(--mv-strong)}
  .scrub-yr::after{background:var(--mv-edge)}
  .scrub-yr.on::after{background:var(--fpt-yellow);box-shadow:0 0 0 2px var(--mv-strong)}
  .scrub-rail{background:var(--mv-line)}
  .scrub-chips .chip{background:#fff;color:var(--mv-ink-2);border-color:var(--mv-edge)}
  .scrub-chips .chip.on{background:var(--mv-btn);border-color:var(--mv-btn);color:var(--mv-btn-ink)}
  .scrub-count{color:var(--mv-ink-3)}
  .nev-cu b{color:var(--mv-link)}
  .nev-back{background:#fff;color:var(--mv-strong)}
  .nev-back .eb{color:var(--mv-kick)}
  .nev-back li b{color:var(--mv-ink-3)}
  .openfleet .badge{background:var(--fpt-yellow);border-color:transparent;color:#141316}
  .lch b.m{color:#155f8c}
  .openfleet{background:#fff;border:1px solid var(--mv-line);box-shadow:var(--mv-shadow);color:var(--mv-strong)}
  .openfleet p,.of-cell .l{color:var(--mv-ink-2)}
  .of-cell{background:var(--mv-well);border-color:var(--mv-line-2)}
  .of-cell .v{color:var(--mv-strong)}
}

/* 10i · the athlete profile. The hero stays a photo card and the trading card stays a card; every data panel that
   was dark (rank boxes, the feature tile, discipline heads, the signature move) is a white card. */
html:root[data-page="athlete"]{
  :is(.pos,.v2-feat,.sig-main){background:#fff;border:1px solid var(--mv-line);box-shadow:var(--mv-shadow);color:var(--mv-strong)}
  :is(.pos,.v2-feat,.sig-main) .hatch{display:none}
  .disc .top{background:var(--mv-well-2);color:var(--mv-strong)}
  /* what was pale blue / yellow / grey for the dark panels, in ink and deep blue */
  :is(.pos .pl,.pv .hash,.pos .cta,.cell .v,.v2-feat .l,.v2-feat .v,.lbl b,.big .l,.big .v,.big .v span,.ev-year h3){color:var(--mv-link)}
  :is(.pos .po,.v2-feat .e,.smeta div,.big .e,.ps div){color:var(--mv-ink-2)}
  :is(.top .pct,.sig-main .sl,.smeta b,.ps b){color:var(--mv-strong)}
  .v2-feat .cta{color:var(--mv-ink-3)}
  .section a,.big .v span{opacity:1}
  :is(.pl .fpt-i,.sec-head .fpt-i,.cell .l,.v2-feat .cta,.v2c .rk,.v2c .l,.l .fpt-i,.v2c .s,.t-lab .fpt-i,.sig-card .mt,.tg-cov .typ,
    .tg-social .lab,.nm .hs-tack,.src-chart .src-cap,.src-cap b,.ev-year .src-pill,.debut .l,.hero-sponsors .lab,
    .m .l,.rr .l,h3 .fpt-i,.mt .typ,.ov .ttl){font-size:11px}
}
html:root .sec-head .kicker{color:var(--mv-kick)}

/* 10j · watch: the page was black from edge to edge. The stage and the tiles are video, so they stay dark; the page
   around them, the rail titles and the search field join the backdrop. */
html:root[data-page="watch"]{
  .rail-title{color:var(--mv-strong)}
  :is(.rail-sub,.rail-count){color:var(--mv-ink-3)}
  .rail-title .ic{color:var(--mv-link)}
  .wsearch{background:var(--mv-field);border-color:var(--mv-edge)}
  .wsearch input{color:var(--mv-field-ink)}
  .wsearch input::placeholder{color:var(--mv-ink-3)}
  .tile-badge{font-size:11px}
}

/* 10k · the moves hub: its dark bands (map, move bag) and dark boards are the backdrop and white cards. Clip cards
   keep their pictures. The head (the picture stage, its stats and ticker) is written in this look's tokens in
   moves.html itself and needs nothing here. */
html:root[data-page="moves"]{
  .band{background:transparent;color:var(--mv-strong)}                      /* the map and move-bag bands lost their inline dark styles in moves.html */
  :is(.board,.geo-panel,.neon .neon-in){background:#fff;border:1px solid var(--mv-line);box-shadow:var(--mv-shadow);color:var(--mv-strong)}
  :is(.geo-search,.mb-find){background:var(--mv-field);border-color:var(--mv-edge);color:var(--mv-field-ink)}
  .band h2{color:var(--mv-strong)}
  /* the move bag: a grid of squares, landed = deep blue, not landed = pale. (Its compact view prints 7px codes inside
     tiny squares, a mosaic; "Show names" is the readable view, and that one follows the 11px rule.) */
  .mb-sq{background:var(--mv-well-2)}
  .mb-sq.on{background:var(--mv-btn)}
  .mb-sq-c{color:var(--mv-ink-3)}
  .mb-sq.on .mb-sq-c{color:#fff}
  .mb-cell{background:#fff;border-color:var(--mv-line)}
  .mb-square.names .mb-sq-n{color:var(--mv-strong)}
  .mb-square.names .mb-sq:is(.on,.funded) .mb-sq-n{color:#fff}
  .mb-square.names .mb-sq-c{color:var(--mv-ink-3);font-size:11px}
  .mb-square.names .mb-sq.on .mb-sq-c{color:#e3f1fb}
  .mb-square.names .mb-sq-f{font-size:11px}
  .mb-veil{background:linear-gradient(180deg,rgba(255,255,255,0),rgba(255,255,255,.96) 78%)}
  .mb-legend i.on{background:var(--mv-btn)}                              /* the legend's swatches follow the squares */
  .mb-legend i.off{background:var(--mv-well-2);box-shadow:inset 0 0 0 1px var(--mv-edge)}
  :is(.sec-head .kick,.sec-head .mb-prog){color:var(--mv-kick)}
  :is(.sec-head p,.sec-head b,#geoChips .chip:not(.on),#geoChips .chip:not(.on) .n,.mb-view .mbtab:not(.on),.mb-legend span){color:var(--mv-ink-2)}
  :is(#mbProg b,.mb-legend .mb-key,.mb-legend .mb-gate){color:var(--mv-link)}
  #publicRows .empty{color:var(--mv-ink-2)}
  .gp-close{color:var(--mv-strong)}
  :is(.geo-search,.tb-search,.mb-tools) input{color:var(--mv-field-ink)}          /* what a person types, and the hint before they do */
  :is(.geo-search,.tb-search,.mb-tools) input::placeholder{color:var(--mv-ink-3);opacity:1}
  :is(.neon .neon-in .neon-move,.min0 .neon-name,
    .min0 .bname,.brow .bval,.gp-kick,.gp-title,.min0 .gp-mv,.gp-row .gp-n){color:var(--mv-strong)}
  :is(.wrap p,.board .sub,.board-tabs .btab:not(.on),#publicRows .empty){color:var(--mv-ink-2)}
  :is(.neon-foot .mini,.mini .lk,.brow .brk){color:var(--mv-link)}
  :is(.min0 .neon-sub,.min0 .bsub,.bval small,.gp-sub,.min0 .gp-riders){color:var(--mv-ink-3)}
  :is(.badge-row .b-src,.badge-row .b-tour,.gp-kick,.av .av-ini,.mchips .tag){font-size:11px}
}

/* 10l · NOT converted, on purpose: the live scores page keeps its broadcast look (live.css, chosen 2026-10-09). It
   has no sample mode, so a light version cannot be checked without a running heat, and a live event is the worst
   place to find unreadable text. It keeps its own dark page; converting it = re-valuing the tokens at the top of
   live.css against a real or recorded heat. */
html:root[data-page="live"] body{background:#0d0c0e}
/* (The two commercial pages, host-an-event and partners, were converted the same evening: their values are the
   tokens at the top of pitch.css, which follow this section's.) */

/* 10m · small pages */
html:root .cs{background:var(--mv-head);color:var(--mv-head-ink)}          /* "coming soon" (games, fantasy) */
html:root .cs::after{display:none}
html:root .cs p{color:var(--mv-head-ink-2)}
html:root .cs .eb{color:var(--mv-head-kick)}
html:root .cs .row .btn{color:var(--mv-strong);border-color:var(--mv-edge);background:#fff}
html:root[data-page="nor"] .cta .btn{color:var(--mv-link)}
html:root #si .si-eb{color:var(--mv-kick)}                                   /* sign-in */

/* 10n · the bracket viewer and the heat-score leaderboards: their dark toolbars become white strips */
html:root[data-page="brackets"]{
  header.brtool{background:#fff;color:var(--mv-strong);border-bottom:1px solid var(--mv-line)}
  .tabs{background:var(--mv-well)}
  .tabs button{color:var(--mv-ink-2)}
  .tabs button.on{color:var(--mv-strong)}
  .legend{background:#fff;color:var(--mv-ink-2);border-bottom:1px solid var(--mv-line-2)}
  .seg button:not(.on){background:var(--mv-well-2);color:var(--mv-ink-2)}
  .seg button.on{background:var(--mv-btn);color:var(--mv-btn-ink)}
  .htop .sub{color:var(--mv-ink-2)}
  .tools .switchbtn{color:var(--mv-strong)}
  .legend span{color:var(--mv-ink-3)}
}
html:root[data-page="heat-leaderboards"]{
  .topbar{background:var(--mv-head);color:var(--mv-head-ink)}
  .topbar h1{color:var(--mv-head-ink)}
  .topbar .sub{color:var(--mv-head-ink-2)}
  :is(.rule b,.row-h .metric){color:var(--mv-link)}
  #sortseg button:not([aria-pressed="true"]){color:var(--mv-strong)}
  #sortseg button[aria-pressed="true"]{background:var(--mv-btn);border-color:var(--mv-btn);color:var(--mv-btn-ink)}
  :is(.metric small,.badges .b){font-size:11px}
}

/* 10o · pages that do not ship in the public build but read this file (staff tools and labs, opened through the
   Hub). The two with a title band follow the heads rule; the card lab keeps its own dark page. */
html:root[data-page="roadmap"]{
  #summ .n{color:var(--mv-link)}
  #summ .l{color:var(--mv-ink-2)}
  #filters .fbtn.on{color:var(--mv-strong)}
  :is(.item .st,.main .t,.main .d){opacity:1}
  .item .st{font-size:11px}
}
html:root[data-page="top-trumps"]{
  .tt-hero h1 .ac{color:var(--mv-link)}
  .tt-tabs .tt-tab:not(.on){color:var(--mv-ink-2)}
  .mode-btn :is(b,small){opacity:1}
}
html:root[data-page="card-review"] body{background:#111013}              /* the trading-card style lab: a dark review page, left as built */

/* 10a · the move page (weights as approved: html:root[data-page] … is (0,3,1), where the review rules sat) */
html:root[data-page="move"]{
  /* the small text a size up (nothing under 11 px), and one button rule */
  .talk-txt{font-size:14px} .talk-who{font-size:13.5px} .talk-when{font-size:11.5px} .talk-act{font-size:12px} .talk-held{font-size:11px}
  .rx-l{font-size:11px} .rx-avg{font-size:12.5px} .mv-card-h{font-size:11.5px} .preview-chip{font-size:11px}
  .talk-tabs button{font-size:11.5px;color:var(--mv-ink-2)} .talk-tabs button.on{color:var(--mv-btn-ink)} .talk-av{font-size:11.5px}
  .num-q{font-size:11.5px} .num-a .u{font-size:13.5px} .num-leg{font-size:12px} .num-scale{font-size:11px} .num-ctx{font-size:13.5px}
  .num-about{font-size:13px} .vnow-m{font-size:13.5px} .vbig-date{font-size:13px}
  .vthumb-meta i,.vt-when,.vt-ct{font-size:12px} .vr-note{font-size:12.5px}
  .fact .l{font-size:12px} .pendnote{font-size:13px}
  #boards .lbcol .sub{font-size:13px} #boards .fpt-lb-row .vl .bn{font-size:11.5px} #boards .bwin{font-size:13px}
  #years .fpt-card .sub{font-size:13px!important} #years .myc-cap-txt{font-size:13px} #years .myc-legend{font-size:13px}
  .bounty-none{font-size:13.5px}
  .vthumb-now,.lbtab .badge{font-size:11px} main .fpt-i{font-size:11.5px}
  .bounty-btn{background:var(--mv-btn);color:var(--mv-btn-ink);border-color:transparent}
  .bounty-btn:hover,.bounty-btn:focus-visible{background:var(--mv-btn-hover);color:var(--mv-btn-hover-ink)}
  .talk-form textarea::placeholder,.talk-rbox textarea::placeholder{color:var(--mv-ink-4);opacity:1}
  .talk-send:disabled{opacity:1;background:var(--mv-well-2);color:var(--mv-ink-3);border-color:var(--mv-edge)}   /* idle, still legible */
  .vt-score{font-size:11.5px} .vt-score em{font-size:11px}

  /* the head band */
  .wrap:has(> .fade-rule){display:none}
  .mhead{background:var(--mv-head);color:var(--mv-head-ink)}
  .mhead h1,.fact .n,.pendnote b{color:var(--mv-head-ink)}
  .mhead .eyebrow{color:var(--mv-head-kick);font-size:11.5px}
  .fact .n .unit{color:var(--mv-head-unit);font-size:13px}
  :is(.fact .l,.pendnote){color:var(--mv-head-ink-2)}
  .fact.freq .n{color:var(--mv-head-link)}
  .famchip{background:#fff;color:#114f75;border-color:#9fcdea}
  .sigchip{background:#fff8cc;color:#4a3d00;border-color:#e6d15c} .sigchip a{color:#141316}

  /* cards */
  .vthumb{border-radius:calc(var(--mv-r) * .8);background:var(--mv-bg);box-shadow:var(--mv-shadow)}
  .vbig-frame,#boards .fpt-lb-one,.talk-form textarea,.talk-fake,.talk-send{border-radius:calc(var(--mv-r) * .7)}
  .mv-player{padding:14px 14px 16px}
  .talk-more:hover{border-color:var(--mv-link)}
  .mv-sh .kicker{color:var(--mv-kick);font-size:11.5px}
  .vr-note,.vr-more,.num-about,.bnote{color:#2f353d}
  .rx-btn.sick.on svg{fill:var(--fpt-yellow);stroke:#141316}
  .preview-chip{color:#5c4700;background:#fff8cc;border-color:#d9c043}
  .lbtab:not(.on){background:rgba(255,255,255,.8)}
  .tut-slot{background:var(--mv-well)}

  /* accents that read on white (the dark-card values are too pale there); yellow becomes ink */
  .num-card.a-blue{--acc:#155f8c} .num-card.a-yellow{--acc:#141316} .num-card.a-green{--acc:#087a51}
  .num-card.a-violet{--acc:#5a48c4} .num-card.a-pink{--acc:#c2255c} .num-card.a-cyan{--acc:#0b6f92}
  #boards .lbcol:nth-child(2) .fpt-card{--acc:#5a48c4} #boards .lbcol:nth-child(3) .fpt-card{--acc:#087a51}
  #years .fpt-card,#years .vnone{--acc:#0b6f92}
  #years .myc-avg{stroke:#141316}
  .techchip{background:#141316;color:#fff;border-color:#141316}
  /* the landing page's section headline: sentence case, large, the kicker above it */
  .mv-sh{flex-direction:column;align-items:flex-start;gap:5px;margin-bottom:16px}
  .mv-sh h2{text-transform:none;font-size:clamp(24px,3.2vw,36px);letter-spacing:-.02em;line-height:1.08}
  .mv-sh .kicker{display:flex;align-items:center;gap:8px}
}

/* 10b · the landing page. Its photo cards (the hero story, the featured athlete, the spotlight, the news lead, the
   move cards, the reel, the ads) keep their pictures and their white-on-photo text; only corners, rim and shadow join in. */
html:root[data-page="home"]{
  :is(.hero,.jumbo-band,.news-band,.feed-band,.champ-band,#boards,#directory){--fpt-muted:var(--mv-ink-3)}
  .news-band{background:transparent}
  :is(.feed-band,.champ-band){background:var(--mv-band);border-color:rgba(255,255,255,.75)}

  /* the head band = the hero */
  .hero{background:var(--mv-head);color:var(--mv-head-ink)}
  .hero .eb{color:var(--mv-head-kick)}
  .hero-links a:hover{color:var(--mv-head-ink)}
  :is(.hfeat,.aotd-face,.jumbo,.news-hero,.reel-shell,.fpta){border-radius:var(--mv-r)}
  :is(.hfeat,.aotd-face,.jumbo,.news-hero,.reel-shell){box-shadow:var(--mv-shadow)}
  .fcard{border-radius:calc(var(--mv-r) * .8);border-color:var(--mv-line);box-shadow:var(--mv-shadow)}

  /* section heads sit on the sky */
  .sec-head h2,.dir-row-head h3{color:var(--mv-strong)}
  :is(.fpt-eyebrow,.live-tag):not(.eb){color:var(--mv-kick)}
  :is(.vcard-go,.rbox-full,.rbox-val,.champ-yr){color:var(--mv-link)}
  .champ-card.gap .champ-yr{color:var(--mv-ink-3)}
  .sec-link{color:var(--mv-link-sky)}
  .champ-most,.champ-card.gap .champ-who{color:var(--mv-ink-3)}
  .champ-x{font-size:11px}

  /* cards */
  :is(.nbox,.rbox,.vcard,.champ-card:not(.gap),.rail-arrow,.dir-ac){
    background:var(--mv-bg);border-color:var(--mv-line);box-shadow:var(--mv-shadow);}
  :is(.nbox,.rbox,.vcard,.champ-card,.dir-ac){border-radius:calc(var(--mv-r) * .7)}
  :is(.rbox,.champ-card:not(.gap)){box-shadow:var(--mv-shadow-sm);border-color:color-mix(in srgb,var(--mv-edge) 60%,transparent)}
  :is(.nbox.active,.rbox.on){border-color:var(--mv-link);box-shadow:0 0 0 3px rgba(21,95,140,.2),var(--mv-shadow-sm)}
  .champ-card.latest{border-color:#141316}
  .champ-card.gap{border-color:var(--mv-edge)}
  .rbox-foot{border-top-color:var(--mv-edge)}
  .rbox.on .rbox-ic{background:var(--fpt-yellow);color:#141316}

  /* controls */
  .gt{background:var(--mv-chip);border-color:var(--mv-edge);color:var(--mv-strong)}
  .gt:hover{border-color:var(--mv-link)}
  .gt.on{background:var(--mv-btn);border-color:var(--mv-btn);color:var(--mv-btn-ink)}
  #dirSearch{background:var(--mv-field);border-color:var(--mv-edge);color:var(--mv-field-ink);border-radius:calc(var(--mv-r) * .7)}
  #dirSearch::placeholder{color:var(--mv-ink-3);opacity:1}
  .hero::before,.hero-dots{display:none}
  .hero-links a{color:var(--mv-link-sky)}
  :is(.hfeat,.aotd-face){border-color:var(--mv-line)}
  /* the standings strip: a white card like the rest */
   /* B2 keeps the strip as it is today */
  .hstrip{background:var(--mv-bg);border-color:var(--mv-line);border-radius:var(--mv-r);box-shadow:var(--mv-shadow);}
  .hstrip .hs-lab{background:var(--mv-well);border-color:var(--mv-line-2)}
  .hstrip .hs-lab .t{color:var(--mv-strong)}
  .hstrip .hs-lab .y{color:var(--mv-kick);font-size:11px}
  .hstrip .hs-tog button{border-color:var(--mv-edge);color:var(--mv-ink-2);font-size:11px}
  .hstrip .hs-tog button.on{background:var(--mv-btn);border-color:var(--mv-btn);color:var(--mv-btn-ink)}
  .hs-athl{color:var(--mv-strong);border-color:var(--mv-line-2)}
  .hs-athl:hover,.hstrip .hs-more:hover{background:var(--mv-well-2);color:var(--mv-strong)}
  .hs-athl .rk{color:var(--mv-ink-3)} .hs-athl.top .rk{color:var(--mv-strong)}
  .hs-athl .who .pt{color:var(--mv-link);font-size:11px}
  .hstrip .hs-more{color:var(--mv-link);border-color:var(--mv-line-2)}
}
