/* ═══════════════════════════════════════════════════════════════════════
   ks4-chrome.css — the KS4 navigation chrome (MRB-301)

   Claude Design's 23 Aug 2026 delivery ("MrBadmusAI Redesign"), ported.
   Source of truth: docs/ks3/design-reference/chrome/.

   ── WHY THIS IS A SEPARATE FILE, AND WHY EVERYTHING IS SCOPED ──────────

   Every KS4 page — the six chrome pages this file dresses AND the ~1,000
   LESSON pages behind them — loads /shared/tokens.css, /shared/styles.css
   and /shared/nav.css. Those three are shared, and MRB-301 covers the
   chrome only: the lesson pages are the next run, and this one had to
   leave them BYTE-IDENTICAL.

   Editing any of those three would have changed the rendered bytes of
   every lesson page (and its cache-bust stamp with them), which is exactly
   the outcome the scope wall forbids. So:

     · nothing here lives in tokens.css / styles.css / nav.css;
     · every rule is scoped under `body[data-chrome="ks4"]`;
     · only the seven chrome makers in generate_site_v5.py emit that
       attribute and link this file.

   A lesson page never sees this stylesheet and never sets the attribute,
   so it cannot be reached by anything below even by accident. The same
   technique KS3 already uses for `[data-mode="ks3"]` in tokens.css.

   ⚠️ The consequence, and it is deliberate: the chrome and the lesson
   pages behind it are two visual worlds until the lesson-page run lands.
   That seam is the scope wall, not drift.

   ── THE MARKUP IT DRESSES ──────────────────────────────────────────────

   `nav_html(chrome=True)` emits Design's header. It keeps the two hooks
   shared/nav.js binds to — `.nav-burger` and `#nav-auth-area` — so the
   auth chip, the "My class" chip and the whole accessible drawer keep
   working with ZERO change to nav.js. The drawer is restyled at the
   bottom of this file rather than re-implemented.

   ── FONTS ──────────────────────────────────────────────────────────────

   Bricolage Grotesque / Instrument Sans / DM Mono are already declared
   as @font-face in shared/tokens.css and already self-hosted in
   shared/fonts/ (KS3 and the student pages brought them in). Nothing new
   is fetched and no Google CDN is involved.
   ═══════════════════════════════════════════════════════════════════════ */

body[data-chrome="ks4"] {
  /* Design's palette, lifted from the delivery. The subject, pathway and
     tier hues are NOT new — Design read them off the live site, so they
     are the same constants generate_site_v5.py already holds
     (PATHWAY_COLORS, TIER_COLORS, SITE_DATA[*]["color"]). */
  --k4-ground:      #FBF3E6;
  --k4-card:        #FFFDF8;
  --k4-sunken:      #F4E9D8;
  --k4-sunken-2:    #F7EFE1;
  --k4-track:       #F0E4CE;
  --k4-border:      #E0D2B9;
  --k4-border-2:    #C3B191;

  --k4-ink:         #1A1714;
  --k4-ink-2:       #3D352C;
  --k4-muted:       #6E655D;
  /* ⊕ Experience run, 24 Sep 2026 (item 13) — was #7A6E5F. That passes AA
     against `--k4-ground` (4.51:1, the only ground it was ever checked
     against) but this token paints kickers, eyebrows and mono labels
     against `--k4-sunken` / `--k4-sunken-2` / `--k4-track` too, and against
     the darkest of those (`--k4-track` #F0E4CE) it measured 3.95:1 on the
     rendered page. Darkened, hue and saturation unchanged, to clear 4.5:1
     on every ground it is actually painted against (4.70:1 on `--k4-track`,
     the worst case; 5.37:1 on `--k4-ground`). */
  --k4-muted-2:     #6D6355;

  --k4-accent:      #E4572E;
  --k4-accent-deep: #A93411;
  --k4-accent-dark: #7F2408;
  --k4-accent-soft: #FCE7DE;
  --k4-accent-lift: #F2946E;

  --k4-dark:        #1A1714;
  --k4-dark-2:      #2A2119;
  --k4-dark-3:      #3E362C;
  --k4-on-dark:     #FBF3E6;
  --k4-on-dark-2:   #C6B9A7;
  --k4-on-dark-3:   #B7AA98;
  --k4-on-dark-4:   #8E8272;

  --k4-combined:      #1D6FB8;
  --k4-combined-soft: #EAF2FA;
  --k4-combined-line: #B9CFE6;
  --k4-combined-deep: #15558F;

  --k4-triple:        #B02342;
  --k4-triple-soft:   #FAEDF0;

  --k4-foundation:      #237A3B;
  --k4-foundation-soft: #EAF3EC;
  --k4-foundation-line: #B9D6C1;
  --k4-foundation-deep: #1B5E30;
  --k4-done:            #12A150;
  --k4-done-soft:       #E4F7EB;
  --k4-done-deep:       #0A6B36;

  --k4-higher:      #7A5F00;
  --k4-higher-soft: #F6EFD6;
  --k4-higher-line: #D9C58A;
  --k4-higher-deep: #5F4A00;

  --k4-display: 'Bricolage Grotesque', system-ui, sans-serif;
  --k4-body:    'Instrument Sans', system-ui, sans-serif;
  --k4-mono:    'DM Mono', ui-monospace, monospace;

  --k4-shell: 1400px;

  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--k4-ground);
  color: var(--k4-ink);
  font-family: var(--k4-body);
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
}

body[data-chrome="ks4"] *,
body[data-chrome="ks4"] *::before,
body[data-chrome="ks4"] *::after { box-sizing: border-box; }

body[data-chrome="ks4"] a { color: var(--k4-accent-deep); text-decoration: none; }
body[data-chrome="ks4"] a:hover { color: var(--k4-accent-dark); text-decoration: underline; }
body[data-chrome="ks4"] button { font: inherit; color: inherit; }
/* ⊕ Experience run, 24 Sep 2026 (item 13, legibility) — the reset above is
   for chrome's OWN buttons, but its specificity (0,1,2: one attribute, two
   types) beats `.chat-fab` / `.close-btn` / `.chat-send-btn`'s own
   `color: var(--on-accent)` (0,1,0) from shared/styles.css, so the floating
   tutor widget's buttons silently inherited the page's dark ink instead of
   white — measured on the rendered page, not read off a table:
   rgb(26,23,20) on the accent fill, 2.78:1, on both `index.html` and every
   KS4-chrome page. The chat widget is not chrome's own furniture; restore
   its intended colour rather than widen the reset's exception list, which
   would have to be kept in step with `shared/styles.css` by hand. */
