/* =============================================================================
   TDS DESIGN SYSTEM
   Ported from the approved mockups. Do not edit colours here — edit the tokens.

   HOW COLOUR WORKS IN THIS PRODUCT
   --------------------------------
   Everything below reads a custom property and never a literal. At runtime the
   API's /api/bootstrap response carries a generated token set for the signed-in
   tenant, and the client writes it into a :root block BEFORE first paint. A
   rebrand is therefore total and instantaneous — including the charts, which
   take their categorical palette from the same source.

   Three families, and the difference between them is deliberate:

     primary-* accent-* neutral-*   GENERATED from the customer's three seed
                                    colours, in OKLCH, at eleven fixed
                                    lightness steps. Steps 600-950 are snapped
                                    until they pass 4.5:1 against white; steps
                                    50-200 until they pass against ink. A
                                    customer cannot brand themselves into an
                                    unreadable interface.

     good warning serious           RESERVED. Never seed-derived. A customer
     critical info (+ -tint)        whose brand colour is red must not end up
                                    with red meaning "normal", and one whose
                                    brand is green must not have "on track"
                                    disappear into the chrome.

     cat-*                          Categorical chart colours. Fixed for the
                                    same reason: a legend has to stay
                                    distinguishable whatever the brand is.

   The values in :root below are FALLBACKS only — the product's own colours,
   used when the bootstrap response has not arrived (a cold offline start, or a
   developer running the client with no API). They are overwritten wholesale the
   moment it does.

   RTL
   ---
   Arabic is a launch language. There is not one physical direction in this file:
   every inline offset is `*-inline-start` / `*-inline-end`, so `dir="rtl"` on
   <html> mirrors the entire interface with no second stylesheet. Adding a
   `margin-left` here would put a hole in that, and CI checks for it.
   ============================================================================= */

:root{
  /* --- generated ramps: fallbacks, replaced at runtime ------------------- */
  --primary-50:#EDF4FE;  --primary-100:#D6E5FC; --primary-200:#B3CFF9;
  --primary-300:#84AEF3; --primary-400:#5189E8; --primary-500:#2A6ADB;
  --primary-600:#0B5FD0; --primary-700:#0A52B5; --primary-800:#0B3E8C;
  --primary-900:#0A2E68; --primary-950:#0A1E44;

  --accent-50:#FBFEE9;   --accent-100:#F2FCCB; --accent-200:#E4F89B;
  --accent-300:#D6F45C;  --accent-400:#C7F000; --accent-500:#B0D400;
  --accent-600:#9FCC00;  --accent-700:#7C9F00; --accent-800:#5E7A00;
  --accent-900:#3E5400;  --accent-950:#25340A;

  --neutral-50:#F7F9FC;  --neutral-100:#EDF1F7; --neutral-200:#E3E8F0;
  --neutral-300:#D7DEE9; --neutral-400:#B4BFD0; --neutral-500:#93A0B5;
  --neutral-600:#6B7A94; --neutral-700:#52617A; --neutral-800:#3A4A66;
  --neutral-900:#22314D; --neutral-950:#0E1B33;

  /* --- surface and ink roles -------------------------------------------- */
  --surface:#FFFFFF;
  --surface-2:var(--neutral-50);
  --surface-3:var(--neutral-100);
  --ink:var(--neutral-950);
  --ink-2:var(--neutral-800);
  --muted:var(--neutral-600);
  --faint:var(--neutral-500);
  --line:var(--neutral-200);
  --line-2:var(--neutral-100);
  --chrome:var(--primary-950);
  --chrome-2:var(--primary-900);

  /* --- reserved semantics ----------------------------------------------- */
  --good:#088357;      --good-tint:#E4F6EE;      --good-ink:#0A5A3B;
  --warning:#A86200;   --warning-tint:#FDF3E1;   --warning-ink:#6E4200;
  --serious:#C2410C;   --serious-tint:#FDEDE4;   --serious-ink:#7A2908;
  --critical:#C62B41;  --critical-tint:#FCEBEE;  --critical-ink:#8A1E2D;
  --info:#0E6C99;      --info-tint:#E4F2F8;      --info-ink:#0A4A69;

  /* --- chrome accents ----------------------------------------------------
     Fixed tones the INTERFACE uses - a violet icon well, a teal chip, the pill
     on an IDP in the week strip. Not series colours: nothing here identifies
     one thing against another, so these do not rebrand and do not need to. */
  --cat-violet:#6E4FE0; --cat-violet-tint:#EFEBFD; --cat-violet-ink:#4A2FB0;
  --cat-teal:#0E9AA7;   --cat-teal-tint:#E4F6F8;   --cat-teal-ink:#0A5D66;

  /* --- the video studio --------------------------------------------------
     The in and out marks, the saved passages, and the frame ruler. Chrome
     accents rather than reserved semantics: an in point is not "good" and an
     out point is not "critical", and borrowing those would make a coach's
     marks change meaning the first time somebody read the legend. They do not
     rebrand either - green-for-in and red-for-out is the convention every
     editing tool a coach has ever used already taught them.

     Read by video-trimmer.js as well as by the rules below: the frame ruler
     is drawn on a canvas, which has no stylesheet, so it asks for these by
     name through getComputedStyle. Renaming one silently greys out the ruler. */
  --vt-in:#2FBF71;      --vt-out:#E8554E;
  --vt-band:#6E4FE0;    --vt-band-live:#C7F000;
  --vt-tick:rgba(140,160,190,.30);
  --vt-tick-major:rgba(140,160,190,.72);
  --vt-stage:#06101F;

  /* A coded moment from an analysis export, and the one the grid has just
     played. DISTINCT FROM --vt-band ON PURPOSE: a band is a passage a coach
     marked and can edit, a tick is a moment a file recorded and nobody can,
     and a timeline that drew them alike would stop saying which marks are the
     coach's. Blue rather than the brand's own accent for the same reason the
     in and out marks are not rebranded - these are chrome describing somebody
     else's data, not a statement about this tenant. Read by the canvas ruler
     in video-trimmer.js by name, as the ticks above are. */
  --vt-marker:rgba(120,170,255,.85);
  --vt-marker-lit:#F2A73B;

  /* --- chart series ------------------------------------------------------
     Step 9.2. GENERATED FROM THE BRAND and overwritten by the tenant's own
     block at runtime - see CategoricalPalette. The values here are the default
     brand's, produced by the same generator and held to the same five checks by
     CategoricalPaletteTests, so the fallback a customer never sees is not a
     palette nobody validated.

     EIGHT, IN A FIXED ORDER, NEVER CYCLED. A ninth series folds into "other".
     Slot 1 is the brand's own hue, so a single-series chart is drawn in the
     customer's colour. */
  --cat-1:#2775E8; --cat-1-tint:#E8F1FF; --cat-1-ink:#0047A2;
  --cat-2:#A09523; --cat-2-tint:#F3F1DC; --cat-2-ink:#564F00;
  --cat-3:#B41C37; --cat-3-tint:#FFEBEA; --cat-3-ink:#930026;
  --cat-4:#C26EE9; --cat-4-tint:#F8EAFF; --cat-4-ink:#711593;
  --cat-5:#26A099; --cat-5-tint:#E0F5F3; --cat-5-ink:#005955;
  --cat-6:#DA7E24; --cat-6-tint:#FFECDE; --cat-6-ink:#743D00;
  --cat-7:#523CBB; --cat-7-tint:#EEEFFF; --cat-7-ink:#482EAD;
  --cat-8:#26A74F; --cat-8-tint:#E1F7E4; --cat-8-ink:#005E25;

  /* The ninth and beyond. Grey on purpose: "other" is not a series, and giving
     it a hue would make it look like one. */
  --cat-other:#6B7280; --cat-other-tint:#F1F2F4; --cat-other-ink:#414750;

  /* --- the pitch -----------------------------------------------------------
     Phase POS, step POS.1.3. RESERVED, like the semantic colours: never
     seed-derived, because a red-branded customer must not get a red pitch and
     a green one must not have its markers vanish into the grass. Navy, as in
     the position map the brief supplied. Only a marker's ring takes the brand
     (its accent), so a rebrand changes the markers and nothing else. */
  --pitch-surface:#132B52;
  --pitch-line:rgba(255,255,255,.55);
  --pitch-marker:#FFFFFF;
  --pitch-marker-ink:#0E1B33;
  --pitch-ink:#FFFFFF;

  /* --- the body outline ----------------------------------------------------
     Phase INJ, step INJ.1.3. RESERVED, like the pitch: never seed-derived, so
     no brand can make an injured part disappear into the figure. The injured
     marker is the reserved serious colour, not a brand hue. */
  --body-fill:#E3E8F0;
  --body-line:#93A0B5;
  --body-marker:#FFFFFF;
  --body-marker-ring:#1F3A66;
  --body-injured:var(--serious);
  --body-ink:#3A4A66;

  /* --- injury body-map heat ramp -------------------------------------------
     Phase INJ, step INJ.6.3. RESERVED and sequential: the body map shades each
     part by how many injuries it carries, light (few) to dark (many). Never
     seed-derived (AC INJ.6.3.6), so a rebrand cannot make a busy part read as a
     quiet one; and every part also shows its number, so the ramp is never the
     only encoding (AC INJ.6.3.3). One hue, six steps, step 0 being "none". */
  --injury-heat-0:#EEF2F7;
  --injury-heat-1:#CFE2F2;
  --injury-heat-2:#94C4E4;
  --injury-heat-3:#4E97CE;
  --injury-heat-4:#2266A8;
  --injury-heat-5:#123F73;

  /* --- shape, shadow, type ----------------------------------------------- */
  --radius:12px;
  --r-sm:8px; --r:var(--radius); --r-lg:16px;
  --sh-1:0 1px 2px rgba(14,27,51,.06), 0 1px 3px rgba(14,27,51,.04);
  --sh-2:0 2px 4px rgba(14,27,51,.05), 0 8px 20px rgba(14,27,51,.06);
  --sh-3:0 12px 32px rgba(10,30,68,.14);

  --font-display:"Archivo";
  --font-body:"Public Sans";
  --type-scale:1;
  --font:var(--font-body),"Inter","Segoe UI",-apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif;

  /* --- touch --------------------------------------------------------------
     44px is the floor for anything a coach taps. The register is used one-handed,
     in the rain, in gloves, while watching a pitch — §4. Nothing interactive in
     this file goes below it, and the mobile overrides at the end enforce it. */
  --tap:44px;
}

*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}

body{
  font-family:var(--font);
  background:var(--surface-2);
  color:var(--ink);
  font-size:calc(14px * var(--type-scale));
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
}

button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
a{color:inherit;text-decoration:none}
svg{display:block}

/* The app fills the viewport in the product. In the mockups it sat inside a
   presentation frame, which is why the border and radius are gone. */
.app{background:var(--surface-2);min-height:100vh;min-height:100dvh}

/* Focus is visible and it is not negotiable. The mockups had no keyboard state
   because nobody tabbed through a picture. */
:focus-visible{outline:2px solid var(--primary-600);outline-offset:2px;border-radius:4px}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;transition-duration:.01ms !important}
}

button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
a{color:inherit;text-decoration:none}
svg{display:block}

/* The presentation frame the mockups sat in - a sticky bar, a rounded card and
   a drop shadow around the whole app - is DELIBERATELY not ported. It belonged
   to the HTML deck, not to the product, and its .app override carried
   overflow:hidden onto a full-page container: everything below the first
   screenful was clipped and the page could not scroll at all. The product's own
   .app rule is above. */

/* ============ TOP BAR ============ */
.topbar{
  background:linear-gradient(100deg,var(--primary-950) 0%,var(--primary-900) 100%);
  color:#fff;display:flex;align-items:center;gap:18px;padding:0 20px;height:60px;
}
.tb-menu{width:34px;height:34px;border-radius:8px;display:grid;place-items:center;color:var(--primary-200)}
.tb-menu:hover{background:rgba(255,255,255,.09);color:#fff}
.tb-title{font-size:15.5px;font-weight:600;letter-spacing:-.01em;white-space:nowrap}
.tb-ma{display:flex;align-items:center;gap:9px;padding:5px 11px 5px 6px;border-radius:99px;background:rgba(255,255,255,.09);border:1px solid rgba(255,255,255,.13)}
.tb-ma .flag{width:26px;height:17px;border-radius:3px;overflow:hidden;flex:none;box-shadow:0 0 0 1px rgba(255,255,255,.25)}
.tb-ma b{font-size:12.5px;font-weight:600}
/* The team logo, scaled to fit the pill whatever shape it was uploaded in:
   a tall crest and a wide wordmark both sit inside the same height. */
.tb-ma .tb-logo{display:block;flex:none;block-size:24px;inline-size:auto;max-inline-size:96px;object-fit:contain}
.tb-ma .chev{color:var(--primary-300)}
.tb-search{
  margin-inline-start:auto;display:flex;align-items:center;gap:9px;
  background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.14);
  border-radius:9px;padding:0 12px;height:36px;width:270px;color:var(--primary-300);
}
.tb-search input{background:none;border:none;outline:none;color:#fff;font:inherit;font-size:13px;width:100%}
.tb-search input::placeholder{color:var(--primary-300)}
/* The results panel. Anchored to the box, above everything, and constrained so
   a long list scrolls inside itself rather than pushing the page around. */
.tb-search{position:relative}
.sr{
  position:absolute;inset-block-start:calc(100% + 6px);inset-inline-start:0;
  inline-size:min(420px, 92vw);max-block-size:60vh;overflow-y:auto;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--sh-2);padding:6px;z-index:60;color:var(--ink)
}
.sr-group h4{
  font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);padding:8px 10px 4px
}
.sr-hit{
  display:block;inline-size:100%;text-align:start;
  padding:8px 10px;border-radius:7px;background:none;border:none;
  font:inherit;color:var(--ink);cursor:pointer;
  /* 48px tap target: two lines of 8px padding plus the text meets it, and the
     min-block-size guarantees it when there is no subtitle. AGENTS.md. */
  min-block-size:48px
}
.sr-hit:hover,.sr-hit:focus-visible{background:var(--primary-50)}
.sr-hit b{display:block;font-size:13px;font-weight:650}
.sr-hit small{display:block;font-size:11.5px;color:var(--muted);margin-block-start:1px}
.sr-note{padding:12px 10px;font-size:12.5px;color:var(--muted)}

.tb-search kbd{font:inherit;font-size:10.5px;background:rgba(255,255,255,.14);padding:2px 6px;border-radius:4px;color:var(--primary-200)}
.tb-ico{width:36px;height:36px;border-radius:9px;display:grid;place-items:center;color:var(--primary-200);position:relative}
.tb-ico:hover{background:rgba(255,255,255,.09);color:#fff}
.tb-ico .badge{position:absolute;top:6px;inset-inline-end:6px;min-width:15px;height:15px;border-radius:99px;background:var(--accent-400);color:var(--accent-950);font-size:9.5px;font-weight:800;display:grid;place-items:center;padding:0 4px;border:2px solid var(--primary-950)}
.tb-user{display:flex;align-items:center;gap:10px;padding-inline-start:14px;margin-inline-start:4px;border-inline-start:1px solid rgba(255,255,255,.15)}
.tb-user .who{line-height:1.25;text-align:end}
.tb-user .who b{display:block;font-size:12.5px;font-weight:600}
.tb-user .who small{color:var(--primary-300);font-size:11px}
.avatar{border-radius:50%;background:linear-gradient(140deg,var(--primary-500),var(--primary-800));color:#fff;display:grid;place-items:center;font-weight:700;flex:none;letter-spacing:.02em}
.avatar.sm{width:26px;height:26px;font-size:10.5px}
.avatar.md{width:34px;height:34px;font-size:12px}
.avatar.lg{width:52px;height:52px;font-size:17px}
.avatar.xl{width:64px;height:64px;font-size:21px}

/* ============ LAYOUT ============ */
.shell{display:grid;grid-template-columns:224px 1fr;min-height:940px}

/* ============ SIDEBAR ============ */
.side{background:var(--primary-600);color:#fff;padding:18px 0 22px;display:flex;flex-direction:column}
.side-brand{display:flex;align-items:center;justify-content:space-between;padding:0 18px 20px}
.fifa-mark{font-weight:900;font-size:23px;letter-spacing:-.055em;font-style:italic}
.side-close{width:24px;height:24px;border-radius:50%;background:rgba(255,255,255,.18);display:grid;place-items:center;font-size:12px;color:var(--neutral-100)}
.side-sec{padding:0 12px;margin-bottom:4px}
.side-cap{font-size:10px;letter-spacing:.15em;text-transform:uppercase;color:var(--primary-300);font-weight:700;padding:14px 8px 7px}
.nav-i{
  display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:8px;
  font-size:13.5px;font-weight:500;color:var(--neutral-100);margin-bottom:1px;transition:.13s;
}
.nav-i:hover{background:rgba(255,255,255,.12)}
.nav-i .ico{width:17px;flex:none;opacity:.85}
.nav-i .chev{margin-inline-start:auto;opacity:.6}
.nav-i.active{background:var(--accent-400);color:var(--accent-950);font-weight:700}
.nav-i.active .ico{opacity:1}
.nav-i.open{background:rgba(255,255,255,.13);font-weight:600;color:#fff}
.nav-sub{padding-inline-start:10px;margin:2px 0 6px;border-inline-start:2px solid rgba(255,255,255,.2);margin-inline-start:18px}
.nav-sub .nav-i{font-size:12.5px;padding:7px 10px;color:var(--primary-200)}
.nav-sub .nav-i.active{background:var(--accent-400);color:var(--accent-950)}
.side-foot{margin-top:auto;padding:0 12px}
.side-foot .nav-i{color:var(--primary-200);font-size:12.5px}
.side-sync{margin:14px 12px 0;padding:10px 11px;border-radius:10px;background:rgba(0,0,0,.16);border:1px solid rgba(255,255,255,.13)}
.side-sync .row{display:flex;align-items:center;gap:7px;font-size:11.5px;font-weight:600;color:var(--neutral-50)}
.side-sync small{display:block;color:var(--primary-300);font-size:10.5px;margin-top:2px}
.pulse{width:7px;height:7px;border-radius:50%;background:var(--accent-400);box-shadow:0 0 0 3px rgba(199,240,0,.22);flex:none}

/* ============ MAIN ============ */
.main{padding:22px 26px 34px;min-inline-size:0}
.crumbs{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--muted);margin-bottom:12px}
.crumbs b{color:var(--ink-2);font-weight:600}
.page-head{display:flex;align-items:flex-end;gap:18px;flex-wrap:wrap;margin-bottom:20px}
.page-head h1{font-size:25px;font-weight:750;letter-spacing:-.025em;line-height:1.2}
.page-head p{color:var(--muted);font-size:13.5px;margin-top:4px}
.head-actions{margin-inline-start:auto;display:flex;align-items:center;gap:9px}

.btn{display:inline-flex;align-items:center;gap:7px;height:36px;padding:0 14px;border-radius:9px;font-size:13px;font-weight:600;transition:.14s;white-space:nowrap}
.btn-ghost{background:var(--surface);border:1px solid var(--line);color:var(--ink-2);box-shadow:var(--sh-1)}
.btn-ghost:hover{border-color:var(--primary-200);color:var(--ink)}
.btn-primary{background:var(--primary-600);color:#fff;box-shadow:0 2px 8px rgba(11,95,208,.28)}
.btn-primary:hover{background:var(--primary-700)}
.btn-accent{background:var(--accent-400);color:var(--accent-950);box-shadow:0 2px 8px rgba(160,196,0,.35)}
.btn-accent:hover{filter:brightness(.96)}
.btn-sm{height:30px;padding:0 11px;font-size:12px;border-radius:8px}

/* ============ KPI STRIP ============ */
.kpis{display:grid;grid-template-columns:repeat(6,1fr);gap:12px;margin-bottom:18px}
.kpi{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:13px 14px;box-shadow:var(--sh-1);position:relative;overflow:hidden;
}
.kpi::before{content:"";position:absolute;inset-inline-start:0;top:0;bottom:0;width:3px;background:var(--primary-600)}
.kpi.k-lime::before{background:var(--accent-400)}
.kpi.k-green::before{background:var(--good)}
.kpi.k-amber::before{background:var(--warning)}
.kpi.k-violet::before{background:var(--cat-violet)}
.kpi.k-teal::before{background:var(--cat-teal)}
.kpi .lab{font-size:11px;color:var(--muted);font-weight:600;letter-spacing:.02em;display:flex;align-items:center;gap:5px}
.kpi .val{font-size:24px;font-weight:750;letter-spacing:-.03em;margin-top:5px;line-height:1;font-variant-numeric:tabular-nums}
.kpi .val small{font-size:13px;font-weight:600;color:var(--muted);letter-spacing:0}
.kpi .sub{font-size:11px;margin-top:6px;display:flex;align-items:center;gap:4px;color:var(--muted)}

/* Step 9.1: a tile with records behind it is a real button. Left-aligned and
   full-width, because a button element otherwise centres its content and shrinks
   to fit, and the row would stop lining up with the tiles that are not
   drillable. Everything else about it is the tile. */
.kpi-drill{
  display:block;width:100%;text-align:start;font:inherit;color:inherit;cursor:pointer;
  appearance:none;
}
.kpi-drill .lab,.kpi-drill .val,.kpi-drill .sub{display:flex}
.kpi-drill:hover{border-color:var(--primary-300);box-shadow:var(--sh-2)}
.kpi-drill:focus-visible{outline:2px solid var(--primary-600);outline-offset:2px}
.kpi-why{
  position:absolute;inset-block-start:11px;inset-inline-end:11px;font-size:10px;font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;color:var(--primary-600);opacity:0;transition:opacity .12s;
}
.kpi-drill:hover .kpi-why,.kpi-drill:focus-visible .kpi-why{opacity:1}

/* ============ DRILL-THROUGH ============ */
.drill-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:14px}
.drill-lab{font-size:11.5px;font-weight:700;letter-spacing:.02em;color:var(--muted)}
.drill-val{font-size:30px;font-weight:750;letter-spacing:-.03em;line-height:1.1;font-variant-numeric:tabular-nums}
.drill-h{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin:16px 0 7px}
.drill-inputs td:first-child{font-weight:600}
.drill-rows{max-width:100%}

/* The untranslated statement. Monospaced and quiet: it is evidence rather than
   prose, and the eye should be able to skip it until it is needed. */
.drill-statement{
  margin-top:16px;padding:9px 11px;background:var(--surface-2);border:1px solid var(--line-2);
  border-radius:var(--r);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11.5px;
  color:var(--ink-2);line-height:1.5;
}
.drill-hash{margin-top:5px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10.5px}

.up{color:var(--good);font-weight:700}
.down{color:var(--critical);font-weight:700}

/* ============ GRID ============ */
.cols{display:grid;grid-template-columns:1.32fr 1fr;gap:16px;align-items:start}
.stack{display:flex;flex-direction:column;gap:16px}

.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--sh-1);overflow:hidden}
.card-h{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--line-2)}
.card-h h2{font-size:14.5px;font-weight:700;letter-spacing:-.01em}
.card-h p{font-size:12px;color:var(--muted);margin-top:1px}
.card-h .right{margin-inline-start:auto;display:flex;align-items:center;gap:8px}
.card-b{padding:16px}
.card-b.tight{padding:12px 16px 16px}
.card-f{padding:11px 16px;border-top:1px solid var(--line-2);background:var(--surface-2);display:flex;align-items:center;gap:10px}
.hicon{width:30px;height:30px;border-radius:9px;display:grid;place-items:center;flex:none;background:var(--primary-50);color:var(--primary-600)}
.hicon.lime{background:var(--accent-100);color:var(--accent-800)}
.hicon.violet{background:var(--cat-violet-tint);color:var(--cat-violet)}
.hicon.amber{background:var(--warning-tint);color:var(--warning)}
.hicon.teal{background:var(--cat-teal-tint);color:var(--cat-teal)}
.link{font-size:12.5px;font-weight:600;color:var(--primary-600);display:inline-flex;align-items:center;gap:4px}
.link:hover{text-decoration:underline}

