/* THE BRAND AND THE FRAME, IN ONE FILE.

   Values chosen 2026-09-06 from a side-by-side comparison of a cool and a warm palette,
   each in both themes, against an identical scene. Warm won. Every ink-on-ground pairing
   below clears WCAG AA (4.5:1), computed rather than assumed.

   THE WALL, and it is the reason this file exists rather than being inlined:
     the FRAME reads --frame-* and nothing else.
     the PLAY AREA reads --scene-* and nothing else.
   A visit that sets a --frame-* token is a gate failure and tools/check.js enforces it.
   Rebranding is then one file, while scene mood varies per visit and per level — which is
   the anti-staleness engine, and the whole point of the wall.

   THE FRAME STAYS QUIET, and that is the real constraint. Duolingo, Khan Academy and Toca
   Boca all put their loud colour on the chrome, because for them the chrome IS the product.
   Here the scene changes per visit and per level, so a loud frame would fight every scene
   we ever build. The brand keeps the blue and the green; the ground gets out of the way. */

:root {
  /* SYSTEM FONT STACK, NO WEB FONT. An external font breaks the assets-stay-on-our-origin
     rule and puts a network wait in front of a child. The system stack renders instantly
     and looks native on the phone she is actually holding. */
  --font-ui: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --radius: 14px;
  --tap-min: 44px;

  --frame-bg:     #FDF7EF;   /* cream ground */
  --frame-line:   #EADFCE;
  --frame-ink:    #2A2119;   /* warm near-black */
  --frame-muted:  #7A6A58;
  --frame-accent: #2D6BE4;   /* the khelosikho blue, unchanged */
  --on-accent:    #FFFFFF;
  --ok:           #12855E;   /* the green already in the mark */
  /* THE CALL TO ACTION (his call, 2026-10-11: "buttons should look the same as the home page"): the
     landing page's green pill, in both themes, on every primary button of the app. White on it is 4.6:1. */
  --cta:          #12855E;
  --on-cta:       #FFFFFF;
  /* LOG OUT ONLY, on the parent's settings page (his call). Never on anything a child answers: there,
     wrong is a consequence, not a verdict, and `--not-yet` stays amber. */
  --danger:       #B83A26;

  /* AMBER, WHERE THE CATEGORY USES RED. Duolingo's #FF4B4B does errors and lost lives.
     Red is a verdict, and the rule here is that wrong is a consequence, never a verdict —
     the token is named `not-yet` for exactly that reason. A red value would quietly
     reintroduce the thing the name was chosen to prevent. */
  --not-yet:      #E39A0C;
}

/* DARK MODE: BUILD BOTH, DEFAULT TO NEITHER — follow the device.

   Checked against the evidence rather than assumed: there is no evidence dark mode reduces
   eye strain in normal light, and for reading, dark-on-light measurably wins. It does help
   in a dim room, which is a real case for a child playing near bedtime.

   The deciding point: in dark mode the pupil dilates, which stops masking optical
   aberration, so white-on-black haloes for astigmatism and myopia. SHE WEARS GLASSES. A
   forced dark default would be betting against her own eyes. Her device already knows
   whether it is bedtime. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --frame-bg: #17120D; --frame-line: #372C20; --frame-ink: #F5EDE1;
    --frame-muted: #B0A08C; --frame-accent: #7FA8FF; --on-accent: #17120D;
    --ok: #3FBF8F; --not-yet: #F0B23C; --danger: #FF8C78;
  }
}

/* The SAME overrides again, so an explicit choice wins BOTH ways. Without this block a
   child whose phone prefers light and who chooses dark gets nothing at all — the media
   query above never matches for her. */
:root[data-theme="dark"] {
  --frame-bg: #17120D; --frame-line: #372C20; --frame-ink: #F5EDE1;
  --frame-muted: #B0A08C; --frame-accent: #7FA8FF; --on-accent: #17120D;
  --ok: #3FBF8F; --not-yet: #F0B23C; --danger: #FF8C78;
}

/* THE SCENE TOKENS' FALLBACKS. A visit's real palette is written from data by scene.js.

   The fallbacks here are NOT a scene palette — they are what a visit looks like if its
   data forgot to set one, and they are deliberately the frame's own values so a forgotten
   scene reads as plain rather than as garish nonsense in front of a child. A real visit
   always overrides all three.

   ⛔ ON :root, NOT ON .stage — moved 2026-09-13, and the difference was visible. scene.js
   writes the visit's palette on the stage's PARENT, the viewport, so the scene bleeds
   sideways on a wide screen. A custom property set on an element beats one it inherits, so
   while these fallbacks sat on .stage the visit's palette never reached the stage at all:
   the play area painted frame cream (#FDF7EF) beside a side bleed in the scene's own colour
   (#F3E7D3), and every --scene-accent inside it was really the frame accent. On :root they
   are the furthest ancestor, so anything the visit writes below them wins. */
:root {
  --scene-bg:     var(--frame-bg);
  --scene-ink:    var(--frame-ink);
  --scene-accent: var(--frame-accent);
}

/* ------------------------------------------------------------------ base reset ------
   EVERY <button> NEEDS color:inherit AND font:inherit. A button does NOT inherit them —
   it falls back to the UA default, which is invisible in light mode and broken in dark.
   This shipped once, making every text answer unreadable.

   Set here, globally, rather than checked: a checker would find it after the fact, and a
   global rule makes the defect structurally impossible instead. Same for the tap floor. */
button, input, select, textarea {
  font: inherit;
  color: inherit;
}
button {
  min-height: var(--tap-min);
  min-width: var(--tap-min);
  cursor: pointer;
  background: none;
  border: 0;
}

/* NO HORIZONTAL SCROLLING AT 360px, enforced structurally rather than hoped for. */
html, body {
  margin: 0;
  padding: 0;
  overflow-x: hidden;
  background: var(--frame-bg);
  color: var(--frame-ink);
  font-family: var(--font-ui);
  /* dvh, not vh — mobile browser chrome makes vh overshoot and clip the bottom bar,
     which is where the mic lives. */
  min-height: 100dvh;
}

/* The one thing every scene needs and no scene should have to remember. */
img, svg { max-width: 100%; }