body[data-chrome="ks4"] .chat-fab,
body[data-chrome="ks4"] .close-btn,
body[data-chrome="ks4"] .chat-send-btn { color: var(--on-accent); }
body[data-chrome="ks4"] ::selection { background: var(--k4-accent-soft); }
/* ⚠️ `hidden` HAS TO WIN. The empty states below ship with the `hidden`
   attribute and are revealed by shared/ks4-chrome.js only when real data
   arrives. But `[hidden]`'s `display:none` comes from the UA sheet, and any
   author rule with a `display` beats it — which is how the Top Stars rail's
   two crossfade dots appeared under "No stars yet" in the first screenshot,
   offering a tier toggle for tiers that had nobody in them. */
body[data-chrome="ks4"] [hidden] { display: none !important; }

body[data-chrome="ks4"] :focus-visible {
  outline: 3px solid var(--k4-accent);
  outline-offset: 2px;
  border-radius: 6px;
}

@keyframes k4-rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes k4-fade { from { opacity: 0; } to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  body[data-chrome="ks4"] *,
  body[data-chrome="ks4"] *::before,
  body[data-chrome="ks4"] *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

/* ── HEADER ─────────────────────────────────────────────────────────────
   Design's header, dressing the SAME element tree nav.js already binds.  */

body[data-chrome="ks4"] .nav {
  position: sticky; top: 0; z-index: 20;
  background: var(--k4-ground);
  border-bottom: 2px solid var(--k4-ink);
  /* nav.css sets a grid/flex on .nav; this wins by specificity and the
     inner .k4-navbar does the actual layout. */
  display: block; padding: 0; margin: 0; box-shadow: none; border-radius: 0;
  height: auto;   /* nav.css pins .nav to 62px; Design's bar is 66px min */
}
body[data-chrome="ks4"] .k4-navbar {
  max-width: var(--k4-shell); margin: 0 auto;
  padding: 10px 24px; min-height: 66px;
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
}
body[data-chrome="ks4"] .nav-brand {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 4px; background: none; border: 0;
  font-family: var(--k4-display); font-weight: 800; font-size: 21px;
  letter-spacing: -.02em; color: var(--k4-ink); text-decoration: none;
}
body[data-chrome="ks4"] .nav-brand:hover { color: var(--k4-ink); text-decoration: none; }
body[data-chrome="ks4"] .nav-brand svg { flex: 0 0 auto; }

body[data-chrome="ks4"] .nav-cluster {
  margin-left: auto;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
body[data-chrome="ks4"] .nav-text-link {
  font-family: var(--k4-mono); font-size: 13px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--k4-muted-2);
  padding: 0 6px; text-decoration: none;
}
body[data-chrome="ks4"] .nav-text-link:hover { color: var(--k4-ink); text-decoration: none; }

body[data-chrome="ks4"] .challenge-chip {
  display: inline-flex; align-items: center; gap: 8px;
  height: 44px; padding: 0 18px; border-radius: 999px;
  background: var(--k4-accent-deep); color: var(--k4-on-dark);
  border: 0; font-weight: 700; font-size: 16px; text-decoration: none;
}
body[data-chrome="ks4"] .challenge-chip:hover { background: var(--k4-accent-dark); color: var(--k4-on-dark); text-decoration: none; }

body[data-chrome="ks4"] .nav-icon-link {
  width: 44px; height: 44px; display: grid; place-items: center;
  border-radius: 12px; background: var(--k4-sunken);
  border: 1.5px solid var(--k4-border); color: var(--k4-ink-2);
  text-decoration: none;
}
body[data-chrome="ks4"] .nav-icon-link:hover { border-color: var(--k4-ink); color: var(--k4-ink-2); text-decoration: none; }

body[data-chrome="ks4"] .nav-burger {
  width: 44px; height: 44px; display: grid; place-items: center; gap: 5px;
  border-radius: 12px; background: var(--k4-sunken);
  border: 1.5px solid var(--k4-border); cursor: pointer;
}
body[data-chrome="ks4"] .nav-burger:hover { border-color: var(--k4-ink); }
body[data-chrome="ks4"] .nav-burger span {
  width: 20px; height: 2.4px; border-radius: 2px; background: var(--k4-ink); display: block;
}

/* The auth area is rendered by shared/nav.js. Its three states — signed
   out (two buttons), signed in (a name pill), and the class chip — are
   restyled here rather than re-emitted, so nav.js stays untouched. */
body[data-chrome="ks4"] #nav-auth-area {
  display: inline-flex; align-items: center; gap: 8px;
}
body[data-chrome="ks4"] #nav-auth-area a,
body[data-chrome="ks4"] #nav-auth-area > span {
  display: inline-flex; align-items: center; gap: 9px;
  height: 44px; padding: 0 16px; border-radius: 999px;
  font-weight: 600; font-size: 16px; text-decoration: none;
  background: var(--k4-card); border: 1.5px solid var(--k4-border);
  color: var(--k4-ink-2);
}
body[data-chrome="ks4"] #nav-auth-area a:hover { border-color: var(--k4-ink); color: var(--k4-ink-2); text-decoration: none; }
body[data-chrome="ks4"] #nav-auth-area .btn-signup {
  background: var(--k4-accent-deep); color: var(--k4-on-dark); border-color: var(--k4-accent-deep);
}
body[data-chrome="ks4"] #nav-auth-area .btn-signup:hover { background: var(--k4-accent-dark); border-color: var(--k4-accent-dark); color: var(--k4-on-dark); }
body[data-chrome="ks4"] #nav-auth-area img {
  width: 28px; height: 28px; border-radius: 999px; object-fit: cover;
}

/* The "My class" chip. shared/class-entry.js inserts `.nav-class-link` into
   `.nav-cluster` immediately before `#nav-auth-area` — an entry point that
   MRB-301 keeps, and keeps working, because the chrome header preserves both
   of those hooks. Design never drew it (she had no class entry in her
   header), so it is dressed here as the sibling of the auth chip it sits
   next to. ⚠️ Not reachable from a static harness: it needs a signed-in
   student with a class, so its markup hooks are asserted rather than its
   pixels. */
body[data-chrome="ks4"] .nav-class-link {
  display: inline-flex; align-items: center; gap: 8px;
  height: 44px; padding: 0 16px; border-radius: 999px;
  background: var(--k4-accent-soft); border: 1.5px solid var(--k4-accent);
  color: var(--k4-accent-deep); font-weight: 700; font-size: 16px;
  text-decoration: none; white-space: nowrap;
}
body[data-chrome="ks4"] .nav-class-link:hover {
  background: var(--k4-accent); color: var(--k4-ink); text-decoration: none;
}

/* Breadcrumbs live in the page body on this design, not in the header —
   nav.css's .nav-crumbs is suppressed so the two do not double up. */
