/* =========================================================
   COTA Learning Platform — design system
   Source: COTA Brand Guide (Colors, Fonts, Logos & Lockups)
   ========================================================= */
:root {
  /* Brand palette (brand guide) */
  --cota-red: #EC1E24;      /* Primary — Pantone P 48-8 C */
  --cota-black: #231F20;    /* Secondary */
  --cota-grey: #898A8D;     /* Tertiary */
  --cota-silver: #D0D4D5;   /* Tertiary */
  --cota-white: #FFFFFF;    /* Tertiary */

  /* Only the five guide colours are used. Hierarchy comes from opacity of those colours, never new
     hues — and each colour has one job, so the palette reads as COTA rather than as generic grey:
       Red    emphasis, the live/active state, key figures
       Black  ground for data, headings, body text
       Grey   the inactive state — not-started, empty track, disabled
       Silver rules and dividers
       White  the page                                                                            */
  --ground: var(--cota-white);                  /* the page is COTA White, not a silver tint */
  --red-dark: var(--cota-red);                  /* hover uses the same red at higher elevation */
  /* COTA Red on a dark surface is 3.14:1 resting and 2.56:1 on a raised card —
     both under the 4.5:1 that small text needs. This is the brand red lightened
     for SMALL TEXT ON DARK only: 6.30:1 resting, 5.14:1 raised. Fills, rules,
     bars and large display type keep the true --cota-red, which is where the
     brand actually lives. The same constraint the other way round (red on
     white, 4.40:1) is open decision #10 and is COTA's call, not ours. */
  --red-on-dark: #FF8F93;
  --red-tint: rgba(236,30,36,.10);              /* COTA Red at 10% */
  --ink: var(--cota-black);
  --muted: rgba(35,31,32,.70);                  /* COTA Black at 70% — body-safe contrast */
  --label: var(--k-72);                         /* COTA Black @72% — Grey is 3.45:1 on white, below AA */
  --line: rgba(208,212,213,.9);                 /* COTA Silver — rules and dividers */
  --line-strong: var(--cota-silver);
  --surface: rgba(137,138,141,.16);             /* COTA Grey @16% — inactive track/chip ground */
  --surface-2: rgba(137,138,141,.08);
  --ok: var(--cota-red);                        /* brand-positive accents: covered, feedback in, answers */
  --ok-tint: rgba(236,30,36,.10);

  /* A RIGHT ANSWER IS GREEN, and this is the one place the five-colour rule
     bends. It was COTA red plus a tick, which is defensible on paper and failed
     in front of two people: Pauline read "Perfect." as having got it wrong, and
     so did Jesse. A child who has just answered correctly should not have to
     decode a palette to find that out.

     So this is a SYSTEM colour, not a brand colour: answer feedback only, never
     branding, never a heading, never a button. `--ok` above is untouched and
     the rest of the interface stays red.

     #046A38 is 5.59:1 on its own tint and 13.12:1 behind white on the dark quiz
     panel, both clear of AA.

     Wrong stays GREY, deliberately. Green-for-right against red-for-wrong is
     the one pairing roughly eight percent of boys cannot separate, and this is
     a Grade 6 course. Green against grey, each with its own glyph, is legible
     to everybody. */
  --correct: #046A38;
  --correct-tint: rgba(4,106,56,.12);

  /* Typography — Gotham is COTA's brand typeface; Montserrat is the licensed-free web fallback */
  --font: "Gotham", "Gotham SSm A", "Gotham SSm B", "Montserrat", "Helvetica Neue", Arial, sans-serif;
  --mono: "SFMono-Regular", Menlo, Consolas, monospace;

  /* Alpha steps — every tint is a brand colour at an opacity, never a new hue */
  --w-06: rgba(255,255,255,.06);   /* white on black: raised surface  */
  --w-12: rgba(255,255,255,.12);   /* white on black: border          */
  --w-20: rgba(255,255,255,.20);   /* white on black: strong border   */
  --k-06: rgba(35,31,32,.06);      /* black on white: hairline shadow */
  --k-72: rgba(35,31,32,.72);      /* black on white: label text (5.4:1) */

  /* Type scale — 11 · 12 · 13 · 14 · 15(base) · 17 · 20 · 24 · 30 · 38 · fluid display */
  --fs-label: 11px; --fs-xs: 12px; --fs-sm: 13px; --fs-md: 14px; --fs-base: 15px;
  --fs-lg: 17px; --fs-xl: 20px; --fs-2xl: 24px; --fs-3xl: 30px; --fs-4xl: 38px;
  --fs-display: clamp(30px, 4vw, 46px);

  /* Motion */
  --t-fast: 120ms; --t-base: 200ms; --t-slow: 320ms; --t-reveal: 600ms;
  --ease-standard: cubic-bezier(.2,.7,.2,1);
  --ease-enter: cubic-bezier(.16,1,.3,1);
  --ease-exit: cubic-bezier(.4,0,1,1);

  /* Spacing scale (4px grid) */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 20px; --s-6: 24px; --s-7: 32px; --s-8: 40px; --s-9: 56px;

  /* Radii — kept tight; this is an engineering brand, not a consumer app */
  --r-1: 3px; --r-2: 4px; --r-3: 6px; --r-4: 8px; --r-5: 10px; --r-full: 99px;
  --radius: var(--r-3);
  --radius-sm: var(--r-2);

  /* Elevation */
  --e-1: 0 1px 2px var(--k-06);
  --e-2: 0 1px 2px var(--k-06);
  --e-3: 0 2px 4px rgba(35,31,32,.07), 0 12px 28px rgba(35,31,32,.13);
  --shadow: var(--e-2);

  --max: 1160px;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; font-family: var(--font); color: var(--ink); background: var(--ground);
  font-size: var(--fs-base); line-height: 1.55; -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { margin: 0; line-height: 1.15; letter-spacing: -.01em; }
h1 { font-size: 34px; font-weight: 800; }
h2 { font-size: 22px; font-weight: 800; }
h3 { font-size: 18px; font-weight: 700; }
h4 { font-size: 15px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--cota-red); margin: 20px 0 6px; }
p { margin: 0 0 12px; }
a { color: var(--cota-red); }
button { font: inherit; }
input, select, textarea { font: inherit; }
.hidden { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.skip { position: absolute; left: 12px; top: -60px; z-index: 100; background: var(--cota-red); color: var(--cota-white);
  font-weight: 700; font-size: var(--fs-md); padding: 10px 16px; border-radius: 0 0 var(--r-2) var(--r-2); text-decoration: none;
  transition: top var(--t-base) var(--ease-standard); }
.skip:focus { top: 0; color: var(--cota-white); }

/* ---------- Layout ---------- */
.wrap { max-width: var(--max); margin: 0 auto; padding: 0 24px; }
main#app { padding-top: 28px; padding-bottom: 64px; }
.row { display: flex; gap: 16px; flex-wrap: wrap; }
.grow { flex: 1; }

/* ---------- Header ---------- */
.topbar { background: var(--cota-white); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 20; }
.topbar .wrap { display: flex; align-items: center; gap: 20px; height: 68px; }
.brand { display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit; }
.brand img { height: 40px; width: auto; display: block; }
.brand .wordmark { border-left: 1px solid var(--line); padding-left: 14px; line-height: 1.1; }
.brand .wordmark b { display: block; font-size: 13px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; }
.brand .wordmark span { font-size: 11px; color: var(--muted); letter-spacing: .08em; text-transform: uppercase; }
.nav { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.nav a, .nav button { text-decoration: none; color: var(--ink); background: none; border: 0; padding: 8px 12px; border-radius: 8px; font-weight: 600; font-size: 14px; cursor: pointer; }
.nav a:hover, .nav button:hover { background: var(--surface); }
.nav a.active { background: var(--cota-black); color: #fff; }
.nav .who { color: var(--muted); font-weight: 500; font-size: 13px; padding: 0 6px; }
.topprog { display: flex; align-items: center; gap: 10px; font-size: 12px; font-weight: 700; color: var(--muted); }
.topprog .bar { width: 110px; }

.bar { height: 8px; background: var(--surface); border: 1px solid var(--line); border-radius: 99px; overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--cota-red); border-radius: 99px; transition: width .5s cubic-bezier(.2,.7,.2,1); }

/* ---------- Buttons ---------- */
.btn { display: inline-flex; align-items: center; gap: 8px; padding: 10px 18px; border-radius: 8px; border: 1px solid transparent; font-weight: 700; font-size: 14px; cursor: pointer; text-decoration: none; transition: background .15s, transform .05s; white-space: nowrap; }
.btn:active { transform: translateY(1px); }
.btn.pri { background: var(--cota-red); color: #fff; }
.btn.pri:hover { background: var(--cota-red); filter: brightness(1.08); }
.btn.dark { background: var(--cota-black); color: #fff; }
.btn.dark:hover { background: var(--cota-black); filter: brightness(1.25); }
.btn.sec { background: #fff; color: var(--ink); border-color: var(--line); }
.btn.sec:hover { background: var(--surface); }
.btn.ghost { background: transparent; color: var(--ink); }
.btn.sm { padding: 7px 12px; font-size: 13px; }
.btn[disabled] { opacity: .55; cursor: not-allowed; }
.btn.danger { background: #fff; color: var(--cota-red); border-color: var(--cota-red); }

/* ---------- Forms ---------- */
.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--label); }
.field input, .field select { padding: 11px 12px; border: 1px solid var(--line); border-radius: 8px; background: #fff; font-size: 15px; }
.field input:focus, .field select:focus { outline: 2px solid var(--cota-red); outline-offset: 1px; border-color: var(--cota-red); }
.field .hint { font-size: 12px; color: var(--muted); }
.error { background: var(--red-tint); color: var(--red-dark); border: 1px solid rgba(236,30,36,.35); padding: 10px 12px; border-radius: 8px; font-size: 14px; font-weight: 600; }
.notice { background: var(--ok-tint); color: var(--ok); padding: 10px 12px; border-radius: 8px; font-size: 14px; font-weight: 600; }

/* ---------- Cards / panels ---------- */
.card { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); }
.panel { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; }
.panel h4 { margin-top: 0; }
.sec-h { display: flex; align-items: baseline; justify-content: space-between; margin: 28px 0 14px; }
.sec-h .hint { font-size: 12px; color: var(--muted); }
.eyebrow { font-size: 12px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--cota-red); }

/* ---------- Hero (dashboard) ---------- */
.hero { background: var(--cota-black); color: #fff; border-radius: var(--radius); padding: 36px 40px; display: flex; align-items: center; gap: 40px; position: relative; overflow: hidden; }
.hero::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 8px; background: var(--cota-red); }
.hero::after { content: ""; position: absolute; right: -80px; top: -80px; width: 320px; height: 320px; border-radius: 50%; border: 60px solid rgba(255,255,255,.04); }
.hero .htxt { flex: 1; position: relative; }
.hero .logo { height: 44px; margin-bottom: 18px; }
.hero h1 { font-size: 40px; margin: 8px 0 12px; }
.hero h1 .accent { color: var(--cota-red); }
.hero p { color: var(--cota-silver); max-width: 560px; font-size: 16px; }
.hero .ring { text-align: center; position: relative; }
.hero .ring .lbl { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--cota-silver); margin-top: 6px; }

/* ---------- Module grid ---------- */
.mgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr)); gap: 18px; }
.mcard { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; cursor: pointer; transition: transform .15s, box-shadow .15s; text-decoration: none; color: inherit; display: flex; flex-direction: column; }
.mcard:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.mcard .top { background: var(--cota-black); color: #fff; padding: 20px 20px 18px; position: relative; min-height: 132px; border-bottom: 4px solid var(--cota-red); }
.mcard .top .no { position: absolute; right: 18px; top: 12px; font-size: 44px; font-weight: 800; color: rgba(255,255,255,.14); letter-spacing: -.03em; }
.mcard .top .ic { width: 34px; height: 34px; color: var(--cota-red); margin-bottom: 12px; }
.mcard .top .ic svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.mcard .top h3 { font-size: 20px; color: #fff; }
.mcard .top .tag { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--cota-silver); margin-top: 6px; font-weight: 700; }
.mcard .bd { padding: 16px 20px 18px; display: flex; flex-direction: column; gap: 12px; flex: 1; }
.mcard .hook { color: var(--muted); font-size: 14px; margin: 0; flex: 1; }
.codes { display: flex; flex-wrap: wrap; gap: 6px; }
.code { font-family: var(--mono); font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 6px; background: var(--surface); border: 1px solid var(--line); color: var(--ink); }
.code.big { font-size: 12px; padding: 5px 10px; background: var(--red-tint); border-color: rgba(236,30,36,.35); color: var(--cota-red); font-family: var(--font); }
.mcard .meta { display: flex; justify-content: space-between; font-size: 12px; color: var(--muted); font-weight: 600; }
.mcard .meta b { color: var(--cota-red); }

/* ---------- Module page ---------- */
.crumbs { font-size: 13px; color: var(--muted); margin-bottom: 14px; display: flex; gap: 8px; align-items: center; }
.crumbs a { color: var(--ink); text-decoration: none; font-weight: 600; }
.crumbs a:hover { text-decoration: underline; }
.mhero { background: var(--cota-black); color: #fff; border-radius: var(--radius); padding: 32px 36px; position: relative; overflow: hidden; }
.mhero::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 8px; background: var(--cota-red); }
.mhero .ic { width: 36px; height: 36px; color: var(--cota-red); margin-bottom: 12px; }
.mhero .ic svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.mhero h1 { font-size: 34px; }
.mhero .hook { color: var(--cota-silver); max-width: 640px; font-size: 16px; margin: 10px 0 16px; }
.mhero .objline { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.mhero .objline .lab { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--cota-silver); font-weight: 700; margin-right: 4px; }
.mhero .code { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.2); color: #fff; }

.llist { display: flex; flex-direction: column; gap: var(--s-6); }
.lgroup { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.lrow { display: flex; align-items: center; gap: 16px; padding: 16px 20px; border-bottom: 1px solid var(--line); cursor: pointer; text-decoration: none; color: inherit; }
.lgroup .lrow:last-child { border-bottom: 0; }

/* ---------- Lesson sections (v2.14) ----------
   A module's lessons can sit under a named run ("Before Race Week"), with the
   rest carrying no heading. The unlabelled run gets a rule rather than a
   label, so the break reads as deliberate and not as a heading that failed to
   render. The list keeps its single border, so a heading has to sit inside it
   without looking like a row you can click. */
.lsec { margin: 0; padding: 14px 20px 8px; background: var(--surface-2);
  border-bottom: 1px solid var(--line); font-size: 11px; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase; color: var(--label); }
.lsec::before { content: ""; display: inline-block; width: 18px; height: 2px;
  background: var(--cota-red); vertical-align: middle; margin-right: 9px; }
.lgroup.unlabelled { border-left: 3px solid var(--cota-grey); }
.lgroup:has(.lsec) { border-left: 3px solid var(--cota-red); }

/* The same break inside the dashboard card's compact list. */
.lsec2 { padding: 9px 12px 4px; font-size: 10px; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase; color: var(--label); }
.lsecrule2 { height: 0; margin: 5px 12px; border-bottom: 1px solid var(--line-strong); }
.sectag { color: var(--cota-red); font-weight: 700; }
.lrow:hover { background: var(--surface-2); }
.lrow .stat { width: 32px; height: 32px; border-radius: 50%; border: 2px solid var(--line); display: grid; place-items: center; font-weight: 800; font-size: 13px; color: var(--muted); flex-shrink: 0; }
.lrow.done .stat { background: var(--cota-red); border-color: var(--cota-red); color: #fff; }
.lrow.started .stat { border-color: var(--cota-red); color: var(--cota-red); }
.lrow .lmain { flex: 1; }
.lrow h4 { margin: 0 0 6px; text-transform: none; letter-spacing: 0; color: var(--ink); font-size: 16px; }
.lrow .sub { display: flex; gap: 10px; align-items: center; font-size: 12px; color: var(--muted); flex-wrap: wrap; }
.pill { font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; padding: 3px 9px; border-radius: 99px; background: var(--surface); color: var(--muted); }
.pill.done { background: var(--red-tint); color: var(--red-dark); }
.pill.started { background: rgba(137,138,141,.18); color: var(--cota-black); }
.pill.ok { background: var(--ok-tint); color: var(--ok); }
.pill.revoked { background: var(--surface); color: var(--cota-black); text-decoration: line-through; }
.lrow .chev { color: var(--cota-grey); }

/* ---------- Lesson page ---------- */
.lesson { max-width: 860px; }
.lhead h1 { font-size: 32px; margin: 12px 0 8px; }
.lhead .dek { font-size: 17px; color: var(--muted); max-width: 720px; }
.ltabs { display: flex; gap: 4px; border-bottom: 2px solid var(--line); margin: 22px 0 18px; }
.ltab { padding: 10px 16px; font-weight: 700; font-size: 14px; color: var(--muted); cursor: pointer; border-bottom: 3px solid transparent; margin-bottom: -2px; background: none; border-top: 0; border-left: 0; border-right: 0; }
.ltab.active { color: var(--cota-red); border-bottom-color: var(--cota-red); }
.ltoolbar { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; }
.lpane { display: none; }
.lpane.show { display: block; }

.content { font-size: 16px; }
.content p { margin: 0 0 14px; }
.content ul { padding-left: 22px; margin: 0 0 14px; }
.content li { margin-bottom: 6px; }
.worked { background: #fff; border: 1px solid var(--line); border-left: 4px solid var(--cota-red); border-radius: var(--radius-sm); padding: 16px 18px; margin: 16px 0; }
.worked .wl { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--label); font-weight: 700; margin-bottom: 10px; }
.worked .step { display: flex; gap: 12px; align-items: baseline; padding: 6px 0; border-bottom: 1px dashed var(--line); }
.worked .step .n { color: var(--cota-red); font-weight: 800; font-family: var(--mono); font-size: 13px; }
.worked .ans { margin-top: 10px; font-weight: 800; color: var(--ok); }
.callout { display: flex; gap: 12px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px 16px; margin: 16px 0; }
.callout .cc { width: 26px; height: 26px; border-radius: 50%; background: var(--cota-black); color: #fff; display: grid; place-items: center; font-weight: 800; font-size: 13px; flex-shrink: 0; }
.callout.eco .cc { background: var(--cota-red); }

.activity { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); padding: 20px 22px; margin: 24px 0; }
.activity .ah { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.activity .ah .dot { width: 10px; height: 10px; border-radius: 50%; background: var(--cota-red); box-shadow: 0 0 0 4px var(--red-tint); }
.activity .ah b { font-size: 16px; }
.activity .ah .try { margin-left: auto; font-size: 10px; letter-spacing: .12em; text-transform: uppercase; font-weight: 800; color: var(--cota-red); border: 1px solid var(--cota-red); padding: 3px 8px; border-radius: 99px; }
.activity input[type=number], .activity input[type=text] { padding: 9px 11px; border: 1px solid var(--line); border-radius: 8px; width: 100%; font-size: 15px; }
/* The accent belongs to the control, not to the page it happens to be on.
   This used to live on `.activity input[type=range]`, and Present mode builds
   the widget in a bare `.plive` that is not inside an `.activity` — so on the
   projector, in front of a class, every slider was the operating system's
   default blue. Five brand colours, and a sixth arrived by omission. */
input[type=range] { accent-color: var(--cota-red); }
.activity input[type=range] { width: 100%; }
.activity .field { flex: 1; min-width: 160px; }
.statbig { font-size: 34px; font-weight: 800; color: var(--cota-red); line-height: 1; }
.stat-lbl { font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--label); font-weight: 700; margin-top: 4px; }
.small { font-size: 13px; color: var(--muted); }
.diagram { width: 100%; max-width: 520px; height: auto; display: block; margin: 0 auto; }
.toggles { display: flex; flex-wrap: wrap; gap: 10px 18px; margin: 12px 0 0; }
.toggle { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; cursor: pointer; }
.toggle input { accent-color: var(--cota-red); }
.barpair { display: flex; gap: 24px; align-items: flex-end; height: 150px; margin-top: 16px; }
.barcol { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; gap: 6px; }
.barcol .bar { width: 100%; max-width: 90px; border-radius: 6px 6px 0 0; height: 0; transition: height .3s; border: 0; background: var(--cota-red); }
.barcol .bv { font-weight: 800; font-size: 14px; }
.barcol .bl { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .08em; font-weight: 700; text-align: center; }
.sortlist { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }
.sortrow { display: flex; align-items: center; gap: 12px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px; padding: 9px 12px; }
.sortrow .idx { color: var(--muted); width: 18px; font-family: var(--mono); }
.sortrow b { flex: 1; }
.sortrow .t { font-family: var(--mono); font-weight: 700; }
.cardsort { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 8px; }
.cardsort .bucket { border: 2px dashed var(--line); border-radius: 10px; padding: 12px; min-height: 140px; }
.cardsort .bucket h5 { margin: 0 0 10px; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--cota-red); }
.cardsort .pool { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px; }
.cs-card { background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; font-size: 13px; font-weight: 600; cursor: pointer; display: flex; gap: 8px; align-items: center; margin-bottom: 8px; }
.cs-card:hover { border-color: var(--cota-red); }
.cs-card.right { border-color: var(--cota-red); background: var(--red-tint); }
.cs-card.wrong { border-color: var(--cota-grey); background: rgba(137,138,141,.18); text-decoration: line-through; }
.cs-card .mv { margin-left: auto; font-size: 11px; color: var(--muted); }

.quiz { background: var(--cota-black); color: #fff; border-radius: var(--radius); padding: 22px 24px; margin: 24px 0; }
.quiz .ql { font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--cota-silver); font-weight: 800; margin-bottom: 8px; }
.quiz .q { font-size: 18px; font-weight: 700; margin-bottom: 14px; }
.opts { display: grid; gap: 8px; }
.opt { display: flex; gap: 12px; align-items: center; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.14); border-radius: 10px; padding: 11px 14px; cursor: pointer; font-weight: 600; }
.opt:hover { background: rgba(255,255,255,.1); }
.opt .mk { width: 26px; height: 26px; border-radius: 50%; background: rgba(255,255,255,.12); display: grid; place-items: center; font-weight: 800; font-size: 12px; flex-shrink: 0; }
.opts.locked .opt { cursor: default; }
.opt.disabled { opacity: .5; }
/* The chosen answer, after the reveal. This was COTA red on a red wash, which
   is the exact mistake --correct was introduced to fix — and it survived here
   because the fix was applied to the feedback box underneath and not to the
   tile itself. The result was a red tile sitting directly above a green panel
   reading "Correct.", which is worse than either on its own: a child looks at
   the colour first and the sentence second.
   Green here, grey for wrong, each with its own glyph, same as the box. */
.opt.correct { background: rgba(4,106,56,.30); border-color: var(--correct); }
.opt.correct .mk { background: var(--correct); }
.opt.wrong { background: rgba(137,138,141,.22); border-color: var(--cota-grey); }
.opt.wrong .mk { background: var(--cota-grey); }
.feedback { display: none; margin-top: 14px; padding: 12px 14px; border-radius: 8px; font-size: 14px; }
.feedback.show { display: block; }
.feedback.ok { background: rgba(4,106,56,.30); }
.feedback.no { background: rgba(137,138,141,.22); }
.quiz .feedback { color: #fff; }
/* A right answer has to LOOK right. This went through two rounds before it
   landed. First it was COTA red on a red wash with no glyph at all, which
   Pauline read as having got the question wrong. Then it was a darkened red
   plus a tick, which passed AA and still read as an error to Jesse — because
   red means wrong, and a tick does not outvote a colour.
   It is green now. See --correct for why that is a system colour rather than a
   sixth brand colour, and why the wrong state stays grey instead of becoming
   the other half of a red/green pair. */
.activity .feedback.ok { background: var(--correct-tint); color: var(--correct); }
.feedback.ok::before { content: "\2713\00a0"; font-weight: 800; }
.activity .feedback.no { background: rgba(137,138,141,.18); color: var(--cota-black); }

.lnav { display: flex; gap: 10px; align-items: center; margin-top: 28px; padding-top: 20px; border-top: 1px solid var(--line); flex-wrap: wrap; }

/* Teacher plan */
.planmeta { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); gap: 14px; margin-bottom: 14px; }
.metacard { background: #fff; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px 16px; }
.metacard .ml { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--label); font-weight: 700; margin-bottom: 8px; }
.metacard ul { margin: 0; padding-left: 18px; font-size: 14px; }
.metacard li { margin-bottom: 4px; }
.metacard .dur { font-size: 34px; font-weight: 800; color: var(--cota-red); line-height: 1; }
.twocol { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 14px; }
.vocab .vrow { display: grid; grid-template-columns: 130px 1fr; gap: 10px; padding: 6px 0; border-bottom: 1px dashed var(--line); font-size: 14px; }
.vocab .vt { font-weight: 800; }
.timeline { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; }
.seg { display: grid; grid-template-columns: 120px 1fr; gap: 14px; background: #fff; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 12px 16px; }
.seg .tmin { display: block; font-weight: 800; color: var(--cota-red); }
.seg .tph { display: block; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); font-weight: 700; }
.seg h5 { margin: 0 0 4px; font-size: 14px; font-weight: 700; }
.seg .role { margin: 0; font-size: 13px; color: var(--muted); }
.panel.support { border-left: 4px solid var(--cota-grey); }
.panel.stretch { border-left: 4px solid var(--cota-red); }
.panel.hw { border-left: 4px solid var(--cota-black); }

/* Worksheet */
.ws { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); padding: 24px 28px; }
.wshead { display: flex; justify-content: space-between; gap: 20px; border-bottom: 2px solid var(--cota-black); padding-bottom: 12px; margin-bottom: 16px; }
.wshead .nm { font-size: 13px; color: var(--muted); text-align: right; line-height: 1.8; }
.wsFoot { display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap; margin-top: var(--s-6);
  padding-top: var(--s-5); border-top: 1px solid var(--line); color: var(--muted); }
