@tailwind base;
@tailwind components;
@tailwind utilities;

/* ShredFast — V6 Premium token system (ported verbatim from
   artefacts/design-systems/shredfast/redesign-mockups/ShredFast-V6-Home-Premium.html :root).
   Quiet authority: green-tinted neutral ladder, elevation by stepping (no drop-shadow),
   the mint is a jewel held under ~10% of any surface — never a wash. */
:root {
  /* green — the single accent */
  --green: #4FFF8B;
  --green-press: #3BE678;
  --green-deep: #068A3D;
  --green-quiet: oklch(0.72 0.10 153);
  --green-dim: oklch(0.58 0.06 153);

  /* neutral ladder (green-tinted) — elevation by stepping */
  --c-void: oklch(0.135 0.006 152);
  --c-base: oklch(0.172 0.007 152);
  --c-surface: oklch(0.212 0.007 152);
  --c-surface-2: oklch(0.238 0.008 152);
  --c-raised: oklch(0.262 0.008 152);

  /* hairlines */
  --line: oklch(0.34 0.007 152 / .7);
  --line-soft: oklch(0.40 0.006 152 / .26);

  /* text ladder */
  --fg: oklch(0.97 0.004 152);
  --fg2: oklch(0.80 0.006 152);
  --fg3: oklch(0.63 0.007 152);
  --muted: oklch(0.55 0.008 152);
  --dim: oklch(0.42 0.006 152);

  --red: #FF6B6B;

  /* radii */
  --r-md: 18px;
  --r-lg: 24px;
  --r-xl: 28px;
  --r-cap: 60px;

  /* type */
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
  /* Exo 2 is now self-hosted via next/font (var --font-display-web) — no raw
     Google Fonts <link>, so no route emits a third-party subresource (R6). */
  --font-display: "Bio Sans", var(--font-display-web), "Inter", sans-serif;
  --font-body: var(--font);

  /* motion + soft elevation (single surgical surface per screen only) */
  --ease: cubic-bezier(.2, .9, .27, 1);
  --elev: 0 18px 40px -18px rgba(0, 0, 0, .7);
  --elev-soft: 0 10px 28px -16px rgba(0, 0, 0, .55);

  /* ── F2a blueprint-grid additions (Fuda T0-662, §01.2) — exactly 5 new vars.
     --green-fill is the mockup's dark-fill role (active nav / avatar / met
     dots / toast grounds); the mockup names it --green-deep, colliding with the
     repo --green-deep (#068A3D, V6 ladder of record) which is LEFT UNCHANGED.
     The event colours seed the palette F2c Calendar reuses. ── */
  --node: oklch(0.52 0.01 152 / .8);
  --amber: #E8B54A;
  --green-fill: oklch(0.30 0.075 153);
  --event-checkin: #A88CE6;
  --event-assess: #5CB8E6;
  /* T0-793: the Methodology & Anatomy event accent, AA-checked like its
     siblings (see the light-theme block below for the paired token). */
  --event-ma: #E68CB8;
  /* T0-838 — the two NON-TYPE states on the day-load bar. Deliberately
     near-achromatic: that is what lets them read as "not one of the five"
     rather than as a sixth event type. Measured by rendering the token and
     reading back the composited sRGB pixel, not eyeballed. Bar segments are
     non-text meaningful graphics, so the bar is WCAG 1.4.11's 3:1, not 4.5:1.
     --event-unavail  6.12:1 vs --c-base, 5.36:1 vs the --c-surface-2 track.
     --event-unknown  4.45:1 vs --c-base, 3.89:1 vs the track. */
  --event-unavail: oklch(0.66 0.012 152);
  --event-unknown: oklch(0.58 0.010 152);

  /* ── F2b on-accent ink trio (Fuda T0-663 §01.3) — exactly 3 new vars. Each is a
     literal already repeated across the ladder; naming it removes the repetition
     with ZERO computed-value change (var value == the replaced hex). The eight
     pre-existing sites are consolidated in the same commit that introduces these.
     Scrim whites (#fff / rgba over photographic-or-gradient plates) are NOT accent
     pairs and stay literal (advisory 2). ── */
  --on-green: #08160d;        /* ink on electric --green fills (btn-solid, play, cur node) */
  --on-green-fill: #eafff2;   /* ink on --green-fill dark fills (active nav, avatar, segtab/chip) */
  --on-green-tint: #bff5d1;   /* hover-brightened green text on ghost/outline hovers */

  /* ── F3a console dashboard (Fuda T0-666 §05.4) — exactly 1 new var. Ink on
     amber-tinted grounds: the needs-attention / stuck family (the mockup's
     #f2d79a). Consumed again by F3b pending chips and F3d stuck pills. No second
     new var without a Fuda amendment; the amber ground (--amber), node, and
     green-fill structural tokens already exist and are matched, not forked. ── */
  --on-amber: #f2d79a;

  /* ── T0-683 Genji light-mode switch (§01 C-1a) — exactly 3 new vars. These are
     BASE (dark) NO-OPS: --green-cta / --on-green-cta alias the electric CTA pair
     and --on-red aliases the existing .btn-solid-danger ink, so every computed
     value in the dark theme is byte-equivalent before and after this Fuda (the
     no-op invariant, proven at V-4). The LIGHT values live in the
     :root[data-theme="light"] override block below, pasted verbatim from
     artefacts/design-systems/shredfast/genji-light-tokens.css (the frozen design
     authority — zero token-value authorship here). ── */
  --green-cta: var(--green);
  --on-green-cta: var(--on-green);
  --on-red: #2a0808;
}

/* ── T0-724 Marine-Teal V6 light theme (§01.1 A3) — a token-VALUE swap over the
   shipped T0-683/T0-684 toggle plumbing (NOT a rebuild). Values adopted VERBATIM
   from the vault canon artefacts/design-systems/shredfast/v6-light-tokens.css
   (Fuda D2981, Kage-signed): shared-vocabulary core (block i) + athlete-portal
   extension (block iv). The operator-REJECTED genji blue-steel palette is DELETED;
   the `.theme-genji` alias is dropped from the selector (zero consumers,
   census-verified — a genji-named alias over marine-teal values is naming drift).
   Applied via <html data-theme="light"> (SSR, app/layout.tsx). 32 custom
   properties + color-scheme. Do NOT edit values here; colour changes route back to
   the vault canon via the operator. Base :root (dark) is BYTE-UNTOUCHED — dark is a
   pixel no-op, proven at V-3, never asserted. Contrast ratios below are
   WCAG-MEASURED (canon V-4), never eyeballed; Genji AA lesson (T0-684) bound:
   mid-lightness fills take DARK ink, deep fills take LIGHT ink. ── */
:root[data-theme="light"] {
  /* green — marine teal (operator palette); everyday accent + deepened tiers */
  --green:        #04998f;                /* everyday accent: ring/dots/toggle/edges/ghost */
  --green-press:  #027770;                /* pressed / deeper; also the deep CTA-fill tone */
  --green-deep:   #1F5763;                /* operator anchor: deep-green replacement / hover / secondary */
  --green-cta:    #027770;                /* DEEP-teal LARGE primary fills (signed .btn.fill tone) */
  --on-green-cta: #f2fdfb;                /* LIGHT ink on the DEEP CTA fill — 5.22:1 (AA). Genji lesson:
                                             the CTA is a DEEP fill (#027770) so it takes LIGHT ink; the
                                             small MID accent (#04998f) takes DARK --on-green. Both
                                             measured — the lesson is the matrix, not a hue rule. */
  --green-quiet:  #027770;                /* green-AS-TEXT on light void — 4.77:1 on --c-void (AA) */
  --green-dim:    oklch(0.66 0.07 189);

  /* neutrals — light teal-tinted chrome (hue ~194; never #fff) */
  --c-void:      oklch(0.955 0.012 194);  /* page + canvas backdrop */
  --c-base:      oklch(0.988 0.006 194);  /* topbar, ledger panel */
  --c-surface:   oklch(0.965 0.010 194);  /* chips, inputs, rows */
  --c-surface-2: oklch(0.945 0.013 194);
  --c-raised:    oklch(0.998 0.004 194);  /* popups, cards — elevated = lighter + shadow */

  /* hairlines — teal-tinted on light */
  --line:      oklch(0.85 0.022 194 / 0.9);
  --line-soft: oklch(0.90 0.015 194 / 0.7);

  /* text ladder — deep teal ink on light (never #000). Measured on --c-void: */
  --fg:    oklch(0.29 0.045 191);         /* primary ~#023532 — 12.21:1 (AAA) */
  --fg2:   oklch(0.41 0.052 202);         /* secondary ~#1F5763 — 7.59:1 (AAA) */
  --fg3:   oklch(0.53 0.038 194);         /* tertiary — 4.56:1 (AA); small labels */
  --muted: oklch(0.61 0.030 194);         /* 3.29:1 — AA LARGE-ONLY; not for small essential text */
  --dim:   oklch(0.71 0.022 194);         /* 2.25:1 — DECORATIVE/DISABLED/placeholder ONLY, never text */

  --red: #b5372b;                         /* deepened for light ground — 5.22:1 as text on --c-void (AA) */
  --on-red: #fff1f2;                      /* light ink on --red destructive button — 5.39:1 (AA) */

  /* on-accent inks */
  --on-green:      #042522;               /* DARK ink on MID accent --green #04998f (small fills) — 4.61:1 (AA) */
  --on-green-fill: #f2fdfb;               /* light ink on deep --green-fill grounds — 7.77:1 (AAA) */
  --on-green-tint: #027770;               /* green hover-text on light ground — 4.77:1 on --c-void (AA) */

  /* structural fills */
  --green-fill:    #1F5763;               /* deep anchor structural fill — active nav / avatar conduit */
  --node:          oklch(0.62 0.030 194 / 0.85);  /* node marker (non-text) */
  --amber:         oklch(0.60 0.13 66);   /* deepened amber — 3.59:1 as text (AA LARGE-ONLY; prefer fill+--on-amber) */
  --on-amber:      oklch(0.18 0.040 68);  /* near-black ink on --amber pills — 4.63:1 (AA) */
  --event-checkin: #6B4FC4;               /* violet event accent — 5.22:1 as label on --c-void (AA) */
  --event-assess:  #256690;               /* blue event accent — 5.47:1 as label on --c-void (AA) */
  --event-ma:      #A03A6B;               /* rose event accent (T0-793) — 5.63:1 as label on --c-void (AA) */
  --event-unavail: oklch(0.50 0.012 194); /* T0-838 achromatic Google-busy — 5.79:1 vs --c-base, 4.80:1 vs track */
  --event-unknown: oklch(0.60 0.010 194); /* T0-838 unknown outline — 3.80:1 vs --c-base, 3.15:1 vs track */

  /* elevation — soft teal-tinted shadow */
  --elev:      0 10px 30px oklch(0.42 0.05 202 / 0.16);
  --elev-soft: 0 6px 20px oklch(0.42 0.05 202 / 0.10);

  color-scheme: light;
}

* {
  box-sizing: border-box;
  -webkit-font-smoothing: antialiased;
}

html, body {
  background-color: var(--c-void);
  color: var(--fg);
  /* UAT round 4: a CLOSED slide-drawer parked at translateX(100%) still
     contributes scrollable overflow (transformed boxes extend the scroll area
     even off-viewport), producing a permanent horizontal scrollbar on any page
     with an always-mounted drawer. Clip horizontal overflow at the root — the
     design is a fixed-max grid; nothing legitimate scrolls the page sideways
     (wide tables own their own overflow). */
  overflow-x: clip;
}

/* body = void neutral + ONE top radial mint glow */
body {
  font-family: var(--font);
  min-height: 100dvh;
  background-image: radial-gradient(140% 60% at 50% -8%,
      color-mix(in oklch, var(--green) 5%, transparent),
      transparent 52%);
  background-repeat: no-repeat;
  background-attachment: fixed;
}

/* Bio Sans — display face (local woff2, already wired) */
/* Austin Pen Bold — typed-signature face, parity with the CS Signing Portal */
/* ── entrance: one considered, eased rise-in per screen; reduced-motion gated ── */
/* UAT round 4 CURE: the final keyframe must be `transform: none`, NOT
   translateY(0) — with `both` fill a persistent non-none transform makes the
   animated frame a CONTAINING BLOCK for every position:fixed descendant
   forever, so the drawers/scrims resolve against the frame instead of the
   viewport: the closed drawer (translateX(100%)) parks past the frame's right
   edge and forces permanent horizontal scroll (the operator's report; same
   mechanism as the r4 map-tooltip bug). `none` is visually identical at rest
   and releases the containing block the moment the entrance completes. */
@keyframes sf-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* UAT r8 CURE — fill-mode is `backwards`, NEVER `both`/`forwards`: a filled
   transform (even the identity that a completed `to{transform:none}` leaves in
   the computed style) makes the animated wrapper a CONTAINING BLOCK for every
   position:fixed descendant — modals and drawers then anchor to the wrapper,
   not the viewport, and open off-screen when the page is scrolled (reproduced
   live: profile drawer at top:-907px). `backwards` covers the pre-delay frame
   and releases the property entirely at animation end. */
.sf-rise {
  animation: sf-rise .52s var(--ease) backwards;
}

/* staggered list rise-in — applied to direct children */
.sf-stagger > * {
  animation: sf-rise .5s var(--ease) backwards;
}
.sf-stagger > *:nth-child(1) { animation-delay: .02s; }
.sf-stagger > *:nth-child(2) { animation-delay: .06s; }
.sf-stagger > *:nth-child(3) { animation-delay: .10s; }
.sf-stagger > *:nth-child(4) { animation-delay: .14s; }
.sf-stagger > *:nth-child(5) { animation-delay: .18s; }
.sf-stagger > *:nth-child(6) { animation-delay: .22s; }
.sf-stagger > *:nth-child(7) { animation-delay: .26s; }

@media (prefers-reduced-motion: reduce) {
  .sf-rise,
  .sf-stagger > * {
    animation: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   BLUEPRINT-GRID SYSTEM (Fuda T0-662 §01.2) — the athlete portal's structural
   language, ported from the operator-approved mockup (artifact 877cdb74). Void
   ground, flush hairline cells, trimmed crosshair joiners. This is pseudo-element
   machinery (corner crosshairs with edge-trimming via structural selectors) that
   Tailwind arbitrary values express badly, so it lives here beside sf-rise — the
   same place the V6 system keeps its non-utility CSS. Colours resolve exclusively
   from the existing OKLCH ladder plus the 5 enumerated new vars above; the mockup's
   own token names (--void/--base/--surface/--surface2/--green-deep/--display/--body)
   are mapped to the repo ladder at authoring time. Class names verified against
   the codebase — no existing selector is shadowed. All rules are inert until a
   class is applied, so other surfaces cannot regress by CSS addition alone.
   First tenant: the athlete Home (F2a). F2b/c/d build on these primitives.
   ═══════════════════════════════════════════════════════════════════════════ */

.tnum { font-variant-numeric: tabular-nums; }

/* ── app shell ── */
.app { display: grid; grid-template-columns: 226px 1fr; min-height: 100dvh; }
.side {
  border-right: 1px solid var(--line-soft);
  background: color-mix(in oklch, var(--c-base) 60%, var(--c-void));
  display: flex; flex-direction: column; padding: 0; gap: 5px;
  position: sticky; top: 0; height: 100dvh;
}
.brand { padding: 20px 14px 14px 18px; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; text-decoration: none; }
.brand svg { height: 15px; width: auto; color: var(--green); display: block; }
.brandsub { font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: var(--fg3); font-weight: 600; }
.ngrp { font-size: 9.5px; letter-spacing: .15em; text-transform: uppercase; color: var(--dim); padding: 13px 14px 5px 18px; font-weight: 600; }
.nav { display: flex; flex-direction: column; gap: 1px; }
.nav a {
  display: flex; align-items: center; gap: 11px; padding: 8px 14px 8px 18px;
  color: var(--fg3); font-size: 13px; font-weight: 500; text-decoration: none;
  transition: .14s var(--ease); border-left: 2px solid transparent; cursor: pointer;
}
.nav a:hover { background: var(--c-surface); color: var(--fg2); }
.nav a.on { background: var(--green-fill); color: var(--on-green-fill); border-left: 2px solid var(--green); }
.nav a svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 1.7; flex-shrink: 0; }
.who { margin-top: auto; display: flex; align-items: center; gap: 10px; padding: 13px 14px 10px 18px; border-top: 1px solid var(--line-soft); }
.ava { width: 30px; height: 30px; display: grid; place-items: center; font-weight: 700; font-size: 12px; background: var(--green-fill); color: var(--on-green-fill); font-family: var(--font-display); overflow: hidden; }
.ava img { width: 100%; height: 100%; object-fit: cover; display: block; object-position: 50% 14%; transform: scale(1.52); transform-origin: 50% 14%; }
.who .nm { font-size: 12.5px; font-weight: 600; color: var(--fg); }
.who .rl { font-size: 10.5px; color: var(--fg3); }
.signout { padding: 4px 14px 14px 18px; }
.signout button {
  width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  display: flex; align-items: center; gap: 9px; padding: 7px 0;
  color: var(--fg3); font-size: 12px; font-weight: 500; font-family: var(--font-body);
  transition: .14s var(--ease);
}
.signout button:hover { color: var(--fg); }
.signout button svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.9; }

/* ── main + grid frame ── */
.main { padding: 0; display: flex; flex-direction: column; min-height: 100dvh; }
.frame { position: relative; background: var(--line-soft); display: flex; flex-direction: column; gap: 1px; flex: 1; }
.gsec { background: var(--line-soft); display: grid; gap: 1px; }
.gcell { position: relative; background: var(--c-base); }
/* blueprint joiners — split into H + V strokes so orphaned prongs trim at edges */
.gcell::before, .gcell::after { content: ""; position: absolute; z-index: 4; pointer-events: none; opacity: .85; background: var(--node); }
.gcell::before { top: -1px; left: -1px; width: 9px; height: 1px; transform: translate(-50%, -50%); }
.gcell::after { top: -1px; left: -1px; width: 1px; height: 9px; transform: translate(-50%, -50%); }
.gsec > .gcell:first-child::before { width: 5px; left: -1px; transform: translate(0, -50%); }
.frame > .gsec:first-child > .gcell::before { display: none; }
.gsec > .gcell:not(:first-child)::after { height: 5px; top: -1px; transform: translate(-50%, 0); }

/* ── hero ── */
.hero { padding: 30px 26px; display: flex; align-items: flex-end; gap: 24px; flex-wrap: wrap; background: radial-gradient(120% 140% at 0% 0%, color-mix(in oklch, var(--green) 8%, transparent), transparent 60%); }
.hero .hmain { flex: 1; min-width: 260px; }
.hero .eyebrow { display: inline-flex; align-items: center; gap: 8px; }
.eyebrow { font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--green-quiet); font-weight: 600; }
.hero .eyebrow .d { width: 7px; height: 7px; border-radius: 50%; background: var(--green); }
.hero h1 { font-family: var(--font-display); font-size: 32px; font-weight: 700; letter-spacing: -.025em; margin-top: 10px; text-wrap: balance; }
.hero .sub { font-size: 14px; color: var(--fg2); margin-top: 9px; max-width: 520px; line-height: 1.55; }
.hero .sub b { color: var(--fg); font-weight: 700; }

/* ── stat strip ── */
.statgrid { grid-template-columns: 1.25fr 1fr 1fr 1fr; }
.statcell { padding: 16px 20px; display: flex; flex-direction: column; gap: 8px; min-height: 104px; }
.statk { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--fg3); font-weight: 600; display: flex; align-items: center; }
.statv { font-family: var(--font-display); font-size: 29px; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; line-height: 1; display: flex; align-items: baseline; gap: 3px; }
.statv .u { font-size: 14px; font-weight: 600; color: var(--muted); font-family: var(--font-body); }
.statv .of { font-size: 15px; color: var(--muted); font-weight: 600; }
/* F4a (T0-674 §01.4, O-42/O-44): app-verified metric awaiting the ShredFast app —
   the em-dash value slot reads in the muted ladder (existing --dim token, zero new
   tokens). Keeps the 29px display size so the cell height/grid geometry is unchanged. */
.statv.awaiting { color: var(--dim); }
.statbar { height: 5px; background: var(--c-surface-2); border-radius: 60px; overflow: hidden; position: relative; margin-top: auto; }
.statbar .fill { position: absolute; inset: 0; border-radius: 60px; background: var(--green); }
.statsub { font-size: 11.5px; color: var(--muted); margin-top: auto; }
.stagecell { background: color-mix(in oklch, var(--green) 4.5%, var(--c-base)); }
.stagebig { font-family: var(--font-display); font-size: 22px; font-weight: 700; letter-spacing: -.02em; line-height: 1; display: flex; align-items: center; gap: 10px; color: var(--fg); }
.stagebig .d { width: 11px; height: 11px; border-radius: 50%; background: var(--green); }
.stagesub { font-size: 11.5px; color: var(--fg3); }
.apptag { width: 11px; height: 11px; color: var(--green-dim); opacity: .85; margin-right: 5px; vertical-align: -1px; }

/* ── panels ── */
.two { grid-template-columns: 1.6fr 1fr; }
.pcell { padding: 0; display: flex; flex-direction: column; }
.ptitle { padding: 15px 20px; display: flex; align-items: center; gap: 10px; border-bottom: 1px solid var(--line-soft); }
.ptitle .pt { font-family: var(--font-display); font-size: 14px; font-weight: 700; letter-spacing: -.01em; }
.ptitle .cnt { font-size: 11px; color: var(--fg3); font-weight: 600; background: var(--c-surface); padding: 2px 9px; border-radius: 60px; }
.ptitle .rt { margin-left: auto; }
.golink { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; color: var(--green-quiet); text-decoration: none; transition: .14s var(--ease); }
.golink:hover { color: var(--on-green-tint); gap: 7px; }
.golink svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2; }
.empty { padding: 26px 20px; text-align: center; color: var(--muted); font-size: 12.5px; }

/* ── next steps ── */
/* UAT r10 (operator ruling): criteria icons TOP-align with the title text on
   every card, both views — not centred against the card */