body[data-chrome="ks4"] .nav-crumbs { display: none; }

/* ── SHELL ──────────────────────────────────────────────────────────── */

body[data-chrome="ks4"] .k4-main {
  flex: 1; width: 100%; max-width: var(--k4-shell); margin: 0 auto;
  padding: 26px 28px 60px; animation: k4-fade .3s both;
}
body[data-chrome="ks4"] .k4-main.k4-home {
  padding: 40px 28px 48px;
  display: flex; flex-direction: column; gap: 26px;
}

body[data-chrome="ks4"] .k4-crumbs {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-family: var(--k4-mono); font-size: 13px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--k4-muted-2); margin-bottom: 26px;
}
body[data-chrome="ks4"] .k4-crumbs a { color: var(--k4-accent-deep); text-decoration: none; }
body[data-chrome="ks4"] .k4-crumbs a:hover { color: var(--k4-accent-dark); text-decoration: underline; }
/* ⊕ Experience run, 24 Sep 2026 (item 13) — was `var(--k4-border-2)`, a
   hairline-border token borrowed for a readable glyph: 1.90:1 on
   `--k4-ground`, measured on the rendered page. `--k4-muted` already clears
   AA against every ground on this page (4.53:1 worst case). */
body[data-chrome="ks4"] .k4-crumbs .k4-sep { color: var(--k4-muted); }

body[data-chrome="ks4"] .k4-eyebrow {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--k4-mono); font-size: 13px; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--k4-muted-2);
}
body[data-chrome="ks4"] .k4-dot {
  width: 16px; height: 16px; border-radius: 999px;
  border: 2px solid var(--k4-ink); flex: 0 0 auto;
}
body[data-chrome="ks4"] .k4-dot.k4-dot-sm { width: 15px; height: 15px; }

body[data-chrome="ks4"] .k4-h1 {
  margin: 14px 0 0; font-family: var(--k4-display); font-weight: 800;
  font-size: clamp(44px, 5.2vw, 74px); line-height: .95; letter-spacing: -.035em;
  color: var(--k4-ink);
}
body[data-chrome="ks4"] .k4-h1.k4-h1-hero {
  margin: 0; font-size: clamp(46px, 5.4vw, 80px); line-height: .94;
}
body[data-chrome="ks4"] .k4-h1.k4-h1-topic { font-size: clamp(48px, 6vw, 86px); line-height: .93; }
body[data-chrome="ks4"] .k4-lede {
  margin: 20px 0 0; font-size: 21px; line-height: 1.55;
  color: var(--k4-ink-2); max-width: 54ch;
}

body[data-chrome="ks4"] .k4-band {
  display: flex; flex-wrap: wrap; gap: 40px; align-items: center;
}
body[data-chrome="ks4"] .k4-band-copy { flex: 1 1 460px; min-width: 0; }
body[data-chrome="ks4"] .k4-band-side { flex: 1 1 320px; max-width: 420px; }

/* ── SCIENCE FACT PANEL (landing hero) — MRB-342.2 Part 4, card redesign
   25 Sep 2026 ────────────────────────────────────────────────────────
   Sits beside the headline on desktop (a `.k4-band-side` sibling of
   `.k4-band-copy`, so `.k4-band`'s own flex-wrap puts it under the lede
   on narrow screens with no extra markup or ordering rule needed — DOM
   order and reading order stay identical at every width).

   Restyled from Claude Design's "Science Fact Card" delivery (repo root,
   `Science Fact Card.html`): a single dealt playing-card — hairline ink
   border, a hard offset shadow instead of a soft blur, two shorter
   rects stacked behind it (`.k4-facts-stack-1/-2`) to read as a deck,
   a pulsing subject dot, a mono uppercase kicker in the subject colour
   (not a neutral grey — that's Design's call, not a token gap), the
   fact itself in the display face, and a footer progress track that
   fills over the hold time. Colours are still this file's own --k4-*
   tokens, not Design's literal hexes: the palette itself didn't change.

   Design's own component renders exactly 6 facts and gives each one its
   own footer segment. This site's deck is ~80 facts (shared/science-
   facts.js) — 80 slivers would be illegible, so the footer is ONE track
   that fills and resets per fact rather than one segment per fact. That
   is the one deliberate departure from the delivery; everything else
   (the card shell, the dot pulse, the kicker, the word-reveal, the deal
   animation) is carried over as drawn.

   shared/k4-facts.js still owns the shuffle-bag rotation, the pause-on-
   hover/focus behaviour and the accessibility contract below — only the
   markup it builds into `#k4-facts-stage` and the CSS dressing it
   changed. Unlike the previous crossfade, only ONE fact's card exists in
   the DOM at a time (rebuilt on each advance, to replay Design's deal +
   word-reveal animation) rather than every fact stacked and crossfaded;
   `min-height` on `.k4-fact-text` is this design's own mitigation for
   the resulting layout shift as fact length varies, not a literal
   zero-shift guarantee like the old stack was. */
