/* KS3 dark theme. TOKENS ONLY — no classes live here (theme run, 26 Sep
   2026; Mide's ruling: light by default, Light/Dark/System on every page).

   Owned by the KS3 lane. Do NOT edit shared/ks4-theme.css from here and do
   not let the KS4 lane's file grow KS3's vocabulary — the two remap the same
   --ks3-* family for two different page sets and are kept as separate files
   on purpose (see docs/theme/REPORT.md, KS3 section).

   ── the surface / ink / accent / ok / alert / stretch / blue family ──
   Reused VERBATIM from shared/ks4-theme.css (same token family, same
   measurements — every -text token there was checked >= 4.5:1). KS3 pages
   carry the identical `body.rd[data-mode="ks3"]` scope KS4's chrome pages
   carry on their own root, so the same values apply unchanged.

   ── print stays light (rule 7) ──
   KS3 never had its own `@media print` rules before this file — a printed
   lesson just printed whatever was on screen. Dark mode is the first thing
   that would make that wrong (dark backgrounds, light text, wasted ink), so
   every rule in this file is wrapped in `@media screen`: printing always
   falls through to tokens.css's un-guarded light values, whatever the
   viewed theme was. */
@media screen {
[data-theme="dark"] .rd[data-mode="ks3"] {
  /* The legacy accent pair KS3 borrows for the shared chrome (tokens.css
     .rd[data-mode="ks3"]: --accent #E4572E, --accent-hover #A93411) does NOT
     flip in dark, so the ink that sits on it must not flip either — without
     this the chat header subtitle took the global dark #241D14 on rust (2.53:1). */
  --on-accent: #FFFFFF; --on-accent-soft: #FBF5F3;
  /* theme run, interaction gate: the borrowed chrome's soft accent (the chat's
     own-message bubble) stayed KS3's light wash under dark ink — 1.03:1. */
  --accent-soft: #3A2218; --accent-border: #6B3A28;
  --ks3-ground: #16120E; --ks3-card: #1F1A15; --ks3-band: #2A231C; --ks3-inset: #231D17; --ks3-row-dim: #1B1611;
  --ks3-rule: #3E352C; --ks3-rule-strong: #5E5246; --ks3-option-border: #4F443A; --ks3-option-spent: #2B241D;
  --ks3-ink: #F3ECE0; --ks3-ink-body: #E3D9CA; --ks3-ink-muted: #C2B6A6; --ks3-ink-faint: #B0A493; --ks3-ink-ghost: #8A7F72;
  --ks3-accent: #F07A4E; --ks3-accent-text: #FF9E78; --ks3-accent-tint: #3A2218; --ks3-accent-hover: #FFC2A8;
  --ks3-ok: #3CC477; --ks3-ok-text: #86E6AC; --ks3-ok-tint: #15301F;
  --ks3-alert: #FFC53D; --ks3-alert-text: #FFDC85; --ks3-alert-tint: #33290F; --ks3-alert-border: #D9821A;
  --ks3-stretch: #9C7BFF; --ks3-stretch-text: #C2ADFF; --ks3-stretch-tint: #261D3D; --ks3-stretch-rule: #44386A;
  /* ⊕ D2 (theme-run audit, 27 Sep 2026): `--ks3-stretch-wash`/`-dash` were
     missing from this remap — the other `--ks3-stretch-*` siblings on this
     line were all flipped, these two weren't. `.ks3-support .ks3-layer-body`
     (the safeguarding/support box on the 4 drugs+DNA lessons) is the one
     consumer of `-wash`, with a dashed `-dash` border; its body text is the
     page's own `--ks3-ink`, which this block already flips to cream, so the
     wash has to go dark enough to hold that cream at >=4.5:1 (measures
     12.3:1 here) the same way `--ks3-stretch-tint` does for `.ks3-layer-body`
     generally. `-dash` is a decorative border only (3.5:1 against the wash,
     clearing the 3:1 non-text floor), picked partway between `-rule` and the
     bold `--ks3-stretch` accent so the dashed variant still reads distinct
     from the solid-bordered `.ks3-layer-body`. */
  --ks3-stretch-wash: #211934; --ks3-stretch-dash: #7A66B5;
  --ks3-blue: #6C8EFF; --ks3-blue-text: #A8C0FF; --ks3-blue-tint: #1B2440;
  /* ink-filled controls (reveal, check, retry, .ks3-btn.is-primary,
     .ks3-compare-head, the is-wrong mark) flip to light fills in dark mode
     (their bg is --ks3-ink or --ks3-accent-text, both flipped above), so
     their label flips dark to stay legible on the now-light fill. */
  --ks3-on-dark: #16120E;

  /* ⊕ D1 (theme-run audit, 27 Sep 2026): the KS3 tutor chat is the ONE piece
     of KS3 chrome that is NOT styled from `--ks3-*` — it is
     `shared/styles.css`'s generic `.chat-msg__bubble { background:
     var(--card) }` etc, shared with every other page family. On a KS3 page
     `--card` doesn't come from tokens.css's own `[data-theme="dark"]` block:
     `.rd` (which every KS3 page also carries, per §8.5) redeclares `--card:
     var(--surface-panel)`, `--sunken: var(--surface-inset)`, `--bg: var(
     --surface-page)`, `--border-strong: var(--rule)`, `--text: var(--ink)`,
     `--muted: var(--ink-muted)` — and NONE of `--surface-panel`,
     `--surface-inset`, `--surface-page`, `--rule`, `--ink`, `--ink-body`,
     `--ink-muted`, `--ink-faint` had a dark value anywhere, on any page, so
     they held their light-theme hex straight through. The message bubble
     background (`--card` → `--surface-panel` = #FFFDF8) and the avatar/
     camera-button ground (`--sunken` → `--surface-inset` = #F7F2E8) both
     stayed near-white while the inherited text (`--text` → `--ink`, or the
     KS3 page's own `--ks3-ink`) flipped cream — 1.15:1 and 1.11:1, measured.
     Fixed at KS3's own scope (not tokens.css's shared `[data-theme="dark"]`
     block, which every other `.rd` family — the KS4 bonding redesign,
     leaderboard/student/teacher `-ds.css` — also reads: touching it there
     risks a family this run did not test). Pointed at the SAME hex as this
     block's own `--ks3-card`/`--ks3-inset`/`--ks3-rule`/`--ks3-ink*` above,
     so the chat overlay reads as part of the same dark KS3 surface rather
     than a mismatched grey panel — not just "passes contrast" but visually
     consistent. Measured after the fix: bubble bg #1F1A15 vs ink #F3ECE0 =
     14.7:1; avatar/inset bg #231D17 vs ink = 14.2:1 (both ✓ AAA). */
  --surface-page: #16120E; --surface-card: #1F1A15; --surface-panel: #1F1A15; --surface-inset: #231D17;
  --rule: #3E352C; --ink: #F3ECE0; --ink-body: #E3D9CA; --ink-muted: #C2B6A6; --ink-faint: #B0A493;

  /* ── the browse-layer surfaces (year/half-term browse pages) ──
     Tints flipped the same direction as --ks3-band/--ks3-inset above: a
     dark, desaturated cousin of the light pastel, so a large bold number
     painted in the (now-light) --ks3-ink still reads on it. --ks3-dot is
     the page's own texture (`body.rd[data-mode="ks3"]`'s radial-gradient) —
     flipped to stay the same barely-there fleck it is in light mode rather
     than becoming a field of bright dots on a dark ground. --ks3-tag mirrors
     --ks3-band exactly, since it is the same "quiet chip" role. */
  --ks3-year7-tint: #3A241C; --ks3-year8-tint: #1C2E22; --ks3-year9-tint: #202A42;
  --ks3-dot: #241E17;
  --ks3-tag: #2A231C;

  /* ── subject identity (biology/chemistry/physics) ──
     Used as large decorative marks (dots, box-shadows) AND as small mono
     text (`.ks3-ht-n`, the half-term card's lesson number) directly on
     --ks3-card, which is now dark. Re-pointed to the matching -text token
     already measured for exactly that job — a light, dark-ground-legible
     tint of the same hue — rather than minting three more values. */
  --ks3-biology: var(--ks3-ok-text);
  --ks3-chemistry: var(--ks3-accent-text);
  --ks3-physics: var(--ks3-blue-text);

  /* `.ks3-nav`'s own background is a literal rgba composited from
     --ks3-ground's LIGHT value (shared/ks3.css ~line 92) — not a var(), so
     it never flipped and every nav-rail text colour (brand, crumbs, the
     theme control itself) was reading against a still-cream bar. Measured:
     contrast_audit found brand text at 1.08:1, crumb links at 1.59:1. Same
     alpha and blur, dark ground instead. */
  --ks3-nav-bg: rgba(22, 18, 14, .93);

  color-scheme: dark;
}

/* ── a dark BODY, full stop, on every page this file loads on ──
   Several hand-written B2C pages paint `<body>`'s own background as a
   LITERAL light hex (go/index.html: `body { background: #FBF3E6 }`,
   "Design's login is full-bleed on the KS3 ground" — `<body>` sits OUTSIDE
   the `.rd[data-mode="ks3"]` scope those pages put on an inner wrapper div,
   so it cannot reach `var(--ks3-ground)` and was written as a literal
   instead). That literal is invisible for most of a normal page load (the
   inner wrapper's own opaque background paints over it), but
   `consumer-common.js`'s `notFound()` — the CONSUMER_SIGNUP_ENABLED-off
   refusal screen, which is what these pages actually show wherever the
   backend flag is off, i.e. everywhere today — replaces `document.body`'s
   children with `.c-notice` and nothing else, so body's own background IS
   what paints. Low specificity (element selector only) so any page whose
   `.rd[data-mode="ks3"]` really does sit on `<body>` keeps winning on its
   own higher-specificity rule; this is a fallback for every other page,
   never a fight. */
[data-theme="dark"] body { background: #16120E; }

/* The floating theme-control badge (18 hand-written B2C pages whose own
   header markup is too heterogeneous to thread THEME_SLOT into individually
   — see the run report). It sits as a sibling of the page's inner
   `.rd[data-mode="ks3"]` wrapper, not a descendant, on purpose (some of
   these pages replace that wrapper's entire contents at runtime), so it
   cannot reach a --ks3-* token at all; its light colours are literals in
   its own inline <style> block for the same reason. This is its dark
   counterpart, kept in the one file that already owns every other dark
   value rather than repeated 18 times. */
[data-theme="dark"] .mrb-theme-float { background: #1F1A15; color: #F3ECE0; }

/* ── large ink text painted directly on a season/browse fill ──
   `.ks3-season-name` (32px/800) and `.ks3-browse-ht .ks3-code` (23px/800)
   both paint `color: var(--ks3-ink)` directly on a season colour
   (`--ks3-autumn`/`-spring`/`-summer`, or the derived `--ks3-season`) —
   ks3.css's own comment names this deliberate: "large text, so ink on the
   season fill passes at 3:1 (R1)". That measurement assumes --ks3-ink is
   its light-theme near-black; once the general block above flips it
   cream for body text everywhere else, these two contrast_audit-measured
   at 2.02–2.29:1 against the same three fills. The season fill itself is
   NOT part of the surface flip (a self-contained coloured tile, same as
   the browse-layer season/year tokens elsewhere in this file), so its ink
   should not be either — scoped back to the fixed light value. */
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-season-tile,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-browse-ht .ks3-code {
  --ks3-ink: #221E1B;
}

/* The end-of-lesson tutor CTA is the same pattern again: `background:
   var(--ks3-accent); color: var(--ks3-ink)`, with its own comment recording
   that 19px/700 was chosen specifically so ink-on-accent clears the LARGE
   3:1 floor at 4.49:1 (light-mode's own near-miss, already documented
   above it). --ks3-accent flips lighter for dark theme, --ks3-ink flips to
   near-white, and light-on-light measured 2.35:1. Same fix: the fill+ink
   pair is self-contained and does not participate in the general flip. */
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-endmatter .ks3-tutor {
  --ks3-ink: #221E1B;
}
/* Re-check N1: the rule-card badge is the same fill+ink pair; its ink is now a
   fixed #1A1714, and the fill must stay the light accent it was measured on. */
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-rule-badge { background: #E4572E; }

/* ── the ink-dark call-out block (hook / practical / keynote) ──
   `.ks3-dark`'s OWN background is `--ks3-ink` (see shared/ks3.css ~line 417),
   which the block above already flips light — unavoidably, since the same
   token is every page's BODY TEXT colour and must flip for that to work at
   all. That forces `.ks3-dark` itself to invert a second time: what was an
   ink-dark panel on a light page becomes a light panel on a dark page.

   Everything painted "on" that panel has to invert with it: its own text
   (`--ks3-on-dark-body`/`-muted`) and every interactive control nested
   inside it (`.ks3-dark .ks3-option`, `.ks3-dark .ks3-reveal`, the dozens of
   `.ks3-dark .ks3-*-tab`/`-panel` lab controls), which sit on a NESTED
   `--ks3-dark-panel`/`--ks3-dark-rule`/`--ks3-dark-track` tray and label
   themselves with the same on-dark family plus, in a few places,
   `--ks3-data`/`--ks3-blue-light`/`--ks3-ok-dark`.

   ⚠️ SCOPED TO NAMED SELECTORS ON PURPOSE — this is not the general dark
   remap and must never be hoisted into the block above (`[data-theme="dark"]
   .rd[data-mode="ks3"]` itself). Every one of these same tokens has a
   SECOND, much more numerous life: standalone instrument trays that do NOT
   appear in this selector list at all (the circuit-board and ray-diagram
   "figwrap" family, `.ks3-canvas-frame`, `.ks3-iboard`/`.ks3-rbench`/
   `.ks3-hrig` and the rest of the interaction boards, sliders,
   `.ks3-hook-art`). Those paint HARDCODED hex figure ink (physics wires,
   needles, rays, particle dots — see the colour audit in
   docs/theme/REPORT.md) directly onto this same dark-panel plate, with no
   token in between. A diagram's plate must not invert (rule 4: figures stay
   on their plate colour in both themes, same as a cream one would) — and
   confirmed by reading every one of those instruments' wrapper markup in
   ks3_art/: none of them appears below, so scoping the flip to these named
   selectors' own subtrees reaches only the call-out blocks and the ~28
   "ink ground" verdict/reveal/result/report/check/why panels named below
   (their nested controls are verified var()-only, no hardcoded hex), and
   never touches a single instrument's drawn figure plate or ink.

   ⊕ D3 (theme-run audit, 27 Sep 2026): this block used to be scoped to
   `.ks3-dark` alone. `.ks3-dark` is three call-out blocks (hook / practical
   / keynote); it is NOT the only "ink ground" idiom in ks3.css. Roughly 30
   more components use the identical pattern — `background: var(--ks3-ink)`
   with children painted in `--ks3-on-dark(-body|-muted)`, occasionally
   `--ks3-alert` or `--ks3-data` directly as text, occasionally a
   `--ks3-dark-panel`/`--ks3-dark-rule` divider — for a verdict, a reveal, a
   "why", a report or a check that arrives on its own dark card after a
   student answers. Because those components are not `.ks3-dark`, none of
   them got the second-inversion this block performs, so in Dark theme their
   card flips light (the same `--ks3-ink` flip that makes body text legible
   elsewhere) while their text stayed the light-ground value — cream on
   cream, 1.1–1.6:1, is what the audit's own `pairs.json`/`inj.py` measured
   across 42 such (panel, text) pairings, 28 of them failing. The fix is the
   same inversion `.ks3-dark` already got, applied to every other selector
   in ks3.css whose own rule sets `background: var(--ks3-ink)` and is not a
   figure plate — found by grepping `background: var(--ks3-ink)` in
   shared/ks3.css and checking each hit's markup in ks3_art/ for hardcoded
   figure-ink children (none of the ones below have any). Selectors that
   share the same `--ks3-ink` background but are CONTROLS, not panels
   (`.ks3-reveal-btn`, `.ks3-retry`, `.ks3-compare-head`, `.ks3-tab[aria-
   pressed="true"]`, `.ks3-bar-btn[aria-pressed="true"]`, the `is-wrong`
   mark, `.ks3-hcurve-bar.is-lit`, `.ks3-cbeam-beam`, `.ks3-lever-bar`) are
   NOT listed here: they already read correctly, because their only label
   colour is the single `--ks3-on-dark` token, which was already flipped in
   the general block above (this file, line 41) — confirmed by reading each
   one's full rule body. Re-running `inj.py`'s method after this change:
   0/42 pairs under 4.5:1 in both themes (see docs/theme/REPORT.md, D3). */
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-dark,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-unit-panel,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-board-verdict,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-case-verdict,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-switch-chain,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-verdict-panel,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-limit-card[data-ground="ink"],
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-pick-reveal,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-lstep-reveal,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-psort-reveal,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-seq-report,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-still-result,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-mchoice-reveal,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-critiq-reveal,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-chroma-say,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-mpb-say,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-cpair-verdict,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-iask-verdict,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-eqb-check,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-fcard .ks3-fcard-reveal,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-tuber-done,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-ctube-open,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-rgrid-result,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-tsort-reveal,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-tempb .ks3-tempb-run,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-rigb .ks3-rigb-panel,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-phbench .ks3-phbench-result,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-amgrid .ks3-amgrid-result,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-namer .ks3-namer-result,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-catb .ks3-catb-result,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-oxb .ks3-oxb-compare,
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-mcov .ks3-mcov-plate {
  --ks3-on-dark-body: #2E2419;
  --ks3-on-dark-muted: #4A3C2E;
  --ks3-dark-panel: #FFFCF5;
  --ks3-dark-rule: #FFFCF5;
  --ks3-dark-track: #F0E9DA;
  --ks3-data: #2545A8;
  --ks3-blue-light: #2545A8;
  --ks3-ok-dark: #0A6B36;
  /* `.ks3-dark .ks3-eyebrow`/`.ks3-commit` paint the amber DIRECTLY as text
     (`color: var(--ks3-alert)`), sound at 10.48:1 against the block's real
     light-mode ink bg (GATE A's own measurement, this file's block
     comment). --ks3-alert is deliberately unchanged everywhere else in dark
     theme (it is a fill/mark colour, legible on both a light card and a
     dark ground) — but here it is BODY-SIZE TEXT on this block's bg, which
     this scope has just flipped light, and #FFC53D on the flipped
     --ks3-ink measured 1.34:1. Needs the LIGHT-ground amber-as-text value —
     which is `--ks3-alert-text`'s own LIGHT-THEME value, #5A430A. Written
     as a literal, not `var(--ks3-alert-text)`: that variable has already
     been flipped to its DARK-ground value (#FFDC85) by the general block
     above, and custom properties resolve from the cascade at use, not from
     "what this file's light-mode block said" — referencing it here would
     silently pick up the wrong (dark-ground) amber. */
  --ks3-alert: #5A430A;
}
/* theme run, interaction gate: a disabled Check read 2.96:1 at .45 opacity in
   dark against the 3:1 disabled floor. */
[data-theme="dark"] .rd[data-mode="ks3"] .ks3-ccheck-check[disabled] { opacity: .55; }
} /* @media screen */