.ws .intro { font-size: 15px; }
.wtask { margin: 14px 0; }
.wtask .qtext { display: flex; gap: 10px; font-weight: 600; }
.wtask .num { width: 24px; height: 24px; border-radius: 50%; background: var(--cota-black); color: #fff; display: grid; place-items: center; font-size: 12px; font-weight: 800; flex-shrink: 0; }
.wtask .ans-space { height: 58px; border-bottom: 1px solid var(--line); margin-left: 34px; }
.wtask .tans { display: none; margin: 8px 0 0 34px; font-size: 13px; color: var(--ok); font-weight: 600; }
.ws.show-ans .tans { display: block; }
.ws.show-ans .ans-space { height: 12px; }
.answers-toggle { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; color: var(--muted); cursor: pointer; margin-bottom: 8px; user-select: none; }

/* ---------- Present mode ---------- */
.present { position: fixed; inset: 0; background: var(--cota-black); color: #fff; z-index: 100; display: none; flex-direction: column; }
.present.on { display: flex; }
.pslide { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; justify-content: center;
  padding: clamp(24px, 6vh, 60px) min(12vw, 160px); max-width: 1400px; margin: 0 auto; width: 100%; }
.pey { font-size: clamp(13px, 1.3vw, 18px); letter-spacing: .18em; text-transform: uppercase; color: var(--cota-red); font-weight: 800; margin-bottom: 18px; display: flex; align-items: center; gap: 12px; }
.pey::before { content: ""; width: 34px; height: 4px; background: var(--cota-red); flex: none; }
/* The eyebrow icon. Sized off the eyebrow text so it holds its proportion from
   the back of a room, and it inherits the eyebrow's red rather than bringing a
   colour of its own. */
.pey-i { width: 1.5em; height: 1.5em; flex: none; }
.pey > span { min-width: 0; }
.pslide h2 { font-size: clamp(30px, 5vw, 68px); font-weight: 800; letter-spacing: -.02em; margin-bottom: 22px; }
.pbody { font-size: clamp(18px, 2vw, 28px); color: var(--cota-silver); line-height: 1.5; max-width: 1000px; }
.pbody ul { padding-left: 1.1em; }
.pbody li { margin-bottom: .4em; }
.pbody b { color: #fff; }

/* The discussion picture, on the Big question and Plenary slides.
   It keeps its own COTA-silver ground rather than being cut out: the artwork
   has white bubbles in it, and knocking the background out would leave those
   floating invisibly on a light surface and shouting on a dark one. As a
   self-contained card on the black slide it stays the picture Jesse drew.
   Left-aligned, not centred, because everything else on the slide is. */
/* max-width AND max-height, with the size left to the picture. The first
   version set width:940px and let object-fit shrink the painting inside it,
   which gave the element a box more than twice the width of what it painted —
   and border-radius rounds the BOX. The result was a card with two rounded
   corners on the left and two square ones on the right, which is what Jesse
   spotted. Sized this way the box is the picture, so all four corners are its
   own.

   align-self matters as much as the sizing: the slide is a flex column, so a
   block child is stretched to the full width unless it is told not to be, and
   a stretched img with no object-fit is a squashed img. */
.ptalk { display: block; align-self: flex-start; width: auto; height: auto;
  max-width: min(100%, 940px); max-height: 34vh;
  margin: clamp(14px, 3vh, 30px) 0 0; border-radius: 12px; }
/* On the plenary it follows the success criteria and takes the smaller share:
   the list is the thing the class is reading, the picture is not.
   34 and 24 are not taste: they are the largest pair that leaves every Big
   question and Plenary in the course fitting on a 1024x576 projector without
   scrolling. 36 pushes the longest big question — "What is F1 ACADEMY, and how
   does its car compare..." — seven pixels off the bottom. */
.pbody + .ptalk { max-height: 24vh; }
/* A projector in a short window has no room for both; the words win. */
@media (max-height: 560px) { .ptalk { display: none; } }

/* ---------- The live interactives on a slide (v2.15) ----------
   Every widget was built for a light column about 700px wide and is now being
   asked to work on a dark screen across a classroom. Rather than restyle
   thirteen widgets one by one, a widget gets a light card to sit on: it keeps
   the exact appearance it has on the lesson page, which is also the appearance
   the teacher already knows, and there is nothing to keep in step twice.

   The quiz does NOT get the card. It is already a dark panel by design and it
   reads correctly on a slide as it is; wrapping it in white and then undoing
   the white again is fighting the design rather than using it.

   `.plive` is also what the keyboard handler looks for, so both carry it. */
.plive { max-width: 1100px; width: 100%; align-self: flex-start;
  margin-top: clamp(14px, 2vh, 26px); max-height: 58vh; overflow: auto; }
.plive.card { background: var(--cota-white); color: var(--ink); border-radius: var(--r-3);
  padding: clamp(16px, 2vh, 28px) clamp(18px, 2vw, 32px); font-size: clamp(15px, 1.15vw, 19px); }

/* The size bump is the part that matters: at the back of a room a 13px label
   is not there at all. The widgets set their type against a 15px page. */
.plive .small, .plive .ql, .plive .ah, .plive label { font-size: clamp(13px, 1vw, 16px); }
.plive .statbig { font-size: clamp(30px, 3vw, 46px); }
.plive input[type="number"], .plive input[type="text"], .plive select { font-size: clamp(15px, 1.2vw, 20px); }
.plive input[type="range"] { height: 28px; }
.plive .cs-card, .plive .cs-place { font-size: clamp(13px, 1.05vw, 17px); }
.plive svg { max-height: 40vh; height: auto; }

/* The quiz, at a size a class can read from the back. */
.plive .quiz { margin: 0; padding: clamp(14px, 2vh, 24px) clamp(16px, 2vw, 28px); }
.plive .quiz .q { font-size: clamp(18px, 1.7vw, 27px); }
.plive .quiz .opt { font-size: clamp(15px, 1.3vw, 22px); padding: clamp(9px, 1.2vh, 15px) clamp(11px, 1vw, 18px); }
.plive .quiz .feedback { font-size: clamp(14px, 1.1vw, 19px); }

/* A check slide's question IS the slide heading, so the copy of it inside the
   quiz is the same sentence twice, in two sizes, on one screen. The eyebrow
   already says which check it is, so that label goes too. */
.pslide.live-quiz .plive .quiz .q,
.pslide.live-exit .plive .quiz .q,
.pslide.live-quiz .plive .quiz .ql,
.pslide.live-exit .plive .quiz .ql { display: none; }

/* And the heading gives up some size: four lines of 68px question leaves no
   room for the four answers underneath it. */
.pslide.live-quiz h2, .pslide.live-exit h2 { font-size: clamp(22px, 2.9vw, 42px); margin-bottom: 14px; }
.pslide.live-quiz .plive, .pslide.live-exit .plive { max-height: 62vh; }

@media (max-width: 900px) { .plive { max-height: 46vh; } }
.pbar { display: flex; align-items: center; gap: 12px; padding: 14px 24px; background: rgba(255,255,255,.06); border-top: 1px solid rgba(255,255,255,.08); }
.pbar button { background: rgba(255,255,255,.1); color: #fff; border: 0; padding: 8px 14px; border-radius: 8px; font-weight: 700; cursor: pointer; }
.pbar button:hover { background: rgba(255,255,255,.18); }
.pbar button.x { background: var(--cota-red); }
.pbar .dots { display: flex; gap: 6px; }
.pbar .dots i { width: 7px; height: 7px; border-radius: 50%; background: rgba(255,255,255,.25); }
.pbar .dots i.on { background: var(--cota-red); }
.pbar .pc { font-size: 12px; color: var(--cota-silver); font-family: var(--mono); }
.pbar .plogo { height: 26px; opacity: .9; }

/* ---------- Auth ---------- */
.auth { max-width: 460px; margin: 30px auto; }
.auth .card { padding: 30px 32px; }
.auth h1 { font-size: 26px; margin-bottom: 4px; }
.auth .sub { color: var(--muted); margin-bottom: 20px; }
.auth form { display: flex; flex-direction: column; gap: 14px; }
.auth .switch { text-align: center; font-size: 14px; color: var(--muted); margin-top: 16px; }
.auth .switch a { font-weight: 700; }
.auth .switch .small { display: inline-block; margin-top: var(--s-2); font-size: var(--fs-sm); }
.authhero { background: var(--cota-black); color: #fff; border-radius: var(--radius); padding: 28px 32px; margin-bottom: 20px; position: relative; overflow: hidden; }
.authhero::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 8px; background: var(--cota-red); }
.authhero img { height: 40px; margin-bottom: 14px; }
.authhero h2 { font-size: 24px; }
.authhero p { color: var(--cota-silver); margin: 8px 0 0; }

/* ---------- Dashboard tiles / tables ---------- */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(170px, 100%), 1fr)); gap: 14px; }
.tile { background: #fff; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 16px 18px; }
.tile .v { font-size: 30px; font-weight: 800; color: var(--cota-red); line-height: 1; }
.tile .l { font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--label); font-weight: 700; margin-top: 8px; }
.tablewrap { overflow-x: auto; background: #fff; border: 1px solid var(--line); border-radius: var(--radius); }
table.tbl { border-collapse: collapse; width: 100%; font-size: 13px; }
.tbl th, .tbl td { padding: 10px 12px; border-bottom: 1px solid var(--line); text-align: left; white-space: nowrap; vertical-align: middle; }
.tbl th { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--label); background: var(--surface-2); position: sticky; top: 0; }
.tbl tr:last-child td { border-bottom: 0; }
.tbl td.c, .tbl th.c { text-align: center; }
.cell { width: 22px; height: 22px; border-radius: 6px; display: inline-grid; place-items: center; font-size: 11px; font-weight: 800; }
.cell.done { background: var(--cota-red); color: #fff; }
.cell.started { background: var(--red-tint); color: var(--red-dark); }
.cell.none { background: var(--surface); color: var(--cota-silver); }
.cell.quiz-ok { box-shadow: inset 0 0 0 2px var(--cota-black); }
.cell.quiz-no { box-shadow: inset 0 0 0 2px var(--cota-grey); }
.legend { display: flex; gap: 16px; font-size: 12px; color: var(--muted); flex-wrap: wrap; align-items: center; margin: 10px 0; }
.legend span { display: inline-flex; gap: 6px; align-items: center; }
.classcard { padding: 18px 20px; display: flex; flex-direction: column; gap: 10px; }
.joincode { font-family: var(--mono); font-size: 26px; font-weight: 800; letter-spacing: .14em; color: var(--cota-red); }
.modbar { display: grid; grid-template-columns: minmax(200px, 280px) 1fr 56px; gap: 12px; align-items: center;
  padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
.modbar:last-child { border-bottom: 0; }
.modbar .small { display: block; color: var(--label); }

.empty { text-align: center; color: var(--muted); padding: 40px 20px; }
.empty b { display: block; color: var(--ink); font-size: 16px; margin-bottom: 6px; }
.toast { position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%); background: var(--cota-black); color: #fff; padding: 12px 18px; border-radius: 10px; font-weight: 600; font-size: 14px; z-index: 200; box-shadow: var(--shadow); }
.foot { text-align: center; color: var(--muted); font-size: 12px; padding: 30px 0 10px; }

/* ---------- Print (teacher plan / worksheet) ---------- */
#printroot { display: none; }
/* Every worksheet handed to a class is printed from a browser, so the browser's
   own header and footer land on it — including the worker URL across the top of
   a pupil's sheet. One rule removes them, and sets a real margin. */
@page { margin: 16mm 14mm; }

@media print {
  body { background: #fff; }
  .topbar, main#app, .present, .toast { display: none !important; }
  /* 12.5px is about 9.4pt. Print wants 12pt or more, and this is read by
     twelve-year-olds off a photocopy. 17px ≈ 12.75pt. */
  #printroot { display: block; font-size: 17px; line-height: 1.45; color: #231F20; }
  .pr-head { display: flex; align-items: center; gap: 14px; border-bottom: 3px solid var(--cota-red); padding-bottom: 10px; margin-bottom: 16px; }
  .pr-head img { height: 34px; }
  .pr-title b { display: block; font-size: 12px; letter-spacing: .12em; text-transform: uppercase; }
  .pr-title span { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: #898A8D; }
  .pr-meta { margin-left: auto; text-align: right; font-size: 11px; color: #231F20; line-height: 1.5; }
  #printroot h1 { font-size: 24px; margin: 0 0 4px; }
  #printroot h3 { font-size: 13px; text-transform: uppercase; letter-spacing: .08em; color: var(--cota-red); margin: 16px 0 8px; }
  .lead { color: rgba(35,31,32,.7); margin-bottom: 12px; }
  .pr-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
  .pr-box { border: 1px solid #D0D4D5; border-radius: 6px; padding: 10px 12px; }
  .pr-box .t { font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: #898A8D; font-weight: 700; margin-bottom: 6px; }
  .pr-box ul { margin: 0; padding-left: 16px; }
  .prseg { display: grid; grid-template-columns: 90px 1fr; gap: 10px; padding: 6px 0; border-bottom: 1px dashed #D0D4D5; }
  .prseg .a { font-weight: 800; color: var(--cota-red); }
  .pr-task { margin: 12px 0; break-inside: avoid; }
  .pr-space { height: 62px; border-bottom: 1px solid #898A8D; margin-top: 6px; }
  .pr-ans { color: var(--cota-red); font-weight: 700; margin-top: 4px; }
}

/* ---------- Responsive ---------- */
@media (max-width: 820px) {
  .topbar .wrap { height: auto; padding-top: 10px; padding-bottom: 10px; flex-wrap: wrap; gap: 10px; }
  .brand .wordmark { display: none; }
  .topprog .bar { width: 70px; }
  .hero { flex-direction: column; align-items: flex-start; padding: 26px 24px; gap: 20px; }
  .hero h1 { font-size: 30px; }
  .mhero { padding: 24px 22px; }
  .mhero h1 { font-size: 26px; }
  .twocol, .cardsort { grid-template-columns: 1fr; }
  .seg { grid-template-columns: 1fr; gap: 6px; }
  .lhead h1 { font-size: 26px; }
  .modbar { grid-template-columns: 1fr; gap: 4px; }
}

/* =========================================================
   v1.1 — design-system additions: motion, spacing, focus,
   dialog, skeletons, 3D hero, tilt cards, stepper
   ========================================================= */

/* Focus rings — every interactive element */
:focus-visible { outline: 3px solid var(--cota-red); outline-offset: 2px; border-radius: 6px; }
.mcard:focus-visible, .lrow:focus-visible, .classcard:focus-visible { outline-offset: 3px; }
.opt:focus-visible, .cs-card:focus-visible { outline-color: #fff; }
.quiz .opt:focus-visible { outline-color: var(--cota-red); }

/* Buttons: press + hover motion */
.btn { transition: background var(--t-fast), transform var(--t-fast) var(--ease-standard), box-shadow var(--t-fast); }
.btn:hover { transform: translateY(-1px); box-shadow: var(--e-1); }
.btn:active { transform: translateY(1px) scale(.99); box-shadow: none; }
.btn.pri { box-shadow: 0 4px 14px rgba(236,30,36,.28); }
.btn.pri:hover { box-shadow: 0 6px 18px rgba(236,30,36,.36); }

/* Reveal on scroll */
[data-reveal] { opacity: 0; transform: translateY(14px); transition: opacity var(--t-reveal) var(--ease-enter) var(--stagger, 0ms), transform var(--t-reveal) var(--ease-enter) var(--stagger, 0ms); }
[data-reveal].is-in { opacity: 1; transform: none; }

/* Tabs underline slide */
.ltab { transition: color var(--t-base), border-color var(--t-base); position: relative; }
.ltab::after { content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 3px; background: var(--cota-red); transform: scaleX(0); transform-origin: left; transition: transform var(--t-slow) var(--ease-standard); }
.ltab.active { border-bottom-color: transparent; }
.ltab.active::after { transform: scaleX(1); }

/* Progress bars fill from zero */
.bar > i { width: 0; transition: width var(--t-reveal) var(--ease-standard) 120ms; }

/* Lesson stepper */
.stepper { display: flex; align-items: center; gap: 8px; margin: 6px 0 14px; font-size: 12px; color: var(--muted); font-weight: 700; letter-spacing: .04em; }
.stepper .steps { display: flex; gap: 5px; }
.stepper .steps i { width: 26px; height: 5px; border-radius: 99px; background: var(--line); display: block; transition: background var(--t-base); }
.stepper .steps i.done { background: var(--cota-red); }
.stepper .steps i.cur { background: var(--cota-black); }

/* Reading progress on lesson pages */
.readprog { position: fixed; left: 0; top: 0; height: 3px; width: 0; background: var(--cota-red); z-index: 30; transition: width 80ms linear; }

/* Next-lesson card */
.nextcard { margin-top: 28px; background: var(--cota-black); color: #fff; border-radius: var(--radius); padding: 22px 26px; display: flex; align-items: center; gap: 18px; position: relative; overflow: hidden; text-decoration: none; }
.nextcard::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 8px; background: var(--cota-red); }
.nextcard .eyebrow { color: var(--cota-silver); }
.nextcard h3 { color: #fff; margin-top: 4px; }
.nextcard .go { margin-left: auto; }

/* Quiz feedback motion */
@keyframes pop { 0% { transform: scale(.98); } 60% { transform: scale(1.02); } 100% { transform: scale(1); } }
@keyframes shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }
.opt.correct { animation: pop var(--t-slow) var(--ease-enter); }
.opt.wrong { animation: shake var(--t-slow) var(--ease-standard); }
.feedback.show { animation: pop var(--t-slow) var(--ease-enter); }

/* Completion state */
@keyframes ringpulse { 0% { box-shadow: 0 0 0 0 rgba(236,30,36,.5); } 100% { box-shadow: 0 0 0 18px rgba(236,30,36,0); } }
.lrow.done .stat, .btn.just-done { animation: ringpulse .9s var(--ease-standard) 1; }
.confetti { position: fixed; inset: 0; pointer-events: none; z-index: 150; }

/* Dialog */
.dlg { border: 0; border-radius: var(--radius); padding: 0; max-width: 460px; width: calc(100% - 32px); box-shadow: var(--e-3); background: #fff; color: var(--ink); }
.dlg::backdrop { background: rgba(35,31,32,.55); backdrop-filter: blur(2px); }
.dlg-in { padding: 24px 26px; display: flex; flex-direction: column; gap: 12px; animation: pop var(--t-slow) var(--ease-enter); }
.dlg h3 { font-size: 20px; }
.dlg p { color: var(--muted); margin: 0; }
.dlg-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 6px; }
.dlg.closing .dlg-in { opacity: 0; transform: scale(.98); transition: opacity var(--t-fast), transform var(--t-fast); }
.dlg label .optional { font-weight: 500; color: var(--label); text-transform: none; letter-spacing: 0; }
.dlg-err { margin: 0; font-size: var(--fs-sm); font-weight: 700; color: var(--cota-black);
  border-left: 3px solid var(--cota-red); background: var(--red-tint); padding: var(--s-3) var(--s-4); border-radius: var(--r-2); }
.copybox { display: flex; align-items: center; gap: 10px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; }
.copybox code { font-family: var(--mono); font-size: 18px; font-weight: 800; letter-spacing: .1em; color: var(--cota-red); flex: 1; }
.invcode { font-family: var(--mono); font-size: var(--fs-sm); font-weight: 700; letter-spacing: .06em; }

/* Skeletons */
@keyframes shimmer { 0% { background-position: -400px 0; } 100% { background-position: 400px 0; } }
.sk { background: linear-gradient(90deg, rgba(208,212,213,.45) 0%, rgba(208,212,213,.18) 50%, rgba(208,212,213,.45) 100%); background-size: 800px 100%; animation: shimmer 1.4s linear infinite; border-radius: 10px; }
.sk.hero { height: 340px; border-radius: var(--radius); }
.sk.card { height: 320px; }
.sk.row { height: 72px; margin-bottom: 8px; }
.sk.line { height: 14px; margin: 8px 0; }

/* Join code display for projecting */
.codewall { text-align: center; padding: 20px 0 6px; }
.codewall .joincode { font-size: clamp(40px, 9vw, 96px); letter-spacing: .2em; }
.codewall .small { margin-top: 6px; }

/* Larger touch targets in widgets */
.sortrow .btn.sm { min-width: 44px; min-height: 40px; justify-content: center; }
.hill3d { width: 100%; height: 260px; border-radius: 10px; background: var(--cota-black); display: block; margin: 8px 0 12px; }

/* Turn 1 hill: the run controls under the canvas. The button is first in the
   row because the run is the point and the slider is the override. */
.kerow { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.kerow input[type=range] { flex: 1 1 180px; min-width: 140px; margin: 0; }
.ke-where { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); min-width: 10.5em; }
/* The bars ease by default, which reads well when a teacher drags the slider
   and reads as mush at sixty frames a second. The run turns the easing off. */
.kerun .barcol .bar { transition: none; }
@media (max-width: 520px) { .ke-where { min-width: 0; } }

/* Toast motion */
@keyframes toastin { from { opacity: 0; transform: translate(-50%, 12px); } to { opacity: 1; transform: translate(-50%, 0); } }
.toast { animation: toastin var(--t-slow) var(--ease-enter); }

/* View transitions */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: 120ms var(--ease-exit) both fade-out; }
::view-transition-new(root) { animation: 220ms var(--ease-enter) both fade-in; }
@keyframes fade-in { from { opacity: 0; transform: translateY(6px); } }
@keyframes fade-out { to { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
  [data-reveal] { opacity: 1; transform: none; }
  .mcard2:hover { transform: none; }
  .bar > i { transition: none; }
}

/* =========================================================
   v1.8 — full-bleed bands, brand-weighted palette,
   quick-jump palette, expandable module cards
   ========================================================= */
body.home main#app, body.bands main#app { max-width: none; padding: 0 0 0; }
.shell2 { max-width: var(--max); margin: 0 auto; padding: 0 var(--s-6); }
.band { position: relative; }
.band + .band { margin-top: 0; }
.band-light { padding: clamp(44px, 6.5vh, 76px) 0; background: var(--ground); }
.band-dark { padding: clamp(44px, 6.5vh, 76px) 0; background: var(--cota-black); color: var(--cota-white); }
.band-dark::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px; background: var(--cota-red); }
.band-rule { border-top: 1px solid var(--line); }

/* ---- Section headings ---- */
.secH { font-size: var(--fs-2xl); font-weight: 800; letter-spacing: -.022em; display: flex; align-items: baseline; gap: var(--s-3); }
.secH::before { content: ""; width: 26px; height: 3px; background: var(--cota-red); flex: none; align-self: center; }
.secH.sm { font-size: var(--fs-xl); }
.band-dark .secH { color: var(--cota-white); }
.secHead { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s-6); flex-wrap: wrap;
  margin-bottom: var(--s-6); padding-bottom: var(--s-4); border-bottom: 1px solid var(--line); }
.band-dark .secHead { border-bottom-color: var(--w-12); }
.secHead .note { font-size: var(--fs-md); color: var(--muted); max-width: 50ch; margin: 0; }
.band-dark .secHead .note { color: var(--cota-silver); }
.note.pad { padding: var(--s-4) 0; color: var(--muted); }
/* --muted is COTA Black at 70% — on a dark band it is invisible (1:1). */
.band-dark .note, .band-dark .note.pad, .band-dark .hint { color: var(--cota-silver); }

/* ---- Hero ---- */
.hero2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.04fr); gap: clamp(28px, 4.5vw, 64px); align-items: center; }
.hero2 .eyebrow { font-family: var(--mono); letter-spacing: .22em; }
.hero2 h1 { font-size: var(--fs-display); font-weight: 800; line-height: 1.02; letter-spacing: -.03em; margin: var(--s-4) 0 var(--s-4); }
.hero2 h1 .acc { color: var(--cota-red); }
.hero2-copy { color: var(--cota-silver); font-size: var(--fs-lg); max-width: 42ch; margin: 0 0 var(--s-6); }
.hero2 .heroRow { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.hero2 .btn.sec { background: transparent; color: var(--cota-white); border-color: var(--w-20); }
.hero2 .btn.sec:hover { background: var(--w-06); border-color: var(--cota-white); }

/* Continue card — red rail, mono meta */
.nextCard-in { display: grid; gap: var(--s-1); text-decoration: none; color: var(--cota-white); position: relative;
  background: var(--w-06); border: 1px solid var(--w-12); border-left: 3px solid var(--cota-red); border-radius: var(--r-3);
  padding: var(--s-5) var(--s-5) var(--s-4); transition: background var(--t-base), border-color var(--t-base), transform var(--t-base) var(--ease-standard); }
.nextCard-in:hover, .nextCard-in:focus-visible { background: var(--w-12); border-color: var(--w-20); border-left-color: var(--cota-red); transform: translateX(3px); }
.nextCard-in .k { font-family: var(--mono); font-size: var(--fs-label); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--cota-silver); }
.nextCard-in .ti { font-size: var(--fs-xl); font-weight: 800; letter-spacing: -.015em; line-height: 1.18; }
.nextCard-in .mt { font-family: var(--mono); font-size: var(--fs-xs); color: var(--cota-silver); }
.nextCard-in .go { margin-top: var(--s-3); font-size: var(--fs-md); font-weight: 800; color: var(--red-on-dark); display: inline-flex; align-items: center; gap: var(--s-2); }
.nextCard-in .go b { transition: transform var(--t-base) var(--ease-standard); }
.nextCard-in:hover .go b { transform: translateX(5px); }

/* ---- Circuit map ---- */
.hero2-map { min-width: 0; }
.mapHold { position: relative; }
.circuit { width: 100%; height: auto; display: block; overflow: visible; }
.circuit .base { fill: none; stroke: var(--cota-grey); stroke-opacity: .55; stroke-width: 14; stroke-linejoin: round; stroke-linecap: round; }
.circuit .hi { fill: none; stroke: var(--cota-red); stroke-width: 14; stroke-linejoin: round; stroke-linecap: round; opacity: 0;
  filter: drop-shadow(0 0 9px rgba(236,30,36,.55)); }
.circuit .pulse { fill: none; stroke: var(--cota-red); stroke-width: 14; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 140 4000; filter: drop-shadow(0 0 10px var(--cota-red)); }
/* The qualifying lap: the stretch of circuit that is run before the race
   counts. Silver, because red already means "the module you are pointing at",
   and brighter than the base so it reads as part of the course rather than as
   track nobody uses. */
.circuit .qual { fill: none; stroke: var(--cota-silver); stroke-opacity: .95; stroke-width: 14;
  stroke-linejoin: round; stroke-linecap: round; filter: drop-shadow(0 0 7px rgba(208, 212, 213, .5)); }
.dot.qualdot .mk { stroke: var(--cota-silver); }

.dot { cursor: pointer; }
.dot .hit { fill: transparent; }
.dot .mk { fill: var(--cota-black); stroke: var(--cota-grey); stroke-width: 5;
  transition: fill var(--t-base), stroke var(--t-base), r var(--t-base) var(--ease-standard); }
.dot.part .mk { stroke: var(--cota-red); }
.dot.done .mk { fill: var(--cota-red); stroke: var(--cota-red); }
.dot.seen .mk { fill: var(--cota-red); fill-opacity: calc(.28 + var(--cover, 0) * .72); stroke: var(--cota-red); }
.dot.next .mk { fill: var(--cota-white); stroke: var(--cota-red); stroke-width: 7; }
.dot.next .hit { animation: dotpulse 2.4s var(--ease-standard) infinite; transform-box: fill-box; transform-origin: center; }
@keyframes dotpulse { 0% { stroke: var(--cota-red); stroke-width: 0; stroke-opacity: .8; } 70%, 100% { stroke: var(--cota-red); stroke-width: 10; stroke-opacity: 0; } }
.dot:hover .mk, .dot:focus-visible .mk { r: 18; fill: var(--cota-red); stroke: var(--cota-white); }
.dot:focus-visible { outline: none; }
.dot:focus-visible .mk { stroke: var(--cota-white); stroke-width: 7; }
#dots.focus .dot:not(.inband) { opacity: .25; }
#dots .dot { transition: opacity var(--t-base); }

/* Hover card — title, dek, state */
.mapTip { position: absolute; z-index: 5; transform: translate(-50%, calc(-100% - 20px)); width: 264px;
  background: var(--cota-white); color: var(--ink); border-radius: var(--r-3); border-top: 3px solid var(--cota-red);
  padding: var(--s-4); box-shadow: var(--e-3); pointer-events: none; }
.mapTip .n { font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .14em; text-transform: uppercase; color: var(--cota-red); }
.mapTip b { display: block; font-size: var(--fs-lg); line-height: 1.2; margin: var(--s-1) 0 var(--s-2); letter-spacing: -.01em; }
.mapTip .dek { display: block; font-size: var(--fs-sm); color: var(--muted); line-height: 1.45; }
.mapTip .st { display: inline-block; margin-top: var(--s-3); font-family: var(--mono); font-size: var(--fs-label);
  letter-spacing: .1em; text-transform: uppercase; color: var(--label); }
.mapTip .st.on { color: var(--cota-red); }
.mapTip.flip { transform: translate(-50%, 20px); border-top: 0; border-bottom: 3px solid var(--cota-red); }
.mapFoot { margin: var(--s-4) 0 0; font-size: var(--fs-sm); color: var(--cota-silver); min-height: 2.8em; max-width: 52ch; }
.mapKeys { margin: var(--s-2) 0 0; font-family: var(--mono); font-size: var(--fs-label); color: var(--cota-grey); letter-spacing: .06em; }
.mapKeys kbd { border-color: var(--w-20); background: var(--w-06); color: var(--cota-silver); }
@media (pointer: coarse) { .mapKeys { display: none; } }
.hero2-ring svg circle:last-of-type { animation: ringdraw 1200ms var(--ease-enter) 200ms both; }
@keyframes ringdraw { from { stroke-dashoffset: var(--c, 400); } }
.hero2-ring { display: flex; align-items: center; gap: var(--s-5); margin-top: var(--s-6);
  padding-top: var(--s-5); border-top: 1px solid var(--w-12); }
.hero2-ring .rl { min-width: 0; flex: 1; }
.hero2-ring .rl b { display: block; font-size: var(--fs-2xl); font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.hero2-ring .rl span { display: block; font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .12em;
  text-transform: uppercase; color: var(--cota-silver); margin-top: 2px; }
.hero2-ring .rb { display: block; height: 3px; background: var(--w-12); margin-top: var(--s-3); overflow: hidden; }
.hero2-ring .rb i { display: block; height: 100%; width: 0; background: var(--cota-red); transition: width var(--t-reveal) var(--ease-standard) 400ms; }

/* ---- Data band: figures on black, red numerals ---- */
.tiles2 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.tile2 { padding: var(--s-5) var(--s-6) var(--s-5) 0; border-right: 1px solid var(--w-12); position: relative; }
.tile2:last-child { border-right: 0; }
.tile2:not(:first-child) { padding-left: var(--s-6); }
.tile2 .v { font-size: clamp(38px, 4.6vw, 58px); font-weight: 800; line-height: .95; letter-spacing: -.04em;
  font-variant-numeric: tabular-nums; color: var(--cota-red); }
.tile2 .v i { font-style: normal; color: var(--cota-silver); font-size: .42em; letter-spacing: 0; margin-left: .06em; }
.tile2 .v i.none { color: var(--cota-grey); font-size: .6em; margin: 0; }
.tile2 .l { font-family: var(--mono); font-size: var(--fs-label); color: var(--cota-silver); margin-top: var(--s-3);
  letter-spacing: .1em; text-transform: uppercase; line-height: 1.5; }

/* Per-module segments, on the dark band */
.segwrap2 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-6); margin-top: var(--s-7);
  padding-top: var(--s-6); border-top: 1px solid var(--w-12); }
.seg2 .sl { display: flex; justify-content: space-between; gap: var(--s-2); font-size: var(--fs-xs); font-weight: 700; margin-bottom: var(--s-3); color: var(--cota-white); }
.seg2 .sl b { color: var(--cota-white); font-family: var(--mono); font-variant-numeric: tabular-nums; }
.segbar2 { height: 4px; background: var(--w-12); overflow: hidden; }
.segbar2 i { display: block; height: 100%; width: 0; background: var(--cota-red); transition: width var(--t-reveal) var(--ease-standard) 120ms; }

/* Keyboard hints */
kbd { font-family: var(--mono); font-size: var(--fs-label); border: 1px solid var(--line-strong); border-bottom-width: 2px;
  border-radius: var(--r-1); padding: 2px 6px; background: var(--surface-2); }

/* Five cards fit a desktop and do not fit a laptop. Three is the step that
   keeps a card wide enough to read its hook. */
@media (max-width: 1180px) {
  .mgrid2 { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
}

/* ---- Module cards ---- */
.mgrid2 { display: grid; grid-template-columns: repeat(var(--mcols, 4), minmax(0, 1fr)); gap: var(--s-4); align-items: stretch; }
.mcard2 { background: var(--ground); border: 1px solid var(--line); border-radius: var(--r-4); overflow: hidden;
  display: flex; flex-direction: column; position: relative; transition: box-shadow var(--t-slow), border-color var(--t-base), transform var(--t-slow) var(--ease-standard); }
.mcard2:hover, .mcard2:focus-within, .mcard2.lit { box-shadow: var(--e-3); border-color: var(--cota-red); transform: translateY(-3px); }
.mcard2.is-next { border-color: var(--cota-red); border-top: 3px solid var(--cota-red); }
.mcard2 .top { background: var(--cota-black); color: var(--cota-white); padding: var(--s-5); position: relative;
  border-bottom: 3px solid var(--cota-red); text-decoration: none;
  display: flex; flex-direction: column; min-height: 168px; }
.mcard2 .top h3 { margin-top: auto; }
.mcard2 .top::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity var(--t-base);
  background: radial-gradient(300px 140px at var(--mx, 50%) var(--my, 50%), var(--w-12), transparent 65%); }
.mcard2:hover .top::after, .mcard2.lit .top::after { opacity: 1; }
.mcard2 .ic { width: 26px; height: 26px; color: var(--cota-red); margin-bottom: var(--s-3); }
.mcard2 .ic svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
  transition: transform var(--t-slow) var(--ease-enter); }
.mcard2:hover .ic svg, .mcard2.lit .ic svg { transform: translateX(4px); }
.mcard2 .no { position: absolute; right: var(--s-5); top: var(--s-4); font-family: var(--mono); font-size: var(--fs-2xl);
  font-weight: 700; color: var(--w-20); letter-spacing: -.02em; }
.mcard2 .top h3 { font-size: var(--fs-lg); color: var(--cota-white); line-height: 1.2; letter-spacing: -.01em; }
.mcard2 .top .tag { font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .12em; text-transform: uppercase;
  color: var(--cota-silver); margin-top: var(--s-2); }
.mcard2 .chip { position: absolute; right: var(--s-5); bottom: calc(var(--s-5) * -1 + 8px); background: var(--cota-red); color: var(--cota-white);
  font-family: var(--mono); font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; padding: 4px 9px; border-radius: var(--r-1); }
.mcard2 .bd { padding: var(--s-5); display: flex; flex-direction: column; gap: var(--s-4); flex: 1; }
.mcard2 .hook { color: var(--muted); font-size: var(--fs-sm); margin: 0; }
.mcard2 .codes { display: flex; flex-wrap: wrap; gap: var(--s-1); }
.mcard2 .meta { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s-2);
  flex-wrap: wrap; font-family: var(--mono); font-size: var(--fs-xs); color: var(--label); }
.mcard2 .meta > span { white-space: nowrap; }
.mcard2 .meta b { color: var(--cota-red); font-variant-numeric: tabular-nums; }

/* Lesson rail — click to expand the list in place */
.railBtn { display: flex; align-items: center; gap: var(--s-3); width: 100%; background: none; border: 0; padding: 0; cursor: pointer; text-align: left; }
.lrail { list-style: none; display: flex; gap: 3px; margin: 0; padding: 0; flex: 1; }
.lrail li { flex: 1; height: 6px; border-radius: var(--r-1); background: var(--surface); }
.lrail li.part { background: rgba(236,30,36,.4); }
.lrail li.done { background: var(--cota-red); }
.lrail li span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.railBtn .caret { font-family: var(--mono); font-size: var(--fs-label); color: var(--cota-red); transition: transform var(--t-base) var(--ease-standard); }
.railBtn[aria-expanded="true"] .caret { transform: rotate(90deg); }
.llist2 { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.llist2 li { border-bottom: 1px solid var(--line); }
.llist2 li:last-child { border-bottom: 0; }
.llist2 a { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-3) 0; text-decoration: none; color: var(--ink); font-size: var(--fs-sm); }
.llist2 a:hover .t { color: var(--cota-red); }
.llist2 .st { width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--cota-grey); flex: none; display: grid; place-items: center;
  font-size: 9px; font-weight: 800; color: var(--cota-white); }
.llist2 .done .st { background: var(--cota-red); border-color: var(--cota-red); }
.llist2 .part .st { border-color: var(--cota-red); }
.llist2 .next .st { border-color: var(--cota-red); box-shadow: 0 0 0 3px var(--red-tint); }
.llist2 .t { flex: 1; line-height: 1.3; }
.llist2 .n { font-family: var(--mono); font-size: var(--fs-label); color: var(--label); }
.mcard2 .open2 { display: block; padding: var(--s-3) 0 0; margin-top: auto; font-family: var(--mono); font-size: var(--fs-xs);
  letter-spacing: .12em; text-transform: uppercase; color: var(--cota-red); text-decoration: none; border-top: 1px solid var(--line); }

/* ---- Run of lesson ---- */
.seq2 { list-style: none; margin: 0; padding: 0; }
.step2 { display: grid; grid-template-columns: 56px minmax(140px, 1fr) 96px minmax(0, 2fr); gap: var(--s-5); align-items: baseline;
  padding: var(--s-4) 0; border-bottom: 1px solid var(--line); }
.step2 .n { font-family: var(--mono); font-size: var(--fs-xl); font-weight: 700; color: var(--cota-red); }
.step2 .h { font-size: var(--fs-lg); font-weight: 800; letter-spacing: -.01em; }
.step2 .tm { font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .1em; text-transform: uppercase; color: var(--label); }
.step2 .p { color: var(--muted); font-size: var(--fs-md); }

/* ---- Ticker on black ---- */
.ticker2 { background: var(--cota-red); overflow: hidden; padding: var(--s-5) 0; position: relative; }
.tk2 { display: flex; align-items: center; gap: var(--s-5); width: max-content; animation: tick2 110s linear infinite; }
.ticker2:hover .tk2 { animation-play-state: paused; }
/* 20px/800 keeps white-on-red above the 3:1 large-text threshold (measured 4.4:1) */
.tk2 span { font-size: var(--fs-xl); font-weight: 800; letter-spacing: -.015em; white-space: nowrap; color: var(--cota-white); }
.tk2 i { font-style: normal; color: var(--cota-white); font-size: var(--fs-sm); }
@keyframes tick2 { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.foot2 { display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-8); justify-content: space-between;
  font-family: var(--mono); font-size: var(--fs-xs); letter-spacing: .1em; text-transform: uppercase; color: var(--label); }
.foot2 b { color: var(--ink); }

/* ---- Quick jump (press /) ---- */
.qjump { position: fixed; inset: 0; z-index: 80; display: grid; place-items: start center; padding: 12vh var(--s-5) var(--s-5);
  background: rgba(35,31,32,.55); backdrop-filter: blur(3px); }
.qjump-in { width: min(640px, 100%); background: var(--ground); border-radius: var(--r-4); border-top: 3px solid var(--cota-red);
  box-shadow: var(--e-3); overflow: hidden; animation: qj-in 200ms var(--ease-enter); }
@keyframes qj-in { from { opacity: 0; transform: translateY(-10px); } }
.qjump input { width: 100%; border: 0; border-bottom: 1px solid var(--line); padding: var(--s-5); font-size: var(--fs-xl);
  font-weight: 700; letter-spacing: -.01em; outline: none; background: none; color: var(--ink); }
.qjump input::placeholder { color: var(--cota-grey); font-weight: 500; }
.qjump ul { list-style: none; margin: 0; padding: var(--s-2) 0; max-height: 46vh; overflow-y: auto; }
.qjump li a { display: grid; grid-template-columns: 34px 1fr auto; gap: var(--s-3); align-items: center;
  padding: var(--s-3) var(--s-5); text-decoration: none; color: var(--ink); }
.qjump li.on a, .qjump li a:hover { background: var(--surface); }
.qjump li.on a { box-shadow: inset 3px 0 0 var(--cota-red); }
.qjump .n { font-family: var(--mono); font-size: var(--fs-label); color: var(--cota-red); }
.qjump .t { font-weight: 700; font-size: var(--fs-md); }
.qjump .m { font-family: var(--mono); font-size: var(--fs-label); color: var(--label); text-transform: uppercase; letter-spacing: .08em; }
.qjump .none2 { padding: var(--s-6) var(--s-5); color: var(--muted); font-size: var(--fs-md); }
.qjump-foot { display: flex; gap: var(--s-4); padding: var(--s-3) var(--s-5); border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: var(--fs-label); color: var(--label); letter-spacing: .06em; }
.qjHint { position: fixed; right: var(--s-5); bottom: var(--s-5); z-index: 20; font-family: var(--mono); font-size: var(--fs-label);
  letter-spacing: .1em; text-transform: uppercase; color: var(--label); background: var(--ground); border: 1px solid var(--line);
  border-radius: var(--r-full); padding: var(--s-2) var(--s-4); cursor: pointer; }
.qjHint:hover { border-color: var(--cota-red); color: var(--cota-red); }
@media (pointer: coarse) { .qjHint { display: none; } }

/* ---- Skeletons ---- */
.sk { display: block; background: linear-gradient(90deg, var(--surface) 25%, var(--surface-2) 37%, var(--surface) 63%);
  background-size: 400% 100%; animation: shimmer 1.4s ease infinite; border-radius: var(--r-1); }
.band-dark .sk { background: linear-gradient(90deg, var(--w-06) 25%, var(--w-12) 37%, var(--w-06) 63%); background-size: 400% 100%; }
.sk-v { width: 92px; height: 42px; }
.sk-l { width: 130px; height: 11px; }

@media (max-width: 1080px) {
  .tiles2, .segwrap2, .mgrid2 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  .tile2 { border-bottom: 1px solid var(--w-12); }
  .tile2:nth-child(2n) { border-right: 0; }
  .step2 { grid-template-columns: 44px minmax(120px, 1fr) 86px; }
  .step2 .p { grid-column: 2 / -1; }
}
@media (max-width: 820px) {
  .hero2 { grid-template-columns: 1fr; }
}
/* Keyboard affordances are pointer-and-width gated — emulators don't always report coarse */
@media (max-width: 820px) { .qjHint, .mapKeys { display: none; } }
@media (max-width: 560px) {
  .tiles2, .segwrap2, .mgrid2 { grid-template-columns: 1fr !important; }
  .tile2 { border-right: 0; padding-left: 0 !important; }
}
@media (prefers-reduced-motion: reduce) {
  .tk2 { animation: none; }
  .dot.next .hit { animation: none; }
  .mcard2:hover, .nextCard-in:hover { transform: none; }
}

/* =========================================================
   v2.0 — teacher-only: delivery tracking, resume, schools
   ========================================================= */

/* ---- Module page: delivery status + the "mark covered" button ---- */
.mstatus { display: flex; align-items: center; gap: clamp(16px, 3vw, 40px); flex-wrap: wrap;
  background: var(--ground); border: 1px solid var(--line); border-left: 3px solid var(--cota-grey);
  border-radius: var(--r-4); padding: var(--s-5) var(--s-6); margin: var(--s-5) 0 var(--s-3);
  transition: border-color var(--t-base); }
.mstatus.is-done { border-left-color: var(--cota-red); }
.mstat-l { flex: 1; min-width: 260px; }
.mstat-num { display: flex; align-items: baseline; gap: var(--s-3); }
.mstat-num b { font-size: var(--fs-3xl); font-weight: 800; line-height: 1; color: var(--cota-red); font-variant-numeric: tabular-nums; }
.mstat-num span { font-family: var(--mono); font-size: var(--fs-xs); letter-spacing: .1em; text-transform: uppercase; color: var(--label); }
.mstat-l .bar { margin-top: var(--s-4); }
.mstat-note { margin-top: var(--s-3); font-size: var(--fs-sm); color: var(--muted); }
.mstat-r { flex: none; }

/* ---- Lesson page: mark as taught ---- */
.markwrap { display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap; }
.marknote { color: var(--muted); max-width: 34ch; }
.linkish { background: none; border: 0; padding: 0; font: inherit; color: var(--cota-red); font-weight: 700; cursor: pointer; text-decoration: underline; }
.linkish:hover { text-decoration: none; }
.mcard2.is-covered .lrail li { background: var(--cota-red); }
.mcard2 .chip.done { background: var(--cota-black); }
.seg2 .sl em { font-style: normal; font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .1em;
  text-transform: uppercase; color: var(--cota-red); margin-left: var(--s-2); }

/* ---- Account: delivery history ---- */
.account { max-width: 860px; margin: 30px auto; display: grid; gap: var(--s-6); }
.acctcard { padding: 28px 30px; }
.acctcard .tiles { margin-bottom: 20px; }
.acthead { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-4);
  flex-wrap: wrap; margin: var(--s-7) 0 var(--s-4); padding-top: var(--s-5); border-top: 1px solid var(--line); }
.acthead h3 { font-size: var(--fs-lg); }
.acthead .note { font-size: var(--fs-sm); color: var(--muted); }

/* A continuous 21-day strip: an idle day is a faint tick, never a missing column. */
.actstrip { display: flex; align-items: flex-end; gap: 3px; height: 96px; padding-bottom: 2px; border-bottom: 1px solid var(--line-strong); }
.actcol { flex: 1; height: 100%; display: flex; align-items: flex-end; }
/* An idle day is a Silver tick on the baseline, never a missing column. */
.actcol i { display: block; width: 100%; min-height: 3px; background: var(--cota-silver);
  border-radius: var(--r-1) var(--r-1) 0 0; transition: background var(--t-base); }
.actcol.on i { background: var(--cota-black); }
.actcol.on:hover i { background: var(--cota-red); }
.actaxis { display: flex; justify-content: space-between; font-family: var(--mono); font-size: var(--fs-label);
  color: var(--label); margin-top: var(--s-2); }

/* Timeline of state changes */
.tline { list-style: none; margin: 0; padding: 0; }
.tev { display: grid; grid-template-columns: 92px minmax(0, 1fr) auto; gap: var(--s-4); align-items: baseline;
  padding: var(--s-3) 0; border-bottom: 1px solid var(--line); font-size: var(--fs-md); }
.tev:last-child { border-bottom: 0; }
.tev .tw { font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .1em; text-transform: uppercase;
  /* COTA Grey on white is 3.45:1 — fine for a rule or an icon, not for an
     11px label, which is what this is. --muted is the same grey family at
     5.58:1. Found by measuring rather than by looking. */
  color: var(--muted); font-weight: 700; }
.tev.ok .tw { color: var(--cota-red); }
.tev.warn .tw { color: var(--cota-black); }
.tev .tt { min-width: 0; font-weight: 700; }
.tev .tt a { text-decoration: none; }
.tev .tt a:hover { text-decoration: underline; }
.tev .tt em { display: block; font-style: normal; font-weight: 500; font-size: var(--fs-sm); color: var(--muted); }
.tev .tdt { font-family: var(--mono); font-size: var(--fs-xs); color: var(--label); white-space: nowrap; }

/* ---- Admin ---- */
.admhead { align-items: center; gap: var(--s-4); flex-wrap: wrap; margin-bottom: var(--s-6); }
.admtabs { margin-bottom: var(--s-6); }
.admpanes { min-height: 240px; }
.minibar { display: inline-block; width: 88px; height: 5px; background: var(--surface); border-radius: 99px; overflow: hidden; vertical-align: middle; }
.minibar i { display: block; height: 100%; background: var(--cota-red); }
.tbl td.cov { color: var(--cota-red); font-weight: 800; }
.tbl td .small { color: var(--label); font-weight: 500; white-space: normal; }

@media (max-width: 720px) {
  .mstatus { flex-direction: column; align-items: stretch; }
  .mstat-r .btn { width: 100%; }
  .tev { grid-template-columns: 1fr auto; }
  .tev .tw { grid-column: 1 / -1; }
}

/* =========================================================
   v2.1 — classes, and end-of-lesson feedback
   ========================================================= */

/* ---- Class switcher in the nav ---- */
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.classpick select { font: inherit; font-size: var(--fs-sm); font-weight: 700; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-3);
  padding: 5px 8px; max-width: 170px; cursor: pointer; }
.classpick select:hover { border-color: var(--cota-red); }
.classone { font-family: var(--mono); font-size: var(--fs-xs); letter-spacing: .06em; text-transform: uppercase;
  color: var(--label); border: 1px solid var(--line); border-radius: var(--r-full); padding: 4px 10px; text-decoration: none; }
.classone:hover { border-color: var(--cota-red); color: var(--cota-red); }

/* ---- Classes page ---- */
.classesview { max-width: 1000px; margin: 0 auto; }
/* min(300px, 100%), not 300px: a fixed minimum in auto-fill does not shrink
   below itself, so at 320px the track was wider than the column it sits in and
   the page scrolled sideways by four pixels. Only visible once the account had
   a class to show, which is why it survived the first pass. */
.cgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); gap: var(--s-4); margin-bottom: var(--s-6); }
.ccard { min-width: 0; border: 1px solid var(--line); border-radius: var(--r-4); padding: var(--s-5); background: var(--ground);
  display: flex; flex-direction: column; gap: var(--s-3); transition: border-color var(--t-base); }