/* ============ COHORT MATRIX ============ */
.cohort-head{display:grid;grid-template-columns:64px 1fr 1fr;gap:10px;padding:0 0 8px;align-items:center}
.cohort-head .ch{font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);display:flex;align-items:center;gap:6px}
.cohort-row{display:grid;grid-template-columns:64px 1fr 1fr;gap:10px;margin-bottom:8px;align-items:stretch}
.cohort-yr{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  background:var(--surface-2);border:1px solid var(--line-2);border-radius:10px;
}
.cohort-yr b{font-size:14px;font-weight:750;letter-spacing:-.02em}
.cohort-yr small{font-size:9.5px;color:var(--faint);font-weight:600;letter-spacing:.04em}
.sq{
  display:flex;align-items:center;gap:10px;padding:9px 11px;border-radius:10px;
  border:1px solid var(--line);background:var(--surface);transition:.14s;cursor:pointer;
}
.sq:hover{border-color:var(--primary-600);box-shadow:0 0 0 3px var(--primary-50);transform:translateY(-1px)}
.sq .st{width:9px;height:9px;border-radius:50%;flex:none}
.st-active{background:var(--good);box-shadow:0 0 0 3px var(--good-tint)}
.st-prep{background:var(--warning);box-shadow:0 0 0 3px var(--warning-tint)}
.st-ynt{background:var(--critical);box-shadow:0 0 0 3px var(--critical-tint)}
.sq .info{min-width:0;flex:1}
.sq .info b{display:block;font-size:12.5px;font-weight:650;letter-spacing:-.01em}
.sq .info small{display:block;font-size:11px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sq .cnt{font-size:11px;font-weight:700;color:var(--ink-2);background:var(--surface-2);border:1px solid var(--line-2);border-radius:7px;padding:3px 7px;flex:none}
.sq.empty{background:repeating-linear-gradient(135deg,var(--surface-2),var(--surface-2) 6px,var(--surface-3) 6px,var(--surface-3) 12px);border-style:dashed;cursor:default;color:var(--faint);justify-content:center;font-size:11.5px;font-weight:600}
.sq.empty:hover{border-color:var(--line);box-shadow:none;transform:none}
/* THE COHORT MATRIX ON A PHONE. AC 2.3.2.
   Two 1fr columns beside a 64px label needs about 520px before the tiles stop
   being readable; at 375 the second column was clipped mid-word by the card,
   which reads as broken rather than as scrollable.

   The grid becomes a list: the year on its own line, then the squads under it
   full width. The alignment that makes the desktop grid worth having - the gap
   where a cohort has no squad - is what the "No squad this cohort" tile carries,
   and it is kept rather than hidden, because the gap IS the information. */
@media (max-width:600px){
  .cohort-head{display:none}
  .cohort-row{
    grid-template-columns:1fr;gap:6px;margin-bottom:14px
  }
  .cohort-yr{
    flex-direction:row;justify-content:flex-start;gap:8px;
    padding:6px 11px;background:none;border:none
  }
  .cohort-yr b{font-size:13px}
  .cohort-yr small{font-size:10.5px}
  /* A tap target that is a whole row, not a 9px dot inside one. */
  .sq{min-block-size:48px}
  .sq.empty{min-block-size:40px;font-size:11px}
}

.legend{display:flex;flex-wrap:wrap;gap:14px;font-size:11.5px;color:var(--muted);padding-top:4px}
.legend i{display:inline-block;width:8px;height:8px;border-radius:50%;margin-inline-end:5px;vertical-align:1px}

/* ============ ATTENTION LIST ============ */
/* WRAPS. Four things in one row - pin, name, due chip, button - fit in a wide
   card and do not fit in a narrow aside, where the nowrap chip refused to shrink
   and sat on top of the name. Wrapping puts the chip and the button on a second
   line instead of truncating somebody's name to make room. */
.att{display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;padding:11px 16px;border-bottom:1px solid var(--line-2);transition:.13s}
.att:last-child{border-bottom:none}
.att:hover{background:var(--surface-2)}
/* Set an attention item aside. Quiet until hovered: it is the least important
   thing on the row, and the action button beside it is the one to press. */
.att-x{inline-size:32px;block-size:32px;border-radius:8px;display:grid;place-items:center;flex:none;color:var(--faint);background:none;border:none;cursor:pointer}
.att-x:hover,.att-x:focus-visible{background:var(--surface-2);color:var(--ink)}
.sr-row{display:flex;align-items:center;gap:4px}
.sr-row .sr-hit{flex:1;min-inline-size:0}
.sr-foot{display:block;inline-size:100%;margin-block-start:4px;padding:10px;border:none;border-block-start:1px solid var(--line-2);background:none;color:var(--primary-600);font:inherit;font-size:12.5px;font-weight:650;text-align:center;cursor:pointer;min-block-size:var(--tap)}
.sr-foot:hover,.sr-foot:focus-visible{background:var(--primary-50)}
/* The attention settings table: rules down, roles across. */
.rule-grid{inline-size:100%;border-collapse:collapse;font-size:12.5px}
.rule-grid th,.rule-grid td{padding:8px 10px;border-bottom:1px solid var(--line-2);text-align:center;vertical-align:middle}
.rule-grid th:first-child,.rule-grid td:first-child{text-align:start;min-inline-size:220px}
/* The rule's name stays in view while ten role columns scroll past it. */
.rule-grid tr > :first-child{position:sticky;inset-inline-start:0;background:var(--surface);z-index:1}
.rule-grid thead th{font-size:11px;font-weight:650;color:var(--muted);white-space:nowrap}
.rule-grid td small{display:block;color:var(--muted);font-size:11.5px;margin-block-start:2px}
.rule-grid input[type=checkbox]{inline-size:18px;block-size:18px;cursor:pointer}
.rule-grid .is-default{color:var(--faint)}
/* Positioned, so a visually-hidden heading inside (position:absolute) is
   clipped by this box. Unpositioned, it escaped to the page and, right to left,
   widened the whole page at phone width. Step ACH.1.3. */
.table-scroll{overflow-x:auto;position:relative}
/* Step PP.1.1. The performance areas: one per row, in rating-grid order. */
.area-grid td{white-space:nowrap}
.area-grid th .chip{margin-inline-start:6px}
.area-grid tr.is-retired th b{color:var(--muted)}
.area-add{display:flex;flex-wrap:wrap;align-items:flex-end;gap:10px;margin-block-start:14px}
.area-add .f{flex:1;min-inline-size:200px}
/* Phase ACH, step ACH.2.3. A child's achievement history, and the match
   sheet's children - one tap each, so each is at least a thumb high. */
.achievement-list{list-style:none;margin:0;padding:0}
.achievement-list li{display:flex;flex-wrap:wrap;align-items:center;gap:6px;padding-block:8px;border-block-end:1px solid var(--line)}
.achievement-list li small{flex-basis:100%}
.achievement-list li.is-voided{color:var(--muted)}
.achievement-players{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px;margin-block-start:12px}
.achievement-players .btn{min-block-size:var(--tap);justify-content:flex-start}
.att .pin{width:32px;height:32px;border-radius:9px;display:grid;place-items:center;flex:none;font-size:15px}
.att .txt{min-width:0;flex:1 1 130px}
.att .txt b{display:block;font-size:12.8px;font-weight:650;letter-spacing:-.005em}
.att .txt small{display:block;color:var(--muted);font-size:11.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* The button goes last on the wrapped line rather than floating mid-row. */
.att > .btn{margin-inline-start:auto}
.chip{display:inline-flex;align-items:center;gap:5px;font-size:10.5px;font-weight:700;padding:3px 8px;border-radius:99px;letter-spacing:.02em;white-space:nowrap}
.c-red{background:var(--critical-tint);color:var(--critical)}
.c-amber{background:var(--warning-tint);color:var(--warning)}
.c-green{background:var(--good-tint);color:var(--good)}
.c-blue{background:var(--primary-50);color:var(--primary-700)}
.c-violet{background:var(--cat-violet-tint);color:var(--cat-violet)}
.c-teal{background:var(--cat-teal-tint);color:var(--cat-teal)}
.c-grey{background:var(--line-2);color:var(--primary-600)}
.c-lime{background:var(--accent-100);color:var(--accent-700)}

/* ============ CALENDAR ============ */
.cal-toolbar{display:flex;align-items:center;gap:8px;padding:10px 16px;border-bottom:1px solid var(--line-2);flex-wrap:wrap}
.cal-nav{display:flex;align-items:center;border:1px solid var(--line);border-radius:8px;overflow:hidden;background:var(--surface)}
.cal-nav button{width:28px;height:28px;display:grid;place-items:center;color:var(--muted)}
.cal-nav button:hover{background:var(--surface-2);color:var(--ink)}
.cal-nav .today{width:auto;padding:0 11px;font-size:12px;font-weight:600;border-inline-start:1px solid var(--line);border-inline-end:1px solid var(--line);color:var(--ink-2)}
.cal-range{font-size:13px;font-weight:650;letter-spacing:-.01em}
.seg{display:flex;background:var(--line-2);border-radius:8px;padding:3px;gap:2px;margin-inline-start:auto}
.seg button{padding:4px 10px;border-radius:6px;font-size:11.5px;font-weight:600;color:var(--muted)}
.seg button.on{background:var(--surface);color:var(--ink);box-shadow:var(--sh-1)}
.filters{display:flex;gap:6px;padding:9px 16px;flex-wrap:wrap;border-bottom:1px solid var(--line-2);align-items:center}
.fchip{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;font-weight:600;padding:4px 10px;border-radius:99px;border:1px solid var(--line);background:var(--surface);color:var(--ink-2)}
.fchip i{width:8px;height:8px;border-radius:2px;display:inline-block}
.fchip.off{opacity:.45;text-decoration:line-through}

.cal{display:grid;grid-template-columns:44px repeat(7,1fr);font-size:11px}
.cal .hcell{padding:7px 4px;text-align:center;border-bottom:1px solid var(--line);border-inline-start:1px solid var(--line-2)}
.cal .hcell:first-child{border-inline-start:none}
.cal .hcell small{display:block;color:var(--faint);font-size:9.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase}
.cal .hcell b{font-size:14px;font-weight:650;display:inline-grid;place-items:center;width:24px;height:24px;border-radius:50%;margin-top:2px}
.cal .hcell.today b{background:var(--primary-600);color:#fff}
.cal .hcell.today small{color:var(--primary-600)}
.cal .tcell{border-top:1px solid var(--line-2);text-align:end;padding:2px 6px 0;color:var(--faint);font-size:9.5px;font-weight:600;height:44px}
.cal .gcell{
  border-top:1px solid var(--line-2);border-inline-start:1px solid var(--line-2);position:relative;
  background-image:repeating-linear-gradient(to bottom,var(--line-2) 0 1px,transparent 1px 46px);
}
.cal .gcell.sat,.cal .gcell.sun{background-color:var(--surface-2)}
.cal .body{grid-column:1/-1;display:grid;grid-template-columns:44px repeat(7,1fr);grid-template-rows:repeat(10,46px);position:relative}
/* The row count above is a FALLBACK. TdsWeekCalendar sets it inline from the
   hours it was given; a page showing an evening programme needs more than ten. */
.ev{
  margin:2px 3px;border-radius:7px;padding:5px 7px;font-size:10.5px;line-height:1.3;
  overflow:hidden;position:relative;cursor:pointer;transition:.13s;
  border-inline-start:3px solid;
}
.ev:hover{filter:brightness(.985);box-shadow:var(--sh-2);z-index:5}
.ev b{display:block;font-weight:700;font-size:11px;letter-spacing:-.01em}
.ev small{display:block;opacity:.82;font-size:9.5px;margin-top:1px}
/* The calendar's events as buttons: no browser chrome, the kind's own colours
   and inline-start stripe, and a focus ring a keyboard user can follow. */
button.ev,button.mev{font:inherit;text-align:start;border-block:0;border-inline-end:0;cursor:pointer}
button.ev{display:block}
button.mev{inline-size:100%}
button.agenda-row{inline-size:100%;font:inherit;text-align:start;background:none;border-block-start:0;border-inline-end:0;cursor:pointer}
button.ev:focus-visible,button.mev:focus-visible{outline:2px solid var(--primary-600);outline-offset:1px;z-index:6}
/* Step 4.1: a cancelled activity is still drawn - faded, its title struck through,
   and its detail line saying "Cancelled" in words (never by strike-through alone). */
.ev.is-cancelled,.mev.is-cancelled,.agenda-row.is-cancelled{opacity:.62;border-style:dashed}
.is-cancelled .ev-title{text-decoration:line-through}
/* Step 4.2: the author's own draft - dashed, and "Draft" in words. */
.ev.is-draft,.mev.is-draft,.agenda-row.is-draft{border-style:dashed}
/* Step AS.2.2. A row of buttons under a form in a card, and a programme's block of seasons. */
.form-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;margin-block:10px 4px}
.prog-block{border-block-start:1px solid var(--line-2);margin-block-start:14px;padding-block-start:12px}
.prog-h{font-size:13px;font-weight:700;letter-spacing:-.01em;margin:0 0 8px}
/* An empty hour on the week grid, as a place to add a session: invisible until
   pointed at or focused, then a tinted cell with a plus. Under the events, so
   an event is still what a click on it opens. */
.cal-add{font:inherit;background:none;border:0;padding:0;cursor:pointer;color:var(--primary-600);
  display:grid;place-items:center;opacity:0;font-size:16px;font-weight:700;border-radius:6px;margin:2px 3px}
.cal-add:hover,.cal-add:focus-visible{opacity:1;background:var(--primary-50)}
.cal-add:focus-visible{outline:2px solid var(--primary-600);outline-offset:-2px}
/* The same on a month day: a small plus beside the date. */
.mday-add{position:absolute;inset-block-start:5px;inset-inline-end:5px;inline-size:21px;block-size:21px;
  display:grid;place-items:center;border:0;border-radius:50%;background:none;color:var(--muted);cursor:pointer;opacity:0}
.mday:hover .mday-add,.mday-add:focus-visible{opacity:1}
.mday-add:hover,.mday-add:focus-visible{background:var(--primary-50);color:var(--primary-600)}
@media (hover:none){.mday-add{opacity:1}}
/* The event details panel. */
.evd{display:grid;gap:14px;min-inline-size:0}
/* A little wider than a form dialog: two columns of label and value. */
.dlg:has(.evd){inline-size:min(620px, 92vw)}
.evd dd{overflow-wrap:anywhere}
.evd-chips{display:flex;gap:6px;flex-wrap:wrap}
.evd h3{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin:0 0 6px}
.evd dl{display:grid;grid-template-columns:minmax(120px,max-content) 1fr;gap:6px 14px;margin:0;font-size:13px}
.evd dt{color:var(--muted)}
.evd dd{margin:0;color:var(--ink);white-space:pre-line}
.evd-files{display:grid;gap:4px;margin:0;padding:0;list-style:none;font-size:13px}
.evd-files li{display:flex;gap:8px;align-items:center}
.evd-note{font-size:12px;color:var(--muted);margin:0}

/* The session write-up. Step SR.1.

   `white-space:pre-line`, because a coach writing three short paragraphs on a
   phone expects three paragraphs back rather than one run-on. Same treatment
   the dd above already gets, for the same reason. */
.evd-report{font-size:13px;color:var(--ink);margin:0 0 6px;white-space:pre-line;overflow-wrap:anywhere}
.evd-report-actions{display:flex;gap:8px;flex-wrap:wrap;margin-block-start:8px}

/* Authored text beside a machine's restatement of it. Phase TR, step TR.3.1.

   THE ORIGINAL IS NOT DIMMED. The obvious styling - full weight on the
   translation the reader can actually read, the original greyed out beneath -
   would say with typography the opposite of what this whole phase says in
   words: that the machine's version is the record and the coach's is a
   footnote. Both paragraphs get the same ink and the same size, and the MARK
   between them is what carries the difference.

   Logical properties throughout, so the border and the indent move to the other
   side under dir="rtl" without a second rule (AGENTS.md section 2). The blocks
   carry their OWN dir, because a Portuguese note read in Arabic puts one
   direction directly above the other. */
.tr{display:grid;gap:6px}
.tr-src{font-size:11px;color:var(--muted);margin:0;text-transform:none}
.tr-orig{font-size:13px;color:var(--ink);margin:0;white-space:pre-line;overflow-wrap:anywhere}

/* The mark. Not colour alone: a glyph and a sentence, either of which survives
   a monochrome print, a forced-colours mode, or a reader who cannot tell the
   tint from the surface. AC TR.3.1.2. */
.tr-mark{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--muted);
  margin-block-start:4px;padding-block-start:6px;border-block-start:1px dashed var(--line)}
.tr-icon{font-size:12px;line-height:1}
.tr-what{overflow-wrap:anywhere}

/* Indented against a border on the reading-start side, so the machine's words
   are visibly a quotation of the record rather than a continuation of it. */
.tr-text{font-size:13px;color:var(--ink);margin:0;white-space:pre-line;overflow-wrap:anywhere;
  padding-inline-start:10px;border-inline-start:2px solid var(--line)}
/* .ev-training and .ev-talentId, NOT .ev-train and .ev-tid. CalendarViewModel
   emits the long names - its own comment says these are the design tokens - and
   nothing in the product has ever emitted the short ones, so training sessions
   and Talent ID activities have been drawing as unstyled boxes on every
   calendar since the view model was written. Two of the four kinds, in the two
   colours a coach uses most. The short names are kept as aliases: they cost a
   line each and removing them is a separate question from making the calendar
   right. */
.ev-training,.ev-train{background:var(--primary-50);border-color:var(--primary-600);color:var(--primary-800)}
.ev-match{background:var(--accent-100);border-color:var(--accent-600);color:var(--accent-900)}
.ev-talentId,.ev-tid{background:var(--warning-tint);border-color:var(--warning);color:var(--warning)}
.ev-idp{background:var(--cat-violet-tint);border-color:var(--cat-violet);color:var(--cat-violet-ink)}
.ev-other{background:var(--line-2);border-color:var(--primary-400);color:var(--primary-700)}

/* ============ RESOURCE TILES ============ */
.tiles{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.tiles.col1{grid-template-columns:1fr}
.tile{
  display:flex;gap:11px;padding:13px;border-radius:11px;border:1px solid var(--line);
  background:var(--surface);transition:.15s;cursor:pointer;align-items:flex-start;
}
.tile:hover{border-color:var(--primary-600);box-shadow:0 0 0 3px var(--primary-50);transform:translateY(-1px)}
.tile .ti{width:34px;height:34px;border-radius:10px;display:grid;place-items:center;flex:none}
.tile b{display:block;font-size:12.8px;font-weight:650;letter-spacing:-.01em}
.tile small{display:block;font-size:11px;color:var(--muted);margin-top:2px;line-height:1.4}
.tile .meta{font-size:10px;color:var(--faint);margin-top:5px;font-weight:600}

/* ============ ACTIVITY FEED ============ */
.feed{position:relative;padding-inline-start:6px}
.feed-i{display:flex;gap:11px;padding:9px 0;position:relative}
.feed-i:not(:last-child)::before{content:"";position:absolute;inset-inline-start:12px;top:30px;bottom:-2px;width:2px;background:var(--line-2)}
.feed-i .fd{width:26px;height:26px;border-radius:50%;display:grid;place-items:center;flex:none;z-index:1;border:2px solid var(--surface)}
.feed-i p{font-size:12px;line-height:1.45;color:var(--ink-2)}
.feed-i p b{font-weight:650;color:var(--ink)}
.feed-i .feed-a{color:inherit;text-decoration:none;display:block}
.feed-i .feed-a:hover p,.feed-i .feed-a:focus-visible p{text-decoration:underline}
.feed-i time{font-size:10.5px;color:var(--faint);font-weight:600;display:block;margin-top:2px}

/* ============ SCREEN 2 : TEAM HEADER ============ */
.team-hero{
  background:linear-gradient(102deg,var(--primary-600) 0%,var(--primary-800) 58%,var(--primary-900) 100%);
  border-radius:var(--r-lg);padding:20px 22px;color:#fff;position:relative;overflow:hidden;
  box-shadow:0 8px 24px rgba(8,51,122,.22);margin-bottom:16px;
}
.team-hero::after{
  content:"";position:absolute;inset-inline-end:-70px;top:-90px;width:300px;height:300px;border-radius:50%;
  background:radial-gradient(circle at 30% 30%,rgba(199,240,0,.20),rgba(199,240,0,0) 62%);
}
.th-top{display:flex;align-items:center;gap:16px;position:relative;z-index:1;flex-wrap:wrap}
.crest{
  width:58px;height:58px;border-radius:15px;flex:none;display:grid;place-items:center;
  background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.26);backdrop-filter:blur(4px);
}
.crest .flag{width:34px;height:22px;border-radius:3px;overflow:hidden}
.th-name h1{font-size:24px;font-weight:750;letter-spacing:-.028em;line-height:1.15}
.th-chips{display:flex;gap:7px;margin-top:7px;flex-wrap:wrap}
.hchip{font-size:11px;font-weight:650;padding:3px 9px;border-radius:99px;background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.2);letter-spacing:.01em}
.hchip.on{background:var(--accent-400);color:var(--accent-950);border-color:transparent}
.th-staff{margin-inline-start:auto;display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.staffgrp{text-align:end}
.staffgrp small{display:block;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--primary-300);font-weight:700;margin-bottom:5px}
.stack-av{display:flex}
.stack-av .avatar{border:2px solid var(--primary-700);margin-inline-start:-8px}
.stack-av .avatar:first-child{margin-inline-start:0}
.stack-av .more{background:rgba(255,255,255,.2);font-size:10px}
.th-actions{display:flex;gap:8px}
.btn-glass{background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.24);color:#fff}
.btn-glass:hover{background:rgba(255,255,255,.24)}

.tabs{display:flex;gap:2px;border-bottom:1px solid var(--line);margin-bottom:18px;overflow-x:auto}
.tab{
  display:inline-flex;align-items:center;gap:8px;padding:10px 15px;font-size:13px;font-weight:600;
  color:var(--muted);border-bottom:2px solid transparent;margin-bottom:-1px;white-space:nowrap;transition:.14s;
}
.tab:hover{color:var(--ink-2)}
.tab.on{color:var(--primary-600);border-bottom-color:var(--primary-600);font-weight:700}
.tab .ti{width:22px;height:22px;border-radius:6px;display:grid;place-items:center;background:var(--line-2);color:var(--muted)}
.tab.on .ti{background:var(--primary-50);color:var(--primary-600)}
.tab .n{font-size:10.5px;font-weight:700;background:var(--line-2);color:var(--muted);border-radius:99px;padding:1px 6px}
.tab.on .n{background:var(--primary-50);color:var(--primary-600)}