.nstep { padding: 15px 20px; display: flex; align-items: flex-start; gap: 14px; border-bottom: 1px solid color-mix(in oklch, var(--line-soft) 55%, transparent); }
.nstep .nsi { margin-top: 0; }
.nstep .nsact { margin-top: 2px; }
.nstep:last-child { border-bottom: none; }
.nsi { width: 30px; height: 30px; flex-shrink: 0; border-radius: 50%; border: 1px solid var(--line-soft); display: grid; place-items: center; color: var(--muted); }
.nsi svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 2; }
.nstep.met .nsi { background: var(--green-fill); border-color: var(--green-dim); color: var(--green); }
.nstep.todo .nsi { border-color: color-mix(in oklch, var(--amber) 45%, transparent); color: var(--amber); }
.nsmain { flex: 1; min-width: 0; }
.nsn { font-size: 13.5px; font-weight: 600; color: var(--fg); display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.nsd { font-size: 11.5px; color: var(--muted); margin-top: 4px; }
.nspill { font-size: 10px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; padding: 2px 8px; border-radius: 60px; }
.np-met { background: color-mix(in oklch, var(--green) 14%, transparent); color: var(--green-quiet); }
.np-rev { background: color-mix(in oklch, var(--amber) 14%, transparent); color: var(--amber); }
.np-todo { background: var(--c-surface); color: var(--muted); }
.nsact { flex-shrink: 0; }
/* social post grid */
.postgrp { margin-top: 11px; }
.postbarhead { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; font-size: 11.5px; color: var(--muted); margin-bottom: 8px; }
.postbarhead b { color: var(--fg); font-variant-numeric: tabular-nums; font-weight: 700; }
.plegend { display: flex; align-items: center; gap: 12px; }
.pl { display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px; color: var(--fg3); }
.pl .pc { width: 12px; height: 12px; aspect-ratio: auto; }
.postgrid { display: grid; grid-template-columns: repeat(15, 1fr); gap: 5px; max-width: 540px; }
.pc { aspect-ratio: 1; border-radius: 3px; position: relative; overflow: hidden; background: var(--c-surface-2); border: 1.5px solid var(--line-soft); display: block; padding: 0; }
.pc.ok { border-color: var(--green); }
.pc.rev { border-color: var(--amber); }
.pc.await { border-color: var(--line-soft); border-style: dashed; cursor: pointer; }
.pc.await:hover { border-color: var(--green-quiet); background: color-mix(in oklch, var(--green) 9%, transparent); }
.pc .th { position: absolute; inset: 0; background-size: cover; background-position: center; }
/* UAT r6 — filled-cell affordances: flat cell + platform glyph badge (admin
   treatment, operator ruling: no gradient fills) + click-through */
.pc.ok, .pc.rev { cursor: pointer; }
.pc.ok:hover { background: color-mix(in oklch, var(--green) 9%, transparent); }
.pc.rev:hover { background: color-mix(in oklch, var(--amber) 9%, transparent); }
.pl .pc.ok, .pl .pc.rev { cursor: default; }
.pl .pc.ok:hover, .pl .pc.rev:hover { background: var(--c-surface-2); }
.pc .pg { position: absolute; right: 1px; bottom: 1px; width: 12px; height: 12px; display: grid; place-items: center; background: rgba(0, 0, 0, .55); border-radius: 3px; color: #fff; }
.pc .pg svg { width: 8px; height: 8px; }
/* post detail dialog (openPost made real) */
.pdplat { display: flex; align-items: center; gap: 9px; font-size: 13.5px; color: var(--fg); }
.pdpi { width: 26px; height: 26px; display: grid; place-items: center; border: 1px solid var(--line-soft); border-radius: 7px; color: var(--fg2); flex-shrink: 0; }
.pdpi svg { width: 14px; height: 14px; }
.pdlink { display: block; margin-top: 10px; word-break: break-all; }
.pdfb { margin-top: 14px; border: 1px solid var(--line-soft); border-radius: 9px; padding: 11px 13px; }
.pdfbl { font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.pdfbt { font-size: 12.5px; color: var(--fg2); margin-top: 5px; line-height: 1.55; }

/* ── upcoming ── */
.upi { display: flex; gap: 13px; align-items: center; padding: 13px 20px; border-bottom: 1px solid color-mix(in oklch, var(--line-soft) 55%, transparent); }
.upi:last-child { border-bottom: none; }
.update { flex: 0 0 44px; text-align: center; border: 1px solid var(--line-soft); border-radius: 8px; padding: 6px 0; }
.update .d { font-family: var(--font-display); font-size: 17px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.update .m { font-size: 9px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin-top: 2px; }
.upmain { min-width: 0; flex: 1; }
.upn { font-size: 13px; font-weight: 600; color: var(--fg); display: flex; align-items: center; gap: 8px; }
.upn .sw { width: 8px; height: 8px; border-radius: 2px; background: var(--uc); flex-shrink: 0; }
.upsub { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.upr { flex-shrink: 0; }

/* ── team feed ── */
.feed { padding: 8px 20px 16px; display: flex; flex-direction: column; }
.feedrow { align-items: stretch; }
.fcard { display: flex; gap: 13px; padding: 16px 0; border-bottom: 1px solid color-mix(in oklch, var(--line-soft) 55%, transparent); }
.fcard:last-child { border-bottom: none; }
.fcav { width: 38px; height: 38px; flex-shrink: 0; display: grid; place-items: center; font-size: 12.5px; font-weight: 700; font-family: var(--font-display); background: var(--green-fill); color: var(--on-green-fill); }
.fcav.coach { background: var(--c-surface-2); color: var(--fg2); }
.fcmain { flex: 1; min-width: 0; }
.fch { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.fch b { font-size: 13px; color: var(--fg); font-weight: 600; }
.frole { font-size: 10px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--green-quiet); background: color-mix(in oklch, var(--green) 12%, transparent); padding: 2px 8px; border-radius: 60px; }
.frole.coach { color: var(--fg3); background: var(--c-surface); }
.ftime { margin-left: auto; font-size: 11px; color: var(--muted); }
.fcbody { font-size: 13px; color: var(--fg2); line-height: 1.6; margin-top: 7px; }
.announce { margin-top: 10px; border: 1px solid var(--line-soft); background: var(--c-void); display: flex; align-items: stretch; gap: 0; overflow: hidden; transition: .14s var(--ease); }
.anthumb { width: 120px; flex-shrink: 0; position: relative; overflow: hidden; background: var(--c-surface-2); }
.anthumb.doc { display: grid; place-items: center; color: var(--fg3); }
.anthumb.doc svg { width: 30px; height: 30px; stroke: currentColor; fill: none; stroke-width: 1.5; }
.anthumb .play { position: absolute; inset: 0; display: grid; place-items: center; color: #fff; }
.anthumb .play svg { width: 30px; height: 30px; filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .5)); }
.anmeta { flex: 1; min-width: 0; padding: 13px 15px; display: flex; flex-direction: column; justify-content: center; }
.antag { font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--green-quiet); display: inline-flex; align-items: center; gap: 6px; }
.antag svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2; }
.antitle { font-size: 13.5px; font-weight: 700; color: var(--fg); margin-top: 5px; font-family: var(--font-display); letter-spacing: -.01em; }
.ansub { font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.anopen { margin-left: auto; align-self: center; padding-right: 15px; color: var(--green-quiet); flex-shrink: 0; }
.anopen svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2; }

/* ── stage tracker (progress-track island) ── */
.trackgsec { min-width: 0; }
.trackcell { padding: 20px 22px; display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.trackhead { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.trackhead .th-t { font-family: var(--font-display); font-size: 14px; font-weight: 700; letter-spacing: -.01em; }
.trackctl { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
/* D1923 — THE SCOPE THIS RULE ACTUALLY OWNS.
   `.trackctl` has TWO consumers and D1911 only looked at one of them:
     admin  components/admin/athlete-profile.tsx — FIVE elements, all inside the
            new `.trackgrp` wrapper, all under `.pfx`
     portal components/portal/progress-track.tsx:40 — ONE element ("Stage N of M"),
            a DIRECT CHILD of `.trackhead`, NOT wrapped and NOT under `.pfx`
   D1911 stripped `margin-left:auto` from the bare rule as well as the `.pfx` twin,
   which cured the admin cluster and pushed the portal's stage counter from the
   right rail to hard against the heading — measured 1059px -> 131px at 1170px, on
   the athlete's own surface, inside the journey being UAT'd.

   THE CHILD COMBINATOR IS THE WHOLE CURE. Every admin `.trackctl` is a child of
   `.trackgrp`, never of `.trackhead`, so this rule cannot reach the cluster at any
   width; the portal's is a direct child, so it gets its rail back verbatim.

   AND THE OBVIOUS ALTERNATIVE IS A TRAP, recorded so nobody "simplifies" this
   back: restoring `margin-left:auto` on the BARE `.trackctl` measures identical to
   this at desktop and reinstates the three-way ~101px split at the <=940px branch,
   where `.pfx .trackgrp` drops to `margin-left:0; width:100%` and the auto margins
   on its children start competing again. It ships back the exact defect item 5
   exists to fix, and a desktop-only raster would have called it green. */
.trackhead > .trackctl { margin-left: auto; }
/* D1911 item 5 — base twin of the .pfx cluster rule; kept in step so the two
   .trackhead consumers cannot disagree about where the controls sit. */
.trackgrp { margin-left: auto; display: flex; align-items: center; justify-content: flex-end; gap: 18px; row-gap: 10px; flex-wrap: wrap; }
.flabel { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .1em; font-weight: 600; }
.trackscroll { overflow-x: auto; padding-bottom: 2px; max-width: 100%; }
.track { display: flex; align-items: flex-start; gap: 0; min-width: 760px; }
.tnode { flex: 1; display: flex; flex-direction: column; align-items: flex-start; gap: 9px; position: relative; text-align: left; min-width: 88px; }
.tnode .seg { position: absolute; top: 12px; left: 13px; width: 100%; height: 2px; background: var(--line); z-index: 0; }
.tnode:last-child .seg { display: none; }
.tnode.done .seg { background: var(--green-dim); }
.tdot { position: relative; z-index: 1; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; background: var(--c-base); border: 2px solid var(--line); color: var(--muted); transition: .2s var(--ease); }
.tdot svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2.4; }
.tnode.done .tdot { background: var(--green-fill); border-color: var(--green-dim); color: var(--green); }
.tnode.cur .tdot { background: var(--green); border-color: var(--green); color: var(--on-green); box-shadow: 0 0 0 4px color-mix(in oklch, var(--green) 18%, transparent); }
.tlab { font-size: 11px; font-weight: 600; color: var(--muted); line-height: 1.25; padding-right: 8px; }
.tnode.done .tlab { color: var(--fg3); }
.tnode.cur .tlab { color: var(--fg); }
.tnode .emb { width: 14px; height: 14px; color: var(--green); }
.tnode.cur .emb { width: 15px; height: 15px; color: var(--on-green); }
.tgate { margin-top: 3px; font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: var(--green-quiet); font-weight: 700; display: inline-flex; align-items: center; gap: 4px; }
.tgate svg { width: 10px; height: 10px; stroke: currentColor; fill: none; stroke-width: 2.2; }
.stagehist { display: flex; flex-direction: column; gap: 0; border-top: 1px solid var(--line-soft); padding-top: 2px; }
.shrow { display: flex; align-items: center; gap: 10px; padding: 7px 0; font-size: 12px; color: var(--fg3); border-bottom: 1px solid color-mix(in oklch, var(--line-soft) 45%, transparent); }
.shrow:last-child { border-bottom: none; }
.shrow .shd { width: 6px; height: 6px; border-radius: 50%; background: var(--green-dim); flex-shrink: 0; }
.shrow b { color: var(--fg2); font-weight: 600; }
.shrow .sht { margin-left: auto; color: var(--muted); font-variant-numeric: tabular-nums; font-size: 11.5px; }
.shtoggle { align-self: flex-start; font-size: 11.5px; color: var(--green-quiet); font-weight: 600; display: inline-flex; align-items: center; gap: 6px; background: none; border: none; cursor: pointer; font-family: var(--font-body); }
.shtoggle svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2; transition: .18s var(--ease); }
.shtoggle.open svg { transform: rotate(180deg); }

/* ── your activity timeline ── */
.tlx { display: flex; flex-direction: column; padding: 6px 20px 14px; }
.tlrow { display: flex; gap: 13px; padding: 12px 2px; position: relative; }
.tlrow:not(:last-child)::before { content: ""; position: absolute; left: 9px; top: 30px; bottom: -12px; width: 1px; background: var(--line); }
.tlrow .tli { width: 19px; height: 19px; flex-shrink: 0; border-radius: 50%; display: grid; place-items: center; border: 1px solid var(--line); background: var(--c-surface); z-index: 1; }
.tlrow .tli svg { width: 11px; height: 11px; stroke: currentColor; fill: none; stroke-width: 2; }
.tlrow.proof .tli { color: var(--green); border-color: var(--green-dim); background: var(--green-fill); }
.tlrow.reject .tli { color: var(--amber); border-color: color-mix(in oklch, var(--amber) 30%, transparent); background: color-mix(in oklch, var(--amber) 8%, transparent); }
.tlrow.stage .tli { color: var(--green); }
.tlrow .tlmain { flex: 1; min-width: 0; }
.tlrow .tlt { font-size: 12.8px; line-height: 1.45; color: var(--fg); }
.tlrow .tlt b { font-weight: 600; }
.tlrow .tlt i { color: var(--muted); font-style: italic; }
.tlrow .tltime { font-size: 11px; color: var(--muted); margin-top: 3px; letter-spacing: .02em; }

/* ── buttons (blueprint) ── */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; border-radius: 60px; font-size: 12.5px; font-weight: 600; height: 38px; padding: 0 18px; cursor: pointer; transition: .16s var(--ease); white-space: nowrap; border: 1px solid transparent; font-family: var(--font-body); }
.btn svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 2; }
/* T0-854 — SHEET-WIDE. A disabled `.btn` computed opacity 1 with the same colour
   and border as a live one: functionally dead, visually alive. That is a lying
   control in the visual register, the same anti-pattern the codebase already
   forbids in the behavioural one. T0-855 measured the gap, cured it for `.pfx`
   only because curing it product-wide was unreviewed at the time, and named this
   ticket as the sweep owner. This is the sweep: measured at 33 disabled `.btn`
   emit sites across 15 files, twelve of them athlete-facing, all rastered.
   Values adopted from T0-855 unchanged (RQ-1 = A, Kage-ratified 2026-08-11 at the preview gate).
   Deliberately NOT extended to `.ic` or `.btn-send` — both already carry their
   own `:disabled` rules, and this rule reaches neither, because `.btn` matches the
   bare token only. Six disabled controls carrying only `btn-*` tokens (no bare
   `btn`) are likewise out of its reach and out of this ticket's scope. */
.btn:disabled { opacity: .42; cursor: not-allowed; }
.btn-solid { background: var(--green-cta); color: var(--on-green-cta); font-weight: 700; } /* T0-683: CTA fill via --green-cta (base no-op; forged green in light) */
.btn-solid:hover { background: var(--green-press); }
.btn-ghost { background: transparent; border: 1px solid color-mix(in oklch, var(--green) 45%, transparent); color: var(--green-quiet); }
.btn-ghost:hover { border-color: var(--green); background: color-mix(in oklch, var(--green) 8%, transparent); color: var(--on-green-tint); }
.btn-line { background: transparent; border: 1px solid var(--line); color: var(--fg2); }
.btn-line:hover { border-color: var(--fg3); color: var(--fg); }
.btn-sm { height: 34px; padding: 0 14px; font-size: 12px; }

/* ── mobile bar + drawer ── */
.mobar { display: none; align-items: stretch; padding: 0; min-height: 52px; border-bottom: 1px solid var(--line-soft); position: sticky; top: 0; background: var(--c-base); z-index: 55; }
.mobar .brandwrap { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 3px; padding: 0 15px; text-decoration: none; }
.mobar .mobwm { height: 14px; width: auto; color: var(--green); display: block; }
.mobar .mobsub { font-size: 9px; letter-spacing: .16em; text-transform: uppercase; color: var(--fg3); font-weight: 600; }
.hamburger { display: grid; place-items: center; width: 52px; border: none; border-right: 1px solid var(--line-soft); background: transparent; color: var(--fg2); cursor: pointer; }
.hamburger svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2; }

/* ── T0-724 P4 scope-add: colour-mode toggle in the persistent shell header (both the
   portal side-nav and the admin console-nav share these classes). This app is
   mobile-first with NO desktop top bar, so the toggle rides EXISTING chrome — the top
   of the sidebar brand row on desktop (.sidehead) and the right end of the mobile top
   bar (.mobar) — never a newly invented chrome bar. The reused ThemeToggle renders the
   repo .tgl switch; here we only position its wrapper. ── */
.sidehead { display: flex; align-items: center; justify-content: space-between; }
.sidehead .brand { flex: 1 1 auto; }
.themehead { display: flex; align-items: center; }
.sidehead .themehead { padding-right: 16px; }
.mobar .themehead { margin-left: auto; padding: 0 15px; }

/* ── T0-724 P4 (operator 2026-07-15): sun/moon toggle affordance — the signed
   .theme-toggle contract ported from the Territory Map so all three ShredFast
   surfaces read consistently. Both glyphs always in the DOM; CSS flips which one
   shows off <html data-theme>. (--r-pill on TM → --r-cap here, AP's pill radius.) ── */
.theme-toggle {
  all: unset; cursor: pointer; display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: var(--r-cap);
  color: var(--fg3); border: 1px solid var(--line-soft);
}
.theme-toggle:hover { color: var(--fg); background: var(--c-surface); }
.theme-toggle svg { width: 16px; height: 16px; }
.theme-toggle .moon { display: none; }
.theme-toggle .sun { display: block; }
:root[data-theme="light"] .theme-toggle .sun { display: none; }
:root[data-theme="light"] .theme-toggle .moon { display: block; }
.navscrim { display: none; position: fixed; inset: 0; background: rgba(0, 0, 0, .55); z-index: 65; }
.navscrim.show { display: block; }

/* ── modals (submit-post + reschedule islands) ── */
.mscrim { display: none; position: fixed; inset: 0; background: rgba(0, 0, 0, .62); z-index: 88; }
.mscrim.show { display: block; }
.modal { display: none; position: fixed; inset: 0; z-index: 90; align-items: center; justify-content: center; padding: 24px; }
.modal.open { display: flex; }
.mcard { width: 480px; max-width: 96vw; max-height: 90vh; background: var(--c-base); border: 1px solid var(--line); display: flex; flex-direction: column; box-shadow: 0 30px 80px -24px rgba(0, 0, 0, .75); animation: mrise .26s var(--ease); }
@keyframes mrise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.mhead { padding: 17px 22px; border-bottom: 1px solid var(--line-soft); display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.meyebrow { font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: var(--green-quiet); font-weight: 600; margin-bottom: 5px; }
.mhead h2 { font-family: var(--font-display); font-size: 18px; font-weight: 700; }
.mbody { padding: 17px 22px; display: flex; flex-direction: column; gap: 13px; }
.mbody p { font-size: 12.5px; color: var(--fg3); line-height: 1.55; }
.mbody p b { color: var(--fg); }
.mfoot { padding: 14px 22px; border-top: 1px solid var(--line-soft); display: flex; gap: 10px; justify-content: flex-end; background: color-mix(in oklch, var(--c-base) 92%, transparent); }
.dclose { width: 32px; height: 32px; display: grid; place-items: center; color: var(--fg3); border: 1px solid var(--line-soft); flex-shrink: 0; background: none; cursor: pointer; }
.dclose:hover { color: var(--fg); border-color: var(--fg3); }
.dclose svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; }
.fld { display: flex; flex-direction: column; gap: 6px; }
.fld .fl { font-size: 11.5px; color: var(--fg3); font-weight: 600; letter-spacing: .02em; }
.in { height: 44px; background: var(--c-surface); border: 1px solid var(--line-soft); padding: 0 13px; font-size: 13.5px; color: var(--fg); outline: none; transition: .16s var(--ease); font-family: var(--font-body); width: 100%; min-width: 0; max-width: 100%; box-sizing: border-box; }
/* UAT r9: date inputs carry an INTRINSIC min-width that ignores width:100% and
   overflows narrow containers (the DOB field) — appearance:none releases it */
input[type="date"].in { appearance: none; -webkit-appearance: none; }
.in::placeholder { color: var(--muted); }
.in:focus { border-color: var(--green-quiet); }
textarea.in { height: auto; padding: 11px 13px; resize: vertical; min-height: 64px; line-height: 1.5; }
.detected { display: none; font-size: 11.5px; padding: 9px 12px; border: 1px solid color-mix(in oklch, var(--green) 38%, transparent); background: color-mix(in oklch, var(--green) 6%, transparent); color: var(--fg2); align-items: center; gap: 9px; }
.detected.show { display: flex; }
.detected b { color: var(--green-quiet); }

/* ── toast ── */
.toast { position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%) translateY(20px); background: var(--c-surface); border: 1px solid var(--line); padding: 11px 16px; display: flex; align-items: center; gap: 10px; font-size: 12.5px; color: var(--fg); z-index: 95; opacity: 0; pointer-events: none; transition: .28s var(--ease); box-shadow: 0 18px 44px -18px rgba(0, 0, 0, .7); }
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast .ti { width: 20px; height: 20px; flex-shrink: 0; border-radius: 50%; display: grid; place-items: center; background: var(--green-fill); color: var(--green); border: 1px solid var(--green-dim); }
.toast .ti svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2.6; }

/* ── blueprint entrance + responsive ── */
.bp-rise { animation: sf-rise .5s var(--ease) backwards; } /* backwards, never both — see the UAT r8 containing-block cure above */
@media (max-width: 940px) {
  .app { grid-template-columns: 1fr; }
  .side { display: flex; position: fixed; top: 0; left: 0; height: 100dvh; width: 236px; transform: translateX(-100%); transition: transform .28s var(--ease); z-index: 70; }
  .side.open { transform: translateX(0); box-shadow: 0 18px 50px -12px rgba(0, 0, 0, .7); }
  .main .mobar { display: flex; }
  .two, .statgrid { grid-template-columns: 1fr; }
  .hero h1 { font-size: 26px; }
  .anthumb { width: 96px; }
}
@media (max-width: 560px) {
  .statgrid { grid-template-columns: 1fr 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .bp-rise, .mcard { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   F2b LIBRARY (Fuda T0-663 §01.3) — the consolidated Documents + Videos screen,
   ported from the operator-approved mockup (artifact 098d5b72) onto the F2a
   blueprint primitives. Colours resolve from the OKLCH ladder + the on-green trio
   above; mockup token names are mapped at authoring time (--void→--c-void,
   --base→--c-base, --surface→--c-surface, --surface2→--c-surface-2,
   --green-deep[dark-fill]→--green-fill, --display→--font-display, --body→--font-body).
   Modal/toast/btn/eyebrow/empty/flabel are REUSED from F2a — the wider library
   modal lands as .mcard.mwide + scoped extensions, never a redefinition. Scrim
   whites (#fff / rgba over photographic-or-gradient plates) stay literal (advisory 2).
   New classes verified absent at ba11bb9. Coming-soon video degrade reuses the
   videos/page precedent's Tailwind utilities (no custom class).
   ═══════════════════════════════════════════════════════════════════════════ */

/* header cell */
.hcell { padding: 18px 22px; display: flex; align-items: flex-start; gap: 20px; flex-wrap: wrap; }
.hcell h1 { font-family: var(--font-display); font-size: 27px; font-weight: 700; letter-spacing: -.02em; margin-top: 6px; text-wrap: balance; }
.hcell .sub { color: var(--fg3); font-size: 13.5px; margin-top: 5px; }
.tools { margin-left: auto; display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }

/* segmented Documents / Videos tab control */
.segtab { display: inline-flex; border: 1px solid var(--line-soft); border-radius: 60px; overflow: hidden; }
.segtab button { height: 34px; padding: 0 16px; font-size: 12.5px; font-weight: 600; color: var(--fg3); background: transparent; border: none; cursor: pointer; transition: .14s var(--ease); display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-body); }
.segtab button.on { background: var(--green-fill); color: var(--on-green-fill); }
.segtab button svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2; }
.segtab .c { font-size: 10.5px; font-weight: 700; opacity: .7; }

/* library section switcher — the promoted, full-width two-up variant */
.libswitch { padding: 0; }
.libswitch .segtab { display: grid; grid-template-columns: 1fr 1fr; width: 100%; border: none; border-radius: 0; }
.libswitch .segtab button { height: auto; padding: 16px 20px; font-size: 14px; justify-content: flex-start; gap: 13px; border-bottom: 2px solid transparent; }
.libswitch .segtab button + button { border-left: 1px solid var(--line-soft); }
.libswitch .segtab button.on { background: color-mix(in oklch, var(--green) 9%, transparent); color: var(--fg); border-bottom-color: var(--green); }
.libswitch .segtab button svg { width: 20px; height: 20px; flex-shrink: 0; }
.libswitch .segtab button.on svg { stroke: var(--green); }
.libswitch .lsw { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.libswitch .lst { font-weight: 700; display: inline-flex; align-items: baseline; gap: 7px; }
.libswitch .lst .c { font-size: 11px; }
.libswitch .lsd { font-size: 11.5px; font-weight: 500; color: var(--fg3); }
.libswitch .segtab button.on .lsd { color: var(--fg2); }

/* toolbar cell: search (left, hairline right border) + filter zone (right) */
.tbar { padding: 0; display: flex; align-items: stretch; flex-wrap: wrap; min-height: 57px; }
.search { position: relative; display: flex; align-items: center; flex: 0 0 300px; border-right: 1px solid var(--line-soft); }
.tbar .search { flex: 0 0 320px; }
.search svg { position: absolute; left: 18px; width: 15px; height: 15px; stroke: var(--muted); fill: none; stroke-width: 1.8; pointer-events: none; }
.search input { height: 100%; min-height: 56px; width: 100%; background: transparent; border: none; padding: 0 16px 0 44px; font-size: 13.5px; color: var(--fg); outline: none; font-family: var(--font-body); }
.search input::placeholder { color: var(--muted); }
.tbfilt { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; padding: 10px 18px; flex: 1; }

/* chips (filters/toggles) — mockup-exact metrics; the mockup system's active
   state is AMBER on every surface (roster Stuck-only, library categories) */
.chip { display: inline-flex; align-items: center; gap: 7px; height: 38px; padding: 0 15px; border-radius: 60px; border: 1px solid var(--line-soft); background: var(--c-void); color: var(--fg3); font-size: 12.5px; font-weight: 600; cursor: pointer; transition: .16s var(--ease); font-family: var(--font-body); }
.chip svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.9; }
.chip:hover { border-color: var(--green-quiet); color: var(--fg2); }
.chip.on { border-color: color-mix(in oklch, var(--amber) 55%, transparent); background: color-mix(in oklch, var(--amber) 12%, transparent); color: var(--amber); }

/* content cell */
.tablesec { flex: 1; }
.libpad { padding: 18px 20px 24px; }
.grouphd { font-size: 11px; text-transform: uppercase; letter-spacing: .09em; color: var(--fg3); font-weight: 600; margin: 16px 2px 11px; }
.grouphd:first-child { margin-top: 2px; }

/* documents grid + cards */
.docgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 12px; }
.doccard { border: 1px solid var(--line-soft); border-radius: 8px; background: var(--c-base); padding: 15px; display: flex; gap: 13px; transition: .14s var(--ease); position: relative; }
.doccard:hover { border-color: var(--green-quiet); background: var(--c-surface); }
.di { width: 44px; height: 52px; flex-shrink: 0; border-radius: 5px; border: 1px solid var(--line-soft); display: grid; place-items: center; color: var(--fg3); background: var(--c-surface); }
.di svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 1.5; }
.dcmain { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.dctitle { font-size: 13.5px; font-weight: 600; color: var(--fg); line-height: 1.3; text-align: left; background: none; border: none; padding: 0; cursor: pointer; font-family: var(--font-body); }
.dctitle:hover { color: var(--green-quiet); }
.dcmeta { font-size: 11.5px; color: var(--muted); margin-top: 5px; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.dcmeta .sep { width: 3px; height: 3px; border-radius: 50%; background: var(--dim); }
.catpill { font-size: 9.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--fg3); border: 1px solid var(--line-soft); padding: 2px 7px; border-radius: 60px; white-space: nowrap; }
.dcacts { margin-top: auto; padding-top: 11px; display: flex; gap: 8px; }
.dcbtn { height: 30px; padding: 0 12px; font-size: 11.5px; border-radius: 60px; display: inline-flex; align-items: center; gap: 6px; font-weight: 600; border: 1px solid var(--line-soft); background: transparent; color: var(--fg2); cursor: pointer; transition: .14s var(--ease); text-decoration: none; }
.dcbtn:hover { border-color: var(--green-quiet); color: var(--fg); }
.dcbtn.pri { border-color: color-mix(in oklch, var(--green) 45%, transparent); color: var(--green-quiet); }
.dcbtn.pri:hover { border-color: var(--green); background: color-mix(in oklch, var(--green) 9%, transparent); color: var(--on-green-tint); }
.dcbtn svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2; }