.ccard.current { border-color: var(--cota-red); border-left-width: 3px; }
.ccard.arch { opacity: .68; }
.chead { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; }
.chead h3 { font-size: var(--fs-lg); letter-spacing: -.01em; }
.ccard .chip { background: var(--cota-red); color: var(--cota-white); font-family: var(--mono); font-size: 10px;
  font-weight: 700; letter-spacing: .1em; text-transform: uppercase; padding: 3px 8px; border-radius: var(--r-1); }
.cmeta { font-size: var(--fs-xs); color: var(--label); font-family: var(--mono); }
.cnum { display: flex; align-items: baseline; gap: var(--s-2); }
.cnum b { font-size: var(--fs-3xl); font-weight: 800; line-height: 1; color: var(--cota-red); font-variant-numeric: tabular-nums; }
.cnum span { font-size: var(--fs-xs); color: var(--label); }
.cfoot { display: flex; gap: var(--s-2); flex-wrap: wrap; margin-top: auto; padding-top: var(--s-3); border-top: 1px solid var(--line); }
.classform { max-width: 460px; margin: var(--s-6) auto; padding: 28px 30px; }
.classform form { display: flex; flex-direction: column; gap: 14px; margin-bottom: var(--s-4); }
.empty2.light { border-color: var(--line-strong); color: var(--ink); }
.empty2.light p { color: var(--muted); }