body[data-chrome="ks4"] .k4-facts {
  position: relative; padding-bottom: 18px;
}
body[data-chrome="ks4"] .k4-facts-stack {
  position: absolute; left: 28px; right: 28px; bottom: 0; height: 40px;
  border-radius: 20px; border: 1px solid var(--k4-border); pointer-events: none;
}
body[data-chrome="ks4"] .k4-facts-stack-1 { background: var(--k4-sunken); }
body[data-chrome="ks4"] .k4-facts-stack-2 {
  left: 14px; right: 14px; bottom: 9px; background: var(--k4-sunken-2);
}
body[data-chrome="ks4"] .k4-facts-stage {
  position: relative; z-index: 1;
}
body[data-chrome="ks4"] .k4-fact-card {
  position: relative; overflow: hidden;
  background: var(--k4-card); border: 1.5px solid var(--k4-ink);
  border-radius: 22px; box-shadow: 0 6px 0 var(--k4-ink);
  animation: k4FactsDeal 520ms cubic-bezier(.2,.8,.2,1);
}
body[data-chrome="ks4"] .k4-fact-glow {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(120% 90% at 100% 0%, var(--k4-fact-soft, transparent), transparent 60%);
}
body[data-chrome="ks4"] .k4-fact-kicker-row {
  position: relative; padding: 26px 30px 0;
  display: flex; align-items: center; gap: 10px; overflow: hidden; white-space: nowrap;
  animation: k4FactsIn 420ms both;
}
body[data-chrome="ks4"] .k4-fact-dot {
  flex-shrink: 0; width: 12px; height: 12px; border-radius: 99px;
  background: var(--k4-fact-color, var(--k4-ink));
  animation: k4FactsPulse 1.6s 300ms both;
}
body[data-chrome="ks4"] .k4-fact-kicker {
  font-family: var(--k4-mono); font-size: 13px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase; color: var(--k4-fact-color, var(--k4-muted-2));
}
body[data-chrome="ks4"] .k4-fact-text {
  position: relative; margin: 0; padding: 22px 30px 30px;
  min-height: 4.2em; font-family: var(--k4-display); font-weight: 600;
  font-size: clamp(20px, 2.1vw, 28px); line-height: 1.22; letter-spacing: -.02em;
  color: var(--k4-ink);
}
body[data-chrome="ks4"] .k4-fact-word {
  display: inline-block; margin-right: .26em;
  animation: k4FactsWord 560ms cubic-bezier(.2,.8,.2,1) both;
}
body[data-chrome="ks4"] .k4-fact-bar {
  position: relative; border-top: 1px solid var(--k4-border);
  padding: 18px 30px;
}
body[data-chrome="ks4"] .k4-fact-bar-track {
  height: 4px; border-radius: 4px; background: var(--k4-track); overflow: hidden;
}
body[data-chrome="ks4"] .k4-fact-bar-fill {
  height: 100%; transform-origin: left; background: var(--k4-fact-color, var(--k4-ink));
  animation: k4FactsFill var(--k4-fact-hold, 6000ms) linear both;
}
body[data-chrome="ks4"] .k4-fact-bar-fill.k4-paused { animation-play-state: paused; }
@keyframes k4FactsWord {
  from { opacity: 0; transform: translateY(.5em); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: none; }
}
@keyframes k4FactsIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes k4FactsFill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes k4FactsPulse {
  0%   { box-shadow: 0 0 0 0 var(--k4-fact-color, var(--k4-ink)); }
  70%  { box-shadow: 0 0 0 9px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@keyframes k4FactsDeal {
  0%   { transform: translateY(0) rotate(0); }
  40%  { transform: translateY(-6px) rotate(-.6deg); }
  100% { transform: none; }
}
/* Assistive tech gets exactly ONE static fact — the whole rotating stage
   above is aria-hidden, and this paragraph (chosen once at load, never
   rewritten) is the only copy a screen reader ever reaches. No aria-live:
   a screen-reader user is never interrupted by a fact changing. Standard
   visually-hidden clip pattern, kept local rather than promoted to a
   site-wide utility since this run's scope is the fact panel alone. */
body[data-chrome="ks4"] .k4-facts-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
@media (prefers-reduced-motion: reduce) {
  body[data-chrome="ks4"] .k4-fact-card,
  body[data-chrome="ks4"] .k4-fact-kicker-row,
  body[data-chrome="ks4"] .k4-fact-word,
  body[data-chrome="ks4"] .k4-fact-dot,
  body[data-chrome="ks4"] .k4-fact-bar-fill { animation: none; }
}
@media (max-width: 900px) {
  body[data-chrome="ks4"] .k4-facts-stack { left: 20px; right: 20px; height: 32px; }
  body[data-chrome="ks4"] .k4-facts-stack-2 { left: 10px; right: 10px; bottom: 7px; }
  body[data-chrome="ks4"] .k4-fact-kicker-row { padding: 20px 22px 0; }
  body[data-chrome="ks4"] .k4-fact-text { padding: 16px 22px 22px; font-size: clamp(18px, 4vw, 24px); }
  body[data-chrome="ks4"] .k4-fact-bar { padding: 14px 22px; }
}
@media (max-width: 400px) {
  /* The narrowest supported width (360-390): panel is close to full
     content width but the type is smaller, so more lines can be needed. */
  body[data-chrome="ks4"] .k4-facts-stack { left: 14px; right: 14px; height: 28px; }
  body[data-chrome="ks4"] .k4-facts-stack-2 { left: 7px; right: 7px; bottom: 6px; }
  body[data-chrome="ks4"] .k4-fact-kicker-row { padding: 16px 18px 0; }
  body[data-chrome="ks4"] .k4-fact-kicker { font-size: 11.5px; }
  body[data-chrome="ks4"] .k4-fact-text { padding: 14px 18px 18px; font-size: clamp(16px, 4.8vw, 21px); line-height: 1.32; }
  body[data-chrome="ks4"] .k4-fact-bar { padding: 12px 18px; }
}

body[data-chrome="ks4"] .k4-section-head {
  display: flex; align-items: center; gap: 14px; margin-bottom: 16px;
}
body[data-chrome="ks4"] .k4-section-label {
  font-family: var(--k4-mono); font-size: 12.5px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase; color: var(--k4-muted-2);
}
body[data-chrome="ks4"] .k4-rule { flex: 1; height: 2px; background: var(--k4-border); }

body[data-chrome="ks4"] .k4-kicker {
  font-family: var(--k4-mono); font-size: 12px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase; color: var(--k4-muted-2);
}
body[data-chrome="ks4"] .k4-kicker.k4-kicker-accent { color: var(--k4-accent-deep); }
body[data-chrome="ks4"] .k4-kicker.k4-kicker-ondark { color: var(--k4-accent-lift); }

/* ── DOOR CARDS (landing, GCSE hub, tier, subject) ──────────────────── */

body[data-chrome="ks4"] .k4-doors {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
  gap: 24px; flex: 1; align-items: stretch;
}
body[data-chrome="ks4"] .k4-grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 24px; }
body[data-chrome="ks4"] .k4-grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 24px; }

body[data-chrome="ks4"] .k4-door {
  text-align: left; display: flex; flex-direction: column; gap: 18px;
  background: var(--k4-card); border: 2px solid var(--k4-ink);
  border-radius: 20px; padding: 34px 34px 30px;
  box-shadow: 4px 4px 0 var(--k4-ink);
  transition: transform .16s, box-shadow .16s;
  color: var(--k4-ink); text-decoration: none;
  animation: k4-rise .55s both;
}
body[data-chrome="ks4"] .k4-door:hover {
  transform: translate(-3px, -3px);
  box-shadow: 7px 7px 0 var(--k4-door-hue, var(--k4-accent));
  color: var(--k4-ink); text-decoration: none;
}
body[data-chrome="ks4"] .k4-door.k4-door-sm { padding: 30px; gap: 16px; }
body[data-chrome="ks4"] .k4-door h2 {
  margin: 0; font-family: var(--k4-display); font-weight: 800;
  font-size: clamp(38px, 3.6vw, 52px); line-height: 1;
  letter-spacing: -.03em; color: var(--k4-ink);
}
body[data-chrome="ks4"] .k4-door.k4-door-sm h2 { font-size: clamp(32px, 3vw, 42px); line-height: 1.02; }
body[data-chrome="ks4"] .k4-door p {
  margin: 0; font-size: 19px; line-height: 1.5; color: var(--k4-ink-2);
  /* The description absorbs the slack, so the pill rows and the "Open X"
     footers pin to the same baseline across a row of cards whatever the copy
     length. Without it Biology's one-line blurb rode its pills 27px above
     Physics's two-line one — visible in the science-picker screenshot. The
     old site solved this the same way (.courses-col .pathway-card p). */
  flex: 1 0 auto;
}
body[data-chrome="ks4"] .k4-door-foot {
  margin-top: auto; padding-top: 22px; border-top: 1.5px solid var(--k4-border);
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--k4-display); font-weight: 800; font-size: 19px;
  color: var(--k4-accent-deep);
}