/* squad grid */
.squad{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.pcard{
  border:1px solid var(--line);border-radius:11px;background:var(--surface);overflow:hidden;
  transition:.15s;cursor:pointer;position:relative;
}
.pcard:hover{border-color:var(--primary-600);box-shadow:0 0 0 3px var(--primary-50);transform:translateY(-1px)}
.pcard.idp{border-color:var(--accent-300);background:linear-gradient(180deg,var(--neutral-50),#fff 55%)}
.pcard.idp:hover{border-color:var(--accent-600);box-shadow:0 0 0 3px rgba(199,240,0,.28)}
.pc-top{display:flex;gap:9px;padding:10px 11px 8px;align-items:flex-start}
.pc-top .info{min-width:0;flex:1}
.pc-top .info b{display:block;font-size:12.5px;font-weight:650;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pc-top .info small{display:block;font-size:10.5px;color:var(--muted)}
.pc-dot{width:8px;height:8px;border-radius:50%;flex:none;margin-top:5px}
.pc-meta{display:flex;align-items:center;gap:8px;padding:7px 11px;border-top:1px solid var(--line-2);background:var(--surface-2);font-size:10.5px;color:var(--muted);font-weight:600}
.pc-meta .flag{width:16px;height:11px;border-radius:2px;overflow:hidden;flex:none}
.pc-meta .sp{margin-inline-start:auto;display:flex;gap:6px;color:var(--faint)}
.pc-idp{padding:7px 11px;border-top:1px solid var(--accent-100);background:var(--accent-50);display:flex;align-items:center;gap:8px}
.bar{height:5px;border-radius:99px;background:var(--line);overflow:hidden;flex:1}
.bar i{display:block;height:100%;border-radius:99px;background:linear-gradient(90deg,var(--accent-600),var(--accent-500))}
.bar.blue i{background:linear-gradient(90deg,var(--primary-500),var(--primary-600))}
.pc-idp small{font-size:10px;font-weight:700;color:var(--accent-800);flex:none}
.pc-idp.none{background:var(--surface-2);border-top-color:var(--line-2);justify-content:center}
.pc-idp.none small{color:var(--faint);font-weight:600;font-size:10.5px;letter-spacing:.01em}

/* focus areas */
.fa{display:flex;align-items:center;gap:11px;padding:10px 0;border-bottom:1px solid var(--line-2)}
.fa:last-child{border-bottom:none}
.fa .fi{width:30px;height:30px;border-radius:9px;display:grid;place-items:center;flex:none;font-size:14px}
.fa .nm{flex:1;min-width:0}
.fa .nm b{display:block;font-size:12.5px;font-weight:650}
.fa .nm small{font-size:11px;color:var(--muted)}
.stars{display:flex;gap:1.5px;flex:none}
.stars span{color:var(--neutral-300);font-size:12px}
.stars span.f{color:var(--warning)}

/* fixture */
.fixture{padding:14px 16px}
.fx-row{display:flex;align-items:center;gap:12px}
.fx-team{flex:1;display:flex;align-items:center;gap:9px;min-width:0}
.fx-team.r{justify-content:flex-end;text-align:end}
.fx-badge{width:38px;height:38px;border-radius:11px;display:grid;place-items:center;flex:none;background:var(--surface-2);border:1px solid var(--line)}
.fx-team b{font-size:12.5px;font-weight:650;letter-spacing:-.01em}
.fx-team small{display:block;font-size:10.5px;color:var(--muted)}
.fx-vs{font-size:11px;font-weight:800;color:var(--faint);letter-spacing:.06em}
.fx-meta{display:flex;gap:14px;margin-top:12px;padding-top:11px;border-top:1px dashed var(--line);flex-wrap:wrap}
.fx-meta div{font-size:11px;color:var(--muted)}
.fx-meta b{display:block;font-size:12px;color:var(--ink);font-weight:650;margin-top:1px}

/* mini stats */
.mini{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.mstat{border:1px solid var(--line-2);border-radius:10px;padding:11px 12px;background:var(--surface-2)}
.mstat .l{font-size:10.5px;color:var(--muted);font-weight:650;letter-spacing:.02em}
.mstat .v{font-size:19px;font-weight:750;letter-spacing:-.03em;margin-top:3px;font-variant-numeric:tabular-nums}
.mstat .v small{font-size:11px;color:var(--muted);font-weight:600;margin-inline-start:4px}

/* donut */
.donut-wrap{display:flex;align-items:center;gap:16px}
.donut{width:96px;height:96px;border-radius:50%;flex:none;display:grid;place-items:center;position:relative}
.donut::after{content:"";position:absolute;inset:17px;border-radius:50%;background:var(--surface)}
.donut .dv{position:relative;z-index:1;text-align:center;line-height:1.1}
.donut .dv b{display:block;font-size:19px;font-weight:750;letter-spacing:-.03em}
.donut .dv small{font-size:9.5px;color:var(--muted);font-weight:650;letter-spacing:.04em}
.dleg{flex:1;display:flex;flex-direction:column;gap:7px}
.dleg div{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--ink-2)}
.dleg i{width:9px;height:9px;border-radius:3px;flex:none}
.dleg b{margin-inline-start:auto;font-weight:700;font-variant-numeric:tabular-nums}
/* The share beside the count. Fixed width so the column of them lines up. */
.dleg .dleg-share{inline-size:36px;text-align:end;color:var(--muted);font-weight:650;font-variant-numeric:tabular-nums}

/* video row */
.vrow{display:flex;gap:10px;padding:9px 0;border-bottom:1px solid var(--line-2);align-items:center}
.vrow:last-child{border-bottom:none}
.vthumb{width:74px;height:44px;border-radius:8px;flex:none;position:relative;overflow:hidden;background:linear-gradient(140deg,var(--good),var(--good-ink))}
.vthumb .pl{position:absolute;inset:0;display:grid;place-items:center;color:#fff}
.vthumb .dur{position:absolute;inset-inline-end:3px;bottom:3px;background:rgba(0,0,0,.7);color:#fff;font-size:8.5px;font-weight:700;padding:1px 4px;border-radius:3px}
.vrow .vi{min-width:0;flex:1}
.vrow .vi b{display:block;font-size:12.2px;font-weight:650;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vrow .vi small{font-size:10.5px;color:var(--muted)}

/* upcoming list */
.upc{display:flex;gap:11px;padding:10px 0;border-bottom:1px solid var(--line-2);align-items:center}
.upc:last-child{border-bottom:none}
.upc .d{width:40px;text-align:center;flex:none;border:1px solid var(--line);border-radius:8px;padding:4px 0;background:var(--surface-2)}
.upc .d small{display:block;font-size:9px;font-weight:800;letter-spacing:.08em;color:var(--critical);text-transform:uppercase}
.upc .d b{display:block;font-size:15px;font-weight:750;letter-spacing:-.03em;line-height:1.1}
.upc .ui{min-width:0;flex:1}
.upc .ui b{display:block;font-size:12.3px;font-weight:650}
.upc .ui small{font-size:11px;color:var(--muted)}

.notice{
  display:flex;gap:10px;align-items:flex-start;padding:11px 13px;border-radius:10px;
  background:var(--primary-50);border:1px solid var(--primary-200);font-size:11.5px;color:var(--primary-800);line-height:1.5;
}
.notice b{font-weight:700}

@media(max-width:1180px){
  .kpis{grid-template-columns:repeat(3,1fr)}
  .cols{grid-template-columns:1fr}
  .squad{grid-template-columns:repeat(2,1fr)}}
@media(max-width:820px){
  .shell{grid-template-columns:1fr}
  .side{display:none}
  .kpis{grid-template-columns:repeat(2,1fr)}
  .tiles{grid-template-columns:1fr}

  /* THE TOP BAR HAD NO RESPONSIVE RULES AT ALL.
     The mockups were only ever viewed at desktop width, so at 375px the sync
     pill, the bell and the user block ran 143px past the edge and every screen
     in the product scrolled sideways on a phone. The layout breakpoints below
     were carried over from the mockups; this was simply missing.

     What goes, in order of how much it costs to lose it:
       - the customer's name, which is on the page anyway
       - the user's name and role, leaving the avatar, which is the affordance
     What STAYS is the sync pill: §7 requires it on screen on every screen, and
     a coach on a touchline needs it more than a coach at a desk. */
  .tb-ma{display:none}
  .tb-user .who{display:none}
  .tb-user{padding-inline-start:8px;margin-inline-start:0}
  .tb-title{
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-inline-size:0
  }
  .topbar{gap:8px;padding-inline:10px}}

/* ============================================================
   EXTRA COMPONENTS — forms, tables, month calendar, charts
   Extends the base TDS design system. Same tokens throughout.
   ============================================================ */

/* ---------- FRAME NAV (multi-page) ---------- */
.frame-nav{margin-inline-start:auto;display:flex;align-items:center;gap:8px}

/* ---------- PAGE TITLE ROW WITH CONTEXT CHIP ---------- */
.ctx-chip{
  display:inline-flex;align-items:center;gap:8px;height:34px;padding:0 13px 0 5px;border-radius:99px;
  background:var(--primary-600);color:#fff;font-size:12.5px;font-weight:650;box-shadow:0 2px 8px rgba(11,95,208,.25);
}
.ctx-chip .ci{width:26px;height:26px;border-radius:50%;background:var(--accent-400);color:var(--accent-950);display:grid;place-items:center;flex:none}
.ctx-arrow{color:var(--faint);font-weight:700}
.ctx-plain{
  display:inline-flex;align-items:center;height:34px;padding:0 13px;border-radius:9px;
  background:var(--surface);border:1px solid var(--line);font-size:12.5px;font-weight:650;box-shadow:var(--sh-1);
}

/* ---------- FILTER BAR ---------- */
.fbar{
  display:flex;align-items:center;gap:9px;flex-wrap:wrap;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r);padding:10px 12px;box-shadow:var(--sh-1);margin-bottom:16px;
}
.fld{display:flex;flex-direction:column;gap:4px;min-width:0}
.fld > label{font-size:10.5px;font-weight:700;color:var(--muted);letter-spacing:.03em}
.ctrl{
  display:flex;align-items:center;gap:7px;height:34px;padding:0 11px;border-radius:8px;
  border:1px solid var(--line);background:var(--surface);font-size:12.5px;color:var(--ink);
  font-weight:500;white-space:nowrap;transition:.14s;
}
.ctrl:hover{border-color:var(--primary-200)}
.ctrl svg{flex:none;color:var(--muted)}
.ctrl .ph{color:var(--faint);font-weight:500}
.ctrl.grow{flex:1;min-width:170px}
.ctrl.w-sm{width:106px}
.ctrl.w-md{width:150px}
.ctrl.w-lg{width:196px}
.ctrl .chev{margin-inline-start:auto;color:var(--faint)}
.viewtog{display:flex;border:1px solid var(--line);border-radius:8px;overflow:hidden;background:var(--surface)}
.viewtog button{width:34px;height:34px;display:grid;place-items:center;color:var(--muted)}
.viewtog button.on{background:var(--primary-50);color:var(--primary-600)}

/* ---------- SECTION FORM CARD ---------- */
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;align-items:start}
.fsec{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--sh-1);overflow:hidden;position:relative;
}
.fsec::before{content:"";position:absolute;inset-inline-start:0;top:0;bottom:0;width:3px;background:var(--primary-600)}
.fsec.a-amber::before{background:var(--warning)}
.fsec.a-green::before{background:var(--good)}
.fsec.a-violet::before{background:var(--cat-violet)}
.fsec.a-teal::before{background:var(--cat-teal)}
.fsec.a-rose::before{background:var(--critical)}
.fsec.a-lime::before{background:var(--accent-600)}
.fsec-h{display:flex;align-items:center;gap:10px;padding:12px 15px 12px 16px;border-bottom:1px solid var(--line-2)}
.fsec-n{
  width:22px;height:22px;border-radius:7px;background:var(--primary-50);color:var(--primary-600);
  display:grid;place-items:center;font-size:11px;font-weight:800;flex:none;
}
.fsec.a-amber .fsec-n{background:var(--warning-tint);color:var(--warning)}
.fsec.a-green .fsec-n{background:var(--good-tint);color:var(--good)}
.fsec.a-violet .fsec-n{background:var(--cat-violet-tint);color:var(--cat-violet)}
.fsec.a-teal .fsec-n{background:var(--cat-teal-tint);color:var(--cat-teal)}
.fsec.a-rose .fsec-n{background:var(--neutral-100);color:var(--critical)}
.fsec.a-lime .fsec-n{background:var(--accent-100);color:var(--accent-800)}
.fsec-h h3{font-size:13.5px;font-weight:700;letter-spacing:-.01em}
.fsec-h .hint{margin-inline-start:auto;font-size:11px;color:var(--faint);display:flex;align-items:center;gap:6px}
.fsec-b{padding:14px 16px}

.fields{display:grid;gap:12px}
.fields.c2{grid-template-columns:1fr 1fr}
.fields.c3{grid-template-columns:1fr 1fr 1fr}
/* Four across, for the assessment scores: technical, tactical, physical,
   mental. They are one judgement made in one pass, and a column of four
   full-width selects reads as four unrelated questions. */
.fields.c4{grid-template-columns:repeat(4,1fr)}
/* One column on a phone. These had NO responsive rule at all, so a two-column
   dialog at 375px gave each select about 103px - too narrow to read "Data
   Protection Owner" or "The whole programme" in its closed state, and the
   three-column squad dialog was worse. A form control the reader cannot read is
   not narrow, it is broken, and stacking costs nothing but height on a screen
   that scrolls anyway. */
@media (max-width:900px){
  /* Four narrow selects go to two-by-two before they go to one column: the
     scores are short words and a 2x2 block still reads as one control. */
  .fields.c4{grid-template-columns:1fr 1fr}
}
@media (max-width:560px){
  .fields.c2,.fields.c3,.fields.c4{grid-template-columns:1fr}
}
.f{display:flex;flex-direction:column;gap:5px;min-width:0}
.f > label{font-size:11px;font-weight:650;color:var(--ink-2);letter-spacing:.01em}
.f > label .req{color:var(--critical);margin-inline-start:2px}
.inp{
  display:flex;align-items:center;gap:8px;height:36px;padding:0 11px;border-radius:8px;
  border:1px solid var(--line);background:var(--surface);font-size:12.5px;color:var(--ink);transition:.14s;
}
.inp:hover{border-color:var(--primary-200)}
.inp.focus{border-color:var(--primary-600);box-shadow:0 0 0 3px var(--primary-50)}
.inp .val{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.inp .ph{color:var(--faint)}
.inp svg{flex:none;color:var(--muted)}
.inp .chev{margin-inline-start:auto;color:var(--faint)}
.inp.ro{background:var(--surface-2);color:var(--ink-2)}

/* A field's own validation message. Step 11.3, AC 11.3.4.

   The colour is NOT the message: the text says what is wrong, and the field it
   belongs to is named by aria-describedby. Red here is emphasis for the people
   who can see it, never the thing carrying the meaning - which is also why the
   border below changes as well as the text, so the field is findable by someone
   who cannot separate red from grey. */
.f-err{font-size:11px;font-weight:600;color:var(--critical);margin:0;line-height:1.45}

/* A statement of fact beside a field, not a validation failure. Step GB.5.0:
   "nobody here can be recorded as delivering this" is true, actionable and not
   the coach's mistake, so it reads in muted ink rather than in the critical
   colour that means they typed something wrong. */
.f-hint{font-size:11px;color:var(--muted);margin:0;line-height:1.45}
.f:has(.f-err) .inp{border-color:var(--critical)}
.f:has(.f-err) .inp:focus-within{box-shadow:0 0 0 3px var(--critical-tint)}
.ta{
  border:1px solid var(--line);border-radius:8px;background:var(--surface);padding:9px 11px;
  font-size:12.5px;color:var(--faint);min-height:64px;position:relative;line-height:1.5;
}
.ta.filled{color:var(--ink-2)}
.ta .count{position:absolute;inset-inline-end:8px;bottom:5px;font-size:10px;color:var(--faint);font-weight:600}
.ta .grip{position:absolute;inset-inline-end:4px;bottom:4px;color:var(--primary-200)}

/* segmented control */
.segc{display:flex;border:1px solid var(--line);border-radius:8px;overflow:hidden;background:var(--surface)}
.segc span{
  flex:1;text-align:center;padding:7px 4px;font-size:11.5px;font-weight:600;color:var(--muted);
  border-inline-start:1px solid var(--line-2);white-space:nowrap;
}
.segc span:first-child{border-inline-start:none}
.segc span.on{background:var(--primary-600);color:#fff;font-weight:700}
.segc.lime span.on{background:var(--accent-400);color:var(--accent-950)}

/* toggle */
.tgl{display:flex;align-items:center;gap:9px;font-size:12.5px;font-weight:600;color:var(--ink-2)}
.tgl i{
  width:34px;height:19px;border-radius:99px;background:var(--neutral-200);position:relative;flex:none;transition:.15s;
}
.tgl i::after{content:"";position:absolute;top:2px;inset-inline-start:2px;width:15px;height:15px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.22);transition:.15s}
.tgl.on i{background:var(--good)}
.tgl.on i::after{inset-inline-start:17px}

/* checkbox */
.cbx{width:16px;height:16px;border-radius:4px;border:1.5px solid var(--neutral-300);background:var(--surface);display:inline-grid;place-items:center;flex:none}
.cbx.on{background:var(--primary-600);border-color:var(--primary-600);color:#fff}
.cbx.lime.on{background:var(--accent-600);border-color:var(--accent-600);color:var(--accent-900)}

/* stepper */
.step{display:flex;align-items:center;border:1px solid var(--line);border-radius:8px;overflow:hidden;height:36px;background:var(--surface)}
.step .n{flex:1;text-align:center;font-size:14px;font-weight:700;font-variant-numeric:tabular-nums}
.step .ar{display:flex;flex-direction:column;border-inline-start:1px solid var(--line-2)}
.step .ar button{width:24px;height:17px;display:grid;place-items:center;color:var(--muted)}
.step .ar button:first-child{border-bottom:1px solid var(--line-2)}
.step .ar button:hover{background:var(--surface-2);color:var(--ink)}

/* dropzone */
.dz{
  border:1.6px dashed var(--primary-300);border-radius:11px;background:var(--neutral-50);padding:16px;text-align:center;
}
.dz .di{width:34px;height:34px;border-radius:50%;background:var(--primary-50);color:var(--primary-600);display:grid;place-items:center;margin:0 auto 8px}
.dz b{display:block;font-size:12.5px;font-weight:650}
.dz small{display:block;font-size:11px;color:var(--muted);margin-top:2px}
.dz-btns{display:flex;gap:8px;justify-content:center;margin-top:11px;flex-wrap:wrap}
/* The dropzone IS the file input: transparent, covering the area, so a dropped
   file lands anywhere on it. The buttons sit above it and stay clickable. */
.dz{position:relative}
.dz-input{position:absolute;inset:0;inline-size:100%;block-size:100%;opacity:0;cursor:pointer}
.dz-btns{position:relative;z-index:1}
.dz-spent{display:none}
.dz:has(.dz-input:focus-visible){outline:2px solid var(--primary-600);outline-offset:2px}
label.btn{cursor:pointer}
.filerow .fr-x{inline-size:26px;block-size:26px;border-radius:7px;display:grid;place-items:center;color:var(--muted);background:none;border:none;cursor:pointer}
.filerow .fr-x:hover,.filerow .fr-x:focus-visible{background:var(--surface-2);color:var(--critical)}
/* Players picked for a session or a match. */
.pick-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:2px 12px;margin-block-start:10px;max-block-size:280px;overflow-y:auto;padding:4px;border:1px solid var(--line);border-radius:9px}
.pick-list label{display:flex;align-items:center;gap:8px;min-block-size:var(--tap);padding:0 6px;border-radius:7px;font-size:12.5px;cursor:pointer}
.pick-list label:hover{background:var(--surface-2)}
.pick-list .num{color:var(--faint);font-size:11px;font-weight:700;min-inline-size:18px;text-align:end}
.pick-tools{display:flex;gap:8px;margin-block-start:8px;flex-wrap:wrap}
/* Step 4.3 and INJ.4.1: a child who cannot be picked, or only after a confirming tap. */
.pick-list label.is-unavailable{color:var(--muted)}
.pick-why{margin-inline-start:auto;font-size:11px;color:var(--muted)}
.pick-confirm{grid-column:1/-1;display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:6px 8px;border-radius:7px;background:var(--surface-2);font-size:12px}
.form-note{font-size:11.5px;color:var(--muted);margin-block-start:8px}
.tpl-list{display:grid;gap:4px}
.clip-pick{display:grid;gap:4px;max-block-size:50vh;overflow-y:auto}
.clip-pick label{display:flex;align-items:center;gap:10px;min-block-size:var(--tap);padding:6px 8px;border-radius:8px;cursor:pointer;font-size:12.5px}
.clip-pick label:hover{background:var(--surface-2)}
.clip-pick small{display:block;color:var(--muted);font-size:11px}
/* The notification panel opens from the bell, near the end of the bar. */
.tb-notes{position:relative}
.tb-notes .sr{inset-inline-start:auto;inset-inline-end:0;inline-size:min(380px, 92vw)}
.season-pick{position:relative;display:inline-block}
.season-pick .sr{inline-size:min(260px, 92vw)}
.filerow{
  display:flex;align-items:center;gap:9px;padding:8px 10px;border:1px solid var(--line);border-radius:9px;
  background:var(--surface);margin-top:9px;font-size:12px;
}
.filerow .fi{width:26px;height:26px;border-radius:6px;display:grid;place-items:center;flex:none;font-size:9px;font-weight:800;color:#fff}
.filerow .fi.pdf{background:var(--critical)}
.filerow .fi.xls{background:var(--good)}
.filerow .fi.vid{background:var(--cat-violet)}
.filerow b{font-weight:650;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.filerow time{color:var(--faint);font-size:10.5px;font-weight:600;white-space:nowrap}
.filerow .ok{color:var(--good)}

/* attendance / selection list */
.plist{border:1px solid var(--line-2);border-radius:9px;overflow:hidden}
.plist-h{display:grid;gap:8px;padding:7px 11px;background:var(--surface-2);border-bottom:1px solid var(--line-2);font-size:10px;font-weight:750;color:var(--muted);letter-spacing:.06em;text-transform:uppercase}
.plist-r{display:grid;gap:8px;padding:7px 11px;border-bottom:1px solid var(--line-2);font-size:12px;align-items:center}
.plist-r:last-child{border-bottom:none}
.plist-r:hover{background:var(--surface-2)}
.plist-r .idx{color:var(--faint);font-weight:650;font-variant-numeric:tabular-nums}
.plist-r b{font-weight:600}
.plist-scroll{max-height:212px;overflow:hidden;position:relative}
.plist-scroll::after{content:"";position:absolute;inset-inline-start:0;inset-inline-end:0;bottom:0;height:26px;background:linear-gradient(transparent,#fff)}

/* ---------- FOOTER ACTION BAR ---------- */
.actionbar{
  display:flex;align-items:center;gap:10px;padding:13px 16px;margin-top:16px;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh-1);
}
.actionbar .note{font-size:11.5px;color:var(--muted);display:flex;align-items:center;gap:6px}
.actionbar .sp{margin-inline-start:auto;display:flex;gap:9px}

/* THE ACTION BAR HAD NO PHONE LAYOUT. Found in task 7.3 on the IDP screen at
   375 px: the note and the buttons shared one row, so a two-line note squeezed
   "Publish plan" until it was clipped by the viewport. It stacks now - the note
   above, the buttons on their own full-width row - which is also the order
   somebody reads them in. Section 12: the primary action is at the bottom of
   the thumb zone, full width, always reachable one-handed. */
@media(max-width:720px){
  .actionbar{flex-wrap:wrap;padding:12px}
  .actionbar .note{flex-basis:100%;order:-1}
  .actionbar .sp{margin-inline-start:0;inline-size:100%;justify-content:stretch}
  .actionbar .sp > *{flex:1 1 0;min-inline-size:0}
  .actionbar .sp .btn{inline-size:100%;justify-content:center}
}

/* ---------- DATA TABLE ---------- */
.dt{width:100%;border-collapse:collapse;font-size:12.3px}

/* ---- controls INSIDE a table cell -------------------------------------------
   `.inp` is the wrapper TdsField draws around a control, not the control, so it
   cannot be reused here: a nine-column grid of editable cells needs the control
   itself to be the compact thing. Borderless until hovered or focused, because
   nine bordered boxes per row across six rows is a screen of boxes rather than
   a plan. */
.gi{
  inline-size:100%;min-inline-size:0;box-sizing:border-box;
  font:inherit;font-size:12px;color:var(--ink);
  background:transparent;border:1px solid transparent;border-radius:6px;
  padding:4px 6px;
}
.gi:hover:not(:disabled){border-color:var(--line);background:var(--surface)}
.gi:focus{outline:none;border-color:var(--primary-600);box-shadow:0 0 0 3px var(--primary-50);background:var(--surface)}
.gi:disabled{color:var(--ink-2);background:transparent;border-color:transparent;cursor:not-allowed}
.gi-area{resize:vertical;line-height:1.35;min-block-size:38px}

/* A focus row is the part the child acts on, so it is the part that stands out
   on the coach's screen too. */
.dt tr.row-focus > td{background:var(--primary-50)}

/* An overdue review is the row somebody has to act on. Tinted, not shouted: a
   list where half the rows are red is a list nobody reads. */
.dt tr.row-overdue > td{background:var(--warning-tint)}

/* One number, said once, large. The "gap" card on the IDP report. */
.fig-lg{font-size:34px;font-weight:750;letter-spacing:-.02em;line-height:1.1;margin:0 0 4px}

.gchk{display:inline-flex;align-items:center;justify-content:center}
.gchk input{inline-size:16px;block-size:16px;accent-color:var(--primary-600);cursor:pointer}
.gchk input:disabled{cursor:not-allowed}

/* A video card that is a play control says so on hover and on focus. Without
   the focus ring the library is reachable by keyboard and invisible to one. */
/* The card's picture-and-title is a real <button>; its footer buttons are
   siblings of it, never children. Reset the button to look like the card. */
.vcard-hit{display:block;inline-size:100%;margin:0;padding:0;border:0;background:none;color:inherit;font:inherit;text-align:start;cursor:pointer}
.vcard-hit.is-static{cursor:default}
.vcard-hit .vshot,.vcard-hit .vmeta,.vcard-hit .tagrow{display:block}
.vcard-hit .tagrow{display:flex;flex-wrap:wrap;gap:6px}
.vcard-hit:focus-visible{outline:2px solid var(--primary-600);outline-offset:-2px;border-radius:12px 12px 0 0}
.vcard-hit:hover .vshot{filter:brightness(1.04)}
.vfoot .ib{cursor:pointer}
.vfoot .ib.is-on{color:var(--primary-600);border-color:var(--primary-600);background:var(--primary-50)}
.pin-meter{display:flex;align-items:center;gap:10px;margin-block:4px 12px}
.pin-meter .bar{flex:1;block-size:6px}
.pin-meter small{color:var(--muted);white-space:nowrap}
.vfoot .ib:focus-visible{outline:2px solid var(--primary-600);outline-offset:2px}
/* Link and share dialogs */
.link-players{display:grid;gap:6px;max-block-size:320px;overflow:auto;margin-block-start:6px}
.link-player{display:flex;align-items:center;gap:10px;padding:7px 10px;border:1px solid var(--line);border-radius:8px}
.link-player input{inline-size:16px;block-size:16px;accent-color:var(--primary-600)}
.link-player .nm{flex:1;min-inline-size:0}
.link-player .nm small{display:block;color:var(--muted);font-size:11.5px}
.link-player.is-off{background:var(--surface-2)}
.link-player.is-off .nm b{color:var(--muted)}
.share-url{display:flex;gap:8px;align-items:center;margin-block-start:10px}
.share-url .gi{flex:1;min-inline-size:0}
.share-list{display:grid;margin-block-start:14px}
.share-row{display:flex;align-items:center;gap:10px;padding:9px 0;border-block-start:1px solid var(--line-2)}
.share-row .who{flex:1;min-inline-size:0}
.share-row .who small{display:block;color:var(--muted);font-size:11.5px}
.share-blocked{margin:6px 0 0;padding-inline-start:18px}

/* The upload progress bar in the dialog. */
.up-prog{display:flex;align-items:center;gap:10px;margin-block-start:10px}
.up-prog .bar{block-size:6px}
.vplayer{inline-size:100%;max-block-size:60vh;background:var(--ink);border-radius:10px;display:block}
.up-prog small{font-variant-numeric:tabular-nums;color:var(--muted);min-inline-size:38px;text-align:end}
.dt thead th{
  text-align:start;padding:9px 11px;background:var(--surface-2);border-bottom:1px solid var(--line);
  font-size:10.5px;font-weight:750;color:var(--muted);letter-spacing:.05em;text-transform:uppercase;white-space:nowrap;
}
.dt tbody td{padding:9px 11px;border-bottom:1px solid var(--line-2);vertical-align:middle}
.dt tbody tr:last-child td{border-bottom:none}
.dt tbody tr:hover td{background:var(--surface-2)}
.dt tbody tr.sel td{background:var(--primary-50)}
.dt tbody tr.sel td:first-child{box-shadow:inset 3px 0 0 var(--primary-600)}
.dt .num{font-variant-numeric:tabular-nums}
.dt .pl{display:flex;align-items:center;gap:8px;font-weight:650;white-space:nowrap}
.dt .pl a{color:var(--primary-600)}
.dt .muted{color:var(--muted)}
.trend{font-weight:800;font-size:13px}
.trend.up{color:var(--good)}
.trend.flat{color:var(--faint)}
.trend.down{color:var(--critical)}
.trend.warn{color:var(--warning)}

.pager{display:flex;align-items:center;gap:6px;padding:11px 16px;border-top:1px solid var(--line-2);background:var(--surface-2)}
.pager .info{font-size:11.5px;color:var(--muted);font-weight:600}
.pager .pgs{margin-inline-start:auto;display:flex;gap:4px}
.pager .pgs button{
  min-width:28px;height:28px;padding:0 8px;border-radius:7px;border:1px solid var(--line);background:var(--surface);
  font-size:12px;font-weight:600;color:var(--ink-2);display:grid;place-items:center;
}
.pager .pgs button.on{background:var(--primary-600);border-color:var(--primary-600);color:#fff}

/* ---------- MONTH CALENDAR ---------- */
.mcal{border-top:1px solid var(--line-2)}
.mcal-h{display:grid;grid-template-columns:repeat(7,1fr)}
.mcal-h div{padding:8px 6px;text-align:center;font-size:10px;font-weight:750;color:var(--muted);letter-spacing:.09em;text-transform:uppercase;border-inline-start:1px solid var(--line-2)}
.mcal-h div:first-child{border-inline-start:none}
.mcal-g{display:grid;grid-template-columns:repeat(7,1fr);grid-auto-rows:96px}
.mday{border-top:1px solid var(--line-2);border-inline-start:1px solid var(--line-2);padding:5px;overflow:hidden;position:relative}
.mday:nth-child(7n+1){border-inline-start:none}
.mday.out{background:var(--surface-2)}
.mday.out .dn{color:var(--neutral-300)}
.mday.wknd{background:var(--surface-2)}
.mday .dn{font-size:11.5px;font-weight:650;color:var(--ink-2);display:inline-grid;place-items:center;width:21px;height:21px;border-radius:50%;font-variant-numeric:tabular-nums}
.mday.today .dn{background:var(--primary-600);color:#fff}
.mev{
  display:block;margin-top:3px;padding:3px 6px;border-radius:5px;font-size:10px;font-weight:650;line-height:1.25;
  border-inline-start:2.5px solid;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;
}
.mev small{display:block;font-weight:600;opacity:.78;font-size:9px}
/* .training and .talentId are what CalendarViewModel sends - the same names as
   the week grid's .ev-training. Only .train and .tid existed, so every training
   session and Talent ID activity in the month view was drawn uncoloured. */
.mev.train,.mev.training{background:var(--primary-50);border-color:var(--primary-600);color:var(--primary-800)}
.mev.match{background:var(--accent-100);border-color:var(--accent-600);color:var(--accent-900)}
.mev.tid,.mev.talentId{background:var(--warning-tint);border-color:var(--warning);color:var(--warning)}
.mev.idp{background:var(--cat-violet-tint);border-color:var(--cat-violet);color:var(--cat-violet-ink)}
.mev.more{background:none;border:none;color:var(--muted);font-size:9.5px;padding-inline-start:3px}

/* ---------- CHART PANELS ---------- */
.chart-grid{display:grid;gap:14px}
.chart-grid.c4{grid-template-columns:repeat(4,1fr)}
.chart-grid.c3{grid-template-columns:repeat(3,1fr)}
.chart-grid.c2{grid-template-columns:repeat(2,1fr)}
.cp{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh-1);padding:13px 14px 14px;display:flex;flex-direction:column}
.cp-h{display:flex;align-items:center;gap:7px;margin-bottom:11px}
.cp-h b{font-size:10.5px;font-weight:750;letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
.cp-h .i{margin-inline-start:auto;color:var(--neutral-300)}
.cp-body{flex:1;display:flex;align-items:center}
/* Step 9.3: the panel heading is a real h3, so eight panels are eight landmarks
   rather than a wall of figures. It wears the label's type, not a heading's. */
.cp-h h3{font-size:10.5px;font-weight:750;letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
/* In a panel the switcher is icons only, whatever the viewport. A quarter-width
   panel has room for a title OR three words, and the panel was 11px wider than
   its neighbours until this: the buttons keep their aria-labels and titles. */
.cp-h .chsw{margin-inline-start:auto;flex:none}
.cp-h .chsw-b span{display:none}
.cp-empty{font-size:11.5px;margin:auto;text-align:center}

/* Step 9.8: a chart's numbers, in the same panel as the chart. Sized to sit in
   a quarter-width panel without scrolling for the six or eight rows these
   carry; a longer one scrolls inside the panel rather than stretching it. */
.figs{inline-size:100%;border-collapse:collapse;font-size:11.5px;align-self:flex-start}
.figs th,.figs td{padding:4px 6px;text-align:start;border-block-end:1px solid var(--line-2)}
.figs thead th{
  font-size:10px;font-weight:750;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);
  border-block-end:1px solid var(--line);
}
.figs tbody th{font-weight:600;color:var(--ink-2)}
.figs .num{text-align:end;font-variant-numeric:tabular-nums;font-weight:650}
.cp-body:has(.figs){align-items:flex-start;overflow:auto;max-block-size:190px}
/* The panel rows keep the same rhythm as the cards below them. */
.chart-grid.panels{margin-bottom:16px}
.cp .donut-wrap{flex-direction:column;gap:11px;align-items:stretch;inline-size:100%}
.cp .donut{margin-inline:auto}
.cp .chart{inline-size:100%}
.cp .mos{block-size:28px}
.cp svg{width:100%;height:auto;overflow:visible}

/* treemap */
.tmap{display:grid;gap:2px;height:132px;grid-template-columns:1.35fr 1.25fr 1fr;grid-template-rows:1fr 1fr}
.tmap div{border-radius:5px;padding:8px 9px;color:#fff;display:flex;flex-direction:column;justify-content:flex-end;overflow:hidden}
.tmap b{font-size:12.5px;font-weight:750;letter-spacing:-.02em;line-height:1.1}
.tmap small{font-size:9.5px;opacity:.88;font-weight:600;margin-top:1px}
.tmap .t1{grid-row:1/3}
.tmap .t2{grid-row:1/3}

/* progress ring */
.ring{width:74px;height:74px;border-radius:50%;display:grid;place-items:center;position:relative;flex:none}
.ring::after{content:"";position:absolute;inset:9px;border-radius:50%;background:var(--surface)}
.ring b{position:relative;z-index:1;font-size:16px;font-weight:750;letter-spacing:-.03em}

/* ---------- INFO PANEL ROWS ---------- */
.irow{display:flex;align-items:flex-start;gap:9px;padding:7px 0;font-size:12px}
.irow .ii{width:22px;height:22px;border-radius:6px;background:var(--surface-2);border:1px solid var(--line-2);display:grid;place-items:center;color:var(--muted);flex:none}
.irow .il{color:var(--muted);font-weight:600;width:112px;flex:none}
.irow b{font-weight:650}
.pathway{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;text-align:center}
.pathway div{border:1px solid var(--line-2);border-radius:10px;padding:10px 6px;background:var(--surface-2)}
.pathway .pi{color:var(--primary-600);margin:0 auto 5px}
.pathway b{display:block;font-size:19px;font-weight:750;letter-spacing:-.03em;line-height:1}
.pathway small{display:block;font-size:10px;color:var(--muted);font-weight:600;margin-top:3px}

/* ---------- MONITORING TIMELINE ---------- */
.tl{position:relative;padding-inline-start:4px}
.tl-i{display:flex;gap:11px;padding:7px 0;position:relative}
.tl-i:not(:last-child)::before{content:"";position:absolute;inset-inline-start:5.5px;top:22px;bottom:-4px;width:2px;background:var(--line-2)}
.tl-d{width:13px;height:13px;border-radius:50%;flex:none;margin-top:3px;border:3px solid var(--surface);z-index:1}
.tl-i b{display:block;font-size:11.8px;font-weight:650}
.tl-i small{display:block;font-size:10.5px;color:var(--muted)}
.tl-i time{font-size:10px;color:var(--faint);font-weight:700;letter-spacing:.02em}

.assess{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.assess div{text-align:center;border:1px solid var(--line-2);border-radius:9px;padding:8px 4px;background:var(--surface-2)}
.assess small{display:block;font-size:9.5px;color:var(--muted);font-weight:700;letter-spacing:.04em;text-transform:uppercase}
.assess b{display:block;font-size:15px;font-weight:750;margin-top:3px;letter-spacing:-.02em}
.assess b span{font-size:10px;color:var(--faint);font-weight:600}

/* ---------- VIDEO GRID ---------- */
.vgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.vcard{border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--surface);transition:.15s;box-shadow:var(--sh-1)}
.vcard:hover{border-color:var(--primary-600);box-shadow:var(--sh-2);transform:translateY(-2px)}
.vshot{position:relative;aspect-ratio:16/9;overflow:hidden}
/* The poster fills the same 16:9 box the pitch graphic did, cropped rather than
   letterboxed so a portrait phone clip does not sit in a stripe of black. */
.poster-actions{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-block-start:10px}
.vposter{position:absolute;inset:0;inline-size:100%;block-size:100%;object-fit:cover;display:block}
.vshot .play{
  position:absolute;inset:0;display:grid;place-items:center;
}
.vshot .play span{width:42px;height:42px;border-radius:50%;background:rgba(255,255,255,.92);color:var(--primary-950);display:grid;place-items:center;box-shadow:0 3px 12px rgba(0,0,0,.3)}
.vshot .dur{position:absolute;inset-inline-end:7px;bottom:7px;background:rgba(6,14,28,.82);color:#fff;font-size:10px;font-weight:700;padding:2px 6px;border-radius:4px;font-variant-numeric:tabular-nums}
.vshot .kb{position:absolute;inset-inline-start:7px;top:7px;font-size:9px;font-weight:800;letter-spacing:.08em;padding:3px 7px;border-radius:4px;background:rgba(6,14,28,.72);color:#fff;text-transform:uppercase}
.vshot .men{position:absolute;inset-inline-end:7px;top:7px;width:24px;height:24px;border-radius:6px;background:rgba(6,14,28,.55);color:#fff;display:grid;place-items:center}
.vmeta{padding:10px 12px 11px}
.vmeta .tagrow{margin-bottom:6px}
.vmeta b{display:block;font-size:12.8px;font-weight:650;letter-spacing:-.01em;line-height:1.3}
.vmeta small{display:block;font-size:11px;color:var(--muted);margin-top:3px}
.vfoot{display:flex;align-items:center;gap:6px;padding:8px 12px;border-top:1px solid var(--line-2);background:var(--surface-2)}
.vfoot .ib{width:26px;height:26px;border-radius:6px;border:1px solid var(--line);background:var(--surface);display:grid;place-items:center;color:var(--muted)}
.vfoot .ib:hover{color:var(--primary-600);border-color:var(--primary-600)}

/* pitch-ish thumbnail backgrounds */
.pitch{position:absolute;inset:0}
.pitch.p1{background:linear-gradient(170deg,var(--good) 0%,var(--good) 55%,var(--good-ink) 100%)}
.pitch.p2{background:linear-gradient(170deg,var(--cat-teal) 0%,var(--cat-teal-ink) 55%,var(--cat-teal-ink) 100%)}
.pitch.p3{background:linear-gradient(170deg,var(--cat-violet) 0%,var(--cat-violet-ink) 55%,var(--cat-violet-ink) 100%)}
.pitch.p4{background:linear-gradient(170deg,var(--warning) 0%,var(--warning) 55%,var(--warning-ink) 100%)}
.pitch.p5{background:linear-gradient(170deg,var(--primary-600) 0%,var(--primary-700) 55%,var(--primary-900) 100%)}
.pitch.p6{background:linear-gradient(170deg,var(--primary-800) 0%,var(--primary-900) 100%)}
.pitch::before{
  content:"";position:absolute;inset:0;
  background:repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 26px,rgba(255,255,255,0) 26px 52px);
}
.pitch::after{
  content:"";position:absolute;inset-inline-start:50%;top:50%;width:52px;height:52px;margin:-26px 0 0 -26px;
  border:1.5px solid rgba(255,255,255,.22);border-radius:50%;
}

/* ---------- IDP TABLE (big) ---------- */
.idpt{width:100%;border-collapse:separate;border-spacing:0;font-size:11.8px}
.idpt th{
  text-align:start;padding:9px 10px;background:var(--primary-900);color:#fff;font-size:9.8px;font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;vertical-align:middle;
}
.idpt th:first-child{border-radius:9px 0 0 0}
.idpt th:last-child{border-radius:0 9px 0 0}
.idpt td{padding:10px;border-bottom:1px solid var(--line-2);vertical-align:middle;background:var(--surface)}
.idpt tr:hover td{background:var(--surface-2)}
.idpt tr.focus td{background:var(--neutral-50)}
.idpt tr.focus:hover td{background:var(--neutral-50)}
.area-nm{display:flex;align-items:center;gap:9px;min-width:0}
.area-nm .ai{width:28px;height:28px;border-radius:8px;display:grid;place-items:center;flex:none;font-size:13px}
.area-nm b{font-weight:650;line-height:1.25;display:block}
.mini-inp{
  display:flex;align-items:flex-start;gap:6px;min-height:30px;padding:6px 8px;border-radius:7px;
  border:1px solid var(--line);background:var(--surface);font-size:11.3px;color:var(--ink-2);
  line-height:1.35;
}
.mini-inp svg{margin-top:1px;flex:none}
.mini-inp .chev{margin-top:1px}
.mini-inp .chev{margin-inline-start:auto;color:var(--faint)}
.mini-inp.empty{color:var(--faint);background:var(--surface-2);align-items:center;justify-content:center}

/* ---------- PLAYER HEADER CARD ---------- */
.phero{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--sh-1);
  padding:16px 18px;display:flex;gap:18px;align-items:center;flex-wrap:wrap;margin-bottom:16px;position:relative;overflow:hidden;
}
.phero::before{content:"";position:absolute;inset-inline-start:0;top:0;bottom:0;width:4px;background:linear-gradient(180deg,var(--primary-600),var(--accent-600))}
.phero .pid{display:flex;gap:14px;align-items:center;min-width:210px}
.phero .pid h1{font-size:21px;font-weight:750;letter-spacing:-.028em;line-height:1.15}
.phero .pid .team{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--muted);font-weight:600;margin-top:3px}
.pfacts{display:flex;gap:22px;flex-wrap:wrap;flex:1}
.pfact{display:flex;gap:8px;align-items:flex-start}
.pfact .fi{width:24px;height:24px;border-radius:7px;background:var(--surface-2);border:1px solid var(--line-2);display:grid;place-items:center;color:var(--muted);flex:none}
.pfact small{display:block;font-size:10px;color:var(--muted);font-weight:650;letter-spacing:.03em}
.pfact b{display:block;font-size:12.3px;font-weight:650;margin-top:1px}

/* focus area cards */
.facards{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.facard{
  border:1px solid var(--line);border-radius:12px;padding:13px 14px;background:var(--surface);
  display:flex;gap:11px;align-items:flex-start;transition:.15s;cursor:pointer;
}
.facard:hover{border-color:var(--primary-600);box-shadow:0 0 0 3px var(--primary-50)}
.facard .fi{width:34px;height:34px;border-radius:10px;display:grid;place-items:center;flex:none;font-size:16px}
.facard b{display:block;font-size:12.6px;font-weight:700;letter-spacing:-.01em}
.facard small{display:block;font-size:11px;color:var(--muted);margin-top:3px;line-height:1.4}
.facard .arw{margin-inline-start:auto;color:var(--faint);flex:none;align-self:center}

/* stars (input) */
.stars-in{display:flex;gap:2px;align-items:center}
.stars-in span{color:var(--neutral-300);font-size:13px;cursor:pointer}
.stars-in span.f{color:var(--warning)}
.stars-in em{font-style:normal;font-size:10px;color:var(--muted);font-weight:650;margin-inline-start:5px}

/* TdsStarInput - the editable twin. Radios underneath, stars on top; the focus
   ring is drawn on the LABEL because the input itself is visually hidden, and a
   rating you cannot see the focus on is one a keyboard user cannot use. */
/* ---------------------------------------------------------------- task 7.3
   ONE AREA PER SCREEN ON A PHONE, all six at once on a desk.

   The same table serves both. Below the breakpoint every row but the current
   one is hidden and the remaining one is laid out as a stack of labelled
   fields; above it, the stepper disappears and the table is a table. A second
   form would be a second place for the autosave, the consent gate and the
   focus rule each to be wrong in. Section 12's "tables become cards". */
.idp-stepper{display:none}
.idp-stepcount{display:none}

.vfield{position:relative;display:block}
/* Room for the microphone, so the last word of a sentence is not underneath
   it. Logical, so it moves to the other side in Arabic with the button. */
.vfield textarea{inline-size:100%;padding-inline-end:36px}

/* The microphone sits INSIDE the field's corner rather than beside it: a
   column of nine already has no width to spare, and a button on its own line
   would push the grid wider on the one layout that cannot afford it. */
.vmic{
  position:absolute;inset-block-end:5px;inset-inline-end:5px;
  inline-size:26px;block-size:26px;display:grid;place-items:center;
  border:1px solid var(--line-2);border-radius:7px;background:var(--surface);
  color:var(--muted);cursor:pointer;padding:0;
}
.vmic:hover{color:var(--primary-600);border-color:var(--primary-300)}
.vmic:focus-visible{outline:2px solid var(--primary-600);outline-offset:1px}

/* Listening is a STATE somebody can see from across a pitch, not a subtle
   tint: a coach who cannot tell whether it is recording will not use it. */
.vmic.on{background:var(--critical);border-color:var(--critical);color:#fff}

@media(max-width:820px){
  /* WRAPS, and the numbers come first. At 375 px "Back", six circles and
     "Next step" do not fit on one line - laid out as a single row the Next
     button ran 15 px past the edge, which put a horizontal scrollbar on the
     document and, through it, made the fixed bottom bar 16 px too wide on
     EVERY phone screen. A fixed element at inset-inline:0 spans the initial
     containing block, and the scrollbar had widened it. */
  .idp-stepper{
    display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
    gap:8px;margin-block:12px 6px;min-inline-size:0;
  }
  .idp-steps{
    order:-1;flex-basis:100%;display:flex;justify-content:center;gap:6px;
  }
  .idp-stepper > .btn{flex:1 1 0;min-inline-size:0;white-space:nowrap}
  .idp-step{
    inline-size:30px;block-size:30px;border-radius:50%;border:1px solid var(--line-2);
    background:var(--surface);color:var(--muted);font-weight:700;font-size:12px;cursor:pointer;
  }
  .idp-step.done{border-color:var(--good);color:var(--good)}
  .idp-step.on{background:var(--primary-600);border-color:var(--primary-600);color:#fff}
  .idp-step:focus-visible{outline:2px solid var(--primary-600);outline-offset:2px}

  .idp-stepcount{display:block;margin:0 0 10px;font-size:12.5px;font-weight:650}

  /* The step IS the filter. Five of the six rows are not on screen at all,
     which is what makes "one task per screen" true rather than "one task,
     scrolled to". */
  .idp-areas .dt tbody tr:not(.is-step){display:none}

  /* The remaining row becomes a stack. Each cell carries its column's heading
     through the data-label attribute, because a field with no label is a field
     nobody fills in correctly. */
  .idp-areas .dt,
  .idp-areas .dt tbody,
  .idp-areas .dt tbody tr,
  .idp-areas .dt tbody td{display:block;inline-size:auto}
  .idp-areas .dt thead{display:none}
  .idp-areas .dt tbody tr{padding:4px 2px 12px}
  .idp-areas .dt tbody td{
    border:0;padding:8px 2px 0;
  }
  .idp-areas .dt tbody td::before{
    content:attr(data-label);display:block;margin-block-end:4px;
    font-size:10.5px;font-weight:750;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);
  }
  .idp-areas .dt tbody td.num{text-align:start}
  .idp-areas .table-wrap{overflow-x:visible}
}

/* The unsent-edits list inside a conflict notice. Task 7.10. */
.stack-tight{margin:8px 0;padding-inline-start:18px;display:flex;flex-direction:column;gap:4px}
.stack-tight li{font-size:12.5px;line-height:1.45}

.stars-set{display:flex;gap:2px;align-items:center;border:0;padding:0;margin:0;min-inline-size:0}
.star-lbl{color:var(--neutral-300);font-size:15px;line-height:1;cursor:pointer;padding:1px}
.star-lbl.f{color:var(--warning)}
.star-radio:focus-visible + .star-lbl{outline:2px solid var(--primary-600);outline-offset:1px;border-radius:3px}
.stars-set:disabled .star-lbl{cursor:default;opacity:.6}
.star-lbl:hover{color:var(--warning)}
.stars-set:disabled .star-lbl:hover{color:inherit}

/* group heading inside lists */
.grp{
  display:flex;align-items:center;gap:9px;margin:16px 0 10px;font-size:11px;font-weight:750;
  letter-spacing:.09em;text-transform:uppercase;color:var(--muted);
}
.grp::after{content:"";flex:1;height:1px;background:var(--line-2)}
.grp .n{background:var(--line-2);color:var(--muted);border-radius:99px;padding:1px 7px;font-size:10px;letter-spacing:0}

@media(max-width:1180px){
  .form-grid{grid-template-columns:1fr}
  .chart-grid.c4{grid-template-columns:repeat(2,1fr)}
  .vgrid{grid-template-columns:repeat(2,1fr)}}

/* The studio on a phone. The frame ruler survives - a coach on a touchline
   marking a passage is the case this was built for - but the transport wraps
   and every control goes back up to the 44px tap floor. */
@media(max-width:700px){
  .vt-stage video{max-block-size:38vh}
  .vt-transport{gap:7px}
  .vt-tbtn{inline-size:var(--tap);block-size:var(--tap)}
  .vt-tbtn.play{inline-size:var(--tap);block-size:var(--tap)}
  .vt-tc .big,.vt-tc .frame{font-size:14px}
  .vt-tc .lab{display:none}
  .vt-spacer{display:none}
  .vt-fine{block-size:44px}
  .vt-seg{flex-wrap:wrap}}

/* proportional mosaic (replaces the crude treemap) */
.mosaic{display:flex;flex-direction:column;gap:3px;height:142px;width:100%}
.mosaic .mrow{display:flex;gap:3px;min-height:0}
.mosaic .mrow > div{
  border-radius:6px;padding:7px 9px;color:#fff;display:flex;flex-direction:column;justify-content:flex-end;
  overflow:hidden;min-width:0;
}
.mosaic b{font-size:13px;font-weight:750;letter-spacing:-.02em;line-height:1.05;font-variant-numeric:tabular-nums}
.mosaic small{font-size:9.5px;font-weight:650;line-height:1.2;margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mosaic small.nm{white-space:normal;line-height:1.15;font-size:9px}


/* =============================================================================
   COMPONENT LAYER

   One block per component in Tds.Ui, in the same order as the folder. Written
   against the design language ported above — same radii, same shadows, same
   type scale — so a component added later has an obvious house style to follow.

   Not one literal colour below this line. Every value is a token, which is what
   makes a rebrand total rather than a theming pass. §5.
   ============================================================================= */

/* ---------------------------------------------------------------- page furniture */
.main{padding:22px 26px 34px;min-inline-size:0}

.page-h1{font-size:20px;font-weight:750;letter-spacing:-.02em;margin-bottom:4px}

.page-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:16px}

.muted{color:var(--muted);font-size:12.5px}

.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px}
.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:16px}
.grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:16px}

.stat{font-size:26px;font-weight:750;letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.stat small{font-size:14px;font-weight:600;color:var(--muted);letter-spacing:0}

.kv{display:grid;grid-template-columns:auto 1fr;gap:6px 18px;font-size:12.5px}
.kv dt{color:var(--muted);font-weight:600}
.kv dd{font-weight:600}

.note{font-size:12.5px;padding:10px 12px;border-radius:var(--r-sm);margin-top:12px}
.note--info{background:var(--info-tint);color:var(--info-ink);border:1px solid var(--info)}
.note--good{background:var(--good-tint);color:var(--good-ink);border:1px solid var(--good)}
.note--warning{background:var(--warning-tint);color:var(--warning-ink);border:1px solid var(--warning)}

.input{
  height:var(--tap);padding:0 12px;border-radius:var(--r-sm);
  border:1px solid var(--line);background:var(--surface);color:var(--ink);
  font:inherit;font-size:13px;inline-size:100%;max-inline-size:360px;
}
.input:focus{outline:none;border-color:var(--primary-600);box-shadow:0 0 0 3px var(--primary-50)}

.filters{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:16px}

/* The pre-boot state. Deliberately unbranded: painting a guessed brand and
   correcting it a moment later is worse than painting nothing at all. §5. */
.boot{min-block-size:100vh;display:grid;place-items:center;gap:14px;color:var(--muted)}
.boot__spinner{
  inline-size:28px;block-size:28px;border-radius:50%;
  border:2.5px solid var(--line);border-block-start-color:var(--primary-600);
  animation:tds-spin .8s linear infinite;
}
@keyframes tds-spin{to{transform:rotate(360deg)}}

/* ---------------------------------------------------------------- TdsIcon */
.tds-icon{flex:none}

/* ---------------------------------------------------------------- TdsCard */
.card-h-t{min-inline-size:0}
.card-h-s{font-size:12px;color:var(--muted);margin-block-start:1px}
.card-h-a{margin-inline-start:auto;display:flex;align-items:center;gap:8px}
.card-b.is-flush{padding:0}
.card + .card{margin-block-start:16px}

/* ---------------------------------------------------------------- TdsChip */
.chip.c-neutral{background:var(--surface-3);color:var(--ink-2)}
.chip.c-brand{background:var(--primary-50);color:var(--primary-800)}
.chip.c-good{background:var(--good-tint);color:var(--good-ink)}
.chip.c-warning{background:var(--warning-tint);color:var(--warning-ink)}
.chip.c-serious{background:var(--serious-tint);color:var(--serious-ink)}
.chip.c-critical{background:var(--critical-tint);color:var(--critical-ink)}
.chip.c-info{background:var(--info-tint);color:var(--info-ink)}

/* ---------------------------------------------------------------- TdsButton */
.btn-secondary{background:var(--surface);border:1px solid var(--line);color:var(--ink-2);box-shadow:var(--sh-1)}
.btn-secondary:hover{border-color:var(--neutral-300);color:var(--ink)}
.btn-danger{background:var(--critical);color:var(--surface)}
.btn-danger:hover{filter:brightness(.94)}
.btn.is-block{inline-size:100%;justify-content:center}
.btn[disabled]{opacity:.55;cursor:not-allowed}
.btn-spin{
  inline-size:14px;block-size:14px;border-radius:50%;
  border:2px solid currentColor;border-block-start-color:transparent;
  animation:tds-spin .7s linear infinite;
}

/* ---------------------------------------------------------------- TdsEmptyState */
/* Modal dialog. A real <dialog>, so ::backdrop is the browser's own. */
.dlg{
  border:none;padding:0;border-radius:var(--r);background:var(--surface);color:var(--ink);
  inline-size:min(520px, 92vw);box-shadow:var(--sh-2);
  /* The UA centres a dialog with margin:auto, and the shorthand reset above
     took it away - so it sat in the top-left corner looking like a rendering
     fault rather than a dialog. */
  margin:auto
}
.dlg::backdrop{background:rgba(14,27,51,.45)}
.dlg-head{
  display:flex;align-items:center;gap:12px;
  padding:16px 18px;border-block-end:1px solid var(--line)
}
.dlg-head h2{font-size:15px;font-weight:700;flex:1}
.dlg-x{
  inline-size:32px;block-size:32px;border-radius:8px;border:none;background:none;
  color:var(--muted);display:grid;place-items:center;cursor:pointer
}
.dlg-x:hover{background:var(--surface-2);color:var(--ink)}
.dlg-content{padding:18px}
.dlg-foot{
  display:flex;justify-content:flex-end;gap:8px;
  padding:14px 18px;border-block-start:1px solid var(--line);background:var(--surface-2)
}

.fbar-note{font-size:11.5px;color:var(--muted);margin-block-start:6px;margin-inline-start:2px}

/* Placeholder: a panel the design shows and no phase has built yet. Visually
   quieter than an empty state on purpose - it is not asking to be acted on.
   Logical properties throughout, so it mirrors under RTL without a second rule. */
.ph{
  display:flex;gap:10px;align-items:flex-start;
  padding:18px 20px;
  border:1px dashed var(--line);border-radius:var(--r);
  background:var(--surface-2);color:var(--muted)
}
.ph-icon{flex:none;margin-block-start:1px;color:var(--muted)}
.ph-text{font-size:12.5px;line-height:1.5;max-inline-size:46ch}

.empty{padding:36px 20px;text-align:center;color:var(--muted)}
.empty-ico{
  inline-size:52px;block-size:52px;border-radius:50%;margin:0 auto 12px;
  display:grid;place-items:center;background:var(--surface-3);color:var(--faint);
}
.empty h3{font-size:14px;font-weight:700;color:var(--ink-2)}
.empty p{font-size:12.5px;margin-block-start:5px;max-inline-size:38ch;margin-inline:auto}
.empty-a{margin-block-start:14px}

/* ---------------------------------------------------------------- TdsSideNav */
.side-list{list-style:none;padding:0 12px;display:flex;flex-direction:column;gap:2px}
.side-item{
  display:flex;align-items:center;gap:11px;
  padding:9px 11px;border-radius:9px;
  font-size:13px;font-weight:600;color:var(--primary-100);
  transition:.14s;min-block-size:var(--tap);
}
.side-item:hover{background:rgba(255,255,255,.12);color:#fff}
.side-item.is-active{background:rgba(255,255,255,.18);color:#fff;box-shadow:inset 2px 0 0 var(--accent-400)}
[dir="rtl"] .side-item.is-active{box-shadow:inset -2px 0 0 var(--accent-400)}
.side-badge{
  margin-inline-start:auto;min-inline-size:18px;padding:0 5px;border-radius:99px;
  background:var(--accent-400);color:var(--accent-950);
  font-size:10px;font-weight:800;text-align:center;
}

/* ---------------------------------------------------------------- TdsBottomNav */
/* Hidden on desktop. The rail is the desktop navigation; showing both would be
   two answers to the same question. §12. */
.bottom-nav{display:none}

@media (max-width:900px){
  .bottom-nav{
    display:grid;grid-auto-flow:column;grid-auto-columns:1fr;
    position:fixed;inset-inline:0;inset-block-end:0;z-index:50;
    background:var(--surface);border-block-start:1px solid var(--line);
    padding-block-end:env(safe-area-inset-bottom);
    box-shadow:0 -2px 12px rgba(14,27,51,.08);
  }
}

.bottom-nav__item{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  min-block-size:var(--tap);padding:7px 4px 6px;position:relative;
  color:var(--muted);font-size:10.5px;font-weight:600;
}
.bottom-nav__item.is-active{color:var(--primary-600)}
.bottom-nav__label{line-height:1}
.bottom-nav__badge{
  position:absolute;inset-block-start:4px;inset-inline-end:50%;
  transform:translateX(50%) translateX(12px);
  min-inline-size:16px;padding:0 4px;border-radius:99px;
  background:var(--critical);color:var(--surface);
  font-size:9.5px;font-weight:800;text-align:center;
}

/* ---------------------------------------------------------------- TdsSyncPill */
/* Always on screen, on every screen. Silence is what makes people stop
   believing an offline app — §7. */
.syncpill{
  display:inline-flex;align-items:center;gap:6px;
  padding:5px 11px;border-radius:99px;
  font-size:11.5px;font-weight:700;white-space:nowrap;
  border:1px solid transparent;
}
.syncpill--synced{background:var(--good-tint);color:var(--good-ink)}
.syncpill--syncing{background:var(--info-tint);color:var(--info-ink)}
.syncpill--queued{background:var(--warning-tint);color:var(--warning-ink)}
.syncpill--offline{background:var(--surface-3);color:var(--ink-2);border-color:var(--line)}
.syncpill--attention{background:var(--critical-tint);color:var(--critical-ink);border-color:var(--critical)}
.syncpill__text{line-height:1}
/* A link since phase POS step POS.3.3: to the list of what is waiting. */
a.syncpill{text-decoration:none;cursor:pointer}
a.syncpill:focus-visible{outline:2px solid var(--accent-400);outline-offset:2px}

/* ---------------------------------------------------------------- TdsSyncIssues */
/* Phase POS, step POS.3.3. What this device has not sent, and why. */
.syncissues{display:flex;flex-direction:column;gap:18px;max-inline-size:760px}
.syncissues h3{font-size:14px;margin-block:0 8px}
.syncissues-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}
.syncissue{display:flex;align-items:center;gap:12px;padding:10px 14px;border:1px solid var(--line);border-radius:10px;background:var(--surface)}
.syncissue-text{display:flex;flex-direction:column;gap:3px;flex:1;min-inline-size:0}
.syncissue-reason{color:var(--critical-ink)}

/* Inside the dark top bar the tints have nothing like enough contrast against
   the chrome, so the pill inverts rather than being tinted. */
.topbar .syncpill{background:rgba(255,255,255,.14);color:#fff;border-color:rgba(255,255,255,.2)}
.topbar .syncpill--attention{background:var(--critical);border-color:transparent}

/* ---------------------------------------------------------------- TdsKpiStrip */
.kpi-strip{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-block-end:18px}
.kpi-k{font-size:11px;color:var(--muted);font-weight:600;letter-spacing:.02em}
.kpi-v{font-size:24px;font-weight:750;letter-spacing:-.03em;margin-block-start:5px;line-height:1;font-variant-numeric:tabular-nums}
.kpi-s{font-size:11px;margin-block-start:6px;color:var(--muted)}
.kpi-t{font-size:11px;margin-block-start:4px;font-weight:700}
.kpi-t--up{color:var(--good)}
.kpi-t--down{color:var(--critical)}

/* ---------------------------------------------------------------- TdsSquadTile */
.squad-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(248px,1fr));gap:12px;padding:16px}

.squad-tile{
  display:block;padding:14px;border-radius:var(--r);
  border:1px solid var(--line);background:var(--surface);
  transition:.15s;
}
.squad-tile:hover{border-color:var(--primary-600);box-shadow:0 0 0 3px var(--primary-50);transform:translateY(-1px)}
.squad-tile__h{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.squad-tile__name{font-size:13.5px;font-weight:700;letter-spacing:-.01em}
.squad-tile__meta{font-size:11.5px;color:var(--muted);margin-block-start:2px}

/* Registered against places as a bar, not a number: the question is never
   "how many" but "are we short", and a bar answers that without being read. */
.squad-tile__bar{
  block-size:5px;border-radius:99px;background:var(--line);
  overflow:hidden;margin-block:12px 10px;
}
.squad-tile__bar span{
  display:block;block-size:100%;border-radius:99px;
  background:linear-gradient(90deg,var(--accent-600),var(--accent-800));
}
[dir="rtl"] .squad-tile__bar span{background:linear-gradient(270deg,var(--accent-600),var(--accent-800))}

.squad-tile__f{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:11.5px;color:var(--muted)}
.squad-tile__next{display:inline-flex;align-items:center;gap:5px;font-weight:600;color:var(--ink-2)}
.squad-tile__next.is-empty{color:var(--faint);font-weight:500}

/* ---------------------------------------------------------------- TdsAttentionList */
.attn{list-style:none}
.attn-row{
  display:flex;align-items:center;gap:10px;
  padding:11px 16px;border-block-end:1px solid var(--line-2);
  min-block-size:var(--tap);
}
.attn-row:last-child{border-block-end:none}
.attn-dot{inline-size:8px;block-size:8px;border-radius:50%;flex:none;background:var(--muted)}
.attn-row--warning .attn-dot{background:var(--warning)}
.attn-row--serious .attn-dot{background:var(--serious)}
.attn-row--critical .attn-dot{background:var(--critical)}
.attn-row--info .attn-dot{background:var(--info)}
.attn-text{flex:1;font-size:12.8px;font-weight:600;min-inline-size:0}
.attn-text:hover{color:var(--primary-600)}
.attn-due{font-size:11.5px;color:var(--muted);font-variant-numeric:tabular-nums}
.attn-chev{color:var(--faint)}

/* ---------------------------------------------------------------- TdsWeekStrip */
.weekstrip{display:grid;grid-template-columns:repeat(7,1fr);gap:1px;background:var(--line-2)}
.weekstrip__day{background:var(--surface);padding:10px 8px;min-block-size:118px}
.weekstrip__day.is-today{background:var(--primary-50)}
.weekstrip__dh{display:flex;align-items:baseline;justify-content:space-between;margin-block-end:8px}
.weekstrip__dow{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-weight:700}
.weekstrip__dnum{font-size:14px;font-weight:700;font-variant-numeric:tabular-nums}
.weekstrip__ev{display:flex;flex-direction:column;gap:5px}
.weekstrip__pill{
  display:block;padding:5px 7px;border-radius:7px;
  font-size:10.5px;line-height:1.35;
  background:var(--primary-50);color:var(--primary-800);
  border-inline-start:2.5px solid var(--primary-600);
}
.weekstrip__pill b{display:block;font-variant-numeric:tabular-nums}
.weekstrip__pill--match{background:var(--accent-100);color:var(--accent-900);border-inline-start-color:var(--accent-600)}
.weekstrip__pill--talentidactivity{background:var(--cat-violet-tint);color:var(--cat-violet-ink);border-inline-start-color:var(--cat-violet)}

@media (max-width:900px){
  /* Seven columns on a phone is seven unreadable columns. The week becomes a
     scrollable row of day cards instead, which is the same information in the
     arrangement the device allows. §12. */
  .weekstrip{grid-auto-flow:column;grid-auto-columns:minmax(132px,1fr);grid-template-columns:none;overflow-x:auto}
}

/* ---------------------------------------------------------------- TdsPlayerTable */
.table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
.cell-person{display:flex;align-items:center;gap:9px;font-weight:600}
.cell-warn{color:var(--warning)}

/* ---------------------------------------------------------------- TdsAttendanceSheet */
/* Everything here is sized for a touchline: one hand, in the rain, sometimes in
   gloves, by someone whose attention belongs on the pitch. §4. */
/* The register is its own scroll context so the sticky counts bar stays put
   while forty players scroll under it. */
.register{position:relative}

.register__bar{
  display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  padding:12px 16px;border-block-end:1px solid var(--line);background:var(--surface-2);
  position:sticky;inset-block-start:0;z-index:2;
}
.register__counts{display:flex;gap:6px;flex-wrap:wrap}
.register__list{list-style:none}
.register__row{
  display:flex;align-items:center;gap:12px;
  padding:10px 16px;border-block-end:1px solid var(--line-2);
  min-block-size:56px;
}
.register__num{
  inline-size:26px;text-align:center;flex:none;
  font-size:12px;font-weight:800;color:var(--muted);font-variant-numeric:tabular-nums;
}
.register__name{flex:1;font-size:13.5px;font-weight:600;min-inline-size:0}
.register__states{display:flex;gap:4px;flex:none}
/* Step PP.1.4: the way on to rating, under the register. */
.register__next{padding:12px 16px;margin:0}
.register__state{
  min-block-size:var(--tap);min-inline-size:var(--tap);padding:0 10px;
  border-radius:var(--r-sm);border:1px solid var(--line);
  background:var(--surface);color:var(--muted);
  font-size:11.5px;font-weight:700;transition:.12s;
}
.register__state.is-on.state--present{background:var(--good-tint);border-color:var(--good);color:var(--good-ink)}
.register__state.is-on.state--late{background:var(--warning-tint);border-color:var(--warning);color:var(--warning-ink)}
.register__state.is-on.state--excused{background:var(--info-tint);border-color:var(--info);color:var(--info-ink)}
.register__state.is-on.state--absent{background:var(--critical-tint);border-color:var(--critical);color:var(--critical-ink)}

@media (max-width:600px){
  /* The four state buttons take the full width under the name rather than
     shrinking below the tap target. A register nobody can hit accurately is
     worse than one that scrolls. */
  .register__row{flex-wrap:wrap}
  .register__states{inline-size:100%;flex:1 1 100%}
  .register__state{flex:1}
}

/* ---------------------------------------------------------------- TdsRatingGrid
   Step PP.1.4. One tap per rating: the current cell is outlined, and the ten
   scores are always under the thumb for it. Tokens only, logical sides only. */
.rgrid{position:relative;display:flex;flex-direction:column;gap:12px}
.rgrid__table{border-collapse:collapse;inline-size:100%;font-size:12.5px}
.rgrid__table th,.rgrid__table td{padding:4px;border-block-end:1px solid var(--line-2);text-align:center;vertical-align:middle}
.rgrid__table thead th{font-size:11px;font-weight:700;color:var(--muted);white-space:nowrap}
.rgrid__corner{min-inline-size:120px}
.rgrid__name{text-align:start !important;font-weight:600;font-size:13px;white-space:nowrap;position:sticky;inset-inline-start:0;background:var(--surface);z-index:1}
.rgrid__num{display:inline-block;inline-size:22px;color:var(--muted);font-size:11px;font-weight:800;font-variant-numeric:tabular-nums}
.rgrid__cell{
  position:relative;min-inline-size:var(--tap);min-block-size:var(--tap);inline-size:100%;
  display:inline-flex;align-items:center;justify-content:center;gap:2px;
  border-radius:var(--r-sm);border:1px solid var(--line);background:var(--surface);
  color:var(--ink);font:inherit;font-size:15px;font-weight:800;font-variant-numeric:tabular-nums;cursor:pointer;
}
.rgrid__cell.is-empty{color:var(--faint)}
.rgrid__cell.is-current{outline:3px solid var(--primary-600);outline-offset:1px;background:var(--primary-50)}
.rgrid__cell.is-pending::after{
  content:"";position:absolute;inset-block-start:4px;inset-inline-end:4px;
  inline-size:6px;block-size:6px;border-radius:50%;background:var(--warning);
}
.rgrid__pad{
  position:sticky;inset-block-end:0;z-index:2;
  display:flex;flex-direction:column;gap:8px;padding:12px;
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-lg);
}
.rgrid__target{margin:0;font-size:13px;font-weight:700}
.rgrid__scores{display:grid;grid-template-columns:repeat(5,1fr);gap:6px}
.rgrid__score{
  min-block-size:var(--tap);border-radius:var(--r-sm);border:1px solid var(--line);
  background:var(--surface);color:var(--ink);font:inherit;font-size:17px;font-weight:800;cursor:pointer;
}
.rgrid__score.is-on{background:var(--primary-600);border-color:var(--primary-600);color:var(--surface)}
.rgrid__tools{display:flex;gap:8px;justify-content:flex-end;flex-wrap:wrap}
.rate-areas{display:flex;flex-wrap:wrap;gap:6px;margin-block-end:12px}
.rate-areas button{
  min-block-size:var(--tap);padding:0 12px;border-radius:999px;border:1px solid var(--line);
  background:var(--surface);color:var(--muted);font:inherit;font-size:12.5px;font-weight:700;cursor:pointer;
}
.rate-areas button[aria-pressed="true"]{background:var(--primary-50);border-color:var(--primary-600);color:var(--primary-700)}
.rate-comment{display:flex;flex-direction:column;gap:8px;padding:12px;border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface)}
.rate-comment__actions{display:flex;gap:8px;justify-content:flex-end}

/* ---------------------------------------------------------------- TdsLocalePicker */
.locale-picker label{display:flex;align-items:center;gap:7px;font-size:12.5px;font-weight:600;margin-block-end:7px}
.locale-picker select{
  min-block-size:var(--tap);padding:0 12px;inline-size:100%;max-inline-size:320px;
  border-radius:var(--r-sm);border:1px solid var(--line);
  background:var(--surface);color:var(--ink);font:inherit;font-size:13px;
}
.locale-picker__help{font-size:11.5px;color:var(--muted);margin-block-start:7px}

/* ---------------------------------------------------------------- TdsSuggestion */
/* ADR-09. A suggestion is a DRAFT with a named human accepting it, and it has to
   LOOK like one — dashed, tinted, never mistakable for something the system
   decided on its own. */
.tds-suggestion{
  border:1px dashed var(--cat-violet);background:var(--cat-violet-tint);
  border-radius:var(--r);padding:13px 14px;
}
.tds-suggestion__header{display:flex;align-items:center;gap:8px;margin-block-end:8px}
.tds-suggestion__badge{
  font-size:10px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  color:var(--cat-violet-ink);
}
.tds-suggestion__source{font-size:11px;color:var(--muted);margin-inline-start:auto}
.tds-suggestion__text{font-size:13px;line-height:1.55}
.tds-suggestion__actions{display:flex;gap:8px;margin-block-start:12px;flex-wrap:wrap}

/* ---------------------------------------------------------------- lists */
.act-list{list-style:none}
.act-list a{
  display:flex;align-items:center;gap:12px;
  padding:12px 16px;border-block-end:1px solid var(--line-2);
  font-size:12.8px;min-block-size:var(--tap);
}
.act-list a:hover{background:var(--surface-2)}
.act-list b{font-variant-numeric:tabular-nums;font-weight:700;flex:none}
.act-list span{flex:1;color:var(--muted)}
.act-list svg{color:var(--faint)}

/* ---------------------------------------------------------------- TdsVideoStudio
   The gallery's player: the picture, the transport, the two timelines, the
   mark bar and the list of marked passages.

   WHY THE TIMELINES PIN dir="ltr" AND USE `left`. They are TIME AXES, and
   AC 11.2.5 settled what happens to one of those in Arabic: it does not
   reverse. The same rule TdsLineChart and TdsSparkline follow, for the same
   reason - a playhead that ran right-to-left would be the single most
   confusing thing RTL could do to a video. The `dir="ltr"` is in the markup,
   so `left` here resolves against the axis rather than against the page, and
   everything outside the two tracks still mirrors normally.

   THE STAGE IS ALWAYS DARK, in both colour themes. It is the surround for
   moving pictures, not a panel: a light surround throws its own colour onto
   the footage and is what every video tool avoids. That is why --vt-stage is
   a fixed token rather than a surface role. */

/* Wider than a form dialog - a player at 520px is a postage stamp. The same
   `:has()` trick the event panel uses, for the same reason: the width belongs
   to the content, and the dialog does not know what it was handed. */
.dlg:has(.vt){inline-size:min(1120px, 96vw)}
.dlg:has(.vt) .dlg-content{max-block-size:78vh;overflow:auto}

.vt,.vt-player{display:grid;gap:12px;min-inline-size:0}

/* The confined player, for the one screen a child reads. Hidden outright
   rather than disabled: a scrubber somebody can see and cannot use reads as a
   broken player, and one that is not there reads as a clip. The nodes stay in
   the DOM because video-trimmer.js queries them on initialise. */
.vt-player .is-hidden{display:none}

.vt-stage{position:relative;background:var(--vt-stage);border-radius:10px;overflow:hidden}
.vt-stage video{
  /* 46vh, not more. The notes are the other half of this screen, and a
     picture that fills the dialog pushes every one of them below the fold on
     a laptop - so the coach's commentary, which is the point of the feature,
     is the part nobody sees. */
  inline-size:100%;max-block-size:46vh;display:block;background:var(--vt-stage);
  /* `contain`, not `cover`: a portrait phone clip cropped to fill would hide
     the thing the coach is marking. */
  object-fit:contain;aspect-ratio:16/9
}
.vt-stage:fullscreen video{max-block-size:100vh;block-size:100vh}

/* The timecode over the picture. Monospaced and tabular so the digits do not
   dance while the clip plays. */
.vt-hud{
  position:absolute;top:9px;inset-inline-start:9px;display:flex;gap:6px;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;pointer-events:none
}
.vt-hud span{
  background:rgba(6,16,31,.72);color:#fff;font-size:10.5px;font-weight:700;
  padding:3px 7px;border-radius:4px;font-variant-numeric:tabular-nums
}

.vt-empty{
  position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:7px;color:rgba(255,255,255,.62);font-size:12px;text-align:center
}

/* The confirmation when a mark lands. Half a second of edge glow: enough to
   say "that registered" without a toast for something the coach does forty
   times in a match. */
.vt-flash{position:absolute;top:0;bottom:0;inline-size:34%;opacity:0;transition:opacity .18s;pointer-events:none}
.vt-flash.in{inset-inline-start:0;background:linear-gradient(to right,rgba(47,191,113,.55),transparent)}
.vt-flash.out{inset-inline-end:0;background:linear-gradient(to left,rgba(232,85,78,.55),transparent)}
.vt-flash.show{opacity:1}

.vt-deck{display:grid;gap:10px}

.vt-transport{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.vt-tbtns{display:flex;align-items:center;gap:4px}
.vt-tbtn{
  inline-size:32px;block-size:32px;border-radius:7px;border:1px solid var(--line);
  background:var(--surface);color:var(--ink-2);display:grid;place-items:center;cursor:pointer;
  font-size:10px;font-weight:750;font-variant-numeric:tabular-nums
}
.vt-tbtn:hover{background:var(--surface-2);border-color:var(--primary-600);color:var(--primary-700)}
.vt-tbtn.play{inline-size:38px;block-size:38px;background:var(--primary-600);border-color:var(--primary-600);color:#fff}
.vt-tbtn.play:hover{background:var(--primary-700)}

.vt-tc{
  display:flex;align-items:baseline;gap:2px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-variant-numeric:tabular-nums
}
.vt-tc .big{font-size:16px;font-weight:750;letter-spacing:-.01em}
.vt-tc .frame{font-size:16px;font-weight:750;color:var(--primary-600)}
.vt-tc .lab{font-size:9px;letter-spacing:.08em;color:var(--faint);text-transform:uppercase;margin-inline-start:7px}

.vt-spacer{flex:1}
.vt-field{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--muted)}
.vt-mini{
  border:1px solid var(--line);border-radius:6px;background:var(--surface);color:var(--ink);
  font-size:11px;padding:4px 7px
}

/* --- the two timelines. dir="ltr" is on these elements in the markup. --- */
.vt-over{
  position:relative;block-size:34px;border-radius:7px;background:var(--surface-3);
  border:1px solid var(--line);cursor:pointer;overflow:hidden;touch-action:none
}
.vt-over .buffered{position:absolute;top:0;bottom:0;left:0;width:0;background:var(--line);opacity:.8}
.vt-bands{position:absolute;inset:0}
.vt-band{
  position:absolute;top:0;bottom:0;background:var(--vt-band);opacity:.34;
  border-inline-start:1px solid var(--vt-band);border-inline-end:1px solid var(--vt-band)
}
.vt-band.is-live{opacity:.72;background:var(--vt-band-live)}

/* The coded moments from an analysis export.

   ITS OWN LAYER, ABOVE THE BANDS. See video-trimmer.js for why the two are not
   drawn into one container.

   POINTER-EVENTS:NONE, and this is the load-bearing line. A coded match puts
   two to six hundred of these across a timeline barely a thousand pixels wide;
   if each one took the pointer, dragging the scrubber through a busy passage
   would keep catching. The grid underneath is the thing you click. */
.vt-markers{position:absolute;inset:0;pointer-events:none}
.vt-marker{
  position:absolute;inset-block:0;inline-size:2px;background:var(--vt-marker);
  /* Centred on the moment rather than starting at it: at this width the
     difference is a whole marker, and a tick that sat to the right of its own
     timestamp would make the alignment control look broken. */
  margin-inline-start:-1px
}
.vt-marker.is-lit{
  background:var(--vt-marker-lit);inline-size:3px;margin-inline-start:-1.5px;
  /* Taller than its neighbours as well as brighter: on a timeline this dense,
     colour alone does not find a row for somebody who has just clicked it -
     and colour alone is not an accessible difference either. */
  inset-block:-2px
}
.vt-draft{position:absolute;top:0;bottom:0;background:var(--vt-in);opacity:.26}
.vt-draft.is-open{
  /* An in point with no out point yet: striped, so "this is not finished" is
     visible rather than being a band that happens to be one pixel wide. */
  background:repeating-linear-gradient(45deg,rgba(47,191,113,.5) 0 5px,transparent 5px 10px)
}
.vt-mark{position:absolute;top:0;bottom:0;width:2px}
.vt-mark.in{background:var(--vt-in)}
.vt-mark.out{background:var(--vt-out)}
.vt-mark .flag{
  position:absolute;top:1px;left:2px;font-size:8.5px;font-weight:800;letter-spacing:.05em;
  color:#fff;padding:1px 4px;border-radius:3px;white-space:nowrap
}
.vt-mark.in .flag{background:var(--vt-in)}
.vt-mark.out .flag{background:var(--vt-out)}
.vt-playhead{position:absolute;top:0;bottom:0;width:2px;background:var(--ink);box-shadow:0 0 0 1px rgba(255,255,255,.55)}

.vt-fine-head{display:flex;align-items:center;gap:8px;font-size:10px;letter-spacing:.07em;text-transform:uppercase;color:var(--faint)}
.vt-fine-head .win{margin-inline-start:auto;text-transform:none;letter-spacing:0;font-size:11px}
.vt-fine{
  position:relative;block-size:52px;margin-block-start:5px;border-radius:7px;
  background:var(--surface-3);border:1px solid var(--line);overflow:hidden;
  cursor:ew-resize;touch-action:none
}
.vt-fine canvas{position:absolute;inset:0;inline-size:100%;block-size:100%}
.vt-fine .centre{position:absolute;top:0;bottom:0;left:50%;width:2px;background:var(--ink);opacity:.85}
.vt-fine .hint{
  position:absolute;bottom:2px;inset-inline-end:6px;font-size:9px;color:var(--faint);
  pointer-events:none;user-select:none
}

/* --- the mark bar: in, out, and the note that has to follow them --------- */
.vt-markbar{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:10px 12px;border:1px solid var(--line);border-radius:9px;background:var(--surface-2)
}
.vt-markbar .grp{margin:0;text-transform:none;letter-spacing:0;font-size:11px;color:var(--muted)}
.vt-markbar .grp::after{content:none}
.vt-stamp{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-variant-numeric:tabular-nums;
  font-size:11.5px;font-weight:700;padding:3px 7px;border-radius:5px;background:var(--surface);
  border:1px solid var(--line);color:var(--ink-2);min-inline-size:78px;text-align:center
}
.vt-stamp.set.in{border-color:var(--vt-in);color:var(--vt-in)}
.vt-stamp.set.out{border-color:var(--vt-out);color:var(--vt-out)}

/* The note step. It appears once a passage has both ends, because that is the
   moment the product asks the question - the bounds exist to carry the note. */
.vt-note{display:grid;gap:9px;padding:12px;border:1px solid var(--primary-600);border-radius:9px;background:var(--primary-50)}
.vt-note .row{display:flex;gap:9px;align-items:center;flex-wrap:wrap}
/* "And where does it go" - the last step of the note form. */
.vt-send{display:flex;flex-wrap:wrap;align-items:flex-end;gap:10px}
.vt-send .f{display:grid;gap:3px;min-inline-size:190px;flex:1}
.vt-send .f > span{font-size:10.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.vt-send .vt-mini{inline-size:100%;padding:7px 8px;font-size:12px}
.vt-send .vt-mini:disabled{opacity:.55}
/* The sentence that stands in for an empty picker. Padded to the select's own
   height so the two labels still line up when only one of them has a list. */
.vt-send .f > .vt-none{
  padding:7px 0;font-size:11.5px;line-height:1.35;color:var(--muted);
  text-wrap:pretty;text-transform:none;letter-spacing:normal;font-weight:400
}

.vt-note .row .when{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11.5px;font-weight:700;
  color:var(--primary-800);font-variant-numeric:tabular-nums
}

/* --- the passages, as a list to read and to play back ------------------- */
.vt-list{display:grid;gap:7px}
.vt-seg{
  display:flex;gap:10px;align-items:flex-start;padding:9px 11px;text-align:start;
  border:1px solid var(--line);border-radius:9px;background:var(--surface);inline-size:100%;
  cursor:pointer;font:inherit;color:inherit
}
.vt-seg:hover{border-color:var(--primary-600);background:var(--surface-2)}
.vt-seg.is-live{border-color:var(--primary-600);box-shadow:0 0 0 2px var(--primary-100)}
.vt-seg .at{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;font-weight:750;
  color:var(--primary-700);font-variant-numeric:tabular-nums;white-space:nowrap;padding-block-start:1px
}
.vt-seg .body{flex:1;min-inline-size:0}
.vt-seg .body b{display:block;font-size:12.5px;font-weight:700;letter-spacing:-.01em}
.vt-seg .body p{font-size:12px;color:var(--ink-2);margin-block-start:2px;overflow-wrap:anywhere;white-space:pre-wrap}
.vt-seg .body small{display:block;font-size:10.5px;color:var(--faint);margin-block-start:4px}
.vt-seg-acts{display:flex;gap:5px;flex-shrink:0}

/* --- the coded moments from an analysis export -------------------------- */
/*
   THE GRID SITS UNDER THE PLAYER AND SCROLLS INSIDE ITSELF. A coded match is
   several hundred rows; letting them push the page would put the video off the
   top of the screen, and the whole point of the feature is that you read a row
   while watching the moment it describes. So the list gets a fixed height and
   its own scrollbar, and the player stays where it is.

   EVERY ROW IS A BUTTON WITH SIBLINGS, NOT A BUTTON CONTAINING ONE - the same
   lesson .vt-seg and TdsVideoGrid's card both learned. A button nested inside a
   button is announced as one control and the click resolves to the outer one,
   which is how "add a note" would end up playing the clip. */
.vt-data{display:grid;gap:9px;margin-block-start:12px}
.vt-data-head{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  font-size:11px;color:var(--muted)
}
.vt-data-head .file{
  font-weight:650;color:var(--ink-2);overflow-wrap:anywhere;
  /* The file name is the analyst's, in whatever language and script they use,
     inside a bar that is otherwise ours. It reads as a name, not as a run of
     the surrounding sentence. */
  unicode-bidi:isolate
}
.vt-data-head .vt-spacer{flex:1}
.vt-align{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--muted)}
.vt-align input{
  inline-size:82px;border:1px solid var(--line);border-radius:6px;background:var(--surface);
  color:var(--ink);font-size:11px;padding:4px 7px;font-variant-numeric:tabular-nums
}

.vt-grid{
  display:grid;gap:4px;max-block-size:clamp(180px,34vh,420px);overflow-y:auto;
  padding-inline-end:4px;
  /* Scroll-anchored to the row that is playing rather than to the top, so a
     grid that follows the video does not fight the coach's own scrolling. */
  scroll-behavior:smooth
}
.vt-ev{
  display:flex;gap:9px;align-items:flex-start;padding:6px 9px;text-align:start;
  border:1px solid var(--line);border-radius:8px;background:var(--surface);
  inline-size:100%;font:inherit;color:inherit
}
.vt-ev:hover{border-color:var(--primary-600);background:var(--surface-2)}
.vt-ev.is-lit{border-color:var(--primary-600);box-shadow:0 0 0 2px var(--primary-100)}
.vt-ev .play{
  display:flex;align-items:baseline;gap:8px;flex:1;min-inline-size:0;text-align:start;
  background:none;border:0;padding:0;font:inherit;color:inherit;cursor:pointer
}
.vt-ev .no{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10.5px;
  color:var(--faint);font-variant-numeric:tabular-nums;min-inline-size:2.6em;flex-shrink:0
}
.vt-ev .at{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;font-weight:750;
  color:var(--primary-700);font-variant-numeric:tabular-nums;white-space:nowrap;flex-shrink:0
}
.vt-ev .what{flex:1;min-inline-size:0}
.vt-ev .what b{
  display:block;font-size:12.5px;font-weight:700;letter-spacing:-.01em;
  /* The analyst's own code, in their language. Isolated for the same reason
     the file name above is. */
  unicode-bidi:isolate
}
.vt-ev .what span{display:block;font-size:11px;color:var(--muted);unicode-bidi:isolate}
.vt-ev .noted{
  display:block;font-size:11.5px;color:var(--ink-2);margin-block-start:3px;
  overflow-wrap:anywhere;white-space:pre-wrap
}
.vt-ev .noted small{display:block;font-size:10px;color:var(--faint);margin-block-start:2px}
.vt-ev-acts{display:flex;gap:5px;flex-shrink:0}
.vt-ev-note{display:grid;gap:6px;padding:8px 9px;border:1px solid var(--primary-600);border-radius:8px;background:var(--surface-2)}
.vt-ev-note .row{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.vt-ev-note .when{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;
  color:var(--primary-700);font-variant-numeric:tabular-nums
}

/* ------------------------------------------------- AssignedClips
   The clips a coach pointed at, on a session's write-up or a child's plan.
   Quieter than the studio's own list: this sits inside somebody else's screen
   and the note is the thing to read, not the timestamps. */
.clip-list{display:grid;gap:7px}
.clip-row{
  display:flex;gap:10px;align-items:flex-start;padding:9px 11px;
  border:1px solid var(--line);border-radius:9px;background:var(--surface)
}
.clip-row.is-open{border-color:var(--primary-600);box-shadow:0 0 0 2px var(--primary-100)}
.clip-row .at{
  display:flex;align-items:center;gap:5px;flex-shrink:0;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;font-weight:750;
  font-variant-numeric:tabular-nums;white-space:nowrap;
  padding:4px 8px;border-radius:6px;border:1px solid var(--line);
  background:var(--surface-2);color:var(--primary-700);cursor:pointer;font-style:normal
}
.clip-row .at:hover{border-color:var(--primary-600);background:var(--primary-50)}
.clip-row .at:disabled{opacity:.55;cursor:default}
/* Not a control: the clip cannot be opened, and the reason is in the byline. */
.clip-row .at.is-off{color:var(--faint);cursor:default;background:var(--surface-2)}
.clip-row .body{flex:1;min-inline-size:0}
.clip-row .body b{display:block;font-size:12.5px;font-weight:700;letter-spacing:-.01em}
.clip-row .body p{font-size:12px;color:var(--ink-2);margin-block-start:2px;overflow-wrap:anywhere;white-space:pre-wrap}
.clip-row .body small{display:block;font-size:10.5px;color:var(--faint);margin-block-start:4px}
.clip-row .unavailable{color:var(--warning-ink)}

.evd-clips{display:grid;gap:9px}
.idp-clips{padding:14px 16px}

@media(max-width:700px){
  .clip-row{flex-wrap:wrap}}

/* ---------------------------------------------------------------- mobile */
@media (max-width:900px){
  .kpi-strip{grid-template-columns:repeat(2,1fr)}
  .squad-grid{grid-template-columns:1fr;padding:12px}
  .page-h1{font-size:18px}
}

/* =============================================================================
   MOBILE — §4
   The requirement is not "works on a phone", it is "a rushed coach on a
   touchline keeps using it". Everything below serves that:
   the rail collapses to a bottom bar, the grid becomes one column, targets grow
   to 44px, and the register rows grow rather than shrink.
   ============================================================================= */
@media (max-width:900px){
  .shell{grid-template-columns:1fr}
  .side{display:none}
  .topbar{height:56px;padding:0 12px;gap:10px}
  .tb-search{display:none}
  .tb-title{font-size:15px}
  .main{padding:14px 12px 84px}
  .grid-2,.grid-3,.grid-4{grid-template-columns:1fr}
  .card{border-radius:var(--r)}

  /* Anything tappable clears 44px. */
  .btn,.chip,.tab,.tb-ico,.tb-menu{min-height:var(--tap)}
  .btn{padding-inline:16px}
}

@media (max-width:600px){
  .kpi-strip{grid-template-columns:repeat(2,1fr)}
  .table{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch}
}

/* =============================================================================
   RTL
   No mirrored stylesheet: the rules above are already direction-neutral. Only
   things that are genuinely handed need a rule here — an icon that points the
   way forward points the other way in Arabic.
   ============================================================================= */
[dir="rtl"] .icon-directional{transform:scaleX(-1)}
[dir="rtl"] .side{border-inline-end:none}

/* =============================================================================
   PRINT — the squad sheet a coach pins up. Chrome off, ink on white.
   ============================================================================= */
@media print{
  .topbar,.side,.bottom-nav,.btn,.tb-ico,.crumbs{display:none !important}
  .app,.main{background:#fff;padding:0}
  .card{box-shadow:none;border:1px solid var(--line);break-inside:avoid}
}

/* =============================================================================
   TONE CLASSES FOR THE PORTED SCREENS

   The approved mockups tint these small squares with an inline style holding a
   literal colour. A component cannot do that - rule 2, and CI enforces it - so
   each tint becomes a class here, named for its MEANING rather than its hue.
   "pin-critical" survives a customer whose brand is red; "pin-red" does not.
   ============================================================================= */

.att .pin.pin-critical{background:var(--critical-tint);color:var(--critical-ink)}
.att .pin.pin-warning{background:var(--warning-tint);color:var(--warning-ink)}
.att .pin.pin-serious{background:var(--serious-tint);color:var(--serious-ink)}
.att .pin.pin-good{background:var(--good-tint);color:var(--good-ink)}
.att .pin.pin-info{background:var(--info-tint);color:var(--info-ink)}
.att .pin.pin-brand{background:var(--primary-50);color:var(--primary-700)}
.att .pin.pin-neutral{background:var(--cat-violet-tint);color:var(--cat-violet-ink)}

.tile .ti.ti-brand{background:var(--primary-50);color:var(--primary-600)}
.tile .ti.ti-teal{background:var(--cat-teal-tint);color:var(--cat-teal)}
.tile .ti.ti-violet{background:var(--cat-violet-tint);color:var(--cat-violet)}
.tile .ti.ti-accent{background:var(--accent-100);color:var(--accent-800)}
.tile .ti.ti-good{background:var(--good-tint);color:var(--good-ink)}
.tile .ti.ti-warning{background:var(--warning-tint);color:var(--warning-ink)}

.feed .fd.fd-good{background:var(--good-tint);color:var(--good-ink)}
.feed .fd.fd-violet{background:var(--cat-violet-tint);color:var(--cat-violet)}
.feed .fd.fd-accent{background:var(--accent-100);color:var(--accent-800)}
.feed .fd.fd-warning{background:var(--warning-tint);color:var(--warning-ink)}
.feed .fd.fd-brand{background:var(--primary-50);color:var(--primary-700)}

/* Squad state, as the cohort grid legend draws it. Same three states as the
   .st-* dots above, so a change here is a change in both places or neither. */
.legend i.dot-active{background:var(--good)}
.legend i.dot-prep{background:var(--warning)}
.legend i.dot-ynt{background:var(--critical)}

/* The mockups push these to the far end with margin-left, which does not
   mirror. Logical, so Arabic gets it on the correct side. */
.legend .legend-note{margin-inline-start:auto;color:var(--faint)}
.filters .filters-end{margin-inline-start:auto}
.card-f .card-f-note{margin-inline-start:auto;font-size:11px;color:var(--faint)}

/* Calendar filter swatches. Kind names, matching .ev-* above. */
.fchip i.swatch-training{background:var(--primary-600)}
.fchip i.swatch-match{background:var(--accent-600)}
.fchip i.swatch-talentId{background:var(--warning)}
.fchip i.swatch-idp{background:var(--cat-violet)}
.fchip i.swatch-other{background:var(--neutral-400)}

/* A card that stands alone above a two-column band, as screen 1 draws the
   calendar. Block-end rather than bottom: logical properties everywhere. */
.card.card-spaced{margin-block-end:16px}

/* The chip in an attention row states the urgency; it must not stretch to fill
   the gap the flex row leaves between the text and the action. */
.att .chip{flex:none}
.att .btn{flex:none}

/* --- screen 2: squad overview ------------------------------------------- */

/* Availability, as a token class rather than the mockup's inline colour. */
/* Unknown, and visibly so: availability is not modelled until phase 4, and a
   grey dot says "not known" where a green one would say "fit to play". */
.pc-dot.dot-unknown{background:var(--line);border:1px solid var(--muted)}
.pc-dot.dot-available{background:var(--good)}
.pc-dot.dot-limited{background:var(--warning)}
.pc-dot.dot-unavailable{background:var(--critical)}

.fa-list{display:flex;flex-direction:column}

.fa .fi.fi-brand{background:var(--primary-50);color:var(--primary-600)}
.fa .fi.fi-teal{background:var(--cat-teal-tint);color:var(--cat-teal)}
.fa .fi.fi-violet{background:var(--cat-violet-tint);color:var(--cat-violet)}
.fa .fi.fi-accent{background:var(--accent-100);color:var(--accent-800)}
.fa .fi.fi-warning{background:var(--warning-tint);color:var(--warning-ink)}
.fa .fi.fi-serious{background:var(--serious-tint);color:var(--serious-ink)}

/* --- charts -------------------------------------------------------------
   Every value below is a token. A chart that keeps our blue through a rebrand
   is the most visible place a white-label product can be caught out. */
.chart{margin:0}
.chart-svg{display:block;overflow:visible}
.chart-grid-line{stroke:var(--line);stroke-width:1}
.chart-axis{font-size:10px;font-weight:600;fill:var(--muted)}
.chart-bar{fill:var(--primary-400)}

/* Step 9.2. A value written on its own mark, so the number is read without a
   trip to the axis and survives a screenshot. On the fill it is white; above it
   it is ink - TEXT WEARS TEXT TOKENS, never the series colour, so the coloured
   mark carries identity and the words stay readable. */
.chart-value{font-size:10.5px;font-weight:700;fill:var(--ink-2);font-variant-numeric:tabular-nums}

/* The view switcher on a chart card. Small, quiet, and in the card header where
   it does not compete with the numbers. */
.chsw{display:inline-flex;gap:2px;padding:2px;background:var(--surface-3);border-radius:var(--r-sm)}
.chsw-b{
  display:inline-flex;align-items:center;gap:5px;padding:4px 8px;border-radius:6px;
  font-size:11px;font-weight:650;color:var(--muted);background:transparent;cursor:pointer;
}
.chsw-b:hover{color:var(--ink-2)}
.chsw-b.on{background:var(--surface);color:var(--ink);box-shadow:var(--sh-1)}
.chsw-b:focus-visible{outline:2px solid var(--primary-600);outline-offset:1px}
/* The words go below 560px; the icons carry it, and each button keeps its
   aria-label either way. */
@media (max-width:560px){.chsw-b span{display:none}}
.chart-value.on-mark{fill:#fff}
.chart-series-name{font-size:10.5px;font-weight:700}
/* Step PP.2.3. The radar: a dashed spoke is an area nobody rated in the period. */
/* Drawn 400 wide. Stretched across a page it is one chart per sheet of A4
   with labels at twice the page's text; held near its drawn size it reads
   with the figures table beneath it. */
.chart-radar{inline-size:100%;max-inline-size:480px;margin-inline:auto}
.chart-radar-gap{stroke:var(--muted);stroke-width:1;stroke-dasharray:3 3}
.chart-radar-ring{paint-order:stroke;stroke:var(--surface);stroke-width:3px;stroke-linejoin:round}
.chart-radar-label{font-size:10.5px;font-weight:700;fill:var(--ink)}
.chart-radar-value{font-weight:600;fill:var(--muted)}
.chart-radar-none{font-weight:600;font-style:italic;fill:var(--muted)}

/* The pitch. Phase POS, step POS.1.3. Placement is SVG geometry inside a
   dir="ltr" drawing, so nothing here has a direction to mirror. The colours are
   on the elements themselves, as var(--pitch-*) and var(--accent-400), as the
   charts' are: sizes and weights only here. */
.pitch-figure{inline-size:100%;max-inline-size:560px;margin-inline:auto}
.pitch-svg{display:block;overflow:visible}
.pitch-line{stroke-width:3}
.pitch-marker-disc{stroke-width:4}
.pitch-marker-halo{stroke-width:3}
.pitch-marker-strong .pitch-marker-disc{stroke-width:6}
.pitch-marker-light .pitch-marker-disc{stroke-width:2}
.pitch-marker-face{font-size:17px;font-weight:800}
.pitch-marker-light .pitch-marker-face{font-size:13px;font-weight:700}
.pitch-marker-badge text{font-size:13px;font-weight:800}
.pitch-marker-name{font-size:18px;font-weight:700;paint-order:stroke;stroke-width:4px;stroke-linejoin:round}
.pitch-half .pitch-marker-face{font-size:14px}
.pitch-half .pitch-marker-name{font-size:15px}
/* Step POS.1.4: the editor's pitch. A marker is a button there. */
.pitch-marker[role="button"]{cursor:grab}
.pitch-marker-dragging{cursor:grabbing}
.pitch-marker[role="button"]:focus-visible .pitch-marker-disc,
.pitch-marker-selected .pitch-marker-disc{stroke-width:8}

/* The position catalogue's editor. Phase POS, step POS.1.4. */
.pos-editor{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:20px;align-items:start}
@media (max-width:900px){.pos-editor{grid-template-columns:1fr}}
.pos-list{list-style:none;display:grid;gap:4px}
.pos-list button{inline-size:100%;display:flex;gap:10px;align-items:center;padding-block:8px;padding-inline:10px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);color:var(--ink);text-align:start;cursor:pointer;min-block-size:var(--tap)}
.pos-list button[aria-pressed="true"]{border-color:var(--primary-600);box-shadow:0 0 0 2px var(--primary-50)}
.pos-list .pos-abbr{font-weight:800;min-inline-size:44px}
.pos-list .pos-state{margin-inline-start:auto}
.pos-wording{display:grid;gap:10px}
.pos-wording-state{font-weight:700}
.pos-wording-state.is-missing{color:var(--warning-ink)}
.pos-wording-state.is-complete{color:var(--good-ink)}
.pos-wording-row{display:grid;grid-template-columns:140px minmax(0,1fr) auto;gap:12px;align-items:end;padding-block-end:10px;border-block-end:1px solid var(--line-2)}
@media (max-width:640px){.pos-wording-row{grid-template-columns:1fr}}
.pos-wording-lang{display:flex;gap:6px;align-items:center;font-weight:700;padding-block-end:10px}
.pos-wording-mark.is-complete{color:var(--good)}
.pos-wording-mark.is-missing{color:var(--warning)}
.pos-actions{display:flex;flex-wrap:wrap;gap:8px;margin-block:12px}
.pos-sub{font-size:14px;font-weight:800;margin-block:16px 8px}

/* A player's positions: the picker (step POS.2.3). Ticks for the positions
   held, a star for the preferred one - its weight carried by the fill and the
   ring, not by colour alone. */
.ppick{display:grid;gap:12px}
.ppick-hint{color:var(--muted);font-size:13px}
.ppick-line{border:0;margin:0;padding:0;min-inline-size:0}
.ppick-line legend{font-size:12px;font-weight:800;color:var(--ink-2);margin-block-end:6px;padding:0}
.ppick-opts{display:flex;flex-wrap:wrap;gap:6px}
.ppick-opt{display:inline-flex;align-items:center;gap:2px;border:1px solid var(--line);border-radius:999px;background:var(--surface);padding-inline:10px 4px;min-block-size:var(--tap)}
.ppick-opt label{display:inline-flex;gap:6px;align-items:center;cursor:pointer;padding-block:6px}
.ppick-opt label b{font-size:12px;min-inline-size:28px}
.ppick-opt.on{border-color:var(--primary-600);background:var(--primary-50)}
.ppick-opt.pref{box-shadow:0 0 0 2px var(--primary-600)}
.ppick-star{border:0;background:none;padding:6px;border-radius:999px;cursor:pointer;color:var(--muted);display:inline-flex}
.ppick-star[aria-pressed="true"]{color:var(--primary-600)}
.ppick-star[aria-pressed="true"] svg{fill:currentColor}
.ppick-star:focus-visible{outline:2px solid var(--primary-600);outline-offset:1px}

/* A player's positions beside the picker, and the squad's "needs a position" list. */
.ppos-edit{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);gap:20px;align-items:start}
@media (max-width:760px){.ppos-edit{grid-template-columns:1fr}}
/* A player's position map (step POS.2.4): the words at inline-start, the half
   pitch beside them, never mirrored (TdsPitch pins it left-to-right). */
.pmap{display:grid;grid-template-columns:minmax(0,240px) minmax(0,420px);justify-content:start;gap:28px;align-items:center}
@media (max-width:640px){.pmap{grid-template-columns:1fr}}
.pmap-labels{display:grid;gap:14px;margin:0}
.pmap-labels dt{font-size:12.5px;font-weight:700;color:var(--muted)}
.pmap-labels dd{margin:0;font-weight:600}
.pmap-labels dd.pmap-main{font-size:18px;font-weight:800;color:var(--ink)}
.pmap-pitch .pitch-figure{max-inline-size:420px;margin-inline:0}
@media print{.pmap{grid-template-columns:minmax(0,240px) minmax(0,420px);break-inside:avoid}}
/* A formation (steps POS.2.5, POS.2.6): the whole pitch, and beside it the
   notation and one position per player where the caller may change them. */
.fboard{display:grid;grid-template-columns:minmax(0,280px) minmax(0,1fr);gap:20px;align-items:start}
@media (max-width:760px){.fboard{grid-template-columns:1fr}}
.fboard-pitch .pitch-figure{max-inline-size:280px;margin-inline:0}
.fboard-edit{display:grid;gap:14px;align-content:start}
.fboard-slots{border:0;margin:0;padding:0;min-inline-size:0}
.fboard-slots legend{font-size:12px;font-weight:800;color:var(--ink-2);margin-block-end:6px;padding:0}
.fboard-slots ol{list-style:none;display:grid;gap:6px;margin:0;margin-block-end:10px;padding:0}
.fboard-slots li{display:flex;gap:6px;align-items:end}
.fboard-slots li > :first-child{flex:1;min-inline-size:0}
.fboard-slots select{inline-size:100%;min-inline-size:0}
.fboard-remove{border:1px solid var(--line);background:var(--surface);color:var(--muted);border-radius:var(--r-sm);min-block-size:var(--tap);min-inline-size:var(--tap);display:inline-flex;align-items:center;justify-content:center;cursor:pointer}
.fboard-remove:disabled{opacity:.4;cursor:not-allowed}
.flist{list-style:none;display:grid;gap:4px;margin:0;padding:0}
.flist button{inline-size:100%;display:flex;gap:10px;align-items:center;padding-block:8px;padding-inline:10px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);color:var(--ink);text-align:start;cursor:pointer;min-block-size:var(--tap)}
.flist button[aria-pressed="true"]{border-color:var(--primary-600);box-shadow:0 0 0 2px var(--primary-50)}
.flist .fnotation{font-weight:800;min-inline-size:64px}
.flist .fend{margin-inline-start:auto;display:inline-flex;gap:6px}
.needs-pos{list-style:none;display:grid;gap:6px;margin-block-start:8px}

/* ---------------------------------------------------------------- TdsLineup */
/* Phase POS, step POS.3.4. The match-day squad, Starting or Bench, each with a
   position; the pitch beside the list, above it on a phone. */
.lineup{display:grid;gap:14px}
.lineup-head{display:flex;flex-wrap:wrap;gap:12px;align-items:end;justify-content:space-between}
.lineup-count{font-weight:800;margin:0}
.lineup-head .field{min-inline-size:200px}
.lineup-body{display:grid;grid-template-columns:minmax(0,320px) minmax(0,1fr);gap:20px;align-items:start}
@media (max-width:760px){.lineup-body{grid-template-columns:1fr}}
.lineup-pitch .pitch-figure{max-inline-size:320px;margin-inline:0}
.lineup-list{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.lineup-row{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,200px);gap:8px;align-items:center;padding-block:6px;padding-inline:10px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface)}
.lineup-row.on{border-color:var(--primary-600)}
@media (max-width:560px){.lineup-row{grid-template-columns:1fr auto}.lineup-pos{grid-column:1 / -1}}
.lineup-name{font-weight:700;min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lineup-toggle{display:inline-flex;border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden}
.lineup-toggle button{border:0;background:var(--surface);color:var(--ink-2);padding-inline:10px;min-block-size:var(--tap);font-weight:700;cursor:pointer}
.lineup-toggle button[aria-pressed="true"]{background:var(--primary-50);color:var(--primary-700);box-shadow:inset 0 0 0 2px var(--primary-600)}
.lineup-toggle button:disabled{opacity:.45;cursor:not-allowed}
.lineup-pos select{inline-size:100%;min-block-size:var(--tap)}
.lineup-drafts,.lineup-length{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.lineup-drafts p,.lineup-length p{margin:0;flex-basis:100%}
.lineup-saveformation{display:flex;flex-wrap:wrap;gap:10px;align-items:end}

/* Phase POS, step POS.3.7: a confirmed match sheet's minutes, read-only on the register. */
.register__minutes{font-size:12px;font-weight:700;color:var(--ink-2);white-space:nowrap}
.register__state:disabled{opacity:.35;cursor:not-allowed}

/* ---------------------------------------------------------------- TdsMatchEvents */
/* Phase POS, step POS.3.6. Substitutions and red cards, after the match. */
.matchevents{display:grid;gap:14px}
.matchevents-add{display:flex;flex-wrap:wrap;gap:10px;align-items:end}
.matchevents-add .field{display:flex;flex-direction:column;gap:4px;min-inline-size:0}
.matchevents-add .field-label{font-size:10.5px;font-weight:700;color:var(--muted);letter-spacing:.03em}
.matchevents-add input,.matchevents-add select{min-block-size:var(--tap);min-inline-size:0}
.matchevents-add input[type=number]{inline-size:88px}
.matchevents-list{margin:0;padding:0;list-style:none;display:grid;gap:6px}
.matchevents-list li{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding-block:6px;padding-inline:10px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface)}
.matchevents-what{flex:1;min-inline-size:0;font-variant-numeric:tabular-nums}
.matchevents-blocking{border-color:var(--critical);box-shadow:inset 0 0 0 1px var(--critical)}
.matchevents-flag{color:var(--critical-ink);font-weight:700;font-size:12px}
.matchevents-editminute{inline-size:72px}
.matchevents-confirm{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.matchevents-confirm p{margin:0}

/* ---------------------------------------------------------------- TdsMatchView */
/* Phase POS, step POS.3.5. The pitch, then everybody on the sheet. */
.matchview{display:grid;gap:14px}
.matchview-head{display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between}
.matchview-length{margin:0}
.matchview-pitch .pitch-figure{max-inline-size:360px;margin-inline:auto}
.matchview-list td,.matchview-list th{vertical-align:top}
.matchview-unused{color:var(--muted)}
.matchview-lineage summary{cursor:pointer;font-weight:800;font-variant-numeric:tabular-nums;list-style:none}
.matchview-lineage summary::-webkit-details-marker{display:none}
.matchview-lineage summary::after{content:" ⓘ";color:var(--muted);font-weight:400}
.matchview-lineage ul{margin:6px 0 0;padding-inline-start:16px;text-align:start;font-size:12px;color:var(--ink-2);min-inline-size:220px}
@media print{
  .matchcard{break-inside:avoid}
  .matchview-head .segc{display:none}
  .matchview-lineage ul{display:block}
  .matchview-lineage summary::after{content:""}
}

.needs-pos li{display:flex;align-items:center;gap:10px}
.needs-pos li span{flex:1}

/* =============================================================================
   PLAYER REPORT - step PP.2.4. One section: a drawing, then its figures as
   buttons, so every number opens the ratings it was made of.
   ============================================================================= */
.rsec{display:grid;gap:12px}
.rsec-h{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
.rsec-h h3{margin:0;font-size:15px}
.rsec-body{display:grid;gap:12px}
.rsec-trend{display:grid;gap:6px;align-content:start}
/* Side by side: each trend is drawn for a panel (TdsLineChart Compact), and
   stretched across a whole page it prints at twice the size of everything else. */
.rsec-trends{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(min(100%,280px),1fr))}
.rsec-trend h4{margin:0;font-size:13px}
.rsec-points{display:flex;flex-wrap:wrap;gap:6px}
.rsec-fig{border:1px solid var(--line);background:var(--surface);color:var(--ink);border-radius:var(--r-lg);padding-block:2px;padding-inline:8px;font:inherit;font-weight:700;cursor:pointer}
.rsec-fig:hover,.rsec-fig:focus-visible{border-color:var(--primary-600);color:var(--primary-700)}
.rsec-none{color:var(--muted);font-style:italic;margin:0}
.rsec-caption{display:block;color:var(--muted);font-size:11.5px;font-weight:500;margin:0}
.rsec-t{inline-size:100%;border-collapse:collapse}
.rsec-t th,.rsec-t td{text-align:start;padding-block:6px;padding-inline:8px;border-block-end:1px solid var(--line);vertical-align:top}
.rsec-t thead th{font-size:12px;color:var(--muted)}

.rlist{list-style:none;margin:0;padding:0}
.rlist li a{display:flex;gap:12px;align-items:center;padding-block:12px;padding-inline:16px;border-block-end:1px solid var(--line);color:var(--ink);text-decoration:none}
.rlist-period{font-weight:700;flex:1}
.rlist-kind{color:var(--muted)}
.rlist-status{border-radius:var(--r-lg);padding-block:2px;padding-inline:8px;background:var(--warning-tint);color:var(--warning-ink);font-size:12px;font-weight:700}
.rlist-status.final{background:var(--good-tint);color:var(--good-ink)}

.rnew{border:0;padding:0;margin-block:0 16px;display:grid;gap:8px}
.rnew legend{font-weight:700;margin-block-end:6px}
.rnew-dates{display:flex;gap:12px;flex-wrap:wrap}
.rnew-dates label{display:grid;gap:4px}
.rnew-go{display:flex;gap:8px;justify-content:flex-end}
.rnew-select{font:inherit;padding-block:6px;padding-inline:8px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);color:var(--ink)}
.rsched{display:flex;gap:12px;align-items:center;flex-wrap:wrap;padding-block:12px;padding-inline:16px;border-block-end:1px solid var(--line)}
.rep-pad{padding-block:12px;padding-inline:16px;margin:0}

.report{display:grid;gap:16px}
.logo-row{display:flex;gap:12px;align-items:flex-end;flex-wrap:wrap;margin-block:6px}
.logo-preview{display:block;block-size:56px;inline-size:auto;max-inline-size:200px;object-fit:contain;padding:6px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface)}
.rep-brand{display:flex;justify-content:flex-start}
.rep-brand img{display:block;block-size:56px;inline-size:auto;max-inline-size:200px;object-fit:contain}
.rep-note{margin:0;padding-block:8px;padding-inline:12px;border-radius:var(--r-lg);background:var(--info-tint);color:var(--info-ink)}
.rep-note.rep-changed{background:var(--warning-tint);color:var(--warning-ink)}
.rep-edit{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.rep-summary{inline-size:100%;font:inherit}
.rep-words{white-space:pre-wrap;margin:0}
/* A draft's summary is a text box on screen and words on paper. */
.rep-print{display:none}
.rep-check{display:flex;gap:6px;align-items:center}
.rep-points,.rep-sessions,.rep-clips,.rep-drill-list{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.rep-sessions li,.rep-clips li,.rep-drill-list li{display:flex;gap:12px;align-items:center;flex-wrap:wrap}
.rep-sessions li > span:first-child,.rep-clips li > span:first-child{flex:1}
.rep-video{inline-size:100%;max-block-size:360px;background:var(--ink)}

/* Printed through the browser (D-PP2): the report, not the builder. */
@media print{
  .report .rep-edit,.report .rep-drill,.report .rep-video,.report .rsec-h .chsw,.report .tb-ico{display:none !important}
  .report .rep-section,.report .rep-full{break-inside:avoid}
  .rsec-fig{border:0;padding:0}
  .report .rep-summary{display:none !important}
  .report .rep-print{display:block}
}

/* --- the phone dashboard, step 9.5 --------------------------------------
   Three figures, one sparkline and a sentence. Generous type and spacing on
   purpose: this is read at arm's length on a touchline, not at a desk. */
.phd{display:flex;flex-direction:column;gap:14px}
.phd-figs{display:flex;flex-direction:column;gap:10px}
.phd-fig{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:13px 15px;box-shadow:var(--sh-1);position:relative;overflow:hidden;
}
.phd-fig::before{content:"";position:absolute;inset-inline-start:0;top:0;bottom:0;width:3px;background:var(--primary-600)}
.phd-lab{display:block;font-size:11.5px;color:var(--muted);font-weight:650;letter-spacing:.02em}
.phd-val{display:block;font-size:30px;font-weight:750;letter-spacing:-.03em;line-height:1.15;font-variant-numeric:tabular-nums}
.phd-sub{display:block;font-size:11.5px;color:var(--muted);margin-block-start:2px}
.phd-spark{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);padding:12px 15px 6px;box-shadow:var(--sh-1)}
.phd-asof{font-size:11px;color:var(--faint);text-align:center}
.phd-note{
  display:flex;gap:11px;align-items:flex-start;padding:13px 15px;border-radius:var(--r);
  background:var(--info-tint);color:var(--info-ink);
}
.phd-note b{display:block;font-size:13px;font-weight:700;margin-block-end:3px}
.phd-note p{font-size:12px;line-height:1.5}
.spark{margin:0}
.spark-svg{display:block;overflow:visible}

/* --- mosaic: a composition as one divided bar --------------------------- */
.mosaic{display:flex;flex-direction:column;gap:9px}
.mos{display:flex;block-size:34px;border-radius:var(--r-sm);overflow:hidden;gap:2px;background:var(--surface)}
.mos-seg{display:grid;place-items:center;min-inline-size:4px;transition:flex .2s}
.mos-v{font-size:10.5px;font-weight:700;color:#fff;font-variant-numeric:tabular-nums}
.mos-leg{display:flex;flex-wrap:wrap;gap:6px 14px;font-size:11.5px;color:var(--ink-2)}
.mos-leg span{display:inline-flex;align-items:center;gap:6px}
.mos-leg b{font-weight:700;font-variant-numeric:tabular-nums}
.mos-leg i{inline-size:9px;block-size:9px;border-radius:3px;flex:none}

/* --- the series swatches ------------------------------------------------
   One class per slot, written out, because the CI check that every var() names
   a property tds.css defines cannot see through an interpolated token name. */
.swatch-cat-1{background:var(--cat-1)}
.swatch-cat-2{background:var(--cat-2)}
.swatch-cat-3{background:var(--cat-3)}
.swatch-cat-4{background:var(--cat-4)}
.swatch-cat-5{background:var(--cat-5)}
.swatch-cat-6{background:var(--cat-6)}
.swatch-cat-7{background:var(--cat-7)}
.swatch-cat-8{background:var(--cat-8)}
.swatch-cat-other{background:var(--cat-other)}
.chart-bar:hover{fill:var(--primary-600)}

/* Present to a screen reader, absent to the eye. Not display:none, which would
   take it out of the accessibility tree along with everything else. */
/* On a WRAPPER, never on a table: a table ignores width:1px and grows to its
   content, clipped from sight but still widening the page - a printed report
   ran 50px off the paper that way. */
.visually-hidden{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0;
}

/* --- screen 3: players and IDPs ------------------------------------------ */

/* The mockups draw filters as styled spans. They are real inputs here, so the
   control has to carry the field rather than the text. A filter a keyboard user
   cannot reach is not a filter. */
.ctrl input,.ctrl select{
  inline-size:100%;border:none;background:none;font:inherit;color:inherit;
  outline:none;min-inline-size:0;appearance:none;cursor:pointer;
}
.ctrl input::placeholder{color:var(--faint)}
.ctrl select{padding-inline-end:14px}
.ctrl:focus-within{border-color:var(--primary-600);box-shadow:0 0 0 3px var(--primary-50)}

.staff-list .staff-row{padding-inline:0}
.btn.btn-icon{inline-size:30px;padding:0;justify-content:center}

.notice.notice--info{background:var(--info-tint);color:var(--info-ink);border-color:var(--info)}
.notice.notice--good{background:var(--good-tint);color:var(--good-ink);border-color:var(--good)}
.notice.notice--warning{background:var(--warning-tint);color:var(--warning-ink);border-color:var(--warning)}
.notice .notice-icon{flex:none;margin-block-start:1px}

/* Screen 3 shows four across where screen 2 shows three. */
.squad.squad-4{grid-template-columns:repeat(4,1fr)}
.pcard .pc-tag{padding:0 11px 8px}

.ctx-bar{display:flex;align-items:center;gap:10px;margin-block-end:16px;flex-wrap:wrap}
.cols.cols--aside{grid-template-columns:1fr 300px}

.dt td.nowrap,.dt th.nowrap{white-space:nowrap}
.dt td.cell-end,.dt th.cell-end{text-align:end}
.dt td b{font-weight:650}

/* --- forms: real controls inside the mockups' shapes ---------------------
   The approved screens draw these as static spans. Making them real inputs is
   not a liberty: a field a keyboard user cannot reach is not a field, and
   retrofitting that after sign-off never happens. The shapes are unchanged. */
.inp input,.inp select{
  flex:1;min-inline-size:0;border:none;background:none;font:inherit;color:inherit;
  outline:none;appearance:none;
}
.inp input::placeholder{color:var(--faint)}
.inp:focus-within{border-color:var(--primary-600);box-shadow:0 0 0 3px var(--primary-50)}
.inp.ro input,.inp.ro select{color:var(--ink-2)}

.ta textarea{
  inline-size:100%;min-block-size:64px;border:none;background:none;font:inherit;
  color:inherit;outline:none;resize:vertical;padding:0;
}

/* The segmented control is a radio group; the labels carry what .segc span did. */
.segc label{
  padding:7px 11px;font-size:11.5px;font-weight:600;color:var(--muted);
  border-inline-start:1px solid var(--line);cursor:pointer;flex:1;text-align:center;
}
.segc label:first-child{border-inline-start:none}
.segc label.on{background:var(--primary-600);color:#fff;font-weight:700}
.segc:focus-within{box-shadow:0 0 0 3px var(--primary-50)}

.tgl-list{display:flex;flex-direction:column;gap:10px;padding-block-start:4px}
.tgl{cursor:pointer}
.tgl .tgl-end{margin-inline-start:auto}

.filerow .fi.doc{background:var(--primary-600)}
.fields-spaced{margin-block-start:12px}
.fields-spaced-b{margin-block-end:12px}
.f-end{justify-content:flex-end}
/* Padding inside a Flush card. Three pages used this class before it existed. */
.card-pad{padding:14px 16px}
.block{display:block}
.confirm-check{gap:10px;margin-block-start:12px;justify-content:flex-start}
.dt .figure-good{color:var(--good)}
.vfoot .vsize{margin-inline-start:auto;font-size:10.5px;color:var(--faint);font-weight:600}

/* --- dashboards ---------------------------------------------------------
   Categorical tokens for donut legends and pathway markers. The ramp families
   are seed-derived; cat-* and the semantics are not, which is why a legend
   stays distinguishable whatever the customer's brand turns out to be. */
:root{
  --cat-brand:var(--primary-600);
  --cat-accent:var(--accent-600);
  --cat-neutral:var(--neutral-500);
}
.dleg i.swatch-cat-brand{background:var(--cat-brand)}
.dleg i.swatch-cat-accent{background:var(--cat-accent)}
.dleg i.swatch-cat-teal{background:var(--cat-teal)}
.dleg i.swatch-cat-violet{background:var(--cat-violet)}
.dleg i.swatch-cat-neutral{background:var(--cat-neutral)}

.pathway .pi{
  inline-size:30px;block-size:30px;border-radius:9px;display:grid;place-items:center;
  margin:0 auto 6px;background:var(--primary-50);color:var(--primary-600);
}
.pathway .pi.pi-accent{background:var(--accent-100);color:var(--accent-800)}
.pathway .pi.pi-good{background:var(--good-tint);color:var(--good-ink)}
.pathway .pi.pi-neutral{background:var(--surface-3);color:var(--muted)}
.pathway b{display:block;font-size:19px;font-weight:750;letter-spacing:-.03em}
.pathway small{display:block;font-size:10.5px;color:var(--muted);font-weight:600}

.pcard .pc-status{flex:none;align-self:flex-start}
.pcard .pc-focus{padding:0 11px 9px;font-size:10.5px;color:var(--muted);font-weight:600;line-height:1.4}
.cols.cols--wide-aside{grid-template-columns:1fr 320px}

/* The aside variants need their OWN responsive rule.
   `.cols{grid-template-columns:1fr}` inside the 1180px media query does not
   reach them: `.cols.cols--aside` is two classes to its one and comes later in
   the file, so it wins on specificity even inside the query. The settings page
   therefore kept a fixed 300px aside beside a 1fr main at 375px and overflowed
   the viewport by 155px - every card in that column pushed off-screen.
   Pre-existing, found while checking the calendar connection card at phone
   width. Same shape as the .fields.c2 rule in task 3.2. */
@media(max-width:1180px){
  .cols.cols--aside,.cols.cols--wide-aside{grid-template-columns:1fr}
}

/* --- IDP tables (screens 15 and 16) ------------------------------------- */
.dt td.cell-prose{color:var(--ink-2);line-height:1.4;min-inline-size:150px}
.dt .bar.bar-inline{display:inline-block;inline-size:56px;vertical-align:middle;margin-inline-end:6px}
.area-nm .ai{
  inline-size:26px;block-size:26px;border-radius:8px;display:grid;place-items:center;
  flex:none;background:var(--primary-50);color:var(--primary-600);
}
.area-nm .ai.ai-serious{background:var(--serious-tint);color:var(--serious-ink)}
.area-nm .ai.ai-teal{background:var(--cat-teal-tint);color:var(--cat-teal)}
.area-nm .ai.ai-violet{background:var(--cat-violet-tint);color:var(--cat-violet)}
.area-nm .ai.ai-accent{background:var(--accent-100);color:var(--accent-800)}
.area-nm .ai.ai-warning{background:var(--warning-tint);color:var(--warning-ink)}
.boot .btn{margin-block-start:12px}

/* --- settings: generated ramp preview ------------------------------------
   The swatch colours are inline because they ARE the data: values generated
   per tenant and delivered by /api/bootstrap. Everything around them is a
   token, as usual. */
.swatches{display:flex;gap:6px;flex-wrap:wrap}
.swatch{text-align:center;min-inline-size:52px}
.swatch .swatch-chip{
  display:block;block-size:34px;border-radius:8px;border:1px solid var(--line);
  margin-block-end:5px;
}
.swatch b{display:block;font-size:11px;font-weight:700;font-variant-numeric:tabular-nums}
.swatch small{display:block;font-size:9.5px;color:var(--faint);font-family:ui-monospace,monospace}
.ramp-label{display:block;font-size:11px;font-weight:650;color:var(--ink-2);margin-block-end:6px}
.dt code{font-family:ui-monospace,monospace;font-size:11px}

/* --- demonstration persona switcher --------------------------------------
   Development scaffolding, and dressed to look like it: a labelled control in
   the top bar rather than something resembling an account menu. Somebody being
   shown the product should be able to tell that this changes seats and does not
   sign anybody in. */
/* Development-only scaffolding, and it must not decide the product's layout.
   At 1024px the tag plus a 230px select pushed the top bar 18px wider than the
   viewport - so the whole page scrolled sideways, at tablet width, because of a
   control that does not ship. min-inline-size:0 is what lets a flex item shrink
   below its content; without it the select refuses and the bar overflows. */
.demo-persona{display:flex;align-items:center;gap:7px;margin-inline-start:auto;min-inline-size:0}
.demo-persona__tag{
  font-size:9.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
  color:var(--accent-400);white-space:nowrap;
}
.demo-persona select{
  background:rgba(255,255,255,.12);border:1px solid rgba(255,255,255,.22);
  color:#fff;border-radius:8px;padding:5px 9px;font:inherit;font-size:11.5px;
  font-weight:600;max-inline-size:230px;min-inline-size:0;
}
/* The tag is the first thing to go: "DEMO - VIEWING AS" is a label, and the
   name beside it carries the meaning. Then the selects narrow, then they go.

   TASK 7.2 FOUND THAT THIS WAS STILL NOT ENOUGH. Task 2.3 fixed the top bar at
   375px and at 1024 measured only the persona switcher; with BOTH switchers
   shown, `.tb-user` was 547px at a 1009px viewport and every screen in the
   product scrolled sideways by 123px - not just the IDP grid that was being
   checked when this surfaced.

   The two switchers are 392px of that, and NEITHER OF THEM SHIPS: they are the
   demonstration academy picker and the persona picker. A control that does not
   exist in the product breaking the layout of every screen in it, at the most
   ordinary laptop width there is, is the worst possible trade - so they narrow
   hard rather than pushing real chrome off the edge. 1024 is a width AC 7.2.4
   names explicitly and the width a demonstration is most likely to be given at. */
@media (max-width:1200px){
  .demo-persona__tag{display:none}
  .demo-persona select{max-inline-size:150px}
}
@media (max-width:1100px){
  /* The user's own name goes before the demo controls do: it is on the page
     already, and the avatar keeps the affordance. */
  .tb-user .who{display:none}
  .demo-persona select{max-inline-size:124px}
}
@media (max-width:900px){ .demo-persona{display:none} }
.demo-persona select option{color:var(--ink);background:var(--surface)}

/* --- staff and roles, task 2.5 -------------------------------------------
   A role and its remove control are ONE object, so they share a border and the
   chip loses its own right radius into the button. Two separate controls side
   by side would read as "a role" and "a delete", and on a row with four roles
   nobody could tell which delete belonged to which role.

   The remove control is 24px, below the 44px floor - deliberately, and only
   here. §4's floor is for a coach outdoors on a touchline; this is an
   administrator at a desk, and a 44px target on every chip in a four-role row
   would make the table taller than the screen. The confirmation dialog is what
   protects against the mis-tap, and its buttons are full size. */
.role-chips{display:flex;flex-wrap:wrap;gap:6px}
.role-chip{
  display:inline-flex;align-items:center;gap:0;
  border:1px solid var(--line-2);border-radius:99px;background:var(--surface);
  padding-inline-end:2px;
}
.role-chip .chip{border-start-end-radius:0;border-end-end-radius:0}
.role-scope{
  font-size:10px;font-weight:600;color:var(--muted);
  padding-inline:6px;white-space:nowrap;max-inline-size:12ch;
  overflow:hidden;text-overflow:ellipsis;
}
.role-x{
  display:inline-flex;align-items:center;justify-content:center;
  inline-size:24px;block-size:24px;border:none;background:none;cursor:pointer;
  color:var(--muted);border-radius:99px;padding:0;
}
.role-x:hover{color:var(--critical-ink);background:var(--critical-tint)}
.role-x:focus-visible{outline:2px solid var(--primary-600);outline-offset:1px}

/* The invitation token. Monospace and selectable, because the copy button can
   fail - a browser without clipboard permission, or a page not on a secure
   origin - and when it does, reading the token off the screen has to work. It
   wraps rather than scrolling for the same reason: a token with its end off the
   side of a box is a token somebody will copy three quarters of. */
.token-row{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin-block-start:12px;
}
.token{
  flex:1 1 260px;min-inline-size:0;
  font-family:ui-monospace,monospace;font-size:12px;line-height:1.5;
  padding:9px 11px;border:1px solid var(--line-2);border-radius:10px;
  background:var(--surface-2);color:var(--ink);
  overflow-wrap:anywhere;user-select:all;
}

/* --- the mobile agenda, task 3.2 -----------------------------------------
   A list rather than a squeezed grid. At 390px a week grid gives each day 47
   pixels, which will not hold a squad name, so the phone gets a different view
   and not a smaller one.

   Every row clears 44px comfortably (§4). This is read on a touchline, in the
   rain, one-handed, by somebody watching a pitch rather than the screen. */
.agenda{display:flex;flex-direction:column}
.agenda-day{border-bottom:1px solid var(--line-2)}
.agenda-day:last-child{border-bottom:none}

/* Sticky, so a thumb scrolling fast always knows which day is on screen. The
   offset is the card header's height; without it the first row of a day slides
   under the card title rather than under its own heading. */
.agenda-h{
  position:sticky;top:0;z-index:2;
  display:flex;align-items:baseline;gap:8px;
  margin:0;padding:8px 16px;
  background:var(--surface-2);border-bottom:1px solid var(--line-2);
}
.agenda-day.is-today .agenda-h{background:var(--primary-50,var(--surface-2))}
.agenda-rel{font-size:12px;font-weight:750;color:var(--ink)}
.agenda-day.is-today .agenda-rel{color:var(--primary-600)}
.agenda-date{font-size:11px;color:var(--muted)}

.agenda-empty{margin:0;padding:12px 16px;font-size:12px;color:var(--faint)}

.agenda-row{
  display:flex;align-items:center;gap:12px;
  min-block-size:56px;padding:10px 16px;
  border-bottom:1px solid var(--line-2);
  color:inherit;
}
.agenda-row:last-child{border-bottom:none}
.agenda-row:hover{background:var(--surface-2)}
.agenda-row:focus-visible{outline:2px solid var(--primary-600);outline-offset:-2px}

/* The kind stripe on the inline-start edge, so it is on the right in Arabic
   without a second rule. */
.agenda-row{border-inline-start:3px solid transparent}
.ag-training{border-inline-start-color:var(--primary-600)}
.ag-match{border-inline-start-color:var(--good)}
.ag-talentId{border-inline-start-color:var(--warning,var(--accent-400))}
.ag-idp{border-inline-start-color:var(--neutral-400)}

.agenda-time{
  flex:none;inline-size:52px;
  display:flex;flex-direction:column;align-items:flex-start;
  font-variant-numeric:tabular-nums;
}
.agenda-time b{font-size:14px;font-weight:700;line-height:1.15}
.agenda-time small{font-size:10.5px;color:var(--faint)}
.agenda-cont{display:inline-flex;color:var(--muted)}

.agenda-what{flex:1;min-inline-size:0}
.agenda-what b{display:block;font-size:13px;font-weight:650;line-height:1.3}
.agenda-what small{
  display:block;font-size:11px;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* --- which view a screen gets --------------------------------------------
   The grid and the agenda are BOTH rendered and one is hidden, rather than the
   page choosing by a media query in C#. A JavaScript-free swap survives a
   rotation, a split-screen resize and a desktop browser dragged narrow - all of
   which happen, and none of which fires a Blazor re-render.

   768px is the tablet boundary the rest of the product uses. */
.cal-grid-view{display:block}
.cal-agenda-view{display:none}

@media (max-width:768px){
  .cal-grid-view{display:none}
  .cal-agenda-view{display:block}
}

/* A reader who has explicitly asked for the agenda gets it at any width, and a
   reader who has asked for a grid on a phone gets the grid, scrolling
   sideways. Choosing is allowed to override guessing. */
.cal-view-agenda .cal-grid-view{display:none}
.cal-view-agenda .cal-agenda-view{display:block}
.cal-view-grid .cal-grid-view{display:block}
.cal-view-grid .cal-agenda-view{display:none}

/* The week grid is the one thing on a phone that may scroll sideways: seven
   columns of a working day cannot be made narrower and still read. It scrolls
   inside its own wrapper so the PAGE never does. */
.cal-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.cal-scroll>.cal{min-inline-size:640px}

/* The filter chips became real buttons in task 3.2 - they were styled spans,
   which meant the filters could not be reached by keyboard at all. A button
   inherits none of a span's typography, so the family and size are restated. */
button.fchip{font:inherit;font-size:11.5px;font-weight:600;cursor:pointer;min-block-size:28px}
button.fchip:hover{background:var(--surface-2)}
button.fchip:focus-visible{outline:2px solid var(--primary-600);outline-offset:1px}

/* Clashes, listed above the grid. Two overlapping boxes look like a busy
   Tuesday; the sentence says what is actually wrong. */
.cal-clashes{padding:12px 16px 0}
.clash-list{margin:6px 0 0;padding-inline-start:18px;display:flex;flex-direction:column;gap:3px}
.clash-list li{font-size:11.5px;line-height:1.45}

/* Subscribe instructions, one per client. Three journeys, and a coach on a
   phone should not have to work out which of them they are on. */
.feed-how{
  margin:12px 0 0;padding-inline-start:18px;
  display:flex;flex-direction:column;gap:6px;
}
.feed-how li{font-size:11.5px;line-height:1.5;color:var(--ink-2)}

/* One sentence per connection state, saying what to DO about it. */
.feed-state{margin:0 0 10px;font-size:12px;line-height:1.5;color:var(--ink-2)}

/* What the feed can and cannot see. Collapsed by default because most readers
   want the link, not the essay - and open to anybody who wants the essay, which
   is the point of AC 3.8.3. */
.feed-perms{margin-block-start:14px;border-top:1px solid var(--line-2);padding-block-start:10px}
.feed-perms summary{
  font-size:11.5px;font-weight:650;color:var(--primary-600);cursor:pointer;
  list-style:none;padding:2px 0;
}
.feed-perms summary::-webkit-details-marker{display:none}
.feed-perms summary::before{content:"\203A  ";display:inline-block;transition:transform .12s}
.feed-perms[open] summary::before{transform:rotate(90deg)}
.feed-perms ul{margin:8px 0 0;padding-inline-start:16px;display:flex;flex-direction:column;gap:6px}
.feed-perms li{font-size:11.5px;line-height:1.55;color:var(--ink-2)}
.feed-perms li b{color:var(--ink)}

/* =============================================================================
   BLAZOR'S ERROR BAR

   index.html carries the framework's error bar and nothing hid it, so every page
   in the client ended with "An unexpected error has occurred. Reload" in plain
   text - on pages where nothing had gone wrong. Hidden until the runtime shows
   it (it sets display:block inline on a real unhandled exception), and then
   pinned to the bottom where it cannot be mistaken for page content.
   ============================================================================= */
#blazor-error-ui{
  display:none;position:fixed;inset-inline:0;inset-block-end:0;z-index:1000;
  padding:10px 16px;background:var(--warning-tint);color:var(--ink);
  border-block-start:1px solid var(--warning);box-shadow:var(--sh-2);font-size:13px
}
#blazor-error-ui .reload{margin-inline-start:8px;font-weight:650}
#blazor-error-ui .dismiss{cursor:pointer;position:absolute;inset-inline-end:14px;inset-block-start:8px}

/* --- a squad's completed sessions. Step SH.1. -----------------------------
   Rows are ANCHORS, so the whole row is one keyboard target and one thing a
   screen reader announces; the grid inside each is laid out with logical
   properties only, so the whole list mirrors in Arabic without a second
   stylesheet. */
.sh-list{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.sh-row{
  display:grid;gap:10px;align-items:center;padding:10px 12px;text-decoration:none;
  grid-template-columns:minmax(6.5em,auto) minmax(0,1fr) auto auto;
  border:1px solid var(--line);border-radius:10px;background:var(--surface);color:inherit
}
.sh-row:hover{border-color:var(--primary-600);background:var(--surface-2)}
.sh-row:focus-visible{outline:2px solid var(--primary-600);outline-offset:2px}
.sh-when b{display:block;font-size:12.5px;font-weight:700;letter-spacing:-.01em}
.sh-when span{
  display:block;font-size:11px;color:var(--muted);
  font-variant-numeric:tabular-nums;white-space:nowrap
}
.sh-what{min-inline-size:0}
/* The opposition and the venue are somebody's own words, in their own script:
   isolated so a right-to-left name cannot reorder the line around it. */
.sh-what b{
  display:block;font-size:12.5px;font-weight:700;letter-spacing:-.01em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;unicode-bidi:isolate
}
.sh-what span{
  display:block;font-size:11px;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;unicode-bidi:isolate
}
.sh-tags{display:flex;flex-wrap:wrap;gap:4px;justify-content:flex-end}
.sh-reg{font-size:11.5px;color:var(--ink-2);white-space:nowrap}
.sh-foot{
  display:flex;flex-wrap:wrap;gap:10px;align-items:center;justify-content:space-between;
  margin-block-start:12px
}

/* A phone holds four columns badly: the chips and the register drop under the
   session rather than squeezing the thing the reader is scanning for. */
@media (max-width:719px){
  .sh-row{grid-template-columns:minmax(0,1fr) auto}
  .sh-tags{grid-column:1 / -1;justify-content:flex-start}
}

/* The body outline. Phase INJ, step INJ.1.3. Colours are on the elements, as
   var(--body-*), like the pitch; this only sizes and states. */
.body-figure{inline-size:100%;max-inline-size:520px;margin-inline:auto}
.body-svg{display:block;overflow:visible}
.body-view-label{font-size:18px;font-weight:700}
.body-marker-disc{stroke-width:3}
.body-marker[role="button"]{cursor:pointer}
.body-marker[role="button"]:focus-visible .body-marker-disc,
.body-marker-selected .body-marker-disc{stroke-width:6}
.body-marker-light{opacity:.45}

/* The injury form. Phase INJ, step INJ.3.1. */
.injury-form{display:grid;gap:12px}
.injury-form-body{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;align-items:start}
@media (max-width:640px){.injury-form-body{grid-template-columns:1fr}}
.injury-form-help,.injury-form-note{font-size:13px;margin-block:4px 8px}

/* The register row's injury action and chip. Phase INJ, step INJ.3.2. */
.register__injured{flex:none}
/* Phase INJ, step INJ.4.2. A proposal from an injury record is not a mark:
   outlined rather than filled, and the row is marked as proposed. */
.register__proposal{flex:none;background:transparent;box-shadow:inset 0 0 0 1px currentColor;border-style:dashed}
.register__row--proposed{background:var(--serious-tint)}
.register__unpicked{flex:none}
.register__more{flex:none;inline-size:var(--tap);block-size:var(--tap);display:grid;place-items:center;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);color:var(--ink-2);cursor:pointer}
.register__more:focus-visible{outline:2px solid var(--primary-600);outline-offset:2px}

/* A child's injuries on the IDP page. Phase INJ, step INJ.3.2. */
.injury-list{list-style:none;display:grid;gap:12px}
.injury-otherwise-head{font-size:12px;font-weight:700;margin-block:8px 4px}
.injury-otherwise{list-style:none;display:grid;gap:4px;font-size:12.5px}
.injury-row{display:grid;gap:4px;padding-block-end:12px;border-block-end:1px solid var(--line-2)}
.injury-row-head{display:flex;gap:8px;align-items:center;justify-content:space-between;flex-wrap:wrap}
.injury-note{font-size:14px;color:var(--ink-2)}
.injury-return{display:flex;gap:8px;align-items:end;flex-wrap:wrap}
.injury-revisions{list-style:disc;padding-inline-start:20px;font-size:13px;color:var(--ink-2)}

/* The injury history, grouped by season. Phase INJ, step INJ.5.2. */
.injury-history{display:grid;gap:8px}
.injury-hist-print-toggle{display:inline-flex;gap:6px;align-items:center;font-size:12.5px;color:var(--muted)}
.injury-season{border-block-end:1px solid var(--line-2);padding-block-end:8px}
.injury-season:last-child{border-block-end:0}
.injury-season-summary{display:flex;gap:12px;align-items:baseline;justify-content:space-between;flex-wrap:wrap;cursor:pointer;padding-block:8px}
.injury-season-label{font-weight:800}
.injury-season-figures{font-size:12.5px}
.injury-season-empty{margin-block:4px 8px}
.injury-season-body{display:grid;grid-template-columns:minmax(0,240px) minmax(0,1fr);gap:20px;align-items:start}
@media (max-width:640px){.injury-season-body{grid-template-columns:1fr}}
.injury-season-body .body-figure{max-inline-size:240px}
.injury-hist-list{list-style:none;display:grid;gap:12px;margin:0;padding:0}
.injury-row-tags{display:inline-flex;gap:6px;align-items:center;flex-wrap:wrap}
.injury-row-meta{font-size:12.5px}

/* The note travels further on paper than on screen, so it is held back from
   print unless the reader ticks "include notes" (AC INJ.5.2.3). */
@media print{
  .injury-hist-print-toggle{display:none}
  .injury-hist-note{display:none}
  .injury-history.print-notes .injury-hist-note{display:block}
}