/* ---- Feedback: the nudge on the dashboard ---- */
.fbnudge { display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap; margin-top: var(--s-6);
  padding: var(--s-4) var(--s-5); border: 1px solid var(--w-12); border-left: 3px solid var(--cota-red); border-radius: var(--r-3); }
.fbnudge.done { border-left-color: var(--cota-grey); }
.fbnudge .k { font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .12em; text-transform: uppercase;
  color: var(--red-on-dark); font-weight: 700; }
.fbnudge.done .k { color: var(--cota-silver); }
.fbnudge .v { flex: 1; min-width: 240px; color: var(--cota-silver); font-size: var(--fs-sm); }

/* ---- Feedback: the line under the lesson tick ---- */
.fbline { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; width: 100%;
  margin-top: var(--s-3); padding-top: var(--s-3); border-top: 1px dashed var(--line-strong); }
.fbline .k { font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .12em; text-transform: uppercase;
  color: var(--label); font-weight: 700; }
.fbline.on .k { color: var(--cota-red); }
.fbline .v { flex: 1; min-width: 200px; font-size: var(--fs-sm); color: var(--muted); }

/* ---- Feedback form ---- */
.fbdlg .dlg-in { max-width: 560px; }
.fbhead { border-bottom: 1px solid var(--line); padding-bottom: var(--s-4); margin-bottom: var(--s-4); }
.fbhead .k { font-family: var(--mono); font-size: var(--fs-label); font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--cota-red); }
.fbhead h3 { font-size: var(--fs-xl); margin: var(--s-2) 0 2px; letter-spacing: -.01em; }
.fbhead .sub { font-size: var(--fs-sm); color: var(--muted); margin: 0; }
.fbq { border: 0; padding: 0; margin: 0 0 var(--s-5); }
.fbq legend { font-size: var(--fs-md); font-weight: 700; padding: 0; margin-bottom: var(--s-3); }
.fbopts { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.fbchip { font: inherit; font-size: var(--fs-sm); font-weight: 600; text-align: left; cursor: pointer;
  background: var(--ground); color: var(--ink); border: 1px solid var(--line-strong); border-radius: var(--r-full);
  padding: 8px 14px; min-height: 38px; transition: border-color var(--t-fast), background var(--t-fast), color var(--t-fast); }
.fbchip:hover { border-color: var(--cota-red); }
.fbchip.on { background: var(--cota-red); border-color: var(--cota-red); color: var(--cota-white); }
.fbopts.one .fbchip { flex: 1 1 140px; text-align: center; }
.fbactions { border-top: 1px solid var(--line); padding-top: var(--s-4); }

/* ---- Admin: feedback + class drill-down ---- */
.fbbar { display: grid; grid-template-columns: minmax(120px, 1fr) 90px 34px; gap: var(--s-3); align-items: center;
  padding: 6px 0; font-size: var(--fs-sm); }
.fbbar b { text-align: right; font-variant-numeric: tabular-nums; }
.panel.flag { border-left: 3px solid var(--cota-red); }
.disc { background: none; border: 0; cursor: pointer; font-family: var(--mono); font-size: var(--fs-lg);
  color: var(--cota-red); line-height: 1; padding: 0 4px; transition: transform var(--t-base) var(--ease-standard); }
.disc.open { transform: rotate(90deg); }
.crow { background: var(--surface-2); }
.crow .cname { font-weight: 700; }
.crow .small { display: block; color: var(--label); font-weight: 500; }
/* The "last in ..." caption needs room, or the teacher column folds to one word per line. */
.tbl td.tname { min-width: 230px; white-space: normal; }
.tbl td.tname .small { line-height: 1.35; }

/* ---- Delivery: four lenses on one drill-down table ---- */
/* The lens strip is a second-order tab bar — quieter than the admin tabs above
   it, or the page reads as having two equal navigations. */
.ltabs.lenses { gap: var(--s-1); border-bottom: 1px solid var(--line); }
.ltabs.lenses .ltab { font-size: var(--fs-sm); padding: var(--s-3) var(--s-4); }

.tbl.drill td { vertical-align: top; }
.tbl.drill .dcell { display: flex; align-items: baseline; gap: var(--s-2); white-space: normal; min-width: 260px; }
.drill .disc.ghost { display: inline-block; width: 20px; }
.drill .dtxt { display: grid; }
.drill .lnum { font-family: var(--mono); font-size: var(--fs-label); color: var(--label); margin-right: var(--s-2); }
.drill .lname { font-weight: 700; }
.drill .lsub { font-size: var(--fs-xs); color: var(--label); font-weight: 500; line-height: 1.35; }
.drill .of { font-style: normal; color: var(--label); font-size: .82em; }
.drill .tick { color: var(--cota-red); font-weight: 800; }
.drill .dash { color: var(--cota-grey); }
.drill .arch { font-style: normal; font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .1em;
  text-transform: uppercase; color: var(--label); margin-left: var(--s-2); }

/* Depth is a red rail that steps in, not an indent — an indent alone gets lost
   once a table scrolls sideways. */
.drill tr.d1 .dcell { padding-left: 22px; box-shadow: inset 2px 0 0 var(--surface); }
.drill tr.d2 .dcell { padding-left: 44px; box-shadow: inset 2px 0 0 var(--surface), inset 24px 0 0 -22px var(--surface); }
.drill tr.d3 .dcell { padding-left: 66px; box-shadow: inset 2px 0 0 var(--surface), inset 24px 0 0 -22px var(--surface), inset 46px 0 0 -44px var(--surface); }
.drill tr.d1 { background: var(--surface-2); }
.drill tr.d2, .drill tr.d3 { background: var(--surface); }
.drill tr.on .dcell { box-shadow: inset 3px 0 0 var(--cota-red); }
.drill tr.d1.on .dcell { box-shadow: inset 3px 0 0 var(--cota-red), inset 22px 0 0 -20px var(--surface); }
/* A lesson nobody has taught is the inactive state — Grey's one job. */
.drill tr.cold .lname, .drill tr.cold .lsub { color: var(--cota-grey); }
.drill [data-open][aria-expanded="true"] { transform: rotate(90deg); }

@media (max-width: 760px) {
  .tbl.drill .dcell { min-width: 200px; }
  .drill tr.d2 .dcell, .drill tr.d3 .dcell { padding-left: 28px; }
}

@media (max-width: 900px) {
}
@media (max-width: 720px) {
  .classpick select { max-width: 120px; }
  .fbopts.one .fbchip { flex: 1 1 100%; }
}

/* =========================================================
   v2.2 — the course is always visible; starter back on lessons
   ========================================================= */

/* ---- Homepage with no class yet ---- */
/* The hero keeps its shape: the Continue card's slot carries the one thing
   we need instead, so the page never turns into a form. */
.nextCard.addclass .nextCard-in { cursor: default; }
.nextCard.addclass .nextCard-in:hover { transform: none; }
.nextCard.addclass .mt { max-width: 46ch; font-family: var(--font); font-size: var(--fs-sm);
  letter-spacing: 0; text-transform: none; line-height: 1.5; }
.nextCard.addclass .btn { margin-top: var(--s-4); align-self: flex-start; }
.hero2-ring.noclass { display: block; }
.hero2-ring.noclass .rl b { color: var(--cota-white); }

/* ---- Lesson starter (the pit-stop clock) ---- */
.starter { border: 1px solid var(--line); border-left: 3px solid var(--cota-red);
  border-radius: var(--r-4); margin: 0 0 var(--s-6); overflow: hidden; background: var(--ground); }
.starterBtn { display: grid; grid-template-columns: auto 1fr auto auto; gap: var(--s-4); align-items: center;
  width: 100%; background: none; border: 0; padding: var(--s-4) var(--s-5); cursor: pointer; text-align: left; font: inherit; }
.starterBtn .k { font-family: var(--mono); font-size: var(--fs-label); font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--cota-red); white-space: nowrap; }
.starterBtn .t { font-weight: 700; font-size: var(--fs-md); color: var(--ink); }
.starterBtn .hint { font-size: var(--fs-xs); color: var(--label); white-space: nowrap; }
.starterBtn .caret { font-family: var(--mono); font-size: var(--fs-lg); color: var(--cota-red); line-height: 1;
  transition: transform var(--t-base) var(--ease-standard); }