body[data-chrome="ks4"] .k4-pills { display: flex; flex-wrap: wrap; gap: 8px; }
body[data-chrome="ks4"] .k4-pill {
  padding: 8px 15px; border-radius: 999px;
  background: var(--k4-sunken); border: 1.5px solid var(--k4-border);
  font-weight: 600; font-size: 15px; color: var(--k4-ink-2);
}
body[data-chrome="ks4"] .k4-pill-foundation {
  padding: 7px 14px; background: var(--k4-foundation-soft);
  border-color: var(--k4-foundation-line); color: var(--k4-foundation-deep);
}
body[data-chrome="ks4"] .k4-pill-higher {
  padding: 7px 14px; background: var(--k4-higher-soft);
  border-color: var(--k4-higher-line); color: var(--k4-higher-deep);
}
body[data-chrome="ks4"] .k4-tag {
  padding: 6px 13px; border-radius: 8px; background: var(--k4-sunken);
  font-family: var(--k4-mono); font-size: 12.5px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--k4-ink-2);
}
body[data-chrome="ks4"] .k4-tag-rp {
  background: var(--k4-combined-soft); border: 1.5px solid var(--k4-combined-line);
  color: var(--k4-combined-deep);
}
body[data-chrome="ks4"] .k4-tag-lg {
  padding: 8px 15px; border: 1.5px solid var(--k4-border); font-size: 13px;
}

/* ── NOTE CARD (the "not sure which?" / "which tier?" asides) ───────── */

body[data-chrome="ks4"] .k4-note {
  background: var(--k4-sunken); border: 1.5px solid var(--k4-border);
  border-radius: 16px; padding: 22px 24px;
}
body[data-chrome="ks4"] .k4-note.k4-note-plain { background: var(--k4-card); }
body[data-chrome="ks4"] .k4-note p {
  margin: 12px 0 0; font-size: 18px; line-height: 1.55; color: var(--k4-ink-2);
}

/* ── SUBJECT CARD (the science picker) ──────────────────────────────── */

body[data-chrome="ks4"] .k4-subject-top {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
}
body[data-chrome="ks4"] .k4-subject-mark {
  width: 48px; height: 48px; border-radius: 14px;
  border: 2px solid var(--k4-ink); display: grid; place-items: center;
}
body[data-chrome="ks4"] .k4-count {
  font-family: var(--k4-mono); font-size: 13px; letter-spacing: .08em; color: var(--k4-muted-2);
}
body[data-chrome="ks4"] .k4-door.k4-subject h2 {
  font-size: 36px; line-height: 1; color: var(--k4-door-hue, var(--k4-ink));
}
body[data-chrome="ks4"] .k4-door.k4-subject p { font-size: 18px; }

/* ── TOPIC LIST (subject page) ──────────────────────────────────────── */

body[data-chrome="ks4"] .k4-list {
  border: 2px solid var(--k4-ink); border-radius: 18px; overflow: hidden;
  background: var(--k4-card); box-shadow: 4px 4px 0 var(--k4-border);
}
body[data-chrome="ks4"] .k4-row {
  width: 100%; text-align: left; text-decoration: none;
  background: none; border: 0; border-bottom: 1.5px solid var(--k4-track);
  padding: 20px 24px; display: flex; align-items: center; gap: 20px;
  transition: background-color .14s; color: var(--k4-ink);
}
body[data-chrome="ks4"] .k4-row:last-child { border-bottom: 0; }
body[data-chrome="ks4"] .k4-row:hover { background: var(--k4-sunken-2); color: var(--k4-ink); text-decoration: none; }
body[data-chrome="ks4"] .k4-row-num {
  flex: 0 0 46px; height: 46px; border-radius: 12px;
  display: grid; place-items: center;
  font-family: var(--k4-mono); font-size: 15px; font-weight: 500;
  color: var(--k4-ink-2); background: var(--k4-sunken);
  border: 1.5px solid var(--k4-border);
}
body[data-chrome="ks4"] .k4-row-body { flex: 1; min-width: 0; }
body[data-chrome="ks4"] .k4-row-title {
  display: block; font-family: var(--k4-display); font-weight: 800;
  font-size: 24px; letter-spacing: -.02em; color: var(--k4-ink);
}
body[data-chrome="ks4"] .k4-row-meta {
  display: block; margin-top: 5px; font-family: var(--k4-mono);
  font-size: 13px; letter-spacing: .06em; color: var(--k4-muted-2);
}
body[data-chrome="ks4"] .k4-row-arrow { flex: 0 0 auto; }

/* Subtopic rows on the topic page sit a little taller and top-align. */
body[data-chrome="ks4"] .k4-row.k4-row-st { align-items: flex-start; gap: 18px; }
body[data-chrome="ks4"] .k4-row.k4-row-st .k4-row-num {
  flex: 0 0 26px; height: 26px; margin-top: 3px; border-radius: 8px;
  font-size: 12px;
}
body[data-chrome="ks4"] .k4-row.k4-row-st .k4-row-title { font-size: 23px; }
body[data-chrome="ks4"] .k4-row-desc {
  display: block; margin-top: 6px; font-size: 17px; line-height: 1.5; color: var(--k4-ink-2);
}
body[data-chrome="ks4"] .k4-row.k4-row-st .k4-row-meta { margin-top: 8px; font-size: 12.5px; }
body[data-chrome="ks4"] .k4-row.k4-row-st .k4-row-arrow { margin-top: 9px; }

/* ── TOPIC PAGE: two-column body + sidebar ──────────────────────────── */

body[data-chrome="ks4"] .k4-split {
  display: flex; flex-wrap: wrap; gap: 24px; align-items: flex-start;
}
body[data-chrome="ks4"] .k4-split-main { flex: 1 1 560px; min-width: 0; }
body[data-chrome="ks4"] .k4-split-side {
  flex: 1 1 320px; max-width: 440px; display: flex; flex-direction: column; gap: 20px;
}