/* videos grid + cards */
.vidgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 18px; }
.vidcard { display: block; width: 100%; text-align: left; background: none; border: none; padding: 0; cursor: pointer; font-family: var(--font-body); }
.vidthumb { aspect-ratio: 16/9; border-radius: 8px; position: relative; overflow: hidden; border: 1px solid var(--line-soft); background: var(--c-surface-2); transition: .14s var(--ease); }
.vidcard:hover .vidthumb { border-color: var(--green-quiet); }
/* T0-869: signed poster frame under the play glyph — fills the tile, glyph and
   duration chip stay layered above (both are absolutely positioned siblings). */
.vidthumb .vidposter { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vidthumb .play { position: absolute; inset: 0; display: grid; place-items: center; }
.vidthumb .play span { width: 48px; height: 48px; border-radius: 50%; background: rgba(8, 22, 13, .55); backdrop-filter: blur(3px); display: grid; place-items: center; color: #fff; transition: .14s var(--ease); border: 1px solid rgba(255, 255, 255, .25); }
.vidcard:hover .play span { background: var(--green); color: var(--on-green); transform: scale(1.06); }
.vidthumb .play span svg { width: 20px; height: 20px; }
.vidthumb .dur { position: absolute; right: 8px; bottom: 8px; font-size: 10.5px; font-weight: 700; color: #fff; background: rgba(0, 0, 0, .62); padding: 2px 7px; border-radius: 5px; font-variant-numeric: tabular-nums; }
.vidthumb .watched { position: absolute; left: 8px; top: 8px; font-size: 9.5px; font-weight: 700; color: var(--fg2); background: rgba(0, 0, 0, .6); padding: 3px 8px; border-radius: 60px; display: inline-flex; align-items: center; gap: 5px; }
.vidthumb .watched svg { width: 11px; height: 11px; stroke: var(--green); fill: none; stroke-width: 2.6; }
.vidinfo { padding: 11px 2px 0; }
.vidtitle { font-size: 13.5px; font-weight: 600; color: var(--fg); line-height: 1.35; }
.vidsub { font-size: 11.5px; color: var(--muted); margin-top: 4px; }

/* detail modal — wider format lands as .mcard.mwide + scoped extensions;
   base .mscrim/.modal/.mcard/.mbody/.mfoot/.dclose/.toast are F2a, reused. */
.mcard.mwide { width: 560px; position: relative; overflow: hidden; }
.mwide .mbody h2 { font-family: var(--font-display); font-size: 19px; font-weight: 700; letter-spacing: -.01em; }
.docmodalhd { display: flex; gap: 15px; align-items: center; padding: 20px 22px; border-bottom: 1px solid var(--line-soft); }
.docmodalhd .di { width: 52px; height: 62px; }
.docmodalhd h2 { font-family: var(--font-display); font-size: 19px; font-weight: 700; letter-spacing: -.01em; }
.docmodalhd .dclose { margin-left: auto; }
.player { aspect-ratio: 16/9; position: relative; }
/* real playback (UAT r6): the media element fills the player; portrait sources letterbox on black */
.player .realvid { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: #000; }
.player .play { position: absolute; inset: 0; display: grid; place-items: center; cursor: pointer; background: none; border: none; width: 100%; }
.player .play span { width: 64px; height: 64px; border-radius: 50%; background: var(--green); color: var(--on-green); display: grid; place-items: center; box-shadow: 0 8px 30px -6px rgba(79, 255, 139, .5); }
.player .play span svg { width: 26px; height: 26px; }
.player .dclose { position: absolute; top: 14px; right: 14px; z-index: 2; background: rgba(0, 0, 0, .45); color: #fff; border-color: transparent; }
.mmeta { font-size: 12px; color: var(--fg3); margin-top: 7px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.mmeta .sep { width: 3px; height: 3px; border-radius: 50%; background: var(--dim); }
.mdesc { font-size: 13px; color: var(--fg2); line-height: 1.6; margin-top: 13px; }

/* library toolbar stacks the search over the filter zone at the narrow breakpoint */
@media (max-width: 720px) {
  .tbar .search { flex: 1 0 100%; border-right: none; border-bottom: 1px solid var(--line-soft); }
  .tbfilt { width: 100%; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   F2c CALENDAR (Fuda T0-664 §01.5) — the athlete Calendar (view + reschedule-
   request), ported from the operator-approved mockup (artifact 1c54a7d7) onto the
   F2a blueprint primitives. Colours resolve from the OKLCH ladder + the on-green
   trio + the F2a event vars (--green/--event-assess/--amber/--event-checkin) — the
   type→colour map is var-based (per-element --tc custom prop), ZERO new :root vars
   (§01.5, measured three ways). Mockup token names mapped at authoring time
   (--void→--c-void, --base→--c-base, --surface→--c-surface, --surface2→
   --c-surface-2, --green-deep[dark-fill]→--green-fill, --display→--font-display,
   --body→--font-body, #08160d→--on-green, #eafff2→--on-green-fill,
   #bff5d1→--on-green-tint). Empty/btn/dclose/fld/fl/in/textarea.in/toast/ti/
   flabel/eyebrow/hcell/frame/gsec/gcell/tablesec are REUSED from F2a/F2b.
   Event drawer lands as its OWN primitive (.drawer family — Q4), not a restyled
   .mcard. RM/admin residue (.atable, .acbox, .reqacts, .confm, .segsel, .btn-danger,
   .aini, .selpill, .pag, .emailstat, etc.) is NOT ported (§01.5, D-39). New classes
   verified absent at 8bc959a by mechanical sweep. Scrim/overlay literals (rgba,
   #000) + the select chevron data-URI stroke %238f9a8f are AC-3 exempt (verbatim).
   ═══════════════════════════════════════════════════════════════════════════ */

/* agenda empty-state extension (base .empty is F2a, reused) */
.empty .big { font-family: var(--font-display); font-size: 15px; color: var(--fg2); font-weight: 700; margin-bottom: 6px; }

/* icon button (absent in repo — ported from the mockup) */
.ic { display: grid; place-items: center; width: 34px; height: 34px; border: 1px solid var(--line-soft); color: var(--fg3); cursor: pointer; background: none; transition: .14s var(--ease); }
.ic:hover:not(:disabled) { border-color: var(--green-quiet); color: var(--fg); }
.ic:disabled { opacity: .35; cursor: not-allowed; }
.ic svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 2; }

/* calbar: month nav + view toggle + type filters */
.calbar { padding: 11px 18px; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; min-height: 57px; }
.monthnav { display: flex; align-items: center; gap: 6px; }
.monthnav .ic { width: 32px; height: 32px; }
.monthlbl { font-family: var(--font-display); font-size: 15px; font-weight: 700; letter-spacing: -.01em; min-width: 140px; text-align: center; }
.btn-today { height: 32px; padding: 0 13px; font-size: 12px; border-radius: 60px; border: 1px solid var(--line); background: transparent; color: var(--fg2); font-weight: 600; cursor: pointer; font-family: var(--font-body); transition: .16s var(--ease); }
.btn-today:hover { border-color: var(--fg3); color: var(--fg); }
.viewtog { display: inline-flex; border: 1px solid var(--line-soft); border-radius: 60px; overflow: hidden; }
.viewtog button { height: 32px; padding: 0 14px; font-size: 12px; font-weight: 600; color: var(--fg3); background: transparent; cursor: pointer; font-family: var(--font-body); transition: .14s var(--ease); }
.viewtog button.on { background: var(--green-fill); color: var(--on-green-fill); }
.typefilters { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tchip { display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 12px; border-radius: 60px; border: 1px solid var(--line-soft); background: var(--c-void); color: var(--fg3); font-size: 11.5px; font-weight: 600; cursor: pointer; font-family: var(--font-body); transition: .14s var(--ease); }
.tchip .sw { width: 9px; height: 9px; border-radius: 3px; background: var(--tc); }
.tchip.off { opacity: .4; }
.tchip:hover { border-color: var(--fg3); }

/* month grid (calwrap = grid: month main + 316px rail; flex:1 to fill the frame) */
.calwrap { grid-template-columns: 1fr 316px; grid-template-rows: 1fr; flex: 1; }
.calmain { padding: 0; display: flex; flex-direction: column; background: var(--c-void); }
.wkrow { display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid var(--line-soft); }
.wkrow span { padding: 9px 10px; font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--fg3); font-weight: 600; }
.calgrid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; background: var(--line-soft); border-bottom: 1px solid var(--line-soft); }
.dc { background: var(--c-base); min-height: 104px; padding: 6px 7px 8px; display: flex; flex-direction: column; gap: 4px; cursor: pointer; text-align: left; }
.dc.out { background: var(--c-void); }
.dnum { display: flex; align-items: center; justify-content: flex-start; }
.dnum .dd { font-size: 11.5px; font-weight: 600; color: var(--fg3); font-variant-numeric: tabular-nums; width: 22px; height: 22px; display: grid; place-items: center; }
.dc.out .dnum .dd { color: var(--dim); }
.dc.today .dnum .dd { background: var(--green); color: var(--on-green); border-radius: 50%; font-weight: 700; }
.dc.sel .dnum .dd { box-shadow: 0 0 0 1.5px var(--green); border-radius: 50%; }

/* event pill (--tc colour tint + left bar; requested = dashed + amber glyph; past = dimmed) */
.evp { display: flex; align-items: center; gap: 6px; padding: 3px 7px; border-radius: 5px; font-size: 11px; font-weight: 600; color: var(--fg2); background: color-mix(in oklch, var(--tc) 12%, var(--c-surface)); border-left: 3px solid var(--tc); cursor: pointer; white-space: nowrap; overflow: hidden; text-align: left; width: 100%; transition: .12s var(--ease); }
.evp:hover { background: color-mix(in oklch, var(--tc) 20%, var(--c-surface)); color: var(--fg); }
.evp .et { font-variant-numeric: tabular-nums; color: var(--fg3); font-weight: 600; flex-shrink: 0; }
.evp .en { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.evp.req { border-left-style: dashed; }
.evp.past { opacity: .5; }
.evp .rq { margin-left: auto; color: var(--amber); flex-shrink: 0; display: grid; place-items: center; }
.evp .rq svg { width: 11px; height: 11px; stroke: currentColor; fill: none; stroke-width: 2.2; }
.evmore { font-size: 10.5px; color: var(--muted); font-weight: 600; padding: 1px 7px; cursor: pointer; background: none; text-align: left; font-family: var(--font-body); }
.evmore:hover { color: var(--green-quiet); }

/* mobile day dots + selected-day panel (revealed ≤720px) */
.dots { display: none; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.dots .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--tc); }
.dots .dmore { font-size: 9px; color: var(--muted); font-weight: 700; }
.daypanel { display: none; border-top: 1px solid var(--line-soft); background: var(--c-base); }
.daypanel .dphd { padding: 12px 16px; font-family: var(--font-display); font-size: 13px; font-weight: 700; border-bottom: 1px solid var(--line-soft); }
.daypanel .dplist { padding: 0 16px 8px; }

/* right rail: pending requests / upcoming / legend */
.calrail { padding: 0; display: flex; flex-direction: column; background: var(--c-void); }
.railsec { padding: 15px 18px; border-bottom: 1px solid var(--line-soft); }
.railsec:last-child { border-bottom: none; }
.railh { display: flex; align-items: center; gap: 9px; margin-bottom: 12px; }
.railh .rt { font-family: var(--font-display); font-size: 13px; font-weight: 700; letter-spacing: -.01em; }
.railh .cnt { font-size: 10.5px; font-weight: 700; color: var(--amber); background: color-mix(in oklch, var(--amber) 14%, transparent); padding: 2px 8px; border-radius: 60px; }
.reqcard { border: 1px solid color-mix(in oklch, var(--amber) 34%, transparent); background: color-mix(in oklch, var(--amber) 5%, transparent); padding: 11px 12px; display: flex; flex-direction: column; gap: 9px; margin-bottom: 10px; cursor: pointer; text-align: left; width: 100%; }
.reqcard:last-child { margin-bottom: 0; }
.reqtop { display: flex; align-items: center; gap: 9px; }
.reqico { width: 28px; height: 28px; flex-shrink: 0; display: grid; place-items: center; background: var(--c-surface-2); color: var(--fg2); }
.reqico svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 2; }
.reqn { font-size: 12.5px; font-weight: 600; color: var(--fg); }
.reqty { font-size: 11px; color: var(--fg3); margin-top: 1px; display: flex; align-items: center; gap: 6px; }
.reqmove { font-size: 11.5px; color: var(--fg2); display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.reqmove .from { color: var(--muted); text-decoration: line-through; }
.reqmove .to { color: var(--green-quiet); font-weight: 600; }
.reqmove svg { width: 12px; height: 12px; stroke: var(--fg3); fill: none; stroke-width: 2; }

/* F3c (T0-672 §05.3): admin-calendar-only additions. The athlete calendar CSS
   family above is REUSED, not re-ported; genuinely new here are the create-form
   predictive-search list, the request-card stale marker (I-1) + reason/daypart
   meta, and the day-panel empty affordance. Zero new tokens (AC-15). */
.reqmeta { font-size: 11px; color: var(--fg3); }
.reqreason { font-size: 11.5px; color: var(--fg2); line-height: 1.4; }
.reqstale { font-size: 11px; font-weight: 600; color: var(--amber); }
.reqcard.stale { opacity: .72; cursor: default; border-color: color-mix(in oklch, var(--muted) 34%, transparent); background: color-mix(in oklch, var(--muted) 5%, transparent); }
.acempty { font-size: 12px; color: var(--muted); padding: 14px 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.acpick { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 12px; border: 1px solid var(--line); background: var(--c-surface); font-size: 13px; color: var(--fg); }
.aclist { list-style: none; margin: 5px 0 0; padding: 0; border: 1px solid var(--line); background: var(--c-base); max-height: 190px; overflow-y: auto; }
.acopt { display: block; width: 100%; text-align: left; padding: 9px 12px; font-size: 13px; color: var(--fg); background: none; border: none; border-bottom: 1px solid var(--line-soft); cursor: pointer; font-family: var(--font-body); }
.acopt:last-child { border-bottom: none; }
.acopt:hover, .acopt:focus-visible { background: color-mix(in oklch, var(--green) 8%, transparent); }
.fhint { color: var(--muted); font-weight: 500; }
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* rail upcoming (compact agenda rows) + type legend */
.agenda { display: flex; flex-direction: column; gap: 2px; }
.agi { display: flex; gap: 12px; align-items: center; padding: 9px 0; border-bottom: 1px solid color-mix(in oklch, var(--line-soft) 45%, transparent); cursor: pointer; text-align: left; width: 100%; background: none; }
.agi:last-child { border-bottom: none; }
.agi:hover .agn { color: var(--green-quiet); }
.agdate { flex: 0 0 42px; text-align: center; }
.agdate .agd { font-family: var(--font-display); font-size: 17px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.agdate .agm { font-size: 9.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin-top: 2px; }
.agmain { min-width: 0; flex: 1; }
.agn { font-size: 12.5px; font-weight: 600; color: var(--fg); display: flex; align-items: center; gap: 7px; }
.agn .sw { width: 8px; height: 8px; border-radius: 2px; background: var(--tc); flex-shrink: 0; }
.agsub { font-size: 11px; color: var(--muted); margin-top: 2px; }
.leg { display: flex; flex-wrap: wrap; gap: 9px; }
.legi { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; color: var(--fg3); }
.legi .sw { width: 10px; height: 10px; border-radius: 3px; background: var(--tc); }

/* agenda full view (today-forward, grouped by day) */
.agfull { padding: 6px 20px 14px; }
.agday { padding-top: 14px; }
.agdayh { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--fg3); font-weight: 600; padding: 8px 0; border-bottom: 1px solid var(--line-soft); }
.agrow { display: flex; align-items: center; gap: 14px; padding: 12px 0; border-bottom: 1px solid color-mix(in oklch, var(--line-soft) 45%, transparent); cursor: pointer; text-align: left; width: 100%; background: none; }
.agrow:hover { background: var(--c-surface); }
.agrow .tm { flex: 0 0 108px; font-size: 12.5px; font-weight: 600; color: var(--fg2); font-variant-numeric: tabular-nums; }
.agrow .bar { width: 3px; align-self: stretch; background: var(--tc); border-radius: 3px; }
.agrow .info { flex: 1; min-width: 0; }
.agrow .t1 { font-size: 13px; font-weight: 600; color: var(--fg); }
.agrow .t2 { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.agrow .rqp { flex-shrink: 0; }

/* status pill (text, not colour-only — triple-encodes state with dashed pill + rail card) */
.stpill { display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px; font-weight: 700; padding: 2px 9px; border-radius: 60px; text-transform: uppercase; letter-spacing: .03em; }
.st-confirmed { background: color-mix(in oklch, var(--green) 12%, transparent); color: var(--green); }
/* PR-C / D-15 — the unmirrored badge on the ATHLETE PROFILE. Same WORDS as the
   calendar's pill (an RM reading both surfaces must not learn two phrasings for
   one state), but not the same colour, and the difference is load-bearing: on
   the calendar the pill sits inside a labelled "Staff calendar" row, so its
   meaning is carried by the label. On the profile it rides inline in a sentence
   with no label, where st-confirmed's green would read as a state achieved
   rather than a state missed. Amber is the tree's existing "attention, not
   error" token (.stpill.proc). Additive only — the calendar rule is untouched. */
.stpill.nomirror { background: color-mix(in oklch, var(--amber) 14%, transparent); color: var(--amber); }
.st-requested { background: color-mix(in oklch, var(--amber) 14%, transparent); color: var(--amber); }
.st-done { background: var(--c-surface-2); color: var(--fg2); }
.st-declined { background: color-mix(in oklch, var(--red) 12%, transparent); color: var(--red); }

/* UAT round 3 — athlete assessment booking panel (Assessment stage only). */
.bookcell { display: flex; flex-direction: column; gap: 14px; padding: 18px 20px; }
.bookform { display: grid; grid-template-columns: 1.2fr 1fr 1fr auto; gap: 10px; align-items: end; }
.bookform .fld { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.bookform .bookno { grid-column: 1 / -2; }
.bookform .btn { white-space: nowrap; }
.booklist { display: flex; flex-direction: column; }
.bookrow { display: flex; align-items: center; gap: 12px; padding: 8px 2px; border-top: 1px solid color-mix(in oklch, var(--line-soft) 55%, transparent); font-size: 12.5px; }
.bookrow .bk { font-weight: 600; color: var(--fg); }
.bookrow .bd { color: var(--fg3); }
.bookrow .stpill { margin-left: auto; }
@media (max-width: 760px) { .bookform { grid-template-columns: 1fr 1fr; } .bookform .bookno { grid-column: 1 / -1; } }

/* event drawer — NEW primitive (right slide-in, scrim), reuses .dclose + field classes */
.dscrim { display: none; position: fixed; inset: 0; background: rgba(0, 0, 0, .55); z-index: 78; }
.dscrim.show { display: block; }
.drawer { position: fixed; top: 0; right: 0; height: 100dvh; width: 452px; max-width: 94vw; background: var(--c-base); border-left: 1px solid var(--line); transform: translateX(100%); transition: transform .3s var(--ease); z-index: 80; display: flex; flex-direction: column; }
.drawer.open { transform: translateX(0); box-shadow: -24px 0 60px -20px rgba(0, 0, 0, .7); }
.dhead { padding: 18px 22px; border-bottom: 1px solid var(--line-soft); display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.dhead h2 { font-family: var(--font-display); font-size: 19px; font-weight: 700; letter-spacing: -.01em; }
.dhead .dh2 { font-size: 12.5px; color: var(--fg3); margin-top: 4px; }
.dbody { flex: 1; overflow: auto; padding: 20px 22px; display: flex; flex-direction: column; gap: 15px; }
.dfoot { padding: 15px 22px; border-top: 1px solid var(--line-soft); display: flex; gap: 10px; justify-content: flex-end; background: color-mix(in oklch, var(--c-base) 92%, transparent); }
.drow { display: flex; align-items: center; gap: 11px; padding: 11px 0; border-bottom: 1px solid color-mix(in oklch, var(--line-soft) 50%, transparent); }
.drow:last-child { border-bottom: none; }
.drow .dk { flex: 0 0 96px; font-size: 11.5px; color: var(--fg3); font-weight: 600; }
.drow .dv { font-size: 13px; color: var(--fg); font-weight: 500; display: flex; align-items: center; gap: 8px; }
.reqbox { border: 1px solid color-mix(in oklch, var(--amber) 36%, transparent); background: color-mix(in oklch, var(--amber) 6%, transparent); padding: 12px 13px; display: flex; flex-direction: column; gap: 9px; }
.reqbox .rt { font-size: 11.5px; color: var(--amber); font-weight: 700; display: flex; align-items: center; gap: 7px; }
.reqbox .rt svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2; }
.reqbox .rhint { font-size: 11.5px; color: var(--fg2); line-height: 1.45; }
/* T0-881 — the completed-sitting state in the drawer's "Staff calendar" row.
   `.dv` is a centred flex ROW sized for a pill plus a button; the completed
   branch has no button and a wrapping muted hint instead, so its content
   stacks. Scoped under `.drow .dv` — no other row's layout is touched. */
.drow .dv .mstack { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; }
.drow .dv .mstack .dhint { font-size: 11.5px; color: var(--fg2); font-weight: 500; line-height: 1.45; }
.rsintro { font-size: 13px; color: var(--muted); line-height: 1.5; margin: 0 0 4px; }

/* T0-835 — the availability strip. Google busy time used to arrive as a line of
   prose ("Busy: 09:00–10:00"), which reads as a note; it is an obstacle, so it
   is drawn as filled time on a 24-hour rail. Advisory only — nothing here
   disables a control (§01.4). Zero new tokens (AC-15): amber is the same
   attention colour the reschedule cards already use. */
/* T0-838: DE-AMBERED. --amber is the Onboarding-call type colour AND was the
   fill this box and the month strip used for Google busy time. The collision
   was dormant while the strip only ever drew busy time; the moment portal
   events joined the same bar an amber block became ambiguous — onboarding
   call, or the RM's dentist? Google-sourced time is now achromatic and HATCHED
   everywhere it is drawn, so texture carries the distinction in greyscale too.
   The type keeps amber; the diary does not. */
.avbox { gap: 10px; border-color: color-mix(in oklch, var(--event-unavail) 40%, transparent); background: color-mix(in oklch, var(--event-unavail) 6%, transparent); }
.avbox .rt { color: var(--fg2); }
.avbox.av-clear { border-color: var(--line-soft); background: var(--c-void); }
.avbox.av-clear .rt { color: var(--fg3); }
/* A safety net for the zone stamp, NOT a cure — the record is corrected here.
   An earlier note claimed the auto margin pushed this label off the right edge
   at phone width. It does not, and never did: measured at bafa097, the label
   sits 1px inside the box's content edge at a 500px viewport, a 360px
   container and a 210px container alike, and never wraps because it fits.
   The clipped label seen in the first capture was the CAPTURE — headless
   Chrome clamps its window to ~500px, so a 430px screenshot is a crop of a
   500px viewport and simply cut the label off. Keep the wrap anyway: a longer
   zone name ("GMT+5:30") in a narrower box would otherwise have nowhere to go,
   and a wrapped label is always better than a truncated one. */
.avbox .rt { flex-wrap: wrap; row-gap: 3px; }
.avbox .avtz { margin-left: auto; font-size: 10.5px; font-weight: 600; color: var(--muted); }
.avrail { position: relative; height: 12px; background: var(--c-surface-2); border-radius: 3px; overflow: hidden; }
.avblk { position: absolute; top: 0; bottom: 0; border-radius: 2px; background-color: color-mix(in oklch, var(--event-unavail) 38%, transparent); background-image: repeating-linear-gradient(135deg, var(--event-unavail) 0 2px, transparent 2px 5px); }
.avticks { position: relative; height: 11px; margin-top: 4px; }
.avtick { position: absolute; top: 0; transform: translateX(-50%); font-size: 9px; font-weight: 600; color: var(--fg3); font-variant-numeric: tabular-nums; }
.avticks .avtick:first-child { transform: none; }
.avticks .avtick:last-child { transform: translateX(-100%); }
.avlist { display: flex; flex-wrap: wrap; gap: 6px; }
.avrange { font-size: 11px; font-weight: 600; color: var(--fg2); font-variant-numeric: tabular-nums; background: color-mix(in oklch, var(--event-unavail) 16%, transparent); padding: 2px 8px; border-radius: 60px; }

/* T0-838 — THE DAY-LOAD BAR. Replaces the 5px busy-only month strip, whose
   rules are deleted rather than left as selectors nothing emits.

   ONE INSTRUMENT: how spoken-for is this day, and by how many things. Pinned to
   the cell floor (margin-top:auto) so bars align across a row and a week reads
   as one comparison. It is NOT a timeline — see the island comment for why
   positioning was discarded.

   THE 2px GAP IS LOAD-BEARING and is the one piece of the anatomy not to trade
   away. Adjacent type colours measure 1.02:1 to 1.26:1 against each other: a
   continuous bar of them is a single smear, uncountable AND a WCAG 1.4.11
   failure. The gap in the track colour cures the contrast bar and carries the
   count with one mechanism.

   The 1px border is what makes an EMPTY track visible: "we looked, nothing on"
   is a positive statement and needs a positive mark. */
.loadbar { position: relative; display: flex; align-items: stretch; gap: 2px; align-self: stretch; width: 100%; height: 9px; margin-top: auto; border: 1px solid var(--line-soft); border-radius: 3px; background: var(--c-surface-2); }

/* flex-shrink: 1 (the middle `1`) is the F-1 cure (D787). The per-segment
   inline width is TRUE duration ∝ the 8h scale, but nothing capped the SUM and
   the 2px gaps ride OUTSIDE the width model, so a >480-min day (and even a
   480-min day, on gaps alone) painted segments past the bar into the next cell —
   the container is deliberately un-clipped so tooltips can escape. Letting the
   segments shrink hands the browser the one job it does natively: the flex
   free-space computation subtracts the gaps too, so segments + gaps can never
   exceed the bar. Shrink is a UNIFORM scale (shrink ∝ flex-basis at equal
   flex-shrink), so 90/60 stays 3:2 inside the clamp. flex-grow stays 0 — a light
   day must still read as a part-full bar, never stretch to fill. */
.lbseg { position: relative; flex: 0 1 auto; min-width: 6px; border-radius: 2px; }
.lbseg.k-ma { background: var(--event-ma); }
.lbseg.k-test { background: var(--green); }
.lbseg.k-assess { background: var(--event-assess); }
.lbseg.k-call { background: var(--amber); }
.lbseg.k-checkin { background: var(--event-checkin); }
/* Achromatic + 135deg hatch. Texture is the second channel, so the state
   survives greyscale and a colour-blind reader, not only the amber collision. */
.lbseg.k-busy { background-color: color-mix(in oklch, var(--event-unavail) 38%, transparent); background-image: repeating-linear-gradient(135deg, var(--event-unavail) 0 2px, transparent 2px 5px); }
/* THE LIGHT-THEME SUBSTITUTION, and the only one. --green measures 3.02:1
   against the track in light — a rounding error away from failing 1.4.11 — so
   the ABILITY TEST SEGMENT alone takes the deeper --green-press (3.92:1). The
   chip, the legend swatch and every other use of --green are untouched: a
   single-role substitution inside the bar, not a palette change. Dark theme is
   entirely unaffected. */
:root[data-theme="light"] .lbseg.k-test { background: var(--green-press); }

/* UNKNOWN IS NOT FREE — the third state, carried by STRUCTURE rather than by
   colour alone. A dashed border in a grid of solid ones is legible at a glance
   across a whole month and survives greyscale. */
.loadbar.lb-unread { border-style: dashed; border-color: var(--event-unknown); background: transparent; }
.lbq { position: relative; flex: 0 0 auto; display: grid; place-items: center; width: 10px; font-size: 7px; line-height: 1; font-weight: 700; color: var(--event-unknown); }
/* The bar CAPS rather than lying about scale: at or past 480 committed minutes
   (the boundary day is already gap-compressed) it draws an overflow caret at the
   right edge. */
.loadbar.lb-over::after { content: ""; position: absolute; top: 0; bottom: 0; right: 0; width: 5px; border-radius: 0 2px 2px 0; background: linear-gradient(90deg, transparent, var(--fg3)); }

/* THE HOVER TOOLTIP IS A POINTER-ONLY ENHANCEMENT, bound behind (hover:hover)
   and (pointer:fine) on purpose. A long-press has no affordance, collides with
   the iOS text-selection and context-menu gesture, and fails silently for
   anyone who does not know to try it. On touch the DAY PANEL is the tooltip:
   tapping a cell opens the full schedule beneath the grid — scrollable,
   non-occluding, needing no dismissal. That also settles WCAG 2.5.8: a 9px
   segment can never be a 24x24 target and does not need to be, because the
   equivalent function sits on the 104px cell on every device. */
.lbtip { display: none; }
@media (hover: hover) and (pointer: fine) {
  .lbseg:hover > .lbtip, .lbq:hover > .lbtip { display: flex; }
  .lbtip { position: absolute; bottom: calc(100% + 7px); left: -6px; z-index: 90; flex-direction: column; gap: 3px; width: max-content; max-width: 232px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 6px; background: var(--c-surface-2); box-shadow: 0 14px 34px -12px rgba(0, 0, 0, .66); pointer-events: none; text-align: left; white-space: normal; }
  .lbth { display: flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 700; color: var(--fg); }
  .lbsw { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }
  .lbsw.k-ma { background: var(--event-ma); }
  .lbsw.k-test { background: var(--green); }
  .lbsw.k-assess { background: var(--event-assess); }
  .lbsw.k-call { background: var(--amber); }
  .lbsw.k-checkin { background: var(--event-checkin); }
  .lbsw.k-busy { background-color: color-mix(in oklch, var(--event-unavail) 38%, transparent); background-image: repeating-linear-gradient(135deg, var(--event-unavail) 0 2px, transparent 2px 5px); }
  .lbsw.k-unknown { background: transparent; border: 1px dashed var(--event-unknown); }
  :root[data-theme="light"] .lbsw.k-test { background: var(--green-press); }
  .lbtt { font-size: 11.5px; font-weight: 600; color: var(--fg2); font-variant-numeric: tabular-nums; }
  .lbtr { display: flex; gap: 10px; font-size: 11.5px; margin-top: 1px; }
  .lbtk { flex: 0 0 52px; color: var(--fg3); }
  .lbtv { color: var(--fg); min-width: 0; }
  .lbtn { font-size: 11px; color: var(--muted); line-height: 1.45; margin-top: 4px; padding-top: 6px; border-top: 1px solid var(--line-soft); }
}

/* T0-838 — the agenda / day-panel SCHEDULE ROW. Explicit time RANGE (the
   durations model is what makes an end time possible), a type-coloured rule, a
   type chip on a 16% tint of its own colour, athlete over location, the RM slot
   in the Everyone scope only, and the status pill. */
.agrow .tychip { flex: 0 0 auto; font-size: 11px; font-weight: 600; padding: 3px 9px; border-radius: 60px; color: var(--tc); background: color-mix(in oklch, var(--tc) 16%, transparent); white-space: nowrap; }
.agrow .tychip.ty-unavail { color: var(--fg2); background: color-mix(in oklch, var(--event-unavail) 16%, transparent); }
.agrow .agrm { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 7px; font-size: 11.5px; color: var(--fg2); white-space: nowrap; }
.agrow .rmini { width: 22px; height: 22px; display: grid; place-items: center; font-size: 9.5px; font-weight: 700; font-family: var(--font-display); background: var(--green-fill); color: var(--on-green-fill); border-radius: 50%; }
/* Google-sourced rows ARE listed, interleaved chronologically, in a muted
   register — omitting them would make the agenda claim a day is emptier than it
   is, the very defect the month strip was built to cure. */
.agrow.ag-unavail { cursor: default; }
.agrow.ag-unavail .t1 { color: var(--fg2); font-weight: 600; }
.agrow .bar.bar-hatch { background-color: color-mix(in oklch, var(--event-unavail) 38%, transparent); background-image: repeating-linear-gradient(135deg, var(--event-unavail) 0 2px, transparent 2px 5px); }
/* An unknown day must NEVER render as a day with no rows, which is what "free"
   looks like. One ghost line instead. */
.agrow.ag-unknown { cursor: default; gap: 10px; }
.agrow .ghostbar { flex: 0 0 108px; height: 9px; border: 1px dashed var(--event-unknown); border-radius: 3px; }
.agdayh { display: flex; align-items: center; gap: 12px; }
.agdayh .agdn { flex: 0 0 auto; }
.agdayh .agdtz { font-size: 10px; letter-spacing: 0; text-transform: none; color: var(--muted); font-weight: 500; }
/* The same instrument as the month cell, at 140px: whoever learned to read it
   upstairs reads it here for free, and the agenda gains a per-day density
   signal it has never had. */
.agdayh .agdbar { flex: 0 0 140px; margin-left: auto; display: block; }
.agdayh .loadbar { margin-top: 0; }

/* T0-838 — the desktop day panel (§07). It was already rendered into the DOM at
   every viewport; only display:none hid it above 720px. Enabling it makes the
   touch strategy coherent (the panel is the canonical detail surface, so the
   tooltip is an accelerator everywhere rather than a dependency anywhere) and
   gives the 24-hour rail a permanent home on the surface where an RM books. */
.daypanel { display: block; }
.daypanel .dphd { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.daypanel .dptz { font-family: var(--font-body); font-size: 10.5px; font-weight: 600; color: var(--muted); }
.dpsplit { display: grid; grid-template-columns: 1fr 300px; gap: 18px; padding: 4px 16px 14px; align-items: start; }
.dpsplit .dplist { padding: 0; min-width: 0; }
.dpsplit .dpav { min-width: 0; }
@media (max-width: 940px) {
  .dpsplit { grid-template-columns: 1fr; gap: 12px; }
}

/* styled select — absent in repo; ported. Chevron data-URI stroke %238f9a8f is
   AC-3 EXEMPT (verbatim from the mockup, not an on-green palette value). */
select.in { appearance: none; -webkit-appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238f9a8f' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: calc(100% - 13px) center; background-size: 14px; padding-right: 34px; }

/* T0-838 — THE ≤560px AGENDA REFLOW. .agrow's flat flex row does not reflow: at
   390px the athlete name collides with the status pill. That is a PRE-EXISTING
   property of the row, not something this build introduced, but this build made
   it worse by adding the RM slot and widening the time slot from 62px to 108px.
   Time and status take their own line above; rule, chip, info and RM stack
   full-width below. Specified in the design proposal so it was not discovered
   in UAT. */
@media (max-width: 560px) {
  .agrow { display: grid; grid-template-columns: 3px minmax(0, 1fr) auto; column-gap: 11px; row-gap: 7px; align-items: center; }
  .agrow .tm { grid-area: 1 / 1 / 2 / 3; flex: none; }
  .agrow .stpill { grid-area: 1 / 3 / 2 / 4; justify-self: end; }
  .agrow .bar { grid-area: 2 / 1 / 5 / 2; }
  .agrow .tychip { grid-area: 2 / 2 / 3 / 4; justify-self: start; }
  .agrow .info { grid-area: 3 / 2 / 4 / 4; }
  .agrow .agrm { grid-area: 4 / 2 / 5 / 4; }
  .agrow.ag-unknown { grid-template-columns: 1fr; }
  .agrow.ag-unknown .ghostbar { grid-area: auto; flex: none; width: 108px; }
  .agrow.ag-unknown .info { grid-area: auto; }
  .agdayh { flex-wrap: wrap; row-gap: 6px; }
  .agdayh .agdbar { flex: 1 1 100%; margin-left: 0; }
}

/* responsive: rail stacks ≤1040px; month → dot-grid + day-panel ≤720px */
@media (max-width: 1040px) {
  .calwrap { grid-template-columns: 1fr; grid-template-rows: auto; flex: 0 1 auto; }
}
@media (max-width: 720px) {
  .calbar { gap: 9px; }
  .monthnav { flex: 1; }
  .monthlbl { flex: 1; min-width: 0; }
  .viewtog { order: 4; }
  .typefilters { width: 100%; margin-left: 0; order: 5; }
  .wkrow span { padding: 7px 2px; text-align: center; font-size: 9px; letter-spacing: .04em; }
  .dc { min-height: 46px; padding: 5px 3px; align-items: center; gap: 3px; }
  .dc .dnum { justify-content: center; width: 100%; }
  .dc .dnum .dd { width: 22px; height: 22px; font-size: 12px; }
  .dc .evp, .dc .evmore { display: none; }
  .dots { display: flex; justify-content: center; }
  /* T0-838: 9px reads a hue and still leaves the cell to the pills; at ≤720px
     the cell is 46px tall and the bar takes its compact height. This is a
     VIEWPORT property, not a call-site flag — the same instrument, thinner
     where the cell is. */
  .dc > .loadbar { height: 7px; }
  .dc.sel { background: color-mix(in oklch, var(--green) 8%, var(--c-base)); }
  .dc.sel.out { background: color-mix(in oklch, var(--green) 8%, var(--c-void)); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   F2d PROFILE / ACCOUNT (Fuda T0-665 §01.6) — the athlete Profile settings screen,
   ported from the operator-approved mockup (artifact 3a107338) onto the F2a
   blueprint primitives. Colours resolve from the OKLCH ladder + the on-green trio;
   mockup token names mapped at authoring time (--void→--c-void, --base→--c-base,
   --surface→--c-surface, --surface2→--c-surface-2, --green-deep[dark-fill]→
   --green-fill, --display→--font-display, --body→--font-body, #08160d→--on-green,
   #eafff2→--on-green-fill). Frame/gsec/gcell, hcell/eyebrow/sub/h1, btn/btn-solid/
   btn-line, fld/fl/in/textarea.in, the FULL modal primitive (mscrim/modal/mcard/
   mhead/meyebrow/mbody/mfoot/dclose) and toast/ti are REUSED from F2a — the mockup's
   e-sign modal consumes those names directly (Header correction 2). ZERO new :root
   vars (§01.6, measured three ways: no new names, colliding names map to repo values,
   no JS-embedded colour escapees). Collision resolved: the mockup's panel-left block
   `.pl` collides with the repo's BARE `.pl` (globals.css:265, Home post-legend item
   consumed by submit-post-modal.tsx) — ported as `.pmain` so no scoping accident.
   Confirm dialog lands as `.mcard.mconf` + scoped extensions (NOT the mockup's forked
   .confm/.confcard family). One ink-on-red literal `#2a0808` kept literal per the trio
   rule (single site); the `.btn-solid-danger:hover` color-mix uses the `black` keyword
   (exempt alongside the scrim rgba literals). Removed connected-accounts residue
   (.socic, D-37) and all admin/settings-family residue NOT ported. New classes verified
   absent at the F2c tip by mechanical sweep.
   ═══════════════════════════════════════════════════════════════════════════ */

/* settings shell: left nav column + content pane inside one blueprint section */
.setwrap { grid-template-columns: 236px 1fr; grid-template-rows: 1fr; flex: 1; min-width: 0; }
.setwrap > .gcell { min-width: 0; }
.setnavc { padding: 0; background: var(--c-void); display: flex; flex-direction: column; min-width: 0; }
.setnav { display: flex; flex-direction: column; padding: 12px 0; max-width: 100%; }
.setnav button { display: flex; align-items: center; gap: 11px; padding: 10px 18px; color: var(--fg3); font-size: 13px; font-weight: 500; background: none; border: none; border-left: 2px solid transparent; cursor: pointer; transition: .14s var(--ease); text-align: left; font-family: var(--font-body); }
.setnav button:hover { background: var(--c-surface); color: var(--fg2); }
.setnav button.on { background: var(--green-fill); color: var(--on-green-fill); border-left: 2px solid var(--green); }
.setnav button svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.7; flex-shrink: 0; }
.setmain { padding: 0; background: var(--c-void); display: flex; flex-direction: column; min-width: 0; }
.setmain .setsec, .setmain .panel { min-width: 0; }
.setsec { padding: 24px 26px; max-width: 760px; display: flex; flex-direction: column; gap: 20px; }
.sech { display: flex; align-items: flex-start; gap: 14px; }
.sect { font-family: var(--font-display); font-size: 18px; font-weight: 700; letter-spacing: -.01em; }
.secd { font-size: 12.5px; color: var(--fg3); margin-top: 6px; line-height: 1.55; max-width: 560px; }

/* panel + rows (panel-left ports as .pmain — the bare .pl collision, §01.6) */
.panel { border: 1px solid var(--line-soft); background: var(--c-base); }
.panel .prow { padding: 13px 16px; display: flex; align-items: center; gap: 14px; border-bottom: 1px solid color-mix(in oklch, var(--line-soft) 55%, transparent); }
.panel .prow:last-child { border-bottom: none; }
.prow .pmain { flex: 1; min-width: 0; }
.prow .pmain .n { font-size: 13px; font-weight: 600; color: var(--fg); display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.prow .pmain .d { font-size: 11.5px; color: var(--muted); margin-top: 3px; line-height: 1.45; }
.prow .pr { flex-shrink: 0; display: flex; align-items: center; gap: 10px; }
.rd { font-size: 13px; color: var(--fg); font-variant-numeric: tabular-nums; }

/* status pill (text, not colour-only) */
.statuspill { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 600; padding: 3px 10px; border-radius: 60px; }
.statuspill.ok { background: color-mix(in oklch, var(--green) 13%, transparent); color: var(--green-quiet); }
.statuspill.off { background: var(--c-surface); color: var(--muted); }
.statuspill .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* toggle switch (role=switch button) */
.tgl { width: 40px; height: 23px; border-radius: 60px; background: var(--c-surface-2); border: 1px solid var(--line-soft); position: relative; cursor: pointer; transition: .16s var(--ease); flex-shrink: 0; padding: 0; }
.tgl.on { background: var(--green); border-color: var(--green); }
.tgl .kn { position: absolute; top: 2px; left: 2px; width: 17px; height: 17px; border-radius: 50%; background: var(--fg2); transition: .18s var(--ease); }
.tgl.on .kn { left: 19px; background: var(--on-green); }

/* coach team row */
.tm-av { width: 34px; height: 34px; display: grid; place-items: center; font-size: 12px; font-weight: 700; background: var(--c-surface-2); color: var(--fg2); font-family: var(--font-display); flex-shrink: 0; }
.tm-em { font-size: 11.5px; color: var(--muted); margin-top: 1px; }

/* profile avatar card — square initials plate flush to the card edge (D-38) */
.profcard { padding: 0; overflow: hidden; }
.profhead { display: flex; align-items: stretch; min-height: 88px; }
.profav { flex: 0 0 88px; width: 88px; display: grid; place-items: center; font-size: 24px; font-weight: 700; letter-spacing: .02em; background: var(--green-fill); color: var(--green); border-radius: 0; border-right: 1px solid var(--line); font-family: var(--font-display); }
.profmeta { display: flex; flex-direction: column; justify-content: center; padding: 0 20px; min-width: 0; }
.profmeta .phn { font-size: 16px; font-weight: 700; color: var(--fg); }
.profmeta .phe { font-size: 12.5px; color: var(--muted); margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.profhead .cbtn { margin: auto 18px auto auto; flex-shrink: 0; }

/* settings field grid + save row */
.setrow { display: flex; flex-direction: column; gap: 6px; }
.setgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.setsave { display: flex; gap: 10px; align-items: center; padding-top: 2px; flex-wrap: wrap; }
.setsave .hint { font-size: 11.5px; color: var(--muted); }

/* pill-radius select wrapper (dial-code + gender) — distinct from F2c square select.in */
.selpill { position: relative; display: inline-flex; }
.selpill select { appearance: none; -webkit-appearance: none; height: 44px; background: var(--c-surface); border: 1px solid var(--line-soft); color: var(--fg); font-size: 13.5px; font-family: var(--font-body); padding: 0 34px 0 13px; cursor: pointer; outline: none; transition: .16s var(--ease); border-radius: 60px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238f9a8f' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: calc(100% - 13px) center; background-size: 14px; }
.selpill select:focus { border-color: var(--green-quiet); }

/* phone: dial-code select + number entry */
.phonegrp { display: flex; gap: 8px; align-items: stretch; }
.phonegrp .phonecc { flex: 0 0 auto; }
.phonegrp .phonecc select { padding-right: 30px; }
.phonegrp .in { flex: 1; min-width: 0; }

/* country autocomplete (predictive ISO enum — combobox) */
.acwrap { position: relative; }
.acwrap .in { padding-right: 52px; }
.acbadge { position: absolute; top: 50%; right: 10px; transform: translateY(-50%); font-size: 10.5px; font-weight: 700; letter-spacing: .06em; color: var(--green); background: var(--green-fill); border: 1px solid var(--green-dim); border-radius: 4px; padding: 2px 6px; font-variant-numeric: tabular-nums; pointer-events: none; }
.acmenu { position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 30; background: var(--c-surface); border: 1px solid var(--line); border-radius: 6px; max-height: 236px; overflow-y: auto; box-shadow: 0 16px 40px -14px rgba(0, 0, 0, .7); display: none; }
.acmenu.open { display: block; }
.acitem { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 12px; font-size: 13px; color: var(--fg); cursor: pointer; border-bottom: 1px solid var(--line-soft); background: none; width: 100%; text-align: left; font-family: var(--font-body); }
.acitem:last-child { border-bottom: none; }
.acitem:hover, .acitem.act { background: color-mix(in oklch, var(--green) 8%, transparent); }
.acitem .aciso { font-size: 11px; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; letter-spacing: .04em; }
.acitem.empty { color: var(--muted); cursor: default; justify-content: flex-start; }
.acitem.empty:hover { background: none; }

/* white date-picker icon (native indicator is dark on the dark field — D-38 filter, not a colour) */
input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(1) brightness(1.9); opacity: .8; cursor: pointer; }

/* e-sign modal body: preview banner + clause acknowledgement list + signature pad */
.pvbanner { font-size: 12px; line-height: 1.5; color: var(--amber); background: color-mix(in oklch, var(--amber) 8%, transparent); border: 1px solid color-mix(in oklch, var(--amber) 34%, transparent); padding: 10px 12px; border-radius: 2px; }
.clauses { display: flex; flex-direction: column; margin: 4px 0 2px; border: 1px solid var(--line); border-radius: 2px; overflow: hidden; }
.clause { display: flex; gap: 11px; align-items: flex-start; padding: 12px 13px; cursor: pointer; border-bottom: 1px solid var(--line); transition: background .15s var(--ease); background: none; width: 100%; text-align: left; font-family: var(--font-body); }
.clause:last-child { border-bottom: none; }
.clause:hover { background: rgba(255, 255, 255, .02); }
.clause .cbx { width: 19px; height: 19px; flex-shrink: 0; border: 1.6px solid var(--line); border-radius: 3px; display: grid; place-items: center; margin-top: 1px; transition: .15s var(--ease); }
.clause .cbx svg { width: 12px; height: 12px; stroke: var(--c-void); fill: none; stroke-width: 3; opacity: 0; transition: .15s; }
.clause.on .cbx { background: var(--green); border-color: var(--green); }
.clause.on .cbx svg { opacity: 1; }
.clause .ctxt { font-size: 12.8px; line-height: 1.5; color: var(--fg); }
.sigwrap { margin-top: 15px; }
.sigpad { font-family: 'Austin Pen', cursive; font-weight: 700; font-size: 24px; letter-spacing: .5px; color: var(--green); background: var(--c-void); border: 1px solid var(--line); border-bottom: 2px solid var(--green); border-radius: 2px 2px 0 0; padding: 15px 16px 9px; width: 100%; box-sizing: border-box; outline: none; }
.sigpad::placeholder { font-family: 'Austin Pen', cursive; font-weight: 700; color: var(--muted); opacity: .45; }
.sigmeta { display: flex; justify-content: space-between; font-size: 11px; color: var(--muted); padding: 7px 2px 0; letter-spacing: .02em; }

/* confirm dialog — the mockup's forked .confm family lands on the reused .modal/.mcard
   primitive as .mcard.mconf + scoped extensions (§01.6), role=alertdialog. */
.mcard.mconf { width: 404px; }
.mconf .confhead { padding: 20px 22px 14px; display: flex; gap: 13px; align-items: flex-start; }
.mconf .conficon { width: 36px; height: 36px; flex-shrink: 0; border-radius: 50%; display: grid; place-items: center; background: color-mix(in oklch, var(--red) 13%, transparent); border: 1px solid color-mix(in oklch, var(--red) 40%, transparent); color: var(--red); }
.mconf .conficon svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2; }
.mconf .conft { font-family: var(--font-display); font-size: 16px; font-weight: 700; }
.mconf .confd { font-size: 12.5px; color: var(--fg3); margin-top: 5px; line-height: 1.5; }
.mconf .confd b { color: var(--fg2); }

/* destructive confirm button — one ink-on-red literal (#2a0808) kept literal per the
   trio rule (single site); hover mix uses the `black` keyword (grep-exempt). */
.btn-solid-danger { background: var(--red); color: var(--on-red); font-weight: 700; border: 1px solid var(--red); } /* T0-683 A-6: ink via --on-red (base no-op #2a0808; light #fffafb = 4.64:1 AA on deepened red) */
.btn-solid-danger:hover { background: color-mix(in oklch, var(--red) 88%, black); }

/* responsive: nav collapses to a wrapping row ≤860px; avatar CTA hides ≤520px.
   UAT r7 follow-up (operator ruling): the collapsed tabs are SQUARE, edge-to-edge
   grid cells — the blueprint seam idiom (1px line-colour gaps, no radius, no pill
   padding) — not rounded chips. */
@media (max-width: 860px) {
  .setwrap { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .setnav { flex-direction: row; flex-wrap: wrap; padding: 0; gap: 1px; background: var(--line-soft); border-bottom: 1px solid var(--line-soft); }
  .setnav button { flex: 1 1 auto; justify-content: center; background: var(--c-void); border-left: none; border-bottom: 2px solid transparent; white-space: nowrap; padding: 10px 14px; border-radius: 0; }
  .setnav button:hover { background: var(--c-surface); }
  .setnav button.on { border-left: none; border-bottom: 2px solid var(--green); }
  .setgrid { grid-template-columns: 1fr; }
  .setsec { padding: 18px 16px; }
  .profhead { flex-wrap: wrap; gap: 12px; }
  .profhead .cbtn { margin-left: 0; }
  .prow { flex-wrap: wrap; }
  .prow .pr { margin-left: auto; }
}
@media (max-width: 520px) {
  .profhead .cbtn { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   F3a CONSOLE DASHBOARD (Fuda T0-666 §01.3) — the admin funnel-explorer, ported
   from the operator-approved dashboard mockup (artifact 06c11f86) onto the F2a
   blueprint primitives. Colours resolve from the OKLCH ladder + the on-green trio
   + the 1 new --on-amber var; mockup token names mapped at authoring time
   (--void→--c-void, --base→--c-base, --surface→--c-surface, --surface2→
   --c-surface-2, --display→--font-display, --body→--font-body, #08160d→--on-green,
   #eafff2→--on-green-fill, #bff5d1→--on-green-tint, #f2d79a→--on-amber). The mockup
   value drift is NOT ported (repo ladder governs). Shell classes (.app/.side/.nav/
   .who/.mobar/.navscrim) + .frame/.gsec/.gcell + .hcell/.hcell h1/.hcell .sub/
   .eyebrow/.tnum are REUSED from F2a/F2b. Generic mockup names are scoped or
   renamed to avoid collisions (no bare generic selectors, §05.3): the mockup's
   .panel (funnel cell) → .fpanel (F2d already owns .panel); .hd → .fhd; the whole
   detail-panel family (.row/.big/.conv/.people/.viewall/.hint/.ph/.dh…) is scoped
   under .detail; .hint → .dhint. The DROPPED mockup machinery (period .seg control,
   proofs-pending chips, mockstamp) is NOT ported (§05.3). New classes verified
   absent at a91566d by mechanical sweep. The map cell (.mapsec family) lands with
   the coverage-map unit. Chevron data-URI stroke %2392a596 is AC-3 EXEMPT (verbatim
   from the mockup, not an on-green palette value).
   ═══════════════════════════════════════════════════════════════════════════ */

/* section grids */
.gsec.tiles { grid-template-columns: repeat(5, 1fr); }
.gsec.main2 { grid-template-columns: 1.42fr 1fr; }

/* header scope control */
.scope { margin-left: auto; display: flex; flex-direction: column; gap: 8px; align-items: flex-end; }
.mapfilter { position: relative; display: inline-flex; align-items: center; flex-shrink: 0; }
.mapfilter::after { content: ""; position: absolute; right: 13px; top: 50%; width: 12px; height: 12px; transform: translateY(-50%); pointer-events: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2392a596' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: center; }
.mapfilter select { appearance: none; -webkit-appearance: none; background: var(--c-void); border: 1px solid var(--line-soft); border-radius: 60px; color: var(--fg2); font-family: var(--font-body); font-size: 12px; font-weight: 600; padding: 6px 30px 6px 14px; cursor: pointer; outline: none; transition: .16s var(--ease); }
.mapfilter select:hover { border-color: var(--green-quiet); color: var(--fg); }
.mapfilter select:focus { border-color: var(--green-quiet); color: var(--fg); }

/* KPI tiles */
.tile { padding: 15px 17px; }
.tile .k { font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--fg3); font-weight: 600; }
.tile .v { font-family: var(--font-display); font-size: 26px; font-weight: 700; margin-top: 9px; letter-spacing: -.01em; }
.tile .d { font-size: 11.5px; margin-top: 3px; color: var(--muted); }
.tile .d.warn { color: var(--amber); }
/* the needs-attention tile is a real <button> — normalise it to a cell */
.tile.attn { position: relative; cursor: pointer; transition: .16s var(--ease); display: block; width: 100%; text-align: left; border: none; font-family: var(--font-body); color: inherit; background: var(--c-base); }
.tile.attn:hover { background: color-mix(in oklch, var(--amber) 6%, var(--c-base)); }
.tile.attn.active { background: color-mix(in oklch, var(--amber) 9%, var(--c-base)); box-shadow: inset 2px 0 0 var(--amber); }
.tile.attn .go { position: absolute; top: 15px; right: 15px; color: var(--amber); font-size: 13px; opacity: .7; }

/* funnel panel */
.fpanel { padding: 16px 20px 20px; display: flex; flex-direction: column; min-height: 0; }
.fhd { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 6px; gap: 12px; flex-wrap: wrap; }
.fhd h2 { font-family: var(--font-display); font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: .1em; color: var(--fg2); }
.fhd .note { font-size: 11px; color: var(--muted); }
.funnelwrap { flex: 1; display: flex; align-items: center; padding-top: 4px; }
svg.funnel { width: 100%; height: auto; display: block; overflow: visible; }
.band { cursor: pointer; }
.band .poly { transition: .18s var(--ease); }
.band:hover .poly { filter: brightness(1.16); }
.band.sel .poly { stroke: var(--green); stroke-width: 1.6; }
.band:focus { outline: none; }
.band:focus-visible .poly { stroke: var(--green); stroke-width: 1.6; }
.band .cnt { font-family: var(--font-display); font-weight: 700; fill: var(--fg); font-variant-numeric: tabular-nums; }
.band.sel .cnt, .band:hover .cnt { fill: var(--on-green-fill); }
/* Light-mode legibility: the funnel band is a pale green-tint surface (not the
   deep --green-fill), so the light --on-green-fill ink (#eafff2) is near-white on
   near-white. Give the highlighted/hover count a dark green in LIGHT only; dark
   theme keeps --on-green-fill (no-op). Operator UAT 2026-07-08. */
:root[data-theme="light"] .band.sel .cnt,
:root[data-theme="light"] .band:hover .cnt { fill: var(--green-quiet); }
.band .lab { fill: var(--fg3); font-size: 12.5px; font-weight: 500; }
.band:hover .lab, .band.sel .lab { fill: var(--fg); }
.band .pct { fill: var(--dim); font-size: 10.5px; font-variant-numeric: tabular-nums; }
.gate { fill: var(--amber); font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; font-weight: 600; }
.gateline { stroke: color-mix(in oklch, var(--amber) 50%, transparent); stroke-width: 1; stroke-dasharray: 3 3; }

/* stage / needs-attention detail panel — every generic scoped under .detail */
.detail { padding: 18px 20px; display: flex; flex-direction: column; min-height: 0; }
.detail .ph { font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; font-weight: 600; color: var(--green-quiet); }
.detail .ph.warn { color: var(--amber); }
.detail .dh { font-family: var(--font-display); font-size: 21px; font-weight: 700; margin-top: 5px; letter-spacing: -.01em; }
.detail .dhsub { font-size: 12px; color: var(--fg3); margin-top: 7px; line-height: 1.45; }
/* T0-837 — reserved description region. Every stage description occupies the SAME
   grid cell, so the region is as tall as the tallest one at the current width and
   selecting a stage cannot resize it. `visibility: hidden` (not display:none)
   is load-bearing: the seven inactive descriptions must still be laid out to
   contribute their height, while staying out of the a11y tree and the tab order.
   Measured, not assumed — the tallest description wraps to 3 lines at 1600px and
   4 at 1024px, so no fixed line-count reserve would have held across widths. */
.detail .dhsub { display: grid; }
.detail .dhsub > .dsub { grid-area: 1 / 1; visibility: hidden; }
.detail .dhsub > .dsub.on { visibility: visible; }
.detail .big { display: flex; align-items: baseline; gap: 10px; margin: 13px 0 2px; }
.detail .big .n { font-family: var(--font-display); font-size: 42px; font-weight: 700; line-height: 1; letter-spacing: -.02em; }
.detail .big .u { font-size: 12.5px; color: var(--fg3); }
/* two-figure cohort pair: entered (primary) · still here now (secondary) */
.detail .bigpair { display: flex; align-items: baseline; gap: 26px; }
.detail .bigpair .big { flex-direction: column; align-items: flex-start; gap: 4px; }
.detail .bigpair .herefig .n { font-size: 28px; color: var(--green-quiet); }
.detail .conv { display: flex; gap: 16px; margin: 14px 0 16px; padding: 13px 0; border-top: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft); }
.detail .conv div { display: flex; flex-direction: column; gap: 3px; }
.detail .conv .cl { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); font-weight: 600; }
.detail .conv .cv { font-size: 15.5px; font-weight: 600; font-family: var(--font-display); }
.detail .conv .cv.g { color: var(--green-quiet); }
.detail .conv .cv.r { color: var(--red); }
.detail .people { font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--fg3); font-weight: 600; margin-bottom: 6px; }
/* T0-837 — reserved people-list region. The live rows and a hidden five-row
   skeleton share grid cell 1/1, so the region is always exactly five rows tall
   whether the selected stage holds five athletes, one, or none. Five is the cap
   both list producers enforce (stageDetailFor slices 5; the attn list slices 5),
   so this is the true worst case, not a guess. This was the LARGER of the two
   jitter drivers — up to ~247px of movement per selection, against ~52px from
   the description. align-content:start keeps the reserve at its content height
   when the panel is stretched taller than its content by the grid row. */
.detail .plist { flex: 1; min-height: 0; overflow: auto; display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; }
.detail .plist > .plist-live,
.detail .plist > .plist-reserve { grid-area: 1 / 1; display: flex; flex-direction: column; min-width: 0; }
.detail .plist > .plist-reserve { visibility: hidden; pointer-events: none; }
.detail .row { display: flex; align-items: center; gap: 11px; padding: 7px 8px; transition: .14s var(--ease); border-bottom: 1px solid color-mix(in oklch, var(--line-soft) 55%, transparent); }
/* UAT round 3: people rows are real links to the athlete profile — reset the
   anchor defaults so the row reads exactly as before. */
.detail a.row { text-decoration: none; color: inherit; cursor: pointer; }
.detail .row:last-child { border-bottom: none; }
.detail .row:hover { background: var(--c-surface); }
.detail .row .ini { width: 28px; height: 28px; display: grid; place-items: center; font-size: 11px; font-weight: 700; background: var(--c-surface-2); color: var(--fg2); font-family: var(--font-display); flex-shrink: 0; }
.detail .row .nm { font-size: 12.5px; font-weight: 500; color: var(--fg); }
.detail .row .mt { font-size: 10.5px; color: var(--muted); }
.detail .row .meta2 { margin-left: auto; display: flex; align-items: center; gap: 9px; }
.detail .row .rm { font-size: 10.5px; color: var(--fg3); }
.detail .dstuck { color: var(--red); font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.detail .row .arw { color: var(--dim); transition: .14s var(--ease); }
.detail .row:hover .arw { color: var(--green-quiet); transform: translateX(2px); }
/* T0-837 — reserved click-through region. The live pill and the seven other
   stages' pills share grid cell 1/1, so the pill is as tall as the tallest label
   at the current width. Only observable at ~320px, where the longest stage label
   wraps to two lines and every other stage fits on one. */
.detail .viewallwrap { display: grid; }
.detail .viewallwrap > * { grid-area: 1 / 1; }
.detail .viewall-reserve { visibility: hidden; pointer-events: none; }
.detail .viewall { display: block; width: 100%; text-align: center; margin-top: 12px; padding: 11px 18px; border: 1px solid color-mix(in oklch, var(--green) 45%, transparent); border-radius: 60px; background: transparent; font-size: 12.5px; font-weight: 600; color: var(--green-quiet); transition: .16s var(--ease); text-decoration: none; }
.detail .viewall:hover { border-color: var(--green); background: color-mix(in oklch, var(--green) 8%, transparent); color: var(--on-green-tint); }
.detail .viewall.warn { border-color: color-mix(in oklch, var(--amber) 45%, transparent); color: var(--amber); }
.detail .viewall.warn:hover { border-color: var(--amber); background: color-mix(in oklch, var(--amber) 8%, transparent); color: var(--on-amber); }
.detail .dhint { font-size: 11px; color: var(--muted); text-align: center; margin-top: 11px; }
.detail .dhint b { color: var(--fg3); font-weight: 600; }

/* console dashboard responsive — LAST in source so the tightening wins (media
   source-order rule): main2 stacks, tiles wrap, the attn tile spans full width. */
@media (max-width: 940px) {
  .gsec.main2 { grid-template-columns: 1fr; }
  .gsec.tiles { grid-template-columns: repeat(2, 1fr); }
  .tile.attn { grid-column: 1 / -1; }
  .scope { flex-direction: row; align-items: center; justify-content: flex-start; flex-wrap: wrap; gap: 8px; }
}
@media (max-width: 560px) {
  .gsec.tiles { grid-template-columns: 1fr; }
}

/* ── F3a COVERAGE MAP (Fuda T0-666 §01.3, O-35) — the choropleth cell, ported from
   the dashboard mockup onto the OKLCH ladder. .fhd/.mapfilter are reused from the
   console header above. Tokens mapped (--void→--c-void, --surface→--c-surface,
   --surface2→--c-surface-2, --display→--font-display). Path geometry is the
   decimated world-map-data module (§03.2). ── */
.gsec.mapsec { flex: 1; }
.mapcell { padding: 16px 20px 20px; display: flex; flex-direction: column; min-height: 0; }
.mapgrid { display: grid; grid-template-columns: 2.1fr 1fr; gap: 24px; align-items: start; flex: 1; min-height: 0; margin-top: 8px; }
.mapbox { position: relative; min-width: 0; }
#worldmap { width: 100%; height: auto; display: block; }
#worldmap path { fill: var(--c-surface); stroke: var(--c-void); stroke-width: .4; transition: fill .16s; }
#worldmap path.cov { cursor: pointer; }
#worldmap path.cov:hover { stroke: var(--green); stroke-width: .9; }
.maptip { position: absolute; pointer-events: none; background: var(--c-void); border: 1px solid var(--line); padding: 6px 10px; font-size: 11.5px; color: var(--fg2); transform: translate(-50%, -135%); white-space: nowrap; opacity: 0; transition: opacity .1s; z-index: 20; }
.maptip b { color: var(--fg); font-family: var(--font-display); font-weight: 700; }
.maplegend { position: absolute; left: 12px; bottom: 10px; display: flex; align-items: center; gap: 8px; font-size: 9px; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); pointer-events: none; z-index: 3; }
.maplegend .legram { width: 84px; height: 7px; }
.legram { height: 8px; background: linear-gradient(90deg, color-mix(in oklch, var(--green) 18%, var(--c-surface)), var(--green)); }
.maplist { display: flex; flex-direction: column; min-width: 0; }
.maplist .mt { font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--fg3); font-weight: 600; margin-bottom: 10px; }
.mrow { display: flex; align-items: center; gap: 10px; padding: 4px 0; }
.mrow .flag { font-size: 12.5px; color: var(--fg2); width: 108px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mrow .bar { flex: 1; height: 7px; background: var(--c-surface-2); overflow: hidden; }
.mrow .barf { display: block; height: 100%; background: linear-gradient(90deg, color-mix(in oklch, var(--green) 50%, var(--c-surface)), var(--green)); }
.mrow .mn { font-family: var(--font-display); font-size: 13px; font-weight: 700; color: var(--fg); width: 26px; text-align: right; font-variant-numeric: tabular-nums; }

@media (max-width: 940px) {
  .mapgrid { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   F3b PROOF REVIEW (Fuda T0-667 §01.3 / §05) — the queue screen, review modal,
   nav badge, dashboard needs-attention chips, and the athlete rejected-post lines.
   REUSED (not re-ported): .modal/.mscrim/.mcard/.mhead/.meyebrow/.mbody/.mfoot/
   .dclose/.fld/.in/.toast/.empty/.statcell/.statk/.statv/.statsub/.search/.selpill/
   .flabel/.pc/.postgrid/.btn-solid/.btn-line/.btn-solid-danger/.eyebrow. NEW ports
   only: the queue family, .aini, the nav .badge, .mechtag, review-modal preview,
   the reject-toast variant, the chip, and the reject-line family. Colours resolve
   from the repo OKLCH ladder — ZERO new tokens (#2a0808 rides .btn-solid-danger;
   #08160d/#eafff2/#bff5d1 ride --on-green/--on-green-fill/--on-green-tint).
   Responsive rules sit LAST in source so the tightening wins the cascade.
   ═══════════════════════════════════════════════════════════════════════════ */

/* nav badge — amber count pill, right-aligned; the shell hides it at zero */
.side .nav a .badge { margin-left: auto; background: color-mix(in oklch, var(--amber) 20%, transparent); color: var(--amber); font-size: 10px; font-weight: 700; padding: 1px 7px; border-radius: 60px; font-variant-numeric: tabular-nums; }

/* proof-review 3-col stat strip (base .statcell/.statk/.statv/.statsub reused) */
.pgstats { grid-template-columns: repeat(3, 1fr); }
.statv.warn { color: var(--amber); }

/* filter toolbar (base .search/.selpill/.flabel reused) */
.toolcell { padding: 0; display: flex; align-items: stretch; flex-wrap: wrap; min-height: 57px; }
.toolcell .search { flex: 0 0 300px; min-height: 57px; border-right: 1px solid var(--line-soft); }
.filters { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; padding: 10px 18px; flex: 1; }

/* queue header + rows */
.qhead { padding: 12px 20px; display: flex; align-items: center; gap: 10px; border-bottom: 1px solid var(--line-soft); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--fg3); font-weight: 600; }
.qrow { padding: 14px 20px; display: flex; align-items: center; gap: 18px; border-bottom: 1px solid color-mix(in oklch, var(--line-soft) 55%, transparent); transition: .12s var(--ease); }
.qrow:last-child { border-bottom: none; }
.qrow:hover { background: var(--c-surface); }
.qath { display: flex; align-items: center; gap: 11px; flex: 0 0 210px; min-width: 0; }
.aini { width: 34px; height: 34px; flex-shrink: 0; display: grid; place-items: center; font-size: 11.5px; font-weight: 700; background: var(--c-surface-2); color: var(--fg2); font-family: var(--font-display); }
.qan1 { font-size: 13px; font-weight: 600; color: var(--fg); }
.qan2 { margin-top: 3px; }
.qbadge-stage { display: inline-flex; align-items: center; gap: 6px; padding: 2px 9px; border: 1px solid var(--line-soft); border-radius: 60px; font-size: 10.5px; font-weight: 600; color: var(--fg3); white-space: nowrap; }
.qbadge-stage .d { width: 5px; height: 5px; border-radius: 50%; flex-shrink: 0; }
.ph-Prospect { background: var(--muted); }
.ph-Onboarding { background: var(--amber); }
.ph-Engagement { background: var(--green); }
.qproof { display: flex; align-items: center; gap: 12px; flex: 1; min-width: 220px; cursor: pointer; background: none; border: none; text-align: left; padding: 0; font-family: inherit; color: inherit; }
.qopen { flex-shrink: 0; color: var(--dim); opacity: 0; transition: .14s var(--ease); display: grid; place-items: center; }
.qopen svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2; }
.qproof:hover .qopen, .qproof:focus-visible .qopen { opacity: 1; color: var(--green-quiet); }
.qtile { width: 44px; height: 44px; flex-shrink: 0; border-radius: 4px; display: grid; place-items: center; background: var(--c-surface-2); color: var(--fg3); border: 1.5px solid var(--line-soft); }
.qtile svg { width: 20px; height: 20px; }
.qpmeta { min-width: 0; }
.qpn { font-size: 13px; font-weight: 600; color: var(--fg); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.qpd { font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.mechtag { font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--fg3); display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; border: 1px solid var(--line-soft); border-radius: 60px; white-space: nowrap; }
.mechtag svg { width: 11px; height: 11px; stroke: currentColor; fill: none; stroke-width: 2; }
.qwait { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; padding: 4px 11px; border-radius: 60px; border: 1px solid var(--line-soft); font-size: 11.5px; font-weight: 600; color: var(--fg3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.qwait svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2; }
.qwait.late { border-color: color-mix(in oklch, var(--amber) 48%, transparent); background: color-mix(in oklch, var(--amber) 10%, transparent); color: var(--amber); }
.qacts { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.btn-approve { background: transparent; border: 1px solid color-mix(in oklch, var(--green) 45%, transparent); color: var(--green-quiet); height: 34px; padding: 0 14px; font-size: 12px; border-radius: 60px; display: inline-flex; align-items: center; gap: 7px; font-weight: 600; transition: .16s var(--ease); cursor: pointer; font-family: var(--font-body); }
.btn-approve:hover { border-color: var(--green); background: color-mix(in oklch, var(--green) 9%, transparent); color: var(--on-green-tint); }
.btn-reject { background: transparent; border: 1px solid color-mix(in oklch, var(--red) 42%, transparent); color: var(--red); height: 34px; padding: 0 14px; font-size: 12px; border-radius: 60px; display: inline-flex; align-items: center; gap: 7px; font-weight: 600; transition: .16s var(--ease); cursor: pointer; font-family: var(--font-body); }
.btn-reject:hover { border-color: var(--red); background: color-mix(in oklch, var(--red) 9%, transparent); }
.btn-approve svg, .btn-reject svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2.2; }

/* review modal preview (base .modal/.mcard/.mhead/.mbody/.mfoot/.dclose reused) */
.prpost { display: flex; align-items: center; gap: 13px; border: 1px solid var(--line-soft); background: var(--c-surface); padding: 11px 12px; }
.prthumb { width: 52px; height: 52px; flex-shrink: 0; border-radius: 4px; display: grid; place-items: center; background: var(--c-surface-2); color: var(--fg3); border: 1.5px solid var(--line-soft); }
.prthumb svg { width: 22px; height: 22px; }
.prpmeta { min-width: 0; }
.prpmeta .pf0 { font-size: 12.5px; font-weight: 600; color: var(--fg); }
.prpmeta .pf2 { font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.prhint { font-size: 11.5px; color: var(--fg3); line-height: 1.5; }
.fld .opt { color: var(--muted); font-weight: 500; }
.docprev { border: 1px solid var(--line-soft); background: var(--c-void); overflow: hidden; }
.viewlink { display: flex; align-items: center; justify-content: center; gap: 7px; padding: 11px; font-size: 12px; font-weight: 600; color: var(--green-quiet); text-decoration: none; }
.viewlink:hover { color: var(--on-green-tint); }
.viewlink svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2; }
.mfoot .idem { margin-right: auto; font-size: 11px; color: var(--muted); display: inline-flex; align-items: center; gap: 6px; }
.mfoot .idem svg { width: 13px; height: 13px; stroke: var(--green-dim); fill: none; stroke-width: 1.9; }
.merr { font-size: 12px; line-height: 1.45; padding: 9px 12px; border: 1px solid color-mix(in oklch, var(--red) 40%, transparent); background: color-mix(in oklch, var(--red) 9%, transparent); color: color-mix(in oklch, var(--red) 82%, white); }

/* reject-toast variant (base .toast reused; approve = default green .ti) */
.toast.rej .ti { background: color-mix(in oklch, var(--red) 12%, transparent); color: var(--red); border: 1px solid color-mix(in oklch, var(--red) 40%, transparent); }

/* dashboard needs-attention proofs chip — light amber ink on a dark amber-tint
   ground (the repo amber-pill idiom), consuming --on-amber (F3a) */
.chip-proofs { display: inline-flex; align-items: center; padding: 2px 9px; border-radius: 60px; border: 1px solid color-mix(in oklch, var(--amber) 34%, transparent); background: color-mix(in oklch, var(--amber) 14%, transparent); color: var(--on-amber); font-size: 10.5px; font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* athlete rejected-post lines (portal Home posts block) */
.rejlist { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.rejitem { display: flex; align-items: flex-start; gap: 11px; border: 1px solid color-mix(in oklch, var(--red) 30%, transparent); background: color-mix(in oklch, var(--red) 5%, transparent); padding: 11px 12px; }
.reji { width: 22px; height: 22px; flex-shrink: 0; display: grid; place-items: center; border-radius: 50%; background: color-mix(in oklch, var(--red) 12%, transparent); color: var(--red); border: 1px solid color-mix(in oklch, var(--red) 34%, transparent); }
.reji svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2.4; }
.rejmain { min-width: 0; flex: 1; }
.rejn { font-size: 12.5px; font-weight: 600; color: var(--fg); }
.rejd { font-size: 11.5px; color: var(--fg3); margin-top: 3px; line-height: 1.45; }
.rejlink { display: inline-block; margin-top: 5px; font-size: 11px; color: var(--green-quiet); text-decoration: none; border-bottom: 1px solid color-mix(in oklch, var(--green) 28%, transparent); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rejact { flex-shrink: 0; }

@media (max-width: 940px) {
  .pgstats { grid-template-columns: 1fr; }
  .toolcell .search { flex: 1 0 100%; border-right: none; border-bottom: 1px solid var(--line-soft); }
  .filters { width: 100%; }
  .qrow { flex-wrap: wrap; gap: 12px; }
  .qath { flex: 0 0 100%; }
  .qproof { flex: 1 0 100%; }
  .qacts { margin-left: auto; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   ENTRY SURFACES (Fuda T0-675 §01.4) — the two sessionless entry surfaces (staff
   login + magic-link-expired landing) reskinned from the legacy V6 centred card
   onto the blueprint-grid system. A centred .frame of .gsec/.gcell cells with the
   signature crosshair joiners; the head/body cells carry padding + layout via
   utilities (the pages' established idiom). Every visual class is REUSED, never
   re-ported: .frame/.gsec/.gcell (blueprint.tsx wrappers), .brandsub (the eyebrow
   idiom under the wordmark), .fld/.fl/.in (44px form family), .btn/.btn-solid (the
   system's one capsule; supplies --on-green, retiring the old #08160d literal),
   .bp-rise. Colours resolve exclusively from the existing OKLCH ladder — ZERO new
   :root vars. The single new rule below gives the login CTA a full-width, ≥48px
   touch target: .btn is a 38px inline capsule, so this overrides height/width by
   source order (defined after .btn). Verified absent at a61a2ba.
   ═══════════════════════════════════════════════════════════════════════════ */
.entrycta { width: 100%; height: 50px; font-size: 13.5px; }

/* ═══ ATHLETES ROSTER (F3d presentation pulled forward — operator demo-day ruling
   2026-07-06; design authority athletes-mockup.html; families new at this HEAD,
   verified absent; tokens resolve from the existing ladder, zero new vars) ═══ */
.gsec.tablesec{flex:1}
.tcell{overflow-x:auto;padding:0}
.atable{width:100%;border-collapse:collapse;font-size:13px;min-width:920px}
.atable thead th{text-align:left;padding:12px 20px;font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--fg3);font-weight:600;border-bottom:1px solid var(--line-soft);white-space:nowrap}
.atable thead th.so{cursor:pointer;user-select:none}
.atable thead th.so:hover{color:var(--fg2)}
.ar{color:var(--green-quiet);font-size:9px;margin-left:4px}
.atable tbody tr.arow{border-bottom:1px solid color-mix(in oklch,var(--line-soft) 55%,transparent);cursor:pointer;transition:.12s var(--ease)}
.atable tbody tr.arow:last-child{border-bottom:none}
/* D2008 — HOVER WAS WRITTEN AND HAS NEVER PAINTED.
   This rule shipped reading `background:var(--surface)`. `--surface` is declared
   NOWHERE in this sheet: it is a MOCKUP token name, and every sibling surface's
   header records mapping it to `--c-surface` at authoring time (see the F2a/F2b/
   settings/map/console blocks above — five separate migration notes). This one
   site was missed, and `var()` with no fallback is invalid at computed-value
   time, so `background` computed to unset — transparent — while the `outline:none`
   on the same selector DID apply. Net effect since the surface shipped: no hover
   feedback on any roster row, and an invisible keyboard focus state.
   The repair is the token, not a new treatment — `--c-surface` is exactly what
   .agrow, .qrow and `.detail .row` already hover to. */
.atable tbody tr.arow:hover{background:var(--c-surface);outline:none}
/* D2020 — THE FOCUS RING (Gate-3 D2014 blocking finding). Until this line the
   rule above also carried `:focus-visible`, so a keyboard-focused row got the
   hover surface and `outline:none`. Measured on painted pixels through a real
   Tab drive, that indicator was 1.081:1 (dark) / 1.064:1 (light) against WCAG
   2.2 SC 1.4.11's 3:1 — i.e. the invisible-focus defect D2008 set out to cure
   survived its own cure, because a row TINT is not a focus indicator: it is the
   same treatment the pointer already produces, and it has nowhere to draw the
   contrast from.
   The ring follows this sheet's strongest authored precedent, named as such in
   the .dclose header below: `.btn-line.gconnect:focus-visible` — 2px solid
   var(--green), a token declared in BOTH themes.
   `outline-offset` is NEGATIVE, unlike those precedents, because this is a <tr>
   in a `border-collapse:collapse` table: an outward ring would be drawn over
   the shared 1px row border (and, on the first cell, clipped by the
   `.tcell{overflow-x:auto}` scroll edge). Drawn 2px INSIDE, both of the ring's
   adjacent colours are the focused row's own surface.
   `outline`, not border or box-shadow: no reflow, and a box-shadow on a row box
   is not painted under border-collapse on either engine in use (the D2008 rail
   finding — that is why the pressed rail rides td:first-child).
   Decision 25 is untouched: the pressed rail is on `.pressed`, not on focus. */
.atable tbody tr.arow:focus-visible{background:var(--c-surface);outline:2px solid var(--green);outline-offset:-2px}
/* D2008 — CLICK CONFIRMATION. Stronger than hover and unmistakably a state, not
   a pointer position: the accent tint over the hover surface, plus the left
   accent rail already ratified for a selected/attention row (`.tile.attn.active`
   uses `inset 2px 0 0` for exactly this job). The rail rides the first cell
   rather than the <tr>: with `border-collapse:collapse` a box-shadow on a row
   box is not painted by Blink or WebKit, so on the <tr> it would resolve to
   nothing on the very browsers the operator uses. It must beat `:hover`, which
   is still true of the row under the pointer, hence the second selector. */
.atable tbody tr.arow.pressed,.atable tbody tr.arow.pressed:hover{background:color-mix(in oklch,var(--green) 9%,var(--c-surface))}
.atable tbody tr.arow.pressed td:first-child{box-shadow:inset 2px 0 0 var(--green)}
.atable tbody tr.arow.pressed .rowarw{color:var(--green-quiet);transform:translateX(2px)}
.atable td{padding:11px 20px;vertical-align:middle}
.aname{display:flex;align-items:center;gap:12px}
.an1{font-size:13px;font-weight:600;color:var(--fg)}
.an2{font-size:11.5px;color:var(--muted)}
.badge-stage{display:inline-flex;align-items:center;gap:7px;padding:3px 11px;border:1px solid var(--line-soft);border-radius:60px;font-size:11px;font-weight:600;color:var(--fg2);white-space:nowrap}
.badge-stage .d{width:6px;height:6px;border-radius:50%;flex-shrink:0}
/* UAT round 3 (mockup rowHtml): Certified rows carry the SF logomark in SF green
   instead of the phase dot. */
.markdot{width:13px;height:13px;color:var(--green);flex-shrink:0}
.ph-Prospect{background:var(--muted)}
.ph-Onboarding{background:var(--amber)}
.ph-Engagement{background:var(--green)}
.scell{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.pill-stuck{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:60px;border:1px solid color-mix(in oklch,var(--amber) 48%,transparent);background:color-mix(in oklch,var(--amber) 10%,transparent);color:var(--amber);font-size:10.5px;font-weight:700;white-space:nowrap;font-variant-numeric:tabular-nums}
.ohpcell{font-size:13px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--fg2)}
.hrscell{font-size:13px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--fg)}
.hu{color:var(--muted);font-weight:500;font-size:11px;margin-left:1px}
.rmcell{display:flex;align-items:center;gap:8px;color:var(--fg2);font-size:12.5px;white-space:nowrap}
/* Qualifying-country cell (mockup .ccell). UAT round 4: NO emoji flags — the
   ISO code renders in the account-mockup's green box (.acbadge treatment). */
.ccell{color:var(--fg2);font-size:12.5px;white-space:nowrap}
/* NB: the account mockup writes background:var(--green-deep) — in the MOCKUP's
   palette that name is the dark-fill role, which this repo calls --green-fill
   (the F2a naming-collision note); the repo's --green-deep is the bright V6
   ladder green and would drown the green text. */
.ccode{display:inline-block;font-size:10.5px;font-weight:700;letter-spacing:.06em;color:var(--green);background:var(--green-fill);border:1px solid var(--green-dim);border-radius:4px;padding:2px 6px;font-variant-numeric:tabular-nums;margin-right:6px;vertical-align:1px}
/* Add-drawer phone: dial-code select + national-number input on one line. */
.phrow{display:flex;gap:8px}
.phrow .selpill{flex-shrink:0}
.phrow .in{flex:1;min-width:0}
/* Country select with the green ISO badge (account-mockup acwrap/acbadge). */
.acwrap{position:relative}
.acwrap .acbadge{position:absolute;top:50%;right:30px;transform:translateY(-50%);margin-right:0;pointer-events:none}
.jcell{color:var(--muted);font-size:12px;white-space:nowrap}
.arwcell{text-align:right}
.rowarw{color:var(--dim);transition:.12s}
.arow:hover .rowarw{color:var(--green-quiet);transform:translateX(2px)}
/* Both row states are colour changes with a 120ms ease and one 2px nudge on the
   chevron. Under a reduced-motion request the colour still changes — that is the
   information — and the movement does not.
   D2020 — THIS BLOCK USED TO SIT ~40 LINES ABOVE, AND HALF OF IT WAS DEAD. A
   media query contributes NOTHING to specificity, so `.rowarw{transition:none}`
   in here tied with `.rowarw{color:var(--dim);transition:.12s}` at the rule
   directly above and LOST on source order: measured 0.12s with the media
   feature emulated active. `.atable tbody tr.arow` was fine only by accident —
   its own rule happens to precede the block. Moving the whole block below every
   rule it stills makes the win a property of position rather than of luck, and
   the arm that guards it now resolves the cascade (specificity, then order)
   instead of asserting the declaration is merely PRESENT. Keep this block last
   among the row/chevron rules. */
@media (prefers-reduced-motion: reduce) {
  .atable tbody tr.arow { transition: none }
  .rowarw { transition: none }
  .atable tbody tr.arow:hover .rowarw, .atable tbody tr.arow.pressed .rowarw { transform: none }
}
/* D1911 item 3 — the empty row's own padding was inert: `.aempty` is (0,1,0)
   and `.atable td` (0,1,1) below it wins, so the 28px never applied and the
   copy sat 11px under the header rule. Re-declared AT `.atable td.aempty`
   (0,2,1) so it actually reaches the cell, and the reserve is now vertical
   space for the ratified `.empty` block to centre inside rather than a
   padding number doing the centring itself. */
.atable td.aempty{padding:0;color:var(--muted);text-align:center;height:280px;vertical-align:middle}
/* D1923 sweep — NARROWED TO THE AXIS THIS RULE ACTUALLY NEEDS. It was
   `padding:0 20px`, which also overrode the HORIZONTAL padding and so beat the
   UAT r10 operator ruling below (`@media (max-width:700px)`: empties read
   left-aligned and ON the 16px page margin) by 4px, on the one surface that had
   just started carrying `.empty`. Only the VERTICAL padding needed zeroing —
   the td reserves the height and centres — so the horizontal axis goes back to
   `.empty` and its phone ruling governs untouched. Same fault class as the
   `.trackctl` blocker, found by sweeping it rather than by a second review. */
.atable td.aempty .empty{padding-top:0;padding-bottom:0}
.pagcell{padding:11px 20px;display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.perpage{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--fg3)}
.pnav{margin-left:auto;display:flex;align-items:center;gap:12px}
.pginfo{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.pgctrl{display:flex;align-items:center;gap:7px}
.pgnum{font-size:12.5px;color:var(--fg2);font-weight:600;font-variant-numeric:tabular-nums;min-width:52px;text-align:center}
.dform{flex:1;overflow:auto;padding:20px 22px;display:flex;flex-direction:column;gap:15px}
.dacts{display:flex;gap:10px;justify-content:flex-end;padding-top:6px}
.dferr{font-size:12.5px;color:var(--red)}
.selwide{width:100%}
.selwide select{width:100%}
@media (max-width:940px){.pnav{margin-left:0;width:100%;justify-content:space-between}}

/* ═══ ATHLETE PROFILE (design authority athlete-profile-mockup.html; operator
   directive 2026-07-06: bring the artifact to fruition). The first cut of this
   block redefined shared blueprint families (.statgrid/.pcell/.ptitle/.tl/…)
   at global scope and clobbered the portal-home styles that already carried
   the mockup's values — the "very broken" profile AND collateral drift. Cure:
   every profile-specific rule is scoped under .pfx (the profile page wrapper);
   shared families resolve to their one blueprint definition. ═══ */
.pfx .backlink{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;color:var(--fg3);text-decoration:none;transition:.14s var(--ease);align-self:flex-start}
.pfx .backlink:hover{color:var(--green-quiet)}
.pfx .backlink svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:2}
.pfx .phead{padding:20px 22px;display:flex;align-items:flex-start;gap:20px;flex-wrap:wrap}
.pfx .pheadmain{display:flex;flex-direction:column;gap:14px;min-width:0}
.pfx .pident{display:flex;align-items:flex-start;gap:16px;min-width:0}
.pfx .pav{width:56px;height:56px;flex-shrink:0;display:grid;place-items:center;font-size:20px;font-weight:700;background:var(--c-surface-2);color:var(--fg);font-family:var(--font-display);border:1px solid var(--line-soft)}
.pfx .pidtext{min-width:0}
.pfx .pidtext h1{font-family:var(--font-display);font-size:24px;font-weight:700;letter-spacing:-.01em;margin-top:0;line-height:1.05}
.pfx .pidtext .em{color:var(--fg2);font-size:13px;margin-top:6px;font-weight:500}
/* UAT round 3: the email is a live mailto. */
.pfx .pidtext .emlink{color:inherit;text-decoration:none;border-bottom:1px dotted color-mix(in oklch,var(--fg3) 55%,transparent);transition:.14s var(--ease)}
.pfx .pidtext .emlink:hover{color:var(--green-quiet);border-bottom-color:var(--green-quiet)}
.pfx .pmeta .cflag{font-size:13px}
.pfx .pmeta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:9px;color:var(--fg3);font-size:12.5px}
.pfx .pmeta .mi{display:inline-flex;align-items:center;gap:5px}
.pfx .pmeta .mi svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:1.8;opacity:.8}
.pfx .pmeta .dotsep{width:3px;height:3px;border-radius:50%;background:var(--dim)}
.pfx .ptools{margin-left:auto;display:flex;align-items:flex-start}
.pfx .pbtns{display:flex;align-items:center;gap:9px;flex-wrap:wrap;justify-content:flex-end}
/* D1911 item 5b — payment state in the identity fact row. The badge keeps the
   `.mi` idiom whole (size, weight, gap, glyph stroke); only the GLYPH takes the
   state colour, so the row's typographic rhythm is unchanged and the colour is
   never the sole carrier of the state — the word beside it says it too, which is
   what keeps the badge legible to a colour-blind reader and in a mono print. */
.pfx .mi.pay-paid svg{color:var(--green)}
.pfx .mi.pay-sponsored svg{color:var(--green-quiet)}
.pfx .mi.pay-unpaid svg{color:var(--muted)}
.pfx .rmchip{display:inline-flex;align-items:center;gap:8px;height:34px;padding:0 13px;border:1px solid var(--line-soft);border-radius:60px;background:var(--c-void);font-size:12px;color:var(--fg2);font-weight:600;white-space:nowrap}
.pfx .rmchip .rmlbl{color:var(--fg3);font-weight:600}
.pfx .stagemark{width:22px;height:22px;flex-shrink:0;display:grid;place-items:center}
.pfx .stagemark .d{width:11px;height:11px;border-radius:50%}
.pfx .stagesub{font-size:11.5px;color:var(--fg3);font-weight:500}
.pfx .stagesub .ph{color:var(--green-quiet);font-weight:600}
.pfx .statcell{min-height:112px}
.pfx .statsub.warn{color:var(--amber);font-weight:600;display:inline-flex;align-items:center;gap:6px}
.pfx .statsub.warn svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2;flex-shrink:0}
/* tracker — the mockup rail: nodes flex from the left, seg lines join them */
.pfx .trackcell{padding:20px 22px;display:flex;flex-direction:column;gap:18px;min-width:0}
.pfx .trackhead{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.pfx .trackhead .th-t{font-family:var(--font-display);font-size:14px;font-weight:700;letter-spacing:-.01em}
/* D1911 item 5 — the funnel controls are ONE right-pinned cluster.
   `.trackctl` keeps everything it declares EXCEPT `margin-left:auto`: three
   siblings each claiming the free space split it three ways (measured 174px /
   174px / 173px voids at 1440px) instead of pushing one group to the right rail.
   The auto margin moves up to `.trackgrp`, which owns it once, so the cluster
   pins right and the spacing between members is a real gap. `row-gap` keeps the
   members legible when the row wraps at narrow widths — a wrapped cluster must
   not stack flush. */
.pfx .trackctl{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.pfx .trackgrp{margin-left:auto;display:flex;align-items:center;justify-content:flex-end;gap:18px;row-gap:10px;flex-wrap:wrap}
@media (max-width:940px){.pfx .trackgrp{margin-left:0;width:100%;justify-content:flex-start}}
.pfx .trackctl .flabel{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.1em;font-weight:600}
.pfx .trackscroll{overflow-x:auto;padding-bottom:2px}
.pfx .track{display:flex;align-items:flex-start;gap:0;min-width:760px}
.pfx .tnode{flex:1;display:flex;flex-direction:column;align-items:flex-start;gap:9px;position:relative;text-align:left;min-width:88px}
.pfx .tnode .seg{position:absolute;top:12px;left:13px;width:100%;height:2px;background:var(--line);z-index:0}
.pfx .tnode:last-child .seg{display:none}
.pfx .tnode.done .seg{background:var(--green-dim)}
.pfx .tdot{position:relative;z-index:1;width:26px;height:26px;border-radius:50%;display:grid;place-items:center;background:var(--c-base);border:2px solid var(--line);color:var(--muted);transition:.2s var(--ease)}
.pfx .tdot svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2.4}
.pfx .tnode.done .tdot{background:var(--green-fill);border-color:var(--green-dim);color:var(--green)}
.pfx .tnode.cur .tdot{background:var(--green);border-color:var(--green);color:var(--on-green);box-shadow:0 0 0 4px color-mix(in oklch,var(--green) 18%,transparent)}
.pfx .ndot{width:6px;height:6px;border-radius:50%;background:currentColor;display:block}
.pfx .ndot.big{width:8px;height:8px}
.pfx .tlab{font-size:11px;font-weight:600;color:var(--muted);line-height:1.25;padding-right:8px}
.pfx .tnode.done .tlab{color:var(--fg3)}
.pfx .tnode.cur .tlab{color:var(--fg)}
.pfx .tgate{margin-top:3px;font-size:9px;letter-spacing:.08em;text-transform:uppercase;color:var(--green-quiet);font-weight:700;display:inline-flex;align-items:center;gap:4px}
.pfx .tgate svg{width:10px;height:10px;stroke:currentColor;fill:none;stroke-width:2.2}
.pfx .stagehist{display:flex;flex-direction:column;border-top:1px solid var(--line-soft);padding-top:2px}
.pfx .shrow{display:flex;align-items:center;gap:10px;padding:7px 0;font-size:12px;color:var(--fg3);border-bottom:1px solid color-mix(in oklch,var(--line-soft) 45%,transparent)}
.pfx .shrow:last-child{border-bottom:none}
.pfx .shrow .shd{width:6px;height:6px;border-radius:50%;background:var(--green-dim);flex-shrink:0}
.pfx .shrow b{color:var(--fg2);font-weight:600}
.pfx .shrow .sht{margin-left:auto;color:var(--muted);font-variant-numeric:tabular-nums;font-size:11.5px}
.pfx .shtoggle{align-self:flex-start;font-size:11.5px;color:var(--green-quiet);font-weight:600;display:inline-flex;align-items:center;gap:6px;background:none;border:none;cursor:pointer}
.pfx .shtoggle svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2;transition:.18s var(--ease)}
.pfx .shtoggle.open svg{transform:rotate(180deg)}
/* two-col bands */
.pfx .two{grid-template-columns:1.55fr 1fr}
.pfx .even{grid-template-columns:1fr 1fr}
/* T0-835 — the requirements column stacks (requirements, then assessment
   attempts) and Stage emails sits ALONGSIDE it, spanning both rows down to the
   activity section. Before this, three cells auto-flowed into a 2×2 and left
   the fourth slot empty: that hole showed the .gsec background through as a
   grey block beside the attempts panel, which is the block the operator asked
   to die. It is not an element, so nothing could be deleted to remove it — the
   cure is to stop leaving the slot. */
.pfx .two #emailsCell{grid-row:span 2}
/* …UNLESS the attempts cell is gone. Panel relevance (operator ruling
   2026-08-31) hides Assessment attempts before the assessment stage, which
   empties column 1 row 2 and brings back EXACTLY the grey block the rule above
   was written to kill — the same hole, arrived at from the other direction.
   Higher specificity, so it releases the span wherever the server marks the
   band; no :has(), so the geometry does not depend on selector support. */
.pfx .two.noattempts #emailsCell{grid-row:auto}
/* …and the panel's own list takes the height the span gives it, so the cell is
   filled rather than merely tall. */
.pfx .two #emailsCell .plist{flex:1 1 auto}
.pfx .ptitle .ctx{font-size:11px;color:var(--green-quiet);font-weight:600}
/* One column: the row span would leave a hole again, so release it. `order`
   restores the reading sequence the two-column layout gives the eye —
   requirements, then its attempts, then the emails panel. */
@media (max-width:940px){.pfx .two #emailsCell{grid-row:auto;order:2}.pfx .two #attemptsCell{order:1}
  .pfx .two,.pfx .even{grid-template-columns:1fr}.pfx .ptools{margin-left:0;width:100%}.pfx .pbtns{justify-content:flex-start}.pfx .phead{gap:16px}}
/* requirements + proofs */
.pfx .req{padding:13px 20px;display:flex;align-items:flex-start;gap:13px;border-bottom:1px solid color-mix(in oklch,var(--line-soft) 50%,transparent)}
.pfx .req:last-child{border-bottom:none}
.pfx .reqi{width:22px;height:22px;flex-shrink:0;border-radius:50%;display:grid;place-items:center;margin-top:1px;border:1px solid var(--line-soft);color:var(--muted)}
.pfx .reqi svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2.4}
.pfx .req.met .reqi{background:var(--green-fill);border-color:var(--green-dim);color:var(--green)}
.pfx .req.pending .reqi{background:color-mix(in oklch,var(--amber) 14%,transparent);border-color:color-mix(in oklch,var(--amber) 45%,transparent);color:var(--amber)}
.pfx .reqmain{flex:1;min-width:0}
.pfx .reqtop{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.pfx .reqn{font-size:13px;font-weight:600;color:var(--fg)}
.pfx .mechtag{font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--fg3);display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border:1px solid var(--line-soft);border-radius:60px;white-space:nowrap}
.pfx .mechtag svg{width:11px;height:11px;stroke:currentColor;fill:none;stroke-width:2}
.pfx .mechtag.auto{color:var(--green-quiet);border-color:color-mix(in oklch,var(--green) 32%,transparent)}
.pfx .reqd{font-size:11.5px;color:var(--muted);margin-top:4px}

/* T0-835 — the assessment-attempts rows. `.reqrow`/`.reqhead` were used in the
   markup but never had a rule anywhere in this sheet, so the panel rendered
   with browser defaults: rows flush to the panel's left and top edges, and the
   status label jammed against the test name because `.reqbadge{margin-left:auto}`
   needs a flex parent to push against and `.reqhead` was not one. These two
   rules are the whole defect. They mirror `.req`/`.reqtop` above so the two
   panels in the same column read as one family. */
.pfx .reqrow{padding:13px 20px;border-bottom:1px solid color-mix(in oklch,var(--line-soft) 50%,transparent)}
.pfx .reqrow:last-child{border-bottom:none}
.pfx .reqhead{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.pfx .reqrow .reqd{margin-top:5px;line-height:1.5}
.pfx .reqrow .attempt{white-space:nowrap}
.pfx .reqbadge{font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding:2px 8px;border-radius:60px;margin-left:auto}
.pfx .rb-met{background:color-mix(in oklch,var(--green) 14%,transparent);color:var(--green-quiet)}
.pfx .rb-none{background:var(--c-surface);color:var(--muted)}
.pfx .rb-rev{background:color-mix(in oklch,var(--amber) 14%,transparent);color:var(--amber)}
.pfx .proof{margin-top:10px;border:1px solid color-mix(in oklch,var(--amber) 34%,transparent);background:color-mix(in oklch,var(--amber) 5%,transparent);padding:11px 12px;display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.pfx .proofthumb{width:38px;height:38px;flex-shrink:0;border:1px solid var(--line-soft);background:var(--c-surface);display:grid;place-items:center;color:var(--fg3)}
.pfx .proofthumb svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:1.8}
.pfx .proofmeta{flex:1;min-width:130px}
/* UAT r5: same truncation on the in-panel pending-proof rows (same URL class). */
.pfx .proofmeta{min-width:0;flex:1}
.pfx .proofmeta .pf1{font-size:12px;font-weight:600;color:var(--fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pfx .proofmeta .pf1 a{color:var(--green-quiet);text-decoration:none;border-bottom:1px solid color-mix(in oklch,var(--green) 30%,transparent)}
.pfx .proofmeta .pf2{font-size:11px;color:var(--muted);margin-top:2px}
.pfx .proofacts{display:flex;align-items:center;gap:8px}
.pfx .btn-approve{background:transparent;border:1px solid color-mix(in oklch,var(--green) 45%,transparent);color:var(--green-quiet);height:32px;padding:0 13px;font-size:12px;border-radius:60px;display:inline-flex;align-items:center;gap:7px;font-weight:600;transition:.16s var(--ease);cursor:pointer;font-family:var(--font-body)}
.pfx .btn-approve:hover{border-color:var(--green);background:color-mix(in oklch,var(--green) 9%,transparent)}
.pfx .btn-reject{background:transparent;border:1px solid color-mix(in oklch,var(--red) 42%,transparent);color:var(--red);height:32px;padding:0 13px;font-size:12px;border-radius:60px;display:inline-flex;align-items:center;gap:7px;font-weight:600;transition:.16s var(--ease);cursor:pointer;font-family:var(--font-body)}
.pfx .btn-reject:hover{border-color:var(--red);background:color-mix(in oklch,var(--red) 9%,transparent)}
.pfx .btn-approve svg,.pfx .btn-reject svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2.2}
.pfx .btn-danger{background:var(--red);color:var(--on-red);font-weight:700;border:1px solid var(--red)}/* T0-683 A-6: minified twin of .btn-solid-danger — ink via --on-red */
.pfx .postgrp{margin-top:11px}
.pfx .postgrid{max-width:none}
.pfx .pc .pg{position:absolute;right:1px;bottom:1px;width:12px;height:12px;display:grid;place-items:center;background:rgba(0,0,0,.55);border-radius:3px;color:#fff}
.pfx .pc .pg svg{width:8px;height:8px}
.pfx .postawait{font-size:11px;color:var(--muted);margin-top:8px}
/* stage emails */
.pfx .emrow{padding:13px 20px;display:flex;align-items:center;gap:13px;border-bottom:1px solid color-mix(in oklch,var(--line-soft) 50%,transparent)}
.pfx .emrow:last-child{border-bottom:none}
.pfx .emi{width:30px;height:30px;flex-shrink:0;border:1px solid var(--line-soft);display:grid;place-items:center;color:var(--fg3)}
.pfx .emi svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.8}
.pfx .emmain{flex:1;min-width:0}
.pfx .emn{font-size:12.5px;font-weight:600;color:var(--fg)}
.pfx .emd{font-size:11px;color:var(--muted);margin-top:2px}
.pfx .emsent{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;color:var(--green-quiet);font-weight:600;white-space:nowrap}
.pfx .emsent svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:2.4}
.pfx .btn-send{background:transparent;border:1px solid color-mix(in oklch,var(--green) 45%,transparent);color:var(--green-quiet);height:32px;padding:0 14px;font-size:12px;border-radius:60px;display:inline-flex;align-items:center;gap:7px;font-weight:600;white-space:nowrap;transition:.16s var(--ease);cursor:pointer;font-family:var(--font-body)}
.pfx .btn-send:hover{border-color:var(--green);background:color-mix(in oklch,var(--green) 9%,transparent)}
.pfx .btn-send:disabled{opacity:.5;cursor:default}
/* T0-855 → AMENDED BY T0-854. The T0-855 comment that stood here stated, as a
   MEASUREMENT, that `.btn` and `.btn-solid` carried no `:disabled` rule anywhere
   in this sheet, and scoped its cure to `.pfx` on that basis — explicitly naming
   T0-854 as the owner of the sheet-wide sweep. T0-854 is that sweep, so BOTH the
   measurement and the scoping rationale are now false by construction, and the
   sentence is amended rather than left to rot beside the rule that falsifies it.

   RQ-2 ruled (A) — Kage-ratified 2026-08-11 at the preview gate: the `.pfx .btn:disabled` rule is
   DELETED, exactly subsumed by the sheet-wide rule below at identical values
   (opacity .42, cursor not-allowed). One rule, one value, no divergent control.
   The second scoped cure — an inline `style={{opacity:0.45}}` at
   library-item-view.tsx:223 — is deleted in the same diff; it is deleted under
   every RQ-2 option, because an inline style does not merely re-arm if the global
   is removed, it OVERRIDES the global and would ship a single divergent disabled
   button. If the Kage rules (B) instead, this comment must be re-amended to
   describe the retained `.pfx` rule and reason its retention: a comment that says
   "sheet-wide now" beside a surviving scoped rule is the same defect one
   generation on. */

/* T0-795 (remainder) §01.4-2 — the blocked-control constraint line. A gated
   control renders COPY, never nothing: a fail-closed row that paints blank is
   indistinguishable from a broken one (T0-855 B-1). Deliberately NOT styled as a
   button or a disabled button — it must not read as something to click, and it
   must not borrow the sheet-wide `:disabled` paint T0-854 introduced: a disabled
   control and an ABSENT one say different things, and this line is the second.
   Muted weight, no border, no pointer affordance. */
.pfx .rolelock{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;line-height:1.35;color:var(--muted);font-weight:600;letter-spacing:.01em;white-space:normal}
/* T0-795 (remainder) §01.2-5 — the paused-advancement line on the stage rail. It
   describes a STATE, so it reads as a notice rather than a warning: the engine
   being paused is the correct outcome of an administrator's correction, not a
   fault. Muted amber carries "deliberate, and temporary" without the alarm of an
   error row (§05.5 — never append alarm to a non-alarming fact). */
.pfx .engpaused{margin-top:10px;padding:9px 12px;border-radius:8px;font-size:11.5px;line-height:1.4;font-weight:600;color:var(--fg2);background:color-mix(in oklch,var(--amber,#d99a2b) 9%,transparent);border:1px solid color-mix(in oklch,var(--amber,#d99a2b) 26%,transparent)}
.pfx .btn-send svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2}
.pfx .emdue{display:inline-flex;align-items:center;gap:5px;font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--green-quiet);padding:2px 8px;border:1px solid color-mix(in oklch,var(--green) 34%,transparent);border-radius:60px;margin-left:8px}
.pfx .emailseam{padding:11px 20px;font-size:11px;color:var(--muted);border-top:1px solid var(--line-soft);display:flex;align-items:center;gap:8px;background:color-mix(in oklch,var(--c-base) 60%,var(--c-void));margin-top:auto}
.pfx .emailseam svg{width:13px;height:13px;stroke:var(--green-dim);fill:none;stroke-width:1.9;flex-shrink:0}
/* timeline (check-ins + activity) */
.pfx .tl{padding:16px 20px 18px;display:flex;flex-direction:column;gap:0;position:relative}
/* D2013 / decision 27 — THE EMPTY STATE CENTRES IN THE BAND THAT STRETCHES.
   D2005 gave the profile's final band the `grow` token, so its two panels now
   consume the frame's free space. The copy inside them did not move: at
   1440x1100 "No check-ins yet" stayed at leaf offset 809.28px inside a panel
   that had gone from 174px to 376px tall, leaving 200px of blank ground under a
   line of text pinned to the top of it. Pre-existing treatment, made visible by
   the fill rather than introduced by it (raised as P3 at D2005, confirmed base
   == tip on two instruments at D2009 A-2), and ruled on by the operator.

   Scoped to `.gsec.grow` on purpose, and that is the whole design: the rule is
   keyed on the SAME token that creates the free space, so it applies exactly
   where there is something to centre in, and if the token is ever removed the
   centring retires with it instead of lingering as an orphan. `.empty` is a
   shared class — 20 call sites across 8 files, portal home, calendar, library,
   proof queue, athletes table — so its base rule (:379) and its phone ruling
   (:2183, UAT r10) are untouched here.

   `:only-child` is load-bearing, not defensive dressing. It fires ONLY on a
   panel that is genuinely empty; the moment one timeline row renders, `.empty`
   is gone and the rows stay top-aligned where a chronology belongs. That is why
   the sibling panel in a half-populated band keeps its rows at the top while
   the empty one centres — the two are different states, not different rules.

   `.tl` growing is inert wherever there is no free space (a profile that
   already overflows), and invisible where there is: the ground under the last
   row was `--c-base` before, painted by `.pcell`; it is the same `--c-base`
   now, painted by `.tl`. Nothing moves in the populated case.

   Same fault class as `.atable td.aempty` (:1720, D1911 item 3): an empty state
   whose own box does not inhabit the cell it is sitting in. */
.pfx .gsec.grow .tl{flex:1}
.pfx .gsec.grow .tl>.empty:only-child{margin-block:auto}
.pfx .tli{display:flex;gap:13px;padding:0 0 16px;position:relative;width:auto;height:auto;border:none;background:none;border-radius:0;place-items:unset}
.pfx .tli:last-child{padding-bottom:0}
.pfx .tli::before{content:"";position:absolute;left:8px;top:18px;bottom:-2px;width:1px;background:var(--line-soft)}
.pfx .tli:last-child::before{display:none}
.pfx .tld{width:17px;height:17px;flex-shrink:0;border-radius:50%;background:var(--c-base);border:1px solid var(--line);display:grid;place-items:center;z-index:1;color:var(--fg3);margin-top:1px}
.pfx .tld svg{width:10px;height:10px;stroke:currentColor;fill:none;stroke-width:2.2}
.pfx .tld.g{border-color:var(--green-dim);color:var(--green);background:var(--green-fill)}
.pfx .tlmain{flex:1;min-width:0}
.pfx .tlt{font-size:12.5px;color:var(--fg2);line-height:1.5}
.pfx .tlt b{color:var(--fg);font-weight:600}
.pfx .tltime{font-size:11px;color:var(--muted);margin-top:3px;font-variant-numeric:tabular-nums}
.pfx .cistat{font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding:1px 7px;border-radius:60px;margin-left:7px;background:var(--c-surface);color:var(--muted)}
.pfx .cistat.on_track{background:color-mix(in oklch,var(--green) 14%,transparent);color:var(--green-quiet)}
.pfx .cistat.at_risk{background:color-mix(in oklch,var(--amber) 14%,transparent);color:var(--amber)}
.pfx .cistat.done{background:color-mix(in oklch,var(--green) 20%,transparent);color:var(--green-quiet)}
.pfx .ciact{margin-top:7px;height:28px;padding:0 12px;font-size:11.5px}
.pfx .dferr{font-size:12.5px;color:var(--red)}
/* profile modals (compose / advance gate / post review) */
.pfx .mrow{display:flex;gap:10px;flex-wrap:wrap}
.pfx .recip{display:flex;align-items:center;gap:9px;flex:1;min-width:170px;border:1px solid var(--line-soft);padding:8px 11px;background:var(--c-surface)}
.pfx .recip .ra{width:28px;height:28px;flex-shrink:0;display:grid;place-items:center;font-size:10.5px;font-weight:700;background:var(--c-surface-2);font-family:var(--font-display);color:var(--fg2)}
/* UAT r5: the text column must be allowed to SHRINK (flex min-width default is
   content size) so a long email truncates instead of overrunning the card. */
.pfx .recip > div:last-child{min-width:0;flex:1}
.pfx .recip .rl{font-size:9.5px;color:var(--fg3);text-transform:uppercase;letter-spacing:.1em;font-weight:600}
.pfx .recip .rn{font-size:12.5px;color:var(--fg);font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pfx .recip .re{font-size:11px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pfx .subjbox{background:var(--c-surface);border:1px solid var(--line-soft);padding:9px 12px}
.pfx .subjbox .sl{font-size:9.5px;color:var(--fg3);text-transform:uppercase;letter-spacing:.1em;font-weight:600;margin-bottom:4px;display:block}
.pfx .subjbox .sv{font-size:13px;color:var(--fg);font-weight:600}
.pfx .mfoot .idem{margin-right:auto;font-size:11px;color:var(--muted);display:inline-flex;align-items:center;gap:6px}
.pfx .mfoot .idem svg{width:13px;height:13px;stroke:var(--green-dim);fill:none;stroke-width:1.9}
.pfx .meyebrow.amber{color:var(--amber)}
.pfx .warnicon{width:34px;height:34px;flex-shrink:0;display:grid;place-items:center;border-radius:50%;background:color-mix(in oklch,var(--amber) 14%,transparent);border:1px solid color-mix(in oklch,var(--amber) 45%,transparent);color:var(--amber)}
.pfx .warnicon svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:2}
.pfx .wmsg{font-size:12.5px;color:var(--fg2);line-height:1.55}
.pfx .wlist{border:1px solid var(--line-soft)}
.pfx .prpost{display:flex;align-items:center;gap:13px;border:1px solid var(--line-soft);background:var(--c-surface);padding:11px 12px}
/* UAT r5: flex:1 + one-line ellipsis so a long post URL truncates in the card. */
.pfx .prpmeta{min-width:0;flex:1}
.pfx .prpmeta .pf1{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pfx .prpmeta .pf1 a{color:var(--green-quiet);text-decoration:none;font-size:12.5px;font-weight:600;border-bottom:1px solid color-mix(in oklch,var(--green) 30%,transparent)}
.pfx .prpmeta .pf2{font-size:11.5px;color:var(--muted);margin-top:3px}
.pfx .prhint{font-size:11.5px;color:var(--fg3);line-height:1.5}
.pfx .fnote{color:var(--muted);font-weight:500}
.pfx .frow{display:grid;grid-template-columns:1fr 1fr;gap:12px}

/* Google Meet join affordance — event detail drawers (admin + portal) */
.meetjoin{display:inline-flex;align-items:center;gap:4px;margin-left:8px;font-size:11.5px;font-weight:700;color:var(--green-quiet);text-decoration:none;border-bottom:1px solid color-mix(in oklch,var(--green) 34%,transparent);transition:.14s var(--ease)}
.meetjoin:hover{color:var(--fg)}

/* ═══ SETTINGS (operator item 9; design authority settings-mockup.html; scoped
   under .stx — the settings page wrapper — same discipline as .pfx) ═══ */
.stx .setwrap{grid-template-columns:236px 1fr;flex:1;grid-template-rows:1fr}
.stx .setnavc{padding:0;background:var(--c-void);display:flex;flex-direction:column}
.stx .setnav{display:flex;flex-direction:column;padding:12px 0}
.stx .setnav button{display:flex;align-items:center;gap:11px;padding:10px 18px;color:var(--fg3);font-size:13px;font-weight:500;background:none;border:none;border-left:2px solid transparent;cursor:pointer;transition:.14s var(--ease);text-align:left;font-family:var(--font-body)}
.stx .setnav button:hover{background:var(--c-surface);color:var(--fg2)}
.stx .setnav button.on{background:var(--green-fill);color:var(--on-green-fill);border-left:2px solid var(--green)}
.stx .setnav button svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.7;flex-shrink:0}
.stx .setmain{padding:0;background:var(--c-void);display:flex;flex-direction:column}
.stx .setsec{padding:24px 26px;max-width:760px;display:flex;flex-direction:column;gap:20px}
.stx .sech{display:flex;align-items:flex-start;gap:14px}
.stx .sect{font-family:var(--font-display);font-size:18px;font-weight:700;letter-spacing:-.01em}
.stx .secd{font-size:12.5px;color:var(--fg3);margin-top:6px;line-height:1.55;max-width:560px}
.stx .panel{border:1px solid var(--line-soft);background:var(--c-base)}
.stx .panel .prow{padding:13px 16px;display:flex;align-items:center;gap:14px;border-bottom:1px solid color-mix(in oklch,var(--line-soft) 55%,transparent)}
.stx .panel .prow:last-child{border-bottom:none}
.stx .prow .pl{flex:1;min-width:0}
.stx .prow .pl .n{font-size:13px;font-weight:600;color:var(--fg);display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.stx .prow .pl .d{font-size:11.5px;color:var(--muted);margin-top:3px;line-height:1.45}
.stx .prow .pr{flex-shrink:0;display:flex;align-items:center;gap:10px}
.stx .unit{font-size:12px;color:var(--fg3);font-weight:500}
.stx .termi{color:var(--muted);font-size:12px;font-style:italic}
.stx .setval{color:var(--fg);font-weight:700;font-variant-numeric:tabular-nums}
.stx .phdot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.stx .ph-Prospect{background:var(--muted)}
.stx .ph-Onboarding{background:var(--amber)}
.stx .ph-Engagement{background:var(--green)}
.stx .mechtag{font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--fg3);display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border:1px solid var(--line-soft);border-radius:60px;white-space:nowrap}
.stx .mechtag.auto{color:var(--green-quiet);border-color:color-mix(in oklch,var(--green) 32%,transparent)}
.stx .statuspill{display:inline-flex;align-items:center;gap:6px;font-size:11px;font-weight:600;padding:3px 10px;border-radius:60px}
.stx .statuspill.ok{background:color-mix(in oklch,var(--green) 13%,transparent);color:var(--green-quiet)}
.stx .statuspill.off{background:var(--c-surface);color:var(--muted)}
.stx .statuspill .dot{width:6px;height:6px;border-radius:50%;background:currentColor}
.stx .stagepills{display:flex;gap:8px;flex-wrap:wrap}
.stx .spill{height:32px;padding:0 13px;border-radius:60px;border:1px solid var(--line-soft);background:var(--c-void);color:var(--fg3);font-size:12px;font-weight:600;display:inline-flex;align-items:center;gap:7px}
.stx .spill.on{background:var(--green-fill);color:var(--on-green-fill);border-color:var(--green-dim)}
.stx .tm-av{width:34px;height:34px;display:grid;place-items:center;font-size:12px;font-weight:700;background:var(--c-surface-2);color:var(--fg2);font-family:var(--font-display);flex-shrink:0}
.stx .tm-em{font-size:11.5px;color:var(--muted);margin-top:1px}
.stx .rolepill{font-size:11px;font-weight:600;padding:3px 10px;border-radius:60px;background:var(--c-surface);color:var(--fg2);white-space:nowrap}
.stx .catic{width:38px;height:38px;flex-shrink:0;border:1px solid var(--line-soft);border-radius:8px;display:grid;place-items:center;color:var(--fg2);background:var(--c-surface)}
.stx .catic svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:1.6}
.stx .setnote{font-size:11.5px;color:var(--muted)}
@media(max-width:860px){
  .stx .setwrap{grid-template-columns:1fr;grid-template-rows:auto 1fr}
  /* UAT r8 (operator ruling): square edge-to-edge grid cells — the blueprint
     seam idiom, matching the athlete profile tabs — not rounded chips */
  .stx .setnav{flex-direction:row;flex-wrap:wrap;overflow-x:visible;padding:0;gap:1px;background:var(--line-soft);border-bottom:1px solid var(--line-soft)}
  .stx .setnav button{flex:1 1 auto;justify-content:center;background:var(--c-void);border-left:none;border-bottom:2px solid transparent;white-space:nowrap;padding:10px 14px;border-radius:0}
  .stx .setnav button:hover{background:var(--c-surface)}
  .stx .setnav button.on{border-left:none;border-bottom:2px solid var(--green)}
  .stx .setsec{padding:18px 16px}
}

/* ── entry-surface reticles (operator UAT ruling 2026-07-06): the base joiner
   machinery only mints crosshairs at interior grid joints, which reads sporadic
   on a sparse two-cell frame. Entry frames add reticles at all four OUTER
   corners (the .etick quartet) and at BOTH ends of every section seam (the
   gsec pseudos). Scoped to .entryframe — console/portal surfaces untouched. ── */
.entryframe{position:relative}
.entryframe .etick{position:absolute;width:9px;height:9px;z-index:4;pointer-events:none;opacity:.85}
.entryframe .etick::before,.entryframe .etick::after{content:"";position:absolute;background:var(--node)}
.entryframe .etick::before{width:9px;height:1px}
.entryframe .etick::after{width:1px;height:9px}
.entryframe .etick.tl{top:-1px;left:-1px}
.entryframe .etick.tl::before{top:0;left:0}
.entryframe .etick.tl::after{top:0;left:0}
.entryframe .etick.tr{top:-1px;right:-1px}
.entryframe .etick.tr::before{top:0;right:0}
.entryframe .etick.tr::after{top:0;right:0}
.entryframe .etick.bl{bottom:-1px;left:-1px}
.entryframe .etick.bl::before{bottom:0;left:0}
.entryframe .etick.bl::after{bottom:0;left:0}
.entryframe .etick.br{bottom:-1px;right:-1px}
.entryframe .etick.br::before{bottom:0;right:0}
.entryframe .etick.br::after{bottom:0;right:0}
.entryframe .gsec{position:relative}
/* Seam ticks key on :first-of-type, NOT :first-child — the four <i class="etick">
   elements precede the first section, so :first-child never matches inside an
   entryframe and the TOP section was wrongly minted seam ticks at the frame
   corner (the operator-reported upper prongs). */
.entryframe .gsec:not(:first-of-type)::before,.entryframe .gsec:not(:first-of-type)::after{content:"";position:absolute;z-index:4;pointer-events:none;opacity:.85;background:var(--node)}
.entryframe .gsec:not(:first-of-type)::before{top:-1px;right:-1px;width:5px;height:1px;transform:translateY(-50%)}
.entryframe .gsec:not(:first-of-type)::after{top:-1px;right:-1px;width:1px;height:9px;transform:translate(0,-50%)}
/* The frame's own top-edge joints: the base .gcell joiner straddles the top
   border (and its .frame > .gsec:first-child trim also misses for the same
   :first-child reason) — kill both prongs; the etick quartet owns the corners. */
.entryframe > .gsec:first-of-type > .gcell::before,
.entryframe > .gsec:first-of-type > .gcell::after{display:none}

/* ═══ Mobile craft pass (impeccable sweep, 2026-07-07 — UAT r6 follow-up) ═══
   Tap-target law at thumb scale (≤700px): interactive controls reach a ≥40px
   effective target; the social post grid rebuilds at 6-up so each cell is a
   comfortable fingertip; inline text actions gain real padding. The library
   switcher text is left-aligned at ALL widths (operator ruling — centred label
   text in the two-up tabs was a defect, not a breakpoint issue). */
.libswitch .segtab button, .libswitch .segtab button .lsw { text-align: left; }
/* the switcher icon tops out level with the title line at EVERY width (UAT r7
   follow-up — was mobile-only), not centred against the two-line block */
.libswitch .segtab button { align-items: flex-start; }
.libswitch .segtab button > svg { margin-top: 3px; }

/* UAT r10c (operator ruling, all widths): stage-email tiles — the mail icon and
   the action top-align with the email title; the Due-now pill gets breathing
   room above and below instead of cramping the title line */
.pfx .emrow { align-items: flex-start; }
.pfx .emrow .btn-send, .pfx .emrow .emsent { margin-top: 3px; }
.pfx .emn { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; }
.pfx .emdue { margin-left: 0; padding: 4px 9px; }

/* UAT r7 — Home Upcoming rows click through to the calendar's event drawer;
   the date + title are one anchor, the reschedule button stays its own control */
.uplink { display: flex; gap: 13px; align-items: center; flex: 1; min-width: 0; text-decoration: none; color: inherit; }
.uplink:hover .upn { color: var(--green-quiet); }
.uplink:hover .update { border-color: var(--green-dim); }

@media (max-width: 700px) {
  /* social-posts step: the action drops below the grid; cells at fingertip scale */
  .nstep { flex-wrap: wrap; }
  .nsact { width: 100%; margin-top: 12px; display: flex; }
  .nsact .btn { flex: 1; min-height: 44px; }
  .postgrid, .pfx .postgrid { grid-template-columns: repeat(6, 1fr); max-width: none; }
  .pl .pc { width: 12px; height: 12px; } /* legend swatches stay decorative */
  .pc .pg, .pfx .pc .pg { width: 16px; height: 16px; right: 2px; bottom: 2px; }
  .pc .pg svg, .pfx .pc .pg svg { width: 11px; height: 11px; }
  /* primary nav rows, icon buttons and control chips reach 40px+ */
  .nav a { min-height: 44px; }
  .signout button { min-height: 40px; }
  .ic, .pfx .ic, .monthnav .ic { width: 42px; height: 42px; min-width: 42px; flex-shrink: 0; }
  .pfx .pf1 a { display: inline-block; padding: 9px 0; }
  .dclose { width: 40px; height: 40px; }
  .btn-today { min-height: 40px; }
  .segtab button, .viewtog button { min-height: 40px; }
  .tchip { min-height: 40px; }
  .btn-sm { min-height: 40px; }
  .dcbtn { min-height: 38px; }
  .btn-approve, .btn-reject, .pfx .btn-approve, .pfx .btn-reject, .pfx .btn-send { min-height: 40px; height: auto; }
  /* profile identity: the joined/location/gender row breaks out of the text
     column to sit flush-left under the avatar (UAT r8 — kill the dead space) */
  .pfx .pmeta { margin-left: -72px; } /* avatar 56px + pident gap 16px */
  /* admin Settings rows (UAT r10e — operator ruling): every card left-aligns
     and STACKS — [icon/avatar] + title adjacent, subtext under the title, and
     the values/pills row drops BELOW the text block. Status rows instead pin
     their pill top-right, with the title reserved clear of it. */
  .stx .panel .prow { position: relative; flex-direction: row; flex-wrap: wrap; align-items: flex-start; row-gap: 8px; padding: 16px 16px; }
  .stx .panel .prow .pl { display: block; flex: 1; min-width: 0; }
  .stx .panel .prow .pr { flex-basis: 100%; margin-left: 0; display: flex; justify-content: flex-start; align-items: center; gap: 10px; }
  .stx .panel .prow:has(.statuspill) .pl { padding-right: 172px; } /* clears the widest pill ("Awaiting connection") + gap */
  .stx .panel .prow .pr:has(.statuspill) { flex-basis: auto; }
  .stx .prow .pr .statuspill { position: absolute; top: 16px; right: 16px; }
  /* in-profile proof card (UAT r10f — operator ruling): link icon top-aligned;
     the link + subtext take the FULL card width, then the actions sit below on
     their own row — Reject first, Approve second, aligned to the card's right */
  .pfx .proof { align-items: flex-start; }
  .pfx .proofthumb { margin-top: 1px; }
  .pfx .proofmeta { flex: 1 0 calc(100% - 50px); }
  .pfx .proofacts { flex-basis: 100%; flex-direction: row; justify-content: flex-end; gap: 8px; margin-top: 2px; }
  /* proof-review queue rows (UAT r10d — operator ruling): avatar and username
     top-align; the stage pill hugs the name; the post element sits ON the page
     margin — the hover-only open glyph occupied an invisible slot that inset
     the whole tile on touch screens, where hover doesn't exist */
  .qrow { padding: 16px 16px; }
  .qath { align-items: flex-start; }
  .qath .aini { margin-top: 1px; }
  .qan2 { margin-top: 2px; }
  .qproof .qopen { display: none; }
  /* placeholder/empty states read left-aligned on phones (UAT r10 — operator
     ruling; desktop keeps the centred treatment) */
  .empty, .pfx .empty { text-align: left; padding-left: 16px; padding-right: 16px; }
  /* …and ON the 16px page margin even inside padded parents (UAT r10c): the
     timeline containers carry 20px of their own padding, so their empties
     zero out and pull back 4px to land exactly at the margin */
  .tl .empty, .pfx .tl .empty { padding-left: 0; padding-right: 0; margin-left: -4px; }
  /* stack, don't cram (UAT r10 — operator ruling): inline title·subtext pairs
     break to two lines — the subtext (.ctx) drops below the title as a full
     row; the count + action stay on the title line */
  .pfx .ptitle { flex-wrap: wrap; row-gap: 2px; }
  .pfx .ptitle .ctx { flex-basis: 100%; order: 5; margin-top: 1px; }
  /* airiness (UAT r10): list rows and headers breathe more on phones */
  .nstep { padding: 18px 16px; gap: 12px; }
  .pfx .req { padding: 16px 16px; }
  .pfx .ptitle { padding: 16px 16px; }
  .pfx .emrow { padding: 16px 16px; }
  .panel .prow { padding: 16px 16px; gap: 10px; }
  .setsec { padding: 22px 16px; gap: 22px; }
  /* account cards (agreements, devices — the .prow family): the status pill
     pins top-right, title + subtext keep the full left width, and the action
     buttons drop BELOW the text (UAT r9 — operator layout ruling) */
  .panel .prow { position: relative; flex-direction: column; align-items: stretch; gap: 8px; }
  .prow .pmain { padding-right: 92px; }
  .prow .pr { margin-left: 0; justify-content: flex-start; }
  .prow .pr .statuspill { position: absolute; top: 16px; right: 16px; }
  /* filters and header actions read left-aligned on mobile (UAT r8) — the
     dashboard scope selects, the proof-queue tools, the calendar tools */
  .scope { margin-left: 0; align-items: flex-start; }
  .tools { margin-left: 0; width: 100%; justify-content: flex-start; }
  /* inline text actions: real padding = real hitboxes */
  .shtoggle { padding: 12px 0; }
  .pfx .backlink { padding: 12px 0; }
  .emlink, .pfx .pidtext .emlink { display: inline-block; padding: 7px 0; }
  .meetjoin { padding: 10px 0; display: inline-flex; }
  .dctitle { padding: 10px 0; }
  .rejlink { padding: 7px 0; }
  .golink { padding: 11px 0; }
}

/* ═══ T0-724 light-mode NEON-GREEN accent + legibility pass (dispatch 3007,
   presentational lighter-loop). LIGHT-SCOPED ONLY — every selector below is a
   child of :root[data-theme="light"]; the base :root (dark) block is
   BYTE-UNTOUCHED, so dark is a pixel no-op (V-3 proven by grep, not asserted).
   #4FFF8B = the ShredFast electric green — a THEME-INVARIANT literal (same pin as
   the pass badge), used here as MARKS / BORDERS / RINGS on light and deep-teal
   grounds, never as body text. Items 4-5 are white-text legibility fixes; every
   contrast figure below is WCAG-MEASURED, not eyeballed. ── */

/* (1) Check-mark glyphs → neon green. Container-scoped so only the tick MARK is
   recoloured. Deliberately EXCLUDED: the .clause .cbx tick (a void-on-green
   knock-out punch — neon would kill it), .btn-solid label ticks (light ink on a
   green button), the .tlrow.stage glyph (a progression ARROW, not a tick) and the
   reject-toast (.rej stays red). FULL render-aware census (5 tick sites, each
   currently --green teal on a deep ground → neon reads ≥6:1):
     a. "Your progress" done-rail ticks   .tnode.done .tdot svg
     b. library "Watched" badge           .vidthumb .watched svg
     c. success toasts (submit-post/reschedule/calendar/profile save-preview)
                                          .toast:not(.rej) .ti svg
     d. "Your activity" home timeline proof check   .tlrow.proof .tli svg   ← pass-1 miss
     e. "Next steps" home met-requirement check     .nstep.met .nsi svg     ← pass-1 miss */
:root[data-theme="light"] .tnode.done .tdot svg { stroke: #4FFF8B; }
:root[data-theme="light"] .vidthumb .watched svg { stroke: #4FFF8B; }
:root[data-theme="light"] .toast:not(.rej) .ti svg { stroke: #4FFF8B; }
:root[data-theme="light"] .tlrow.proof .tli svg { stroke: #4FFF8B; }
:root[data-theme="light"] .nstep.met .nsi svg { stroke: #4FFF8B; }

/* (6) Current-stage marker — the CIRCLE (ring around the dot) goes neon green.
   The inner dot stays --on-green (#042522, dark) → 12.4:1 on the neon fill. */
:root[data-theme="light"] .tnode.cur .tdot {
  background: #4FFF8B;
  border-color: #4FFF8B;
  box-shadow: 0 0 0 4px color-mix(in oklch, #4FFF8B 22%, transparent);
}

/* (2) Approved social-post cell (.pc.ok) border — stays the canon marine TEAL
   (--green #04998f). Neon was tried and REVERTED: it read only ~1.3:1 luminance on
   the pale approved-post ground (operator eyeball + raiden backstop). No light
   override here — .pc.ok inherits the base { border-color: var(--green) }. */

/* (3) Active side-nav item left-edge accent → neon green (was --green teal). The
   width/style of the existing 2px left border are retained; only the hue flips. */
:root[data-theme="light"] .nav a.on { border-left-color: #4FFF8B; }

/* (4) Calendar current-day number → WHITE on a deep-teal fill. #fff on --green
   (#04998f) is only 3.52:1 (FAILS AA), so the fill is deepened to --green-press
   (#027770) where #fff clears AA at 5.41:1. Legibility fix (was dark ink, muddy). */
:root[data-theme="light"] .dc.today .dnum .dd {
  background: var(--green-press);
  color: #fff;
}

/* (5) Country ISO-code badge letters → WHITE on the deep --green-fill (#1F5763)
   ground — 8.08:1 (AAA). Was --green teal-on-teal (2.29:1, illegible). */
:root[data-theme="light"] .acbadge { color: #fff; }

/* ══════════════════════════════════════════════════════════════════════════════
   v1.8 AMENDMENT — T0-830 (Fuda B items 2 + 4). SCOPED DELTA, APPEND ONLY.
   ══════════════════════════════════════════════════════════════════════════════
   This block is the WHOLE of app/globals.css's participation in T0-830 (§01.5
   v1.8 annotation row, D-2 convention). Nothing above this banner is edited: no
   token is changed, no existing selector is rewritten, no dark-theme rule is
   amended. Three families only — the callback banner, the `needs_reconnect`
   attention pill, and the self-row control states.

   BOTH THEMES ARE SERVED BY ONE BLOCK. Every value is written in the sheet's
   own token vocabulary (--amber / --red / --green / --line-soft / --fg …), and
   those tokens auto-flip at :root[data-theme="light"]. So there is no per-theme
   override to owe and "dark theme: no-op" stays literally true — dark is
   byte-untouched, it simply inherits.

   CONTRAST, DECIDED RATHER THAN DEFAULTED. This sheet documents at their own
   definition sites that --amber is AA LARGE-ONLY as text (3.59:1 on the light
   ground) and that --red is AA but heavy at body size. So TONE IS CARRIED BY
   STRUCTURE, NOT BY INK: a 2px left accent rule plus a faint tinted ground do
   the signalling, while heading and body stay in the standard --fg / --fg2 text
   ladder that clears AA/AAA in both themes. Colour is never the sole carrier —
   the heading words state the outcome on their own.

   Design authority: settings-mockup.html + ShredFast V6 canon. Square hairline
   callout, not a rounded toast — a failure banner here is DIAGNOSTIC COPY the
   staff member is meant to read and act on, not a chip begging to be dismissed.
   Hence: no dismiss control, no icon-as-decoration, no all-caps display type. */

.gbanner {
  border: 1px solid var(--line-soft);
  border-left: 2px solid var(--line);
  background: var(--c-base);
  padding: 13px 16px;
  margin-bottom: 14px;
}
.gbanner .gb-h { font-size: 13px; font-weight: 600; color: var(--fg); }
.gbanner .gb-b { font-size: 11.5px; color: var(--fg2); margin-top: 4px; line-height: 1.5; max-width: 68ch; }

/* The three tones. The accent rule is the signal; the ground is a whisper of it
   so the box reads as belonging to the tone without tinting the ink. */
.gbanner.success   { border-left-color: var(--green); background: color-mix(in oklch, var(--green) 6%, var(--c-base)); }
.gbanner.attention { border-left-color: var(--amber); background: color-mix(in oklch, var(--amber) 6%, var(--c-base)); }
.gbanner.failure   { border-left-color: var(--red);   background: color-mix(in oklch, var(--red) 6%, var(--c-base)); }

/* Item 4 — `needs_reconnect` (and `partial`) stop sharing `off` with
   `not_connected`. An absence and a died-connection are different facts and had
   been wearing one grey. Ink stays --fg2 rather than --amber because the pill
   text is 11px/600 and --amber is AA LARGE-ONLY; the dot carries the hue, which
   is a non-text indicator at the 3:1 bar. Mirrored into the .stx scope beside
   .ok/.off exactly as this sheet already duplicates that family. */
.statuspill.attn { background: color-mix(in oklch, var(--amber) 15%, transparent); color: var(--fg2); }
.statuspill.attn .dot { background: var(--amber); }
.stx .statuspill.attn { background: color-mix(in oklch, var(--amber) 15%, transparent); color: var(--fg2); }
.stx .statuspill.attn .dot { background: var(--amber); }

/* Item 4 — the self-row Connect / Disconnect controls. This panel's one real
   action, so it should read as one without shouting: the standard .btn-line
   outline, one notch of weight, a green edge on hover for Connect (the
   affirmative), and a VISIBLE FOCUS RING on both. The base .btn-line has a
   hover state and no focus state at all — keyboard users got nothing. */
.btn-line.gconnect,
.btn-line.gdisconnect { font-weight: 600; letter-spacing: .01em; text-decoration: none; }
.btn-line.gconnect:hover { border-color: var(--green); color: var(--green-quiet); background: color-mix(in oklch, var(--green) 8%, transparent); }
.btn-line.gconnect:focus-visible,
.btn-line.gdisconnect:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }

/* ── T0-840 — ATHLETE RM AVAILABILITY (FREE WINDOWS inversion). Achromatic by
   design (§05): NO type palette on this surface. Reuses the D780
   --event-unavail / --event-unknown tokens + the 135deg hatch (additive — no
   existing selector is modified); both themes ride the shared tokens. The header,
   month-nav (.monthnav/.ic/.monthlbl/.btn-today) and .hcell/.eyebrow/.sub are
   reused from the calendar surface. State is carried by STRUCTURE — hatch (no
   free), dashed (unknown), filled bar (free), faint (past) — so it survives
   greyscale and colour-blindness, never colour alone. */
.rmav-empty { padding: 40px 22px; text-align: center; }
.rmav-empty-t { font-family: var(--font-display); font-size: 18px; font-weight: 700; color: var(--fg); margin-bottom: 6px; }
.rmav-empty p { color: var(--fg3); font-size: 13.5px; }

.rmav-standing { margin-top: 12px; padding: 9px 12px; border: 1px solid var(--line-soft); border-left: 2px solid var(--event-unavail); background: color-mix(in oklch, var(--event-unavail) 5%, transparent); color: var(--fg2); font-size: 12.5px; max-width: 620px; }

.rmav-bar { padding: 12px 18px; display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

.rmav-main { padding: 14px 18px 20px; }
.rmav-wkrow { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; margin-bottom: 6px; }
.rmav-wkrow span { font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--fg3); text-align: center; padding: 4px 0; }
.rmav-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.rmav-dc { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 6px; min-height: 58px; padding: 7px 2px; border: 1px solid var(--line-soft); background: var(--c-base); cursor: pointer; transition: .12s var(--ease); }
.rmav-dc:hover { border-color: var(--line); }
.rmav-dc.out { opacity: .5; }
.rmav-dc.today { border-color: var(--fg3); }
.rmav-dc.sel { border-color: var(--fg2); box-shadow: inset 0 0 0 1px var(--fg2); }
.rmav-dc:focus-visible { outline: 2px solid var(--fg2); outline-offset: 1px; }
.rmav-dnum { font-size: 12.5px; font-weight: 600; color: var(--fg2); font-variant-numeric: tabular-nums; }

.rmav-mark { width: 16px; height: 8px; border-radius: 2px; }
/* Free — a clean filled neutral bar (the positive state; achromatic). */
.rmav-m-free { background: color-mix(in oklch, var(--fg2) 42%, transparent); }
/* No free time / fully booked — the achromatic 135deg hatch (shared with busy). */
.rmav-m-none { background-color: color-mix(in oklch, var(--event-unavail) 34%, transparent); background-image: repeating-linear-gradient(135deg, var(--event-unavail) 0 2px, transparent 2px 5px); }
/* Availability unknown — a DASHED outline (structure, not colour). */
.rmav-m-unknown { background: transparent; border: 1px dashed var(--event-unknown); }
/* Past — faint, no affordance. */
.rmav-m-past { background: color-mix(in oklch, var(--fg3) 16%, transparent); }

.rmav-panel { margin-top: 16px; border-top: 1px solid var(--line-soft); padding-top: 14px; }
.rmav-panel-h { font-family: var(--font-display); font-size: 15px; font-weight: 700; color: var(--fg); }
.rmav-panel-sub { display: flex; align-items: center; gap: 8px; margin-top: 10px; font-size: 12px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase; color: var(--fg3); }
.rmav-tz { margin-left: auto; text-transform: none; letter-spacing: 0; font-size: 10.5px; color: var(--muted); }
.rmav-winlist { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; padding: 0; }
.rmav-win { font-size: 13px; font-weight: 600; color: var(--fg); font-variant-numeric: tabular-nums; padding: 5px 12px; border: 1px solid var(--line-soft); border-radius: 60px; background: color-mix(in oklch, var(--fg2) 8%, transparent); }
.rmav-panel-note { margin-top: 12px; font-size: 13px; padding: 10px 12px; border: 1px solid var(--line-soft); }
.rmav-note-unknown { border-style: dashed; border-color: var(--event-unknown); color: var(--fg2); }
.rmav-note-muted { color: var(--fg3); }

.rmav-legend { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line-soft); }
.rmav-legi { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: var(--fg2); }
.rmav-legend .rmav-mark { width: 18px; height: 9px; }

/* ≤560px: tighten the grid but keep 7 columns — a week must stay a week. */
@media (max-width: 560px) {
  .rmav-dc { min-height: 50px; gap: 4px; padding: 6px 1px; }
  .rmav-dnum { font-size: 11.5px; }
  .rmav-mark { width: 13px; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   T0-844 [NEW] F3f-R ADMIN LIBRARY — ported from the Kage-approved D838 mockup
   set (artefacts/design/shredfast/admin-library-redesign/build_css.py, the
   [VERBATIM]/[NEW] audit block). ADDITIVE and namespaced `adm*`-family: every
   [VERBATIM] class already ships above and is NOT duplicated here. Inert until a
   class is applied, so the athlete surface cannot regress by CSS addition alone
   (§01.7). ZERO new :root vars — every colour resolves from the existing ladder.
   ═══════════════════════════════════════════════════════════════════════════ */


/* source / status pills — the two facts the athlete view never shows */
.srcpill{font-size:9.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding:2px 7px;
  border-radius:60px;white-space:nowrap;border:1px solid var(--line-soft);color:var(--muted)}
.srcpill.up{border-color:color-mix(in oklch,var(--green) 38%,transparent);color:var(--green-quiet)}
/* [DEVIATION, declared] The `.stpill` BASE rule from build_css.py is NOT ported.
   The audit marks it [NEW]; it is not — it ships above (line ~891) and is consumed
   by the ATHLETE surface (components/portal/assessment-history, calendar-view,
   assessment-booking) as well as admin-calendar. Re-declaring it here would win on
   source order at equal specificity and silently restyle those consumers, which is
   precisely the regression-by-CSS-addition §01.7 promises is impossible. Only the
   genuinely-new .proc/.err/.dot MODIFIERS below are ported; they compose with the
   shipped base. See the PR body's CSS census. */
.stpill.proc{border:1px solid color-mix(in oklch,var(--amber) 48%,transparent);
  background:color-mix(in oklch,var(--amber) 10%,transparent);color:var(--amber)}
.stpill.err{border:1px solid color-mix(in oklch,var(--red) 45%,transparent);
  background:color-mix(in oklch,var(--red) 9%,transparent);color:var(--red)}
.stpill .dot{width:6px;height:6px;border-radius:50%;background:currentColor}

/* destructive + managed-in-code affordances on a card */
.dcbtn.del{color:var(--red);border-color:color-mix(in oklch,var(--red) 30%,transparent)}
.dcbtn.del:hover{border-color:var(--red);background:color-mix(in oklch,var(--red) 8%,transparent);color:var(--red)}
.dclock{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--muted);height:30px}
.dclock svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:1.9}

/* the delete_failed strip — a card keeps its content and grows an honest footer */
.doccard.failed{border-color:color-mix(in oklch,var(--red) 42%,transparent)}
.dcflag{margin-top:11px;padding:9px 11px;border:1px solid color-mix(in oklch,var(--red) 34%,transparent);
  background:color-mix(in oklch,var(--red) 7%,transparent);display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.dcflag .fx{font-size:11.5px;color:var(--fg2);line-height:1.45;flex:1;min-width:170px}
.dcflag .fx b{color:var(--red);font-weight:700}

/* video card gains a management strip below the info block */
.vidcard.adm .vidinfo{padding:11px 2px 0}
.vidmeta{font-size:11.5px;color:var(--muted);margin-top:6px;display:flex;align-items:center;gap:7px;flex-wrap:wrap}

/* upload dropzone */
.dropz{border:1px dashed var(--line);background:var(--c-surface);padding:20px 16px;display:flex;flex-direction:column;
  align-items:center;gap:8px;text-align:center;cursor:pointer;transition:.16s var(--ease)}
.dropz:hover{border-color:var(--green-quiet);background:color-mix(in oklch,var(--green) 5%,transparent)}
.dropz svg{width:24px;height:24px;stroke:var(--fg3);fill:none;stroke-width:1.6}
.dropz .dz1{font-size:13px;font-weight:600;color:var(--fg)}
.dropz .dz2{font-size:11.5px;color:var(--muted)}
.dropz.has{border-style:solid;border-color:color-mix(in oklch,var(--green) 45%,transparent);align-items:flex-start;
  flex-direction:row;text-align:left;gap:12px;cursor:default}
.dropz.has svg{stroke:var(--green-quiet);flex-shrink:0}
.dropz.has .dzw{flex:1;min-width:0}

/* inline "create a new category" panel — grows INSIDE the field, never a 2nd modal */
.newcat{border:1px solid color-mix(in oklch,var(--green) 38%,transparent);
  background:color-mix(in oklch,var(--green) 5%,transparent);padding:13px;display:flex;flex-direction:column;gap:11px}
.newcat .nch{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--green-quiet)}
.newcat .nchelp{font-size:11.5px;color:var(--fg3);line-height:1.5}
.radrow{display:flex;gap:7px;flex-wrap:wrap}
.rad{display:inline-flex;align-items:center;gap:7px;height:32px;padding:0 13px;border-radius:60px;
  border:1px solid var(--line-soft);background:var(--c-void);color:var(--fg3);font-size:11.5px;font-weight:600;cursor:pointer}
.rad.on{border-color:color-mix(in oklch,var(--green) 55%,transparent);
  background:color-mix(in oklch,var(--green) 10%,transparent);color:var(--green-quiet)}
.rad .rd{width:11px;height:11px;border-radius:50%;border:1.5px solid currentColor}
.rad.on .rd{background:currentColor;box-shadow:inset 0 0 0 2px var(--c-base)}
.newcat .nca{display:flex;gap:8px;justify-content:flex-end}

/* dormancy notice — the honest "not configured yet" state */
.dorm{border:1px solid var(--line-soft);background:var(--c-surface);padding:13px;display:flex;gap:11px;align-items:flex-start}
.dorm svg{width:17px;height:17px;stroke:var(--amber);fill:none;stroke-width:1.8;flex-shrink:0;margin-top:1px}
.dorm .dm{font-size:12.5px;color:var(--fg2);line-height:1.55}
.dorm .dm b{color:var(--fg)}

/* category manager rows */
.catrow{display:flex;align-items:flex-start;gap:12px;padding:12px 0;border-top:1px solid var(--line-soft)}
.catrow:first-child{border-top:none}
.catrow .cn{font-size:13.5px;font-weight:600;color:var(--fg)}
.catrow .cm{font-size:11.5px;color:var(--muted);margin-top:3px;display:flex;gap:7px;align-items:center;flex-wrap:wrap}
.catrow .cx{flex:1;min-width:0}
.catrow .ca{display:flex;gap:7px;flex-shrink:0;padding-top:2px}
.blockmsg{margin-top:11px;padding:11px 12px;border:1px solid color-mix(in oklch,var(--amber) 42%,transparent);
  background:color-mix(in oklch,var(--amber) 9%,transparent);display:flex;flex-direction:column;gap:10px}
.blockmsg .bt{font-size:12.5px;color:var(--fg2);line-height:1.5}
.blockmsg .bt b{color:var(--amber);font-weight:700}
.reassign{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.reassign .rl2{font-size:11.5px;color:var(--fg3);font-weight:600}
.reassign .selpill{flex:1;min-width:170px}
.dangermsg{padding:11px 12px;border:1px solid color-mix(in oklch,var(--red) 34%,transparent);
  background:color-mix(in oklch,var(--red) 7%,transparent);font-size:12.5px;color:var(--fg2);line-height:1.55}
.dangermsg b{color:var(--red);font-weight:700}
.btn-danger{background:var(--red);color:var(--on-red);font-weight:700;border-color:transparent}
.btn-danger:hover{filter:brightness(1.06)}

/* ═══════════════════════════════════════════════════════════════════════════
   T0-845 — ADMIN LIBRARY STYLING PARITY. Four rules, all of them things a
   STATIC plate never had to solve, plus one live-state the plates draw but do
   not name. Everything else in the cure was markup: T0-844 shipped the plates'
   class NAMES without the plates' DOM, so the rules above addressed elements
   that did not exist. Scoped so nothing here can reach the athlete surface:
   .mform, .dropz and .vidstate appear only in components/admin/library-*.
   Zero new :root vars; every colour resolves from the existing ladder.
   ═══════════════════════════════════════════════════════════════════════════ */

/* A modal whose body is a <form> still needs .mbody and .mfoot to be siblings in
   .mcard's flex column — otherwise the footer inherits .mbody's padding and gap
   and the body cannot scroll independently inside max-height:90vh. */
.mcard > .mform { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.mcard > .mform > .mbody { overflow-y: auto; }

/* The plates draw the dropzone as the whole control; a real page needs the file
   input to BE it. The input fills the zone and is transparent, so the pointer
   target and the drawn surface are the same rectangle, and it keeps its own
   focus ring for keyboard users rather than being hidden from them. */
.dropz { position: relative; }
.dropz input[type="file"] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: inherit; }
.dropz:focus-within { border-color: var(--green-quiet); box-shadow: 0 0 0 2px color-mix(in oklch, var(--green) 30%, transparent); }

/* Plates 02 draws the transcoding / failed thumbnail states as inline text; give
   them a class rather than the plate's inline style attribute. */
.vidstate { position: absolute; inset: 0; display: grid; place-items: center; padding: 0 14px; text-align: center; color: var(--fg3); font-size: 12px; font-weight: 600; }
.vidstate.err { color: var(--red); }

/* A failed video card carries the same red border a failed doccard does. */
.vidcard.adm.failed .vidthumb { border-color: color-mix(in oklch, var(--red) 42%, transparent); }

/* ── T0-845 r1 (raiden D865 render-verify, three 390-breakpoint findings) ──
   R3-1: the plates' own .dcacts carries flex-wrap:wrap; globals.css:699 does
   not, and the cure's .di column + per-button icons pushed the failed card's
   action row past 390 so "Retry remove" broke inside its pill. The wrap CANNOT
   be added to bare .dcacts — components/portal/library-view.tsx emits that
   class too, and the athlete surface must not move. Hence the admin-only hook. */
.dcacts.admacts { flex-wrap: wrap; }

/* R3-3: a modal whose body is NOT a form still needs to scroll inside
   max-height:90vh, or .mfoot lands below the card's bottom edge with no way to
   reach it. min-height:0 is what actually lets a flex child scroll. Opt-in by
   class so no other .mcard in the app changes. */
.mcard > .mbody.mscroll { overflow-y: auto; min-height: 0; }
.mcard > .mform > .mbody { min-height: 0; }

@media (max-width: 720px) {
  /* R3-2: at 390 the affordance column and the .cm meta row competed for one
     line and .catpill (white-space:nowrap) could not give way — measured 14×17px
     of overlap. Let the row wrap and give the controls their own line. */
  .catrow { flex-wrap: wrap; }
  .catrow .ca { width: 100%; }
  /* R3-3: with .ca on its own line .cx regains the full row, so .blockmsg is no
     longer a 106px column inside a 296px row. Its children shrink rather than
     render outside the panel's border. */
  .blockmsg { width: 100%; }
  .reassign .selpill { flex: 1 1 140px; min-width: 0; }
  .reassign .btn { flex: 1 1 auto; min-width: 0; }
}

/* ── T0-847 §01.1 row 6 — the .dclose focus rider (RQ-2, ruled GLOBAL) ────────
   raiden A-4 (T0-845 Gate-3 round 1) found that `.dclose` takes the BROWSER'S
   DEFAULT focus ring on modal open, in a design where every other focus state is
   authored (.in:focus, .dropz:focus-within, .btn-line.gconnect:focus-visible).
   raiden A-6 (round 2) minted it as a ticket condition so the design decision was
   asked rather than archived. (The backlog attributed this to "gray-fox A-4";
   measured, that record contains zero occurrences of `dclose` and its two A-4s are
   about something else entirely — T0-847 §00.10 / §10 row 2 corrects the citation.)

   SCOPE: GLOBAL, not admin-scoped. Measured blast radius is 14 emit sites across
   10 files — 7 in components/portal/ and 7 in components/admin/ — so this rule
   MOVES THE ATHLETE SURFACE, deliberately. The alternative (a hook class on the
   admin sites, the .dcacts.admacts precedent) would pin the athlete surface
   byte-identical while leaving it with the default ring the design never uses
   anywhere else; that asymmetry is worse than either uniform state, and a keyboard
   user on the athlete surface is the likelier unassisted one. The athlete modal is
   rastered at both breakpoints either way (states 9 and 10), and the diff against
   the base rasters is the evidence, not this comment.

   `outline` (not border/box-shadow) so the 32px box does not reflow, and
   `:focus-visible` (not `:focus`) so a mouse click does not paint a ring. Follows
   the strongest authored precedent in this sheet, .btn-line.gconnect:focus-visible.
   --green is defined in BOTH themes, so the ring survives the light/dark swap and
   stays legible on `.player .dclose`, which sits on a dark scrim over video. */
.dclose:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