.starterBtn.open .caret { transform: rotate(90deg); }
.starterBtn:hover .t { color: var(--cota-red); }
.starterBody { padding: 0 var(--s-5) var(--s-5); border-top: 1px solid var(--line); }

.warm { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: clamp(20px, 3vw, 44px);
  padding-top: var(--s-5); }
.warm .q { font-size: var(--fs-lg); margin: 0 0 var(--s-5); max-width: 44ch; }
.clock { font-family: var(--mono); font-size: clamp(46px, 7.5vw, 76px); font-weight: 700; line-height: 1; letter-spacing: -.04em;
  font-variant-numeric: tabular-nums; transition: color var(--t-base); }
.clock span { font-size: .3em; color: var(--cota-grey); margin-left: .2em; letter-spacing: 0; }
.clock.live { color: var(--cota-red); }
.warm-row { display: flex; align-items: center; gap: var(--s-4); margin-top: var(--s-5); flex-wrap: wrap; }
.hintk { font-family: var(--mono); font-size: var(--fs-xs); color: var(--label); }
.verdict { margin: var(--s-4) 0 0; font-size: var(--fs-md); color: var(--muted); min-height: 3em; }
.verdict b { color: var(--ink); font-family: var(--mono); }
.verdict b.hit { color: var(--cota-red); }
.warm-r { border-left: 1px solid var(--line); padding-left: clamp(18px, 2vw, 30px); }
.scoreline { display: flex; justify-content: space-between; align-items: baseline; padding: var(--s-3) 0; border-bottom: 1px solid var(--line); }
.scoreline span { font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .14em; text-transform: uppercase; color: var(--label); }
.scoreline b { font-family: var(--mono); font-size: var(--fs-xl); font-variant-numeric: tabular-nums; }
.warm-r .tie { font-size: var(--fs-sm); color: var(--muted); margin-top: var(--s-4); }

@media (max-width: 820px) {
  .starterBtn { grid-template-columns: 1fr auto; row-gap: var(--s-2); }
  .starterBtn .k { grid-column: 1 / -1; }
  .starterBtn .hint { display: none; }
  .warm { grid-template-columns: 1fr; }
  .warm-r { border-left: 0; border-top: 1px solid var(--line); padding: var(--s-4) 0 0; }
}