body[data-chrome="ks4"] .k4-panel {
  background: var(--k4-card); border: 2px solid var(--k4-ink);
  border-radius: 18px; padding: 24px; box-shadow: 4px 4px 0 var(--k4-border);
}
body[data-chrome="ks4"] .k4-panel.k4-panel-soft {
  border: 1.5px solid var(--k4-border); box-shadow: none;
}
body[data-chrome="ks4"] .k4-panel p {
  margin: 12px 0 0; font-size: 17px; line-height: 1.55; color: var(--k4-ink-2);
}
body[data-chrome="ks4"] .k4-formulae { margin-top: 16px; display: flex; flex-direction: column; gap: 10px; }
body[data-chrome="ks4"] .k4-formula {
  padding: 14px 16px; border-radius: 12px; background: var(--k4-sunken-2);
  border: 1.5px solid var(--k4-border); font-family: var(--k4-mono);
  font-size: 18px; line-height: 1.4; color: var(--k4-ink);
}
body[data-chrome="ks4"] .k4-formula.k4-formula-long { font-size: 16px; }

body[data-chrome="ks4"] .k4-formulae-footer {
  margin-top: 16px; padding-top: 16px; border-top: 1.5px solid var(--k4-border);
  display: flex; flex-direction: column; gap: 8px;
}
body[data-chrome="ks4"] .k4-formulae-footer-label {
  margin: 0; font-size: 13px; font-weight: 600; color: var(--k4-muted-2);
}
body[data-chrome="ks4"] .k4-formulae-footer-link {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 700; font-size: 15px; color: var(--k4-accent-deep);
  text-decoration: none;
}
body[data-chrome="ks4"] .k4-formulae-footer-link:hover { text-decoration: underline; }

body[data-chrome="ks4"] .k4-dark {
  background: var(--k4-dark); border-radius: 18px; padding: 24px;
  box-shadow: 4px 4px 0 var(--k4-dark-hue, var(--k4-accent));
  color: var(--k4-on-dark);
}
body[data-chrome="ks4"] .k4-dark h2,
body[data-chrome="ks4"] .k4-dark .k4-dark-title {
  margin: 12px 0 0; font-family: var(--k4-display); font-weight: 800;
  font-size: 26px; line-height: 1.1; letter-spacing: -.02em; color: var(--k4-on-dark);
}
body[data-chrome="ks4"] .k4-dark p { margin: 12px 0 0; font-size: 17px; line-height: 1.55; color: var(--k4-on-dark-2); }

body[data-chrome="ks4"] .k4-cta {
  margin-top: 18px; width: 100%;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  height: 52px; border-radius: 13px; background: var(--k4-accent);
  color: var(--k4-ink); border: 0; cursor: pointer;
  font-family: var(--k4-display); font-weight: 800; font-size: 19px;
  text-decoration: none;
}
body[data-chrome="ks4"] .k4-cta:hover { background: var(--k4-accent-lift); color: var(--k4-ink); text-decoration: none; }
body[data-chrome="ks4"] .k4-cta-solid {
  display: inline-flex; align-items: center; gap: 10px;
  height: 52px; padding: 0 24px; border-radius: 13px;
  background: var(--k4-accent-deep); color: var(--k4-on-dark); border: 0;
  cursor: pointer; font-weight: 700; font-size: 17px; text-decoration: none;
  white-space: nowrap;
}
body[data-chrome="ks4"] .k4-cta-solid:hover { background: var(--k4-accent-dark); color: var(--k4-on-dark); text-decoration: none; }
body[data-chrome="ks4"] .k4-cta-quiet {
  display: inline-flex; align-items: center; gap: 10px;
  height: 50px; padding: 0 22px; border-radius: 13px;
  background: var(--k4-card); border: 2px solid var(--k4-ink);
  cursor: pointer; font-weight: 700; font-size: 17px; color: var(--k4-ink);
  text-decoration: none;
}
body[data-chrome="ks4"] .k4-cta-quiet:hover { background: var(--k4-ground); color: var(--k4-ink); text-decoration: none; }
body[data-chrome="ks4"] .k4-cta-light {
  margin-top: auto; display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  height: 50px; padding: 0 22px; border-radius: 13px; background: var(--k4-on-dark);
  color: var(--k4-ink); border: 0; cursor: pointer; font-weight: 700; font-size: 17px;
  text-decoration: none; white-space: nowrap;
}
body[data-chrome="ks4"] .k4-cta-light:hover { background: var(--k4-card); color: var(--k4-ink); text-decoration: none; }

body[data-chrome="ks4"] .k4-nextrow {
  margin-top: 24px; display: flex; align-items: center; justify-content: space-between;
  gap: 18px; flex-wrap: wrap; padding: 22px 24px; border-radius: 16px;
  background: var(--k4-sunken); border: 1.5px solid var(--k4-border);
}
body[data-chrome="ks4"] .k4-nextrow-title {
  margin: 8px 0 0; font-family: var(--k4-display); font-weight: 800;
  font-size: 26px; letter-spacing: -.02em; color: var(--k4-ink);
}

/* ── THIS WEEK'S CHALLENGE STRIP (landing) ──────────────────────────── */

body[data-chrome="ks4"] .k4-challenge {
  background: var(--k4-sunken); border: 1.5px solid var(--k4-border);
  border-radius: 18px; padding: 22px 26px;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 22px; align-items: center; animation: k4-rise .6s .24s both;
}
body[data-chrome="ks4"] .k4-challenge-cell + .k4-challenge-cell {
  border-left: 1.5px solid var(--k4-border); padding-left: 22px;
}
body[data-chrome="ks4"] .k4-challenge-head {
  margin: 9px 0 0; font-family: var(--k4-display); font-weight: 800;
  font-size: 25px; letter-spacing: -.02em; color: var(--k4-ink);
}
body[data-chrome="ks4"] .k4-challenge-sub { margin: 5px 0 0; font-size: 16px; color: var(--k4-muted); }
body[data-chrome="ks4"] .k4-challenge-go { display: flex; justify-content: flex-end; }
body[data-chrome="ks4"] .k4-challenge-go.k4-challenge-cell { border-left: 0; padding-left: 0; }

/* ── TOP STARS RAIL (GCSE hub) ──────────────────────────────────────── */