/* =========================================================
   v2.3 — one design language on every page
   ========================================================= */

/* ---- The masthead every page opens with ---- */
.phead { padding: clamp(30px, 4.5vh, 52px) 0 0; }
.phead .shell2 { padding-bottom: clamp(26px, 4vh, 42px); }
.crumbs.onDark { color: var(--cota-silver); margin-bottom: var(--s-5); }
.crumbs.onDark a { color: var(--cota-silver); text-decoration: none; }
.crumbs.onDark a:hover { color: var(--red-on-dark); }
.crumbs.onDark span { color: var(--cota-grey); }

/* Red on black measures 3.71:1 — fine for the big figures (they only need 3:1),
   but the eyebrow is an 11–12px kicker and needs 4.5:1. Silver on black is
   10.91:1, and White is 16.30:1 for the word that is live. Red on a dark band
   is now only ever large: the masthead figures, the rules, the rails. */
.band-dark .eyebrow { color: var(--cota-silver); }
.band-dark .eyebrow .acc, .band-dark .eyebrow b { color: var(--cota-white); font-weight: 700; }

.pheadIn { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: clamp(24px, 4vw, 64px); align-items: end; }
.pheadIn.nofig { grid-template-columns: minmax(0, 1fr); }
.pheadTxt .eyebrow { margin-bottom: var(--s-3); }
.pheadTxt h1 { font-size: clamp(28px, 4.2vw, 44px); font-weight: 800; letter-spacing: -.025em; line-height: 1.05;
  color: var(--cota-white); }
.pheadTxt h1 .acc { color: var(--cota-red); }
.pheadDek { margin: var(--s-4) 0 0; font-size: var(--fs-lg); color: var(--cota-silver); max-width: 62ch; }
.pheadDek b { color: var(--cota-white); }

.pheadFig { text-align: right; border-left: 1px solid var(--w-12); padding-left: clamp(20px, 3vw, 40px); }
.pheadFig .v { font-size: clamp(38px, 5.5vw, 60px); font-weight: 800; line-height: 1; letter-spacing: -.03em;
  color: var(--cota-red); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pheadFig .v i { font-style: normal; font-size: .42em; color: var(--cota-grey); margin-left: 2px; }
.pheadFig .l { margin-top: var(--s-3); font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .14em;
  text-transform: uppercase; color: var(--cota-silver); }

/* A rail across the foot of the masthead, filling to the page's own figure. */
.pheadRail { height: 3px; background: var(--w-12); overflow: hidden; }
.pheadRail i { display: block; height: 100%; width: 0; background: var(--cota-red);
  transition: width var(--t-reveal) var(--ease-standard) 200ms; }

/* Actions sitting inside the masthead */
.pheadActions { display: flex; gap: var(--s-3); flex-wrap: wrap; margin-top: var(--s-5); }
.band-dark .btn.sec { background: transparent; color: var(--cota-white); border-color: var(--w-20); }
.band-dark .btn.sec:hover { border-color: var(--cota-red); color: var(--red-on-dark); }
.band-dark .code { background: var(--w-06); border-color: var(--w-20); color: var(--cota-silver); }

/* ---- Shared section rhythm on light bands ---- */
.band-light + .band-light { border-top: 1px solid var(--line); }
.band-light .sec-h { margin-top: 0; }

@media (max-width: 720px) {
  .pheadIn { grid-template-columns: minmax(0, 1fr); }
  .pheadFig { text-align: left; border-left: 0; border-top: 1px solid var(--w-12); padding: var(--s-4) 0 0; }
}

/* ---- Admin: the control surface ---------------------------------------
   Same five colours, same motion, deliberately a different room: the
   masthead is rated top AND bottom in red and carries live figures, the
   content sits on a faintly cooler ground, and table headers go black
   instead of grey. A glance tells you which side of the product you are on.
   ---------------------------------------------------------------------- */
.phead.admhead { padding-bottom: 0; }
.phead.admhead::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: var(--cota-red); }


/* Live figures, in the masthead itself */
.admstrip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1px; margin-top: clamp(22px, 3.5vh, 36px);
  background: var(--w-12); border: 1px solid var(--w-12); }
.admstat { background: var(--cota-black); padding: var(--s-4) var(--s-5); }
.admstat b { display: block; font-size: var(--fs-3xl); font-weight: 800; line-height: 1; color: var(--cota-red);
  font-variant-numeric: tabular-nums; }
.admstat span { display: block; margin-top: var(--s-2); font-family: var(--mono); font-size: var(--fs-label);
  letter-spacing: .12em; text-transform: uppercase; color: var(--cota-silver); }
.admstat .sk { display: block; height: 26px; width: 60%; }

/* Tab bar sits in its own thin band under the masthead */
.band.admbar { padding: 0; background: var(--cota-white); border-bottom: 1px solid var(--line); }
.admtabs { margin: 0; border-bottom: 0; }
.band.admbody { padding-top: clamp(28px, 4vh, 44px); }

/* Black table headers — the clearest small signal that this is the control side */
body.admin .tbl th { background: var(--cota-black); color: var(--cota-white); border-bottom-color: var(--cota-black); }
body.admin .tbl th.c { text-align: center; }
body.admin .tablewrap { border-color: var(--line-strong); }
/* The admin's difference is its chrome, not a tinted page: the ground stays
   COTA White, as the palette audit requires. */
body.admin .panel { border-left: 3px solid var(--cota-black); }
body.admin .panel.flag { border-left-color: var(--cota-red); }
body.admin .tile { border-left: 3px solid var(--cota-red); }

@media (max-width: 900px) { .admstrip { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .admstrip { grid-template-columns: 1fr; } }

/* ---- Motion, applied everywhere rather than only on the homepage ---- */
.tile { transition: border-color var(--t-base), box-shadow var(--t-slow), transform var(--t-slow) var(--ease-standard); }
.tile:hover { border-color: var(--cota-red); box-shadow: var(--e-1); transform: translateY(-2px); }
.tile .v { font-variant-numeric: tabular-nums; }
/* The denominator is quiet but still information — Grey is 3.45:1 on White, so
   it uses the label step (COTA Black @72%, 5.4:1) like every other small label. */
.tile .v i { font-style: normal; font-size: .5em; color: var(--label); margin-left: 1px; }
.lrow { transition: border-color var(--t-base), transform var(--t-fast) var(--ease-standard), box-shadow var(--t-slow); }
.lrow:hover { border-color: var(--cota-red); transform: translateX(2px); box-shadow: var(--e-1); }
.ccard { transition: border-color var(--t-base), box-shadow var(--t-slow), transform var(--t-slow) var(--ease-standard); }
.ccard:hover { border-color: var(--cota-red); box-shadow: var(--e-2); transform: translateY(-3px); }
.modbar .bar i { width: 0; transition: width var(--t-reveal) var(--ease-standard) 120ms; }

/* Stepper and objectives, on the dark masthead */
.stepper.onDark { color: var(--cota-silver); margin: var(--s-5) 0 0; }
.stepper.onDark .steps i { background: var(--w-20); }
.stepper.onDark .steps i.done { background: var(--cota-red); }
.stepper.onDark .steps i.cur { background: var(--cota-white); }
.objline.onDark { margin-top: var(--s-5); color: var(--cota-silver); display: flex; align-items: center;
  gap: var(--s-2); flex-wrap: wrap; }
.objline.onDark .lab { margin-right: var(--s-2); }
.objline.onDark .lab { color: var(--cota-grey); }
.objline .objdesc { font-size: var(--fs-sm); color: var(--cota-silver); margin-left: var(--s-2); }

/* The lesson body now lives in a band, so it needs no card chrome of its own */
.band.lessonband .lesson, .band.classesband .classesview { margin: 0; }

/* ---- Every select, not just the ones inside .field ----
   The admin teachers table puts a bare <select> in each row. Left unstyled the
   browser paints its own greys, and the palette audit counted 580 of them —
   more off-palette pixels than the rest of the app combined. */
select {
  font: inherit; font-size: var(--fs-sm); color: var(--ink); background: var(--cota-white);
  border: 1px solid var(--line-strong); border-radius: var(--r-3); padding: 6px 8px;
  cursor: pointer; transition: border-color var(--t-fast);
}
select:hover { border-color: var(--cota-red); }
select:focus-visible { outline: 3px solid var(--cota-red); outline-offset: 2px; }
.tbl select { max-width: 170px; }

/* ---- The course editor's repeating rows (v2.7 phase 3) ----
   Objectives, success criteria, vocabulary, the five timed segments, the
   worksheet and every configurable activity are all lists of the same shape:
   a row of controls with a way to add another and a way to take one away.
   One set of rules covers all of them, in the five palette colours only. */
.ed-row { display: flex; gap: var(--s-2); align-items: flex-start; margin-bottom: var(--s-2); }
.ed-row > input, .ed-row > textarea { flex: 1; min-width: 0; }
.ed-row > [data-del] { flex: 0 0 auto; line-height: 1; padding: 8px 10px; }
.ed-cols { flex-wrap: wrap; align-items: flex-end;
  border-left: 3px solid var(--line); padding-left: var(--s-3); }
.ed-cell { display: flex; flex-direction: column; gap: 4px; flex: 1 1 160px; min-width: 0; }
.ed-cell input, .ed-cell textarea, .ed-cell select { width: 100%; }
.ed-lab { font-size: var(--fs-label); font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: var(--label); }
.ed-check { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sm);
  color: var(--ink); cursor: pointer; min-height: 24px; }
.ed-check input { accent-color: var(--cota-red); }
.ed-codes { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4);
  border: 1px solid var(--line); border-radius: var(--r-3); padding: var(--s-3); }
@media (max-width: 640px) {
  .ed-cell { flex-basis: 100%; }
}

/* ---- The lesson body, edited as blocks (v2.8) ----
   The body was a textarea full of markup, which made "you can edit the course
   yourself" true only for someone who writes HTML. It is now a stack of blocks
   with the real lesson styles rendering beside it. Five palette colours only,
   same as everywhere else. */
.bodywrap { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr); gap: var(--s-5); align-items: start; }
.bodyprev { position: sticky; top: var(--s-4); border: 1px solid var(--line);
  border-radius: var(--r-4); padding: var(--s-4); background: var(--cota-white); }
.bodyprev-h { font-size: var(--fs-label); font-weight: 800; letter-spacing: .12em;
  text-transform: uppercase; color: var(--label); margin-bottom: var(--s-3);
  padding-bottom: var(--s-2); border-bottom: 1px solid var(--line); }

.blk { border: 1px solid var(--line); border-left: 3px solid var(--line-strong);
  border-radius: var(--r-3); background: var(--cota-white); margin: 0; }
.blk:hover { border-left-color: var(--cota-red); }
.blk.dragging { opacity: .5; }
.blk.over { border-left-color: var(--cota-red); box-shadow: 0 -2px 0 var(--cota-red); }
.blk-h { display: flex; align-items: center; gap: 6px; padding: 6px 8px;
  border-bottom: 1px solid var(--line); background: var(--surface); border-radius: var(--r-3) var(--r-3) 0 0; }
.blk-grip { cursor: grab; color: var(--label); font-size: 14px; line-height: 1; padding: 0 2px; }
.blk-t { font-size: var(--fs-label); font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: var(--label); }
.blk-b { padding: var(--s-3); }
.blk-b .field { margin-bottom: var(--s-2); }

.blk-items { display: flex; flex-direction: column; gap: 6px; }
.blk-item { display: flex; align-items: flex-start; gap: 6px; }
.blk-item .rt { flex: 1; }
.blk-n { font-family: var(--mono); font-size: var(--fs-sm); font-weight: 700;
  color: var(--cota-red); padding-top: 9px; min-width: 14px; }

/* The insert row between blocks: out of the way until you want it. */
.blk-add { display: flex; flex-wrap: wrap; gap: 5px; padding: 5px 0;
  opacity: 0; transition: opacity var(--t-fast); }
.blk-add:hover, .blk-add:focus-within, .blk:hover + .blk-add, .blk-add:last-child { opacity: 1; }

/* An editable run of text. Looks like an input, holds only inline markup. */
.rt { min-height: 38px; padding: 9px 11px; border: 1px solid var(--line-strong);
  border-radius: var(--r-3); font: inherit; font-size: var(--fs-sm); color: var(--ink);
  background: var(--cota-white); line-height: 1.6; }
.rt:focus { outline: 3px solid var(--cota-red); outline-offset: 1px; border-color: var(--cota-red); }
.rt[data-empty]::before { content: attr(data-ph); color: var(--label); }
.rt a { color: var(--cota-red); }

@media (max-width: 900px) {
  .bodywrap { grid-template-columns: minmax(0, 1fr); }
  .bodyprev { position: static; }
}

/* The HTML `hidden` attribute has to win. Several component rules set an
   explicit display (.field is block, .bodywrap is grid), and any of those beats
   the user-agent's [hidden]{display:none} on specificity — so a panel marked
   hidden stayed on screen. Found by the editor's browser test, switching the
   lesson body between blocks and HTML and getting both at once. */
[hidden] { display: none !important; }

/* ---- "Something wrong with this lesson?" (v2.9) ----
   At the foot of every lesson. Quiet enough not to compete with the delivery
   tick, present enough that the teacher who spots the wrong answer key has
   somewhere to put it. */
.lnotes { margin-top: var(--s-6); padding-top: var(--s-4); border-top: 1px solid var(--line); }
.lnote { border-left: 3px solid var(--line-strong); padding: var(--s-2) var(--s-3);
  margin-top: var(--s-3); background: var(--cota-white); }
.lnote .pill { margin-left: var(--s-2); }
.lnote-reply { margin-top: var(--s-2); padding: var(--s-2) var(--s-3);
  background: var(--surface); border-radius: var(--r-3); }

/* ---------- Site footer and the policy pages (v2.11) ----------
   The footer is in index.html rather than rendered by a view, so that it is on
   the sign-in screen too and cannot be lost by a routing change. */
.sitefoot { border-top: 1px solid var(--line); margin-top: var(--s-9); padding: var(--s-5) 0 var(--s-7);
  font-size: var(--fs-sm); color: var(--muted); background: var(--cota-white); }
.sitefoot .wrap { display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap; }
.sitefoot nav { display: flex; gap: var(--s-4); margin-left: auto; flex-wrap: wrap; }
.sitefoot a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.sitefoot a:hover { color: var(--cota-red); }
@media (max-width: 560px) { .sitefoot nav { margin-left: 0; } }

/* Prose keeps a 62ch measure; the data inventory does not. A grid gives both:
   one narrow column that every paragraph sits in, and a second that only the
   tables reach into — so the inventory can use the whole band while the text
   stays readable. At narrow widths the second column collapses to nothing and
   the page is a single column again, which is why this cannot overflow.
   Note the article is a grid, so margins no longer collapse: the heading top
   margins below are the ORIGINAL gaps minus the preceding paragraph's 12px. */
.policy { display: grid; grid-template-columns: minmax(0, 62ch) minmax(0, 1fr); align-content: start; }
.policy > * { grid-column: 1; min-width: 0; }
.policy > .tablewrap { grid-column: 1 / -1; }
.policy h2 { font-size: var(--fs-xl); margin: var(--s-5) 0 var(--s-3); }
.policy h3 { font-size: var(--fs-lg); margin: var(--s-2) 0 var(--s-2); }
.policy p { margin: 0 0 var(--s-3); line-height: 1.65; }
.policy ul { margin: 0 0 var(--s-3); padding-left: var(--s-5); line-height: 1.65; }
.policy li { margin-bottom: var(--s-2); }
.policy .tablewrap { margin: 0 0 var(--s-4); }
.policy .policy-meta { color: var(--muted); margin-bottom: var(--s-5); }
/* Every other table in the product holds a name or a number, so its cells do
   not wrap. This one holds sentences — "which lessons you have taught, to
   which class, and when" — and nowrap turned the data inventory into a
   horizontal scroller with its third column off the edge of the card. */
.policy .tbl th, .policy .tbl td { white-space: normal; vertical-align: top; line-height: 1.5; }
.policy .tbl td { padding-top: var(--s-3); padding-bottom: var(--s-3); }

@media print { .sitefoot { display: none !important; } }

/* The consent line on registration. The whole line is the label, so the target
   is the sentence and not a 13px box — which is also what makes it pass the
   24px minimum target size. */
.field.consent { margin-top: var(--s-4); }
.checkline { display: flex; gap: var(--s-3); align-items: flex-start; cursor: pointer;
  font-weight: 500; line-height: 1.5; padding: var(--s-2) 0; min-height: 24px; }
.checkline input[type="checkbox"] { width: 18px; height: 18px; margin: 2px 0 0; flex: none;
  accent-color: var(--cota-red); cursor: pointer; }
.checkline a { color: var(--cota-red); text-underline-offset: 3px; }

/* A standard from outside the course's own grade. Marked rather than hidden:
   7.7D on Balanced or Unbalanced is correct and deliberate, and an unmarked
   grade 7 code in a grade 6 table reads as a mistake. */