body[data-chrome="ks4"] .k4-stars {
  flex: 1 1 320px; max-width: 420px; background: var(--k4-dark);
  border-radius: 20px; padding: 26px; box-shadow: 4px 4px 0 var(--k4-higher);
  display: flex; flex-direction: column; gap: 18px;
}
body[data-chrome="ks4"] .k4-stars-title {
  margin: 8px 0 0; font-family: var(--k4-display); font-weight: 800;
  font-size: 27px; letter-spacing: -.02em; color: var(--k4-on-dark);
}
body[data-chrome="ks4"] .k4-champ {
  background: var(--k4-dark-2); border-radius: 14px; padding: 16px 18px;
}
body[data-chrome="ks4"] .k4-champ-kicker {
  font-family: var(--k4-mono); font-size: 11.5px; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: #C9BDAC;
}
body[data-chrome="ks4"] .k4-champ-row {
  margin-top: 9px; display: flex; align-items: baseline;
  justify-content: space-between; gap: 12px;
}
body[data-chrome="ks4"] .k4-champ-name {
  font-family: var(--k4-display); font-weight: 800; font-size: 23px;
  color: var(--k4-on-dark); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
body[data-chrome="ks4"] .k4-champ-pct {
  font-family: var(--k4-mono); font-size: 19px; color: var(--k4-accent-lift); flex-shrink: 0;
}
body[data-chrome="ks4"] .k4-stars-slides { display: grid; flex: 1; }
body[data-chrome="ks4"] .k4-stars-slide {
  grid-area: 1 / 1; opacity: 0; transition: opacity .55s ease; pointer-events: none;
  display: flex; flex-direction: column; gap: 12px;
}
body[data-chrome="ks4"] .k4-stars-slide.k4-on { opacity: 1; pointer-events: auto; }
body[data-chrome="ks4"] .k4-stars-slide-head {
  font-family: var(--k4-mono); font-size: 11.5px; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--k4-on-dark-4);
}
body[data-chrome="ks4"] .k4-star-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding-bottom: 11px; border-bottom: 1px solid var(--k4-dark-3);
}
body[data-chrome="ks4"] .k4-star-row:last-child { border-bottom: 0; padding-bottom: 0; }
body[data-chrome="ks4"] .k4-star-who {
  display: flex; align-items: center; gap: 11px;
  color: var(--k4-on-dark); font-size: 17px; font-weight: 600;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
body[data-chrome="ks4"] .k4-star-rank {
  font-family: var(--k4-mono); font-size: 13px; color: var(--k4-on-dark-4); flex-shrink: 0;
}
body[data-chrome="ks4"] .k4-star-pct {
  font-family: var(--k4-mono); font-size: 15px; color: var(--k4-on-dark-3); flex-shrink: 0;
}
body[data-chrome="ks4"] .k4-stars-empty {
  color: var(--k4-on-dark-3); font-size: 16px; font-style: italic; padding: 8px 0;
}
body[data-chrome="ks4"] .k4-stars-dots { display: flex; gap: 7px; }
body[data-chrome="ks4"] .k4-stars-dot {
  width: 9px; height: 9px; border-radius: 50%; border: 0; padding: 0;
  /* NOT --k4-dark-3 (#3E362C): against the #1A1714 card the inactive dot was
     invisible in the populated screenshot, so the rail looked like it had one
     tier and no way to reach the other. */
  cursor: pointer; background: #6A6055; transition: background .2s, transform .2s;
}
body[data-chrome="ks4"] .k4-stars-dot.k4-on { background: var(--k4-accent); transform: scale(1.15); }
body[data-chrome="ks4"] .k4-stars-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: auto;
}

/* ── FOOTER ─────────────────────────────────────────────────────────── */

body[data-chrome="ks4"] .k4-footer {
  border-top: 2px solid var(--k4-ink); background: var(--k4-sunken); margin-top: auto;
}
body[data-chrome="ks4"] .k4-footer-inner {
  max-width: var(--k4-shell); margin: 0 auto; padding: 22px 28px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 18px; flex-wrap: wrap;
}
body[data-chrome="ks4"] .k4-footer-mark {
  font-family: var(--k4-mono); font-size: 13px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--k4-muted-2);
}
body[data-chrome="ks4"] .k4-footer-links { display: flex; gap: 20px; flex-wrap: wrap; font-size: 16px; font-weight: 600; }

/* ── THE FLOATING TUTOR BUTTON HAS TO HAVE SOMEWHERE TO SIT ───────────────
   `.chat-fab` is `position:fixed; bottom:28px; right:28px; height:54px` from
   shared/styles.css, and it is an ENTRY POINT that survives this run — the
   chat is reachable from these pages today and still is.

   But a fixed button in the bottom-right corner lands on whatever is in the
   bottom-right corner, and on Design's layouts that was the landing's "Take
   the challenge" CTA and the footer's own links. Seen in the 1440 screenshot,
   not reasoned about. Mid-scroll overlap is unavoidable with any fixed button
   and is what every page on this site already does; what is fixable is the
   page AT REST, so the last content row and the footer links both get out of
   its lane.                                                                */
body[data-chrome="ks4"] .k4-main { padding-bottom: 118px; }
body[data-chrome="ks4"] .k4-main.k4-home { padding-bottom: 108px; }

/* The landing's challenge strip is the one place where a PRIMARY control sat
   in the corner at rest — "Take the challenge", right-aligned in the last
   cell, with the FAB drawn straight across it. Reserving the FAB's lane keeps
   Design's right alignment and moves the button out from under it. The strip
   is an auto-fit grid, so it simply reflows into the narrower track.       */
@media (min-width: 901px) {
  body[data-chrome="ks4"] .k4-challenge { padding-right: 250px; }
}

@media (min-width: 561px) {
  body[data-chrome="ks4"] .k4-footer-inner { padding-right: 250px; }
}
@media (max-width: 560px) {
  /* Narrow, the footer stacks and the FAB shrinks to its icon, so the lane
     it needs is vertical rather than horizontal. */
  body[data-chrome="ks4"] .k4-footer-inner { padding-bottom: 76px; }
}

/* ── THE SIGNED-IN CHIP ───────────────────────────────────────────────────
   shared/nav.js writes this chip with INLINE styles — `background:
   var(--accent-soft); border:1px solid var(--accent-border); padding:5px 12px;
   font-size:0.82rem` — which is the classic nav's pill and is correct
   everywhere else on the site.

   Inline styles beat any selector, so it arrived inside Design's 44px header
   as a small pink lozenge (visible in the first 390px screenshot). The fix
   has to be `!important` and it has to be CSS: nav.js is loaded by all ~865
   LESSON pages, so editing it would change their bytes and their cache-bust
   stamps, which is the one thing this run may not do.                      */