.code.stretch { border-style: dashed; }
.objline.onDark .code.stretch { border-color: var(--cota-red); color: #fff; }
.objstretch { font-size: var(--fs-xs); color: var(--cota-silver); font-style: italic; }
.objline .objstretch { flex-basis: 100%; }

/* ---------- Reflow at 320px (v2.12) ----------
   WCAG 2.1 1.4.10 asks for no horizontal scroll at a 320px viewport, and ADA
   Title II makes 2.1 AA the floor for public school web content — so this is
   a legal requirement for the districts, not a nicety.
   `.topbar .wrap` already wrapped below 820px, but `.nav` inside it did not:
   one flex row of six items cannot get below about 555px however narrow the
   window is, so the page scrolled sideways. Measured at 320: 555px of content
   in a 320px window. */
.nav { flex-wrap: wrap; row-gap: 4px; min-width: 0; }
.nav .who { min-width: 0; overflow-wrap: anywhere; }

@media (max-width: 700px) {
  .topbar .wrap { height: auto; padding-top: 10px; padding-bottom: 10px; flex-wrap: wrap; gap: 8px; }
  /* The nav becomes its own full-width row under the logo and scrolls
     horizontally only if it still cannot fit — the page never does. */
  .nav { flex-basis: 100%; margin-left: 0; justify-content: flex-start; gap: 2px; }
  .nav a, .nav button { padding: 8px 10px; font-size: 13px; }
  .brand img { height: 32px; }
  .topprog { display: none; }
}

/* Deliberately NOT `html, body { overflow-x: hidden }`. That was the first
   version of this fix and it was wrong twice over: clipping content is its own
   1.4.10 failure, and — worse — it made scrollWidth equal the window width, so
   the reflow test could no longer detect an overflow at all. Removing the
   wrapping rule above then left every check green. A fix that blinds its own
   test is not a fix.
   These two do the honest work instead: let flex children shrink, and break a
   long unbroken string rather than letting it set the page width. */
.wrap { min-width: 0; }
body { overflow-wrap: break-word; }

/* Tab strips wrap rather than setting the page width. Seven admin tabs in one
   nowrap row measured 666px, which is the whole of the reflow failure on that
   screen — and it was invisible for as long as the page was hiding its own
   overflow. Wrapping keeps every tab on screen and reachable; a horizontally
   scrolling strip would hide some of them behind a gesture. */
.ltabs { flex-wrap: wrap; row-gap: 2px; }
@media (max-width: 700px) {
  .ltab { padding: 9px 11px; font-size: 13px; }
  .ltabs.lenses .ltab { padding: var(--s-2) var(--s-3); }
}

/* ---------- Keyboard-operable interactives (v2.12) ----------
   The card sort's cards and the monarch map's stops are real buttons now, so
   they need the look they had as divs without inheriting .btn. */
.cs-card { font-family: inherit; text-align: left; color: var(--ink); width: auto; }
.cs-card[aria-pressed="true"] { outline: 2px solid var(--cota-red); outline-offset: 1px; }
.cs-place { display: block; width: 100%; margin-top: 8px; font-family: inherit; font-size: 12px;
  font-weight: 700; padding: 7px 10px; min-height: 32px; border-radius: 8px; cursor: pointer;
  background: var(--surface-2); border: 1px dashed var(--line-strong); color: var(--ink); }
.cs-place:hover:not(:disabled) { border-color: var(--cota-red); color: var(--cota-red); }
.cs-place:disabled { opacity: .55; cursor: default; }
.mm-keys { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.mm-keys .btn[aria-pressed="true"] { background: var(--cota-black); color: #fff; border-color: var(--cota-black); }

/* ---- The race-week gate -------------------------------------------------
   A locked module or lesson is dimmed and inert. The lock is on the server:
   a locked lesson arrives with no body, no plan and no answers, so this is
   what it looks like rather than what stops it. Kept above the contrast floor
   anyway, because a teacher has to be able to READ the date it opens. */
/* The dashboard card is .mcard2, not .mcard. Written against the wrong class
   name, every one of these rules matched nothing and the only thing marking a
   locked module was the chip. It looked finished in the screenshot. */
/* "Greyed out", meaning it. The first attempt laid a 45% black wash over the
   header, which is already #231F20: black over black, invisible, and it looked
   finished in the screenshot. The header itself goes grey instead, which is
   both the obvious reading of the phrase and the only one that shows.
   White on #4A4749 is 8.2:1, so the title and the date stay readable. */
.mcard2.locked .top { cursor: default; background: #4A4749; }
.mcard2.locked .top .ic { opacity: .55; }
.mcard2.locked .top .no { opacity: .5; }
.mcard2.locked .bd .hook { color: var(--ink-2, #595A5C); }
.mcard2.locked .lrail i, .mcard2.locked .rail { opacity: .45; }
.chip.lock, .pill.lock {
  background: var(--cota-silver, #D0D4D5); color: var(--cota-black, #231F20);
  border: 1px solid var(--line); font-weight: 600;
}
.lrow.locked { cursor: default; background: var(--paper-2, #f7f7f8); }
.lrow.locked h4 { opacity: .66; }
.lrow.locked .stat { background: var(--cota-silver, #D0D4D5); color: var(--cota-black, #231F20); opacity: .8; }
.lrow.locked:hover { transform: none; box-shadow: none; }
.open2.is-locked { color: var(--ink-2, #595A5C); font-weight: 600; cursor: default; }

/* ---- A lesson that is shut inside a module that is open ----
   The F1 ACADEMY lesson sits in Pre-Race Week and opens the week of the race,
   so a teacher reading the open module still meets a row they cannot click. It
   is not a link, it carries the date, and it does not look like "not taught
   yet" — which is a row that *is* clickable and means something else. */
.llist2 li.shut { color: var(--ink-2, #595A5C); display: flex; align-items: center;
  gap: var(--s-3); padding: var(--s-3) 0; font-size: var(--fs-sm); }
.llist2 li.shut .st { border-style: dashed; border-color: var(--cota-grey); color: var(--cota-grey); background: none; }
.llist2 li.shut .t { flex: 1; line-height: 1.3; }
.llist2 li.shut .t em { display: block; font-style: normal; font-family: var(--mono);
  font-size: var(--fs-label); letter-spacing: .08em; text-transform: uppercase; color: var(--label); margin-top: 2px; }
/* A dashed segment on the compact rail, so the card's one-glance summary does
   not count a shut lesson as a lesson still to teach. */
.lrail li.shut { background: repeating-linear-gradient(90deg,
  var(--cota-silver, #D0D4D5) 0 4px, transparent 4px 7px); }

/* A module with no stops on the lap yet, in the delivery band. Its bar is not
   "0% taught", it is "not open", and the two must not read the same. */
.seg2.shut { opacity: .5; }
.seg2.shut .segbar2 { background-image: repeating-linear-gradient(90deg,
  rgba(255,255,255,.22) 0 5px, transparent 5px 9px); }

/* ===================== The guided tour =====================
   A tooltip tethered to real parts of the real page. Positions come from JS
   (public/js/tour.js explains why anchor positioning is not used yet), so
   everything here is appearance only: nothing in this block decides where the
   tooltip goes, which is what keeps the two from fighting. */

/* The dim is a hint, not a cage. pointer-events: none so a teacher who has
   spotted the thing they wanted can click straight through it. */
.tourdim {
  position: fixed; inset: 0; z-index: 900; pointer-events: none;
  background: rgba(35, 31, 32, .55);
}
.tourring {
  position: fixed; z-index: 901; pointer-events: none; border-radius: var(--r-2, 8px);
  opacity: 0;
  /* The cut-out. A huge spread on a transparent box punches the target out of
     the dim layer above without a second element or a mask, and it follows the
     target's own corner radius. */
  box-shadow: 0 0 0 9999px rgba(35, 31, 32, .55), 0 0 0 3px var(--cota-red, #EC1E24);
  transition: opacity var(--t-base, .2s) var(--ease-standard, ease),
              top var(--t-slow, .35s) var(--ease-standard, ease),
              left var(--t-slow, .35s) var(--ease-standard, ease),
              width var(--t-slow, .35s) var(--ease-standard, ease),
              height var(--t-slow, .35s) var(--ease-standard, ease);
}
.tourring.on { opacity: 1; }
/* With the ring doing the dimming there is no need for the flat layer too,
   and two stacked 55% washes is twice as dark as intended. */
.tour-on .tourdim { display: none; }

.tourtip {
  position: fixed; z-index: 902;
  width: min(360px, calc(100vw - 24px));
  margin: 0; padding: var(--s-5, 20px);
  background: var(--cota-white, #fff); color: var(--ink, #231F20);
  border: 1px solid var(--line, #D0D4D5); border-top: 4px solid var(--cota-red, #EC1E24);
  border-radius: var(--r-2, 8px);
  box-shadow: 0 18px 50px rgba(35, 31, 32, .3);
  /* A popover has a UA border and inset we do not want; `inset: auto` lets the
     JS-set top/left win rather than being overridden by the default centring. */
  inset: auto; overflow: visible;
}
/* The polyfill-free fallback: without native popover there is no top layer, so
   the z-index above is doing the work and the element needs to be shown. */
.tourtip.no-popover { display: block; }
.tourtip.is-moving { opacity: 0; }
.tourtip { transition: opacity var(--t-base, .2s) var(--ease-standard, ease); }

.tourstep {
  margin: 0 0 var(--s-2, 6px); font-family: var(--mono, monospace);
  font-size: var(--fs-label, 11px); letter-spacing: .12em; text-transform: uppercase;
  color: var(--label, #6B6C6E);
}
.tourh { margin: 0 0 var(--s-3, 10px); font-size: var(--fs-lg, 19px); line-height: 1.25; letter-spacing: -.01em; }
.tourbody { margin: 0 0 var(--s-4, 16px); font-size: var(--fs-sm, 14px); line-height: 1.55; color: var(--ink-2, #595A5C); }
.tourbtns { display: flex; align-items: center; gap: var(--s-2, 6px); flex-wrap: wrap; }
.tourgrow { flex: 1 1 auto; }

/* The arrow. JS sets the offset along the tooltip's edge; which edge it sits
   on comes from data-side, so the pointer and the position cannot disagree. */
.tourarrow { position: absolute; width: 12px; height: 12px; background: inherit;
  border: 1px solid var(--line, #D0D4D5); transform: rotate(45deg); }
.tourtip[data-side="bottom"] .tourarrow { top: -7px; margin-left: -6px; border-right: 0; border-bottom: 0;
  /* The red top border is the tooltip's, so on this side the arrow wears it. */
  border-top: 3px solid var(--cota-red, #EC1E24); border-left: 3px solid var(--cota-red, #EC1E24); }
.tourtip[data-side="top"] .tourarrow { bottom: -7px; margin-left: -6px; border-left: 0; border-top: 0; }
.tourtip[data-side="right"] .tourarrow { left: -7px; margin-top: -6px; border-right: 0; border-top: 0; }
.tourtip[data-side="left"] .tourarrow { right: -7px; margin-top: -6px; border-left: 0; border-bottom: 0; }

/* The nav's way back in. A question mark, because a teacher looking for help
   looks for one, and it carries a real label for anybody who cannot see it. */
#navtour {
  display: inline-grid; place-items: center; width: 26px; height: 26px;
  border-radius: 50%; border: 1px solid rgba(255, 255, 255, .45);
  background: none; color: var(--cota-white, #fff);
  font-weight: 800; font-size: 13px; line-height: 1; cursor: pointer;
}
#navtour:hover, #navtour:focus-visible { background: var(--cota-red, #EC1E24); border-color: var(--cota-red, #EC1E24); }

@media (max-width: 720px) {
  /* On a phone there is rarely room beside anything, so the tooltip becomes a
     sheet at the foot of the screen and the ring alone does the pointing. JS
     still writes top/left, so they are overridden here rather than trusted. */
  .tourtip {
    top: auto !important; left: 0 !important; right: 0;
    bottom: 0; width: 100%; border-radius: var(--r-2, 8px) var(--r-2, 8px) 0 0;
  }
  .tourarrow { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .tourring, .tourtip { transition: none; }
}

/* ---------- Practice games (v2.16) ----------
   The widgets explain; these ask a child to recall. Brand rule holds: right is
   the primary red plus a tick, wrong is grey, and there is no green anywhere.
   Everything here is a real button, so the states are :disabled and classes
   rather than pointer-only affordances. */
.activity.game .ah .try { color: var(--cota-black); border-color: var(--cota-black); }
.gm-how { margin-top: 0; }
.gm-area { margin: 12px 0 4px; }

.gm-bar { display: flex; align-items: center; gap: 14px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.gm-score { font-size: 14px; color: var(--muted); }
.gm-score b { color: var(--cota-red); font-size: 18px; }
.gm-time { font-size: 13px; color: var(--label); font-variant-numeric: tabular-nums; }
.gm-bar .btn { margin-left: auto; }

/* Match the pairs */
.gm-pairs { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; align-items: start; }
.gm-col { display: flex; flex-direction: column; gap: 8px; }
.gm-card { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; font: inherit; font-weight: 600;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; cursor: pointer; color: var(--ink); }
.gm-card:hover:not(:disabled) { border-color: var(--cota-red); }
.gm-card.sel { border-color: var(--cota-red); box-shadow: 0 0 0 3px var(--red-tint); }
.gm-card.got { background: var(--red-tint); border-color: var(--cota-red); cursor: default; opacity: 1; }
.gm-card.bad { background: var(--surface); border-style: dashed; color: var(--muted); cursor: default; }
.gm-card:disabled { cursor: default; }
.gm-tick { font-weight: 800; color: var(--cota-red); }
.gm-card.bad .gm-tick { color: var(--cota-grey, var(--muted)); }
/* A miss is shown on the card that missed, not only in the counter. */
.gm-card.miss { animation: gmmiss .45s var(--ease-standard, ease); border-color: var(--muted); }
@keyframes gmmiss { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }

/* Bucket race */
.gm-pool { display: flex; flex-wrap: wrap; gap: 8px; min-height: 44px; margin-bottom: 12px; }
.gm-pool .gm-card { width: auto; }
.gm-buckets { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; }
.gm-bin { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 12px; display: flex; flex-direction: column; gap: 8px; }
.gm-bin h5 { margin: 0; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--label); }
.gm-place { font: inherit; font-size: 12px; font-weight: 700; background: transparent; color: var(--cota-red);
  border: 1px dashed var(--cota-red); border-radius: 8px; padding: 7px 10px; cursor: pointer; min-height: 40px; }
.gm-place:disabled { color: var(--muted); border-color: var(--line); cursor: default; }

/* Beat the clock */
.gm-clock { font-size: 40px; font-weight: 800; line-height: 1; color: var(--cota-red); font-variant-numeric: tabular-nums; }
.gm-clock.low { color: var(--cota-black); }
.gm-q { font-size: 20px; font-weight: 700; margin: 14px 0; min-height: 3em; }
.gm-tf { display: flex; gap: 10px; }
.gm-tf .btn { min-width: 110px; min-height: 44px; }

@media (max-width: 560px) { .gm-pairs { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .gm-card.miss { animation: none; } }

/* A draft game: visibly not signed off, and not on the deck. */
.activity.game.draft { border-style: dashed; }
.activity.game.draft .ah .try.draft { color: var(--cota-grey, var(--muted)); border-color: var(--muted); }
.activity.game.draft .drafty { margin: 10px 0 0; }

/* Class or teams. Pressed at the front of a room, often on a touchscreen. */
.gm-modes { display: flex; gap: 6px; margin: 10px 0 4px; }
.gm-mode { font: inherit; font-size: 13px; font-weight: 700; background: var(--surface); color: var(--muted);
  border: 1px solid var(--line); border-radius: 99px; padding: 8px 15px; min-height: 40px; cursor: pointer; }
.gm-mode.on { background: var(--red-tint); color: var(--cota-red); border-color: var(--cota-red); }
.gm-score i { font-style: normal; font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--label); font-weight: 700; margin-right: 8px; }
.gm-team { display: inline-flex; align-items: baseline; gap: 6px; margin-right: 18px; opacity: .55; }
/* Whose go it is has to read from the back of a room. */
.gm-team.up { opacity: 1; }
.gm-team.up i { color: var(--cota-red); }
.gm-team b { font-size: 20px; }

/* The monarch relay. A corridor, not a continent. */
.mr-wrap { display: grid; grid-template-columns: 170px 1fr; gap: 18px; align-items: start; }
.mr-route { width: 100%; height: auto; max-height: 300px; }
.mr-route #mr-fly { transition: cy 1.1s cubic-bezier(.3,.7,.3,1), r .3s; }
.mr-stats { display: flex; gap: 22px; flex-wrap: wrap; }
.mr-ctrl { display: flex; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.mr-ctrl .btn { min-height: 44px; }
@media (max-width: 620px) { .mr-wrap { grid-template-columns: 1fr; } .mr-route { max-height: 220px; } }
@media (prefers-reduced-motion: reduce) { .mr-route #mr-fly { transition: none; } }

/* Monarch run: a decision at a time, with something to lose. */
.mg-top { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; margin-bottom: 14px; }
.mg-gauge { flex: 1; min-width: 180px; }
.mg-gauge .mg-lbl { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--label); font-weight: 700; margin-bottom: 5px; }
.mg-gauge .bar { height: 14px; }
.mg-gauge .bar > i { transition: width .5s cubic-bezier(.3,.7,.3,1), background .3s; }
.mg-nums { display: flex; gap: 18px; font-size: 14px; color: var(--muted); font-variant-numeric: tabular-nums; }
.mg-nums b { color: var(--ink); font-size: 17px; }
.mg-place { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--cota-red); font-weight: 800; display: flex; align-items: center; gap: 10px; }
.mg-ask { font-size: 19px; font-weight: 700; margin: 8px 0 14px; }
.mg-choices { display: flex; flex-direction: column; gap: 9px; }
.mg-pick { font: inherit; font-weight: 600; text-align: left; background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: 10px; padding: 14px 16px; cursor: pointer; min-height: 48px; }
.mg-pick:hover { border-color: var(--cota-red); background: var(--red-tint); }
.mg-fb:not(.show) { display: none; }
.mg-fb { margin-top: 14px; }
.mg-ctrl { margin-top: 14px; }

/* Video. The link under the player is not decoration: a great many school
   networks block the embed, and a teacher needs somewhere to go. */
.vid { margin: 22px 0; }
.vid-frame { position: relative; width: 100%; aspect-ratio: 16 / 9; background: var(--cota-black);
  border-radius: var(--r-3, 12px); overflow: hidden; }
.vid-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* The poster, which is what is there before anybody presses anything. It is a
   real button: pressed from a keyboard, named for a screen reader, and big
   enough to hit from the front of a classroom. */
.vid-poster { position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; border: 0;
  background: var(--cota-black); cursor: pointer; display: block; overflow: hidden; }
.vid-poster img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: .62; transition: opacity var(--t-slow, .3s) ease, transform var(--t-slow, .3s) ease; }
.vid-poster:hover img, .vid-poster:focus-visible img { opacity: .78; transform: scale(1.02); }
.vid-mark { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 72px; height: 72px; border-radius: 50%; background: var(--cota-red); color: var(--cota-white);
  display: grid; place-items: center; box-shadow: 0 6px 24px rgba(0,0,0,.45); }
.vid-mark svg { width: 38px; height: 38px; margin-left: 3px; }
.vid-poster:hover .vid-mark { transform: translate(-50%, -50%) scale(1.06); }
.vid-cap { position: absolute; left: 0; right: 0; bottom: 0; padding: 14px 16px; text-align: left;
  font: inherit; font-size: 14px; font-weight: 700; color: var(--cota-white);
  background: linear-gradient(to top, rgba(35,31,32,.9), rgba(35,31,32,0)); }
.vid-poster:focus-visible { outline: 3px solid var(--cota-red); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  .vid-poster img, .vid-mark { transition: none; }
  .vid-poster:hover img, .vid-poster:focus-visible img { transform: none; }
  .vid-poster:hover .vid-mark { transform: translate(-50%, -50%); }
}
.vid .vid-link { display: inline-block; margin-top: 8px; font-size: 13px; font-weight: 700; color: var(--cota-red); }
.plive .vid, .pslide .vid { margin: 0; }
.pslide .vid-frame { max-height: 52vh; aspect-ratio: 16 / 9; margin: 0 auto; }
.pslide .vid .vid-link { color: var(--cota-silver); }
/* Paper has no iframes. Print the title and where to find it. */
@media print {
  .vid-frame { display: none !important; }   /* poster and player alike */
  .vid .vid-link { color: var(--cota-black); font-size: 12px; }
  .vid .vid-link::after { content: " (" attr(href) ")"; font-weight: 400; }
}

/* The welcome video on the homepage.
   This was two columns — text in one, player in the other — which at a 1160px
   shell left the player about 630px wide: a postcard at the front of the
   course, for the one video COTA supplied. The text is a line of eyebrow, a
   heading and a sentence; it does not need a column of its own. So it sits
   above and the player takes the whole shell.
   The height cap is what keeps "bigger" from becoming "the only thing on the
   screen". A 16:9 frame 1112px wide is 626px tall, which on a laptop pushes the
   Continue card and the modules under the fold — and the first job of this
   screen is still telling a teacher what to teach next. So the width is driven
   FROM a height budget rather than the ratio being fought over: on a 900px-tall
   window the frame settles near 990px, which is 2.5x the area it had, and on a
   tall monitor it stops at the shell.
   The band carried no vertical padding at all, so the white strip butted
   straight onto the dark hero above it. That is why it read as cramped as much
   as small — and note padding-BLOCK below, not the shorthand: .shell2 sets the
   side gutters on this same element, and a `padding: 34px 0` took them away,
   which on a phone put the player edge to edge against the glass. */
.homevid { padding-block: clamp(34px, 5vh, 60px); }
.homevid-txt { margin-bottom: clamp(16px, 2.2vh, 24px); }
.homevid-txt h2 { font-size: clamp(24px, 3vw, 38px); font-weight: 800; letter-spacing: -.015em; margin: 6px 0 10px; }
.homevid-txt p { color: var(--muted); max-width: 56ch; }
.homevid .vid { margin: 0; }
.homevid .vid-frame { width: min(100%, calc(62vh * 16 / 9)); margin-inline: auto; }
/* A 72px play mark is right on a 630px frame and small on a 990px one. */
.homevid .vid-mark { width: 92px; height: 92px; }
.homevid .vid-mark svg { width: 48px; height: 48px; margin-left: 4px; }
.homevid .vid-cap { padding: 18px 20px; font-size: 15px; }
.homevid .vid-link { margin-top: 10px; }
@media (max-width: 860px) {
  .homevid { padding-block: 26px; }
  /* Height-capping a phone-width frame would only letterbox it. */
  .homevid .vid-frame { width: 100%; }
  .homevid .vid-mark { width: 72px; height: 72px; }
  .homevid .vid-mark svg { width: 38px; height: 38px; margin-left: 3px; }
}

/* ===========================================================
   v2.13 — Questions for COTA, the fourth tab on the two lessons
   that collect them. public/js/widgets/questions.js
   =========================================================== */

/* The no-names rule gets the strongest treatment on the panel, because it is
   the one thing on this screen that cannot be undone once it is typed. Black
   left edge rather than red: red is the brand accent and is already doing the
   work of "this is COTA", so a red rule here would read as decoration. */
.qpanel { max-width: 62rem; }
.qp-head h3 { margin: 0 0 4px; font-size: 20px; letter-spacing: -.01em; }
.qp-head p { margin: 0 0 var(--s-4); color: var(--muted); max-width: 60ch; }
.qp-rule { border: 1px solid var(--line); border-left: 3px solid var(--cota-black);
  background: var(--surface-2); padding: var(--s-3) var(--s-4); margin: 0 0 var(--s-5);
  font-size: 14px; line-height: 1.5; }

.qp-for { display: flex; align-items: baseline; gap: var(--s-3); margin: 0 0 var(--s-2); }
.qp-cls { font-weight: 800; }

.qp-list { list-style: none; margin: 0 0 var(--s-4); padding: 0; counter-reset: q; }
/* Numbered by hand so the number keeps its own column and a long question
   wraps under itself rather than under the digit. The printed document COTA
   get is numbered the same way, deliberately. */
.qp-q { counter-increment: q; display: grid;
  grid-template-columns: 1.6rem minmax(0, 1fr) auto; gap: 2px var(--s-3);
  align-items: baseline; padding: var(--s-3) 0; border-bottom: 1px solid var(--line); }
.qp-q::before { content: counter(q) "."; color: var(--muted); font-weight: 700; font-variant-numeric: tabular-nums; }
.qp-txt { grid-column: 2; }
.qp-meta { grid-column: 2; color: var(--muted); }
.qp-act { grid-column: 3; grid-row: 1 / span 2; display: flex; gap: var(--s-2); align-self: center; }

.qp-other { margin-top: var(--s-6); padding-top: var(--s-4); border-top: 1px solid var(--line); }
.qp-other .qp-list { margin-bottom: 0; }
.qp-when { margin-top: var(--s-5); color: var(--muted); }

@media (max-width: 620px) {
  /* The buttons drop under the question rather than squeezing it to nothing. */
  .qp-q { grid-template-columns: 1.6rem minmax(0, 1fr); }
  .qp-act { grid-column: 2; grid-row: auto; margin-top: var(--s-2); }
}

/* ===========================================================
   v2.14 — uploaded pictures and video.
   Blocks: .fig (a photograph) and .clip (a video we host).
   =========================================================== */

/* A picture in a lesson. Capped by height rather than width, because the thing
   that goes wrong on a laptop is a portrait photograph a metre tall pushing the
   rest of the lesson off the screen, and a teacher scrolling past the text they
   are reading from. 46vh leaves the paragraph after it visible. */
.fig { margin: 22px 0; }
.fig img { display: block; width: auto; max-width: 100%; max-height: 46vh;
  border-radius: var(--r-3, 6px); background: var(--surface-2); }
.fig figcaption { margin-top: 8px; font-size: 13.5px; color: var(--muted); max-width: 64ch; }

/* Wider than the column it sits in would be, when the picture is landscape and
   the detail matters — a track map, a diagram of a corner. */
.fig.wide img { width: 100%; max-height: none; }

/* An uploaded clip reuses the whole YouTube poster treatment: same frame, same
   play mark, same caption gradient, so a teacher cannot tell from the look of
   it which kind of video they are about to press. That is the point. */
.clip { margin: 22px 0; }
.clip .vid-frame video { position: absolute; inset: 0; width: 100%; height: 100%;
  border: 0; background: var(--cota-black); object-fit: contain; }
.clip .vid-link { display: inline-block; margin-top: 8px; font-size: 13px; font-weight: 700; color: var(--cota-red); }

/* Present mode: the slide is the whole screen, so a picture may have more of
   it — but still not all, because the heading above it has to stay readable
   from the back of a room. */
.pslide .fig { margin: 0; }
.pslide .fig img { max-height: 52vh; margin: 0 auto; }
.pslide .clip { margin: 0; }
.pslide .clip .vid-link { color: var(--cota-silver); }

/* Paper. A photograph prints; a video cannot, so it prints as its title and
   where to find it, exactly as the YouTube block already does. */
@media print {
  .fig img { max-height: 70mm; break-inside: avoid; }
  .fig figcaption { font-size: 10px; color: var(--cota-black); }
  .clip .vid-frame { display: none !important; }
  .clip .vid-link { color: var(--cota-black); font-size: 12px; }
  .clip .vid-link::after { content: " (in the platform)"; font-weight: 400; }
}

/* ---- The media library, in the admin ---- */

.mlib-up { border: 1px dashed var(--line-strong); border-radius: var(--r-4, 8px);
  padding: var(--s-5); margin: 0 0 var(--s-6); background: var(--surface-2); }
.mlib-up .row { flex-wrap: wrap; gap: var(--s-3); }
.mlib-note { font-size: 13px; color: var(--muted); margin: var(--s-3) 0 0; }

.mlib-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: var(--s-4); }
.mcard { border: 1px solid var(--line); border-radius: var(--r-4, 8px); overflow: hidden;
  background: var(--cota-white); display: flex; flex-direction: column; }
.mcard-th { position: relative; aspect-ratio: 16 / 10; background: var(--cota-black); }
.mcard-th img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* A video with no poster, and a picture that will not load, both land here. */
.mcard-th .none { position: absolute; inset: 0; display: grid; place-items: center;
  color: var(--cota-silver); font-size: 12px; font-weight: 700; text-align: center; padding: 0 10px; }
.mcard-k { position: absolute; left: 8px; top: 8px; font-size: 11px; font-weight: 800;
  letter-spacing: .04em; text-transform: uppercase; padding: 2px 7px; border-radius: 3px;
  background: var(--cota-red); color: var(--cota-white); }
.mcard-b { padding: var(--s-3); display: flex; flex-direction: column; gap: 4px; flex: 1; }
.mcard-b .t { font-weight: 700; font-size: 14px; }
.mcard-b .a { font-size: 12.5px; color: var(--muted); }
/* No alt text should be impossible — the schema requires it — so if one ever
   shows up it is a defect and it says so rather than looking like a blank. */
.mcard-b .a.missing { color: var(--cota-red); font-weight: 700; }
.mcard-b .m { font-size: 11.5px; color: var(--label); margin-top: auto; }
.mcard-acts { display: flex; gap: var(--s-2); padding: 0 var(--s-3) var(--s-3); }

.mpick-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--s-3); max-height: 46vh; overflow: auto; padding: 2px; }
.mpick { border: 2px solid var(--line); border-radius: var(--r-3, 6px); overflow: hidden;
  background: var(--cota-white); cursor: pointer; padding: 0; text-align: left; }
.mpick:hover, .mpick:focus-visible { border-color: var(--cota-red); }
.mpick img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; display: block; background: var(--cota-black); }
.mpick span { display: block; padding: 6px 8px; font-size: 12px; font-weight: 700; }

/* A video somebody else hosts (widgets/vlink.js). It reuses the whole poster
   treatment so a teacher cannot tell from the look of it which of the three
   kinds of video they are about to press — only the caption says, because
   where it is about to send them is the one thing they need to know. */
.vlink { margin: 22px 0; }
.vlink .vid-poster { text-decoration: none; }
.vlink .vid-link { display: inline-block; margin-top: 8px; font-size: 13px; font-weight: 700; color: var(--cota-red); }
.pslide .vlink { margin: 0; }
.pslide .vlink .vid-link { color: var(--cota-silver); }
@media print {
  /* Paper has no player and no new tab, so print where it goes. */
  .vlink .vid-frame { display: none !important; }
  .vlink .vid-link { color: var(--cota-black); font-size: 12px; }
  .vlink .vid-link::after { content: " (" attr(href) ")"; font-weight: 400; }
}

/* ===========================================================
   v2.15 — the pit wall (widgets/pitwall.js). The I-35 route as a
   race strategy board.

   This is the one widget that deliberately borrows another visual
   register: a timing screen. Black ground, tabular figures, red for
   the thing that is wrong. The lesson's whole argument is that a
   migrating butterfly and a race car are solving the same problem,
   and a class that is about to stand at Turn 1 should meet that idea
   looking like a pit wall rather than like a textbook diagram.
   Still the five brand colours — the register comes from the
   typography and the ground, not from a new palette.
   =========================================================== */
.pw { background: var(--cota-black); color: var(--cota-white); border-radius: var(--r-4, 8px);
  padding: var(--s-4) var(--s-4) var(--s-5); font-variant-numeric: tabular-nums; }
.pw-head { display: flex; align-items: baseline; gap: var(--s-3); border-bottom: 2px solid var(--cota-red);
  padding-bottom: var(--s-2); margin-bottom: var(--s-3); }
.pw-ttl { font-size: 12px; font-weight: 800; letter-spacing: .14em; }
.pw-sub { font-size: 12px; color: var(--cota-silver); letter-spacing: .04em; }
.pw-brief { font-size: 13.5px; color: var(--cota-silver); margin: 0 0 var(--s-4); max-width: 68ch; }
.pw-brief b { color: var(--cota-white); }

.pw-legs { display: flex; flex-direction: column; gap: 3px; }
.pw-leg { display: grid; grid-template-columns: minmax(0, 1fr) 72px 90px auto; gap: var(--s-3);
  align-items: center; padding: 7px 10px; background: var(--w-06); border-radius: var(--r-2, 4px);
  border-left: 3px solid transparent; font-size: 13.5px; }
/* A leg she cannot cross. Red, and it is the only red on the board, so the
   class can see the problem from the back of the room without reading it. */
.pw-leg.over { border-left-color: var(--cota-red); background: rgba(236,30,36,.14); }
/* The circuit they are visiting, on the route, two weeks early. */
.pw-leg.cota { border-left-color: var(--cota-white); }
.pw-road i { color: var(--cota-silver); font-style: normal; padding: 0 4px; }
.pw-flag { font-size: 10px; letter-spacing: .1em; background: var(--cota-red); color: var(--cota-white);
  padding: 1px 5px; border-radius: 3px; margin-left: 6px; vertical-align: 1px; }
.pw-mi, .pw-gap { text-align: right; font-weight: 700; }
.pw-mi i, .pw-gap i { font-style: normal; font-weight: 400; font-size: 10.5px;
  color: var(--cota-silver); margin-left: 3px; }
.pw-leg.over .pw-gap { color: var(--red-on-dark); }

.pw-add { display: flex; align-items: center; gap: 6px; }
.pw-add b { min-width: 1.2em; text-align: center; font-weight: 800; }
.pw-b { width: 26px; height: 26px; border-radius: var(--r-2, 4px); border: 1px solid var(--w-20);
  background: transparent; color: var(--cota-white); font: inherit; font-size: 15px; line-height: 1;
  cursor: pointer; }
.pw-b:hover { border-color: var(--cota-red); color: var(--red-on-dark); }
.pw-b:focus-visible { outline: 2px solid var(--cota-red); outline-offset: 2px; }

.pw-foot { display: flex; align-items: center; gap: var(--s-3); margin-top: var(--s-4); }
.pw-tally { font-size: 20px; font-weight: 800; }
.pw-tally i { font-style: normal; font-size: 11.5px; font-weight: 400; color: var(--cota-silver);
  letter-spacing: .06em; margin-left: 6px; }

.pw-out { margin-top: var(--s-4); padding: var(--s-3) var(--s-4); border-radius: var(--r-3, 6px);
  font-size: 14px; line-height: 1.55; border-left: 3px solid; }
.pw-out.bad { background: rgba(236,30,36,.16); border-left-color: var(--cota-red); }
/* Green for arriving, the same green the exit checks use — a right answer is
   green everywhere in this product or it is green nowhere. */
.pw-out.ok { background: rgba(4,106,56,.28); border-left-color: var(--correct); }
.pw-out.ok.warn { background: var(--w-12); border-left-color: var(--cota-silver); }
.pw-tip { display: block; margin-top: 6px; color: var(--cota-silver); font-size: 13px; }

@media (max-width: 680px) {
  .pw-leg { grid-template-columns: minmax(0, 1fr) auto; row-gap: 4px; }
  .pw-mi, .pw-gap { text-align: left; font-size: 12.5px; }
  .pw-add { grid-column: 2; grid-row: 1 / span 2; }
}
/* On the projector the board is the slide, so it may breathe. */
.pslide .pw { padding: var(--s-5) var(--s-5) var(--s-6); }
.pslide .pw-leg { font-size: 15px; padding: 9px 12px; }
@media print { .pw { background: var(--cota-white); color: var(--cota-black); border: 1px solid var(--line); } }