body[data-chrome="ks4"] #nav-auth-area > a {
  background: var(--k4-card) !important;
  border: 1.5px solid var(--k4-border) !important;
  color: var(--k4-ink-2) !important;
  height: 44px !important;
  padding: 0 16px !important;
  border-radius: 999px !important;
  font-family: var(--k4-body) !important;
  font-size: 16px !important;
  font-weight: 600 !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 9px !important;
  white-space: nowrap;
}
body[data-chrome="ks4"] #nav-auth-area > a:hover { border-color: var(--k4-ink) !important; }
body[data-chrome="ks4"] #nav-auth-area > a span {
  color: var(--k4-ink-2) !important;
  font-weight: 600 !important;
  font-size: 16px !important;
}
body[data-chrome="ks4"] #nav-auth-area > a img {
  width: 28px !important; height: 28px !important;
  border: 1.5px solid var(--k4-border) !important;
}

/* ── DRAWER (injected by shared/nav.js — restyled, never re-emitted) ─── */

body[data-chrome="ks4"] .nav-drawer {
  background: var(--k4-ground); border-left: 2px solid var(--k4-ink); color: var(--k4-ink);
}
body[data-chrome="ks4"] .nav-drawer-title {
  font-family: var(--k4-display); font-weight: 800; letter-spacing: -.02em; color: var(--k4-ink);
}
body[data-chrome="ks4"] .nav-drawer-head { border-bottom: 1.5px solid var(--k4-border); }
body[data-chrome="ks4"] .nav-drawer-menu a,
body[data-chrome="ks4"] .nav-drawer-menu .nav-drawer-link {
  color: var(--k4-ink); font-weight: 600; border-bottom: 1.5px solid var(--k4-track);
  background: none; text-decoration: none;
}
body[data-chrome="ks4"] .nav-drawer-menu a:hover,
body[data-chrome="ks4"] .nav-drawer-menu .nav-drawer-link:hover {
  background: var(--k4-sunken-2); color: var(--k4-ink); text-decoration: none;
}
body[data-chrome="ks4"] .nav-drawer-auth { border-top: 1.5px solid var(--k4-border); }
/* ⊕ Mide, 4 Sep 2026 — the drawer's Sign In was rendering invisible: the
   blanket `body[data-chrome="ks4"] a { color: var(--k4-accent-deep) }` above
   beats `.btn-signin`'s own `color: var(--on-accent)` on specificity, and
   `.btn-signin`'s FILL (`background: var(--accent)`, from shared/nav.css)
   was untouched by any KS4 rule — dark text on a dark fill. `#nav-auth-area`
   already restyles both buttons for the desktop bar (a few lines up); the
   drawer needs the identical pair, because `.nav-drawer-auth` is a separate
   DOM location the ID selector above never reaches. Mirrored exactly, not
   reinvented: signin stays the neutral pill, signup stays the filled CTA. */
body[data-chrome="ks4"] .nav-drawer-auth a {
  display: inline-flex; align-items: center; height: 40px; padding: 0 14px;
  border-radius: 999px; font-weight: 600; text-decoration: none;
  background: var(--k4-card); border: 1.5px solid var(--k4-border);
  color: var(--k4-ink-2);
}
body[data-chrome="ks4"] .nav-drawer-auth a:hover { border-color: var(--k4-ink); color: var(--k4-ink-2); text-decoration: none; }
body[data-chrome="ks4"] .nav-drawer-auth .btn-signup {
  background: var(--k4-accent-deep); color: var(--k4-on-dark); border-color: var(--k4-accent-deep);
}
body[data-chrome="ks4"] .nav-drawer-auth .btn-signup:hover { background: var(--k4-accent-dark); border-color: var(--k4-accent-dark); color: var(--k4-on-dark); }
body[data-chrome="ks4"] .nav-drawer-close { color: var(--k4-ink); }

/* ── THE MOBILE PASS ────────────────────────────────────────────────────
   The header-overflow defect class: at 390px the nav cluster used to push
   the shell wider than the viewport and the whole page scrolled sideways.
   Nothing here may exceed 100vw, so the cluster wraps and the two icon
   buttons that duplicate a drawer row stand down below 560px.           */

@media (max-width: 900px) {
  body[data-chrome="ks4"] .k4-main { padding: 20px 18px 48px; }
  body[data-chrome="ks4"] .k4-main.k4-home { padding: 26px 18px 40px; }
  body[data-chrome="ks4"] .k4-navbar { padding: 8px 16px; gap: 10px; }
  body[data-chrome="ks4"] .k4-band { gap: 24px; }
  body[data-chrome="ks4"] .k4-doors { grid-template-columns: 1fr; }
  body[data-chrome="ks4"] .k4-challenge-cell + .k4-challenge-cell {
    border-left: 0; padding-left: 0; border-top: 1.5px solid var(--k4-border); padding-top: 16px;
  }
  body[data-chrome="ks4"] .k4-challenge-go { justify-content: flex-start; }
}

@media (max-width: 560px) {
  /* Both of these have a labelled row in the drawer, so hiding the icon
     costs nothing and buys the header its width back. The Challenge chip
     stays: it is the one action the site is asking for. */
  body[data-chrome="ks4"] .nav-icon-link,
  body[data-chrome="ks4"] .nav-text-link { display: none; }
  body[data-chrome="ks4"] .k4-navbar { padding: 8px 14px; gap: 8px; min-height: 58px; }
  body[data-chrome="ks4"] .nav-brand { font-size: 18px; gap: 7px; }
  body[data-chrome="ks4"] .challenge-chip { height: 40px; padding: 0 14px; font-size: 15px; }
  body[data-chrome="ks4"] .nav-icon-link,
  body[data-chrome="ks4"] .nav-burger { width: 40px; height: 40px; }
  body[data-chrome="ks4"] #nav-auth-area a,
  body[data-chrome="ks4"] #nav-auth-area > span { height: 40px; padding: 0 12px; font-size: 15px; }

  body[data-chrome="ks4"] .k4-door { padding: 24px 22px 22px; }
  body[data-chrome="ks4"] .k4-door.k4-door-sm { padding: 22px; }
  body[data-chrome="ks4"] .k4-row { padding: 16px 16px; gap: 14px; }
  body[data-chrome="ks4"] .k4-row-title { font-size: 20px; }
  body[data-chrome="ks4"] .k4-row.k4-row-st .k4-row-title { font-size: 19px; }
  body[data-chrome="ks4"] .k4-panel, body[data-chrome="ks4"] .k4-dark { padding: 20px; }
  body[data-chrome="ks4"] .k4-stars { padding: 20px; }
  body[data-chrome="ks4"] .k4-nextrow { padding: 18px; }
  body[data-chrome="ks4"] .k4-lede { font-size: 18px; }
  body[data-chrome="ks4"] .k4-crumbs { font-size: 12px; gap: 7px; }
}

/* Long topic titles are the only strings on these pages that can be wider
   than a 360px viewport on their own. */
body[data-chrome="ks4"] .k4-row-title,
body[data-chrome="ks4"] .k4-h1 { overflow-wrap: break-word; }
