/* home.css — the merged product's shell.
 *
 * Two moods from one stylesheet, switched by `body[data-mode]`:
 *
 *   adult — "aurora console": a dark cosmic stage, frosted glass, a little
 *           glow, Space Grotesk display type. Matches the /goals SPA.
 *   kid   — "arcade": warmer, rounder, more colour, Bricolage Grotesque, a
 *           companion and a crown count up top. No streak, no accuracy %, no
 *           timer, no number a child can watch fall (see #stat-streak below).
 *
 * The switch happens on sign-in, so a child never sees an interface designed
 * for someone reading a mortgage question.
 */

/* ------------------------------------------------------------------ themes
 *   data-mode  on <body>  — adult | kid  (font, accent hue, radius, feel)
 *   data-theme on <html>  — always "light" or "dark"; the <head> script
 *                           resolves "auto" against the OS and home.js keeps
 *                           it in sync, so there is no prefers-color-scheme
 *                           media query here.
 *
 * Light is the base; [data-theme="dark"] overrides. The dark side is the
 * original "aurora console" (adult) / "arcade" (kid); the light side is a
 * calmer paper — white cards, hairline borders, soft shadows instead of glow.
 * Kid constraints hold in both: no streak, no number a child can watch fall.
 * (light-dark() is not used — it is colours-only and can't carry the gradients
 * and shadows below.)
 */
:root {
  color-scheme: light;

  /* ADULT · LIGHT */
  --bg: #f5f6fb;  --bg-2: #ffffff;
  --card: #ffffff;  --card-2: #eef1f8;  --glass: rgba(255, 255, 255, 0.7);
  --line: #e3e7f0;  --line-lit: #6366f1;
  --ink: #191c28;  --ink-2: #484f63;  --ink-3: #7b8397;
  --accent: #7c3aed;  --accent-ink: #ffffff;
  --grad: linear-gradient(135deg, #6366f1, #8b5cf6);
  --warm: #7c3aed;  --good: #15803d;  --bad: #dc2626;  --on-good: #ffffff;  --on-bad: #ffffff;
  --radius: 14px;  --radius-lg: 20px;  --radius-xl: 26px;
  --shadow: 0 12px 30px -14px rgba(30, 30, 70, 0.2);
  --card-shadow: 0 4px 16px -10px rgba(30, 30, 70, 0.16);
  --track: rgba(20, 22, 45, 0.09);
  --scrim: rgba(25, 22, 50, 0.42);
  --hero-bg: linear-gradient(180deg, rgba(124, 58, 237, 0.05), #ffffff);
  --hero-shadow: 0 32px 80px -42px rgba(80, 60, 160, 0.32);
  --hero-ring-opacity: 0.32;
  --title-grad: linear-gradient(104deg, #4338ca 12%, #7c3aed 42%, #0ea5e9 66%, #4338ca 90%);
  --cta-shadow: 0 10px 26px -10px rgba(99, 102, 241, 0.5);
  --stage: none;

  --font:         "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-display: "Space Grotesk", var(--font);
  --font-mono:    "JetBrains Mono", ui-monospace, Menlo, Consolas, monospace;
}

:root[data-theme="dark"] {
  color-scheme: dark;

  /* ADULT · DARK — the "aurora console" */
  --bg: #05060d;  --bg-2: #0b0d18;
  --card: rgba(12, 16, 28, 0.55);  --card-2: rgba(255, 255, 255, 0.06);  --glass: rgba(255, 255, 255, 0.045);
  --line: rgba(255, 255, 255, 0.11);  --line-lit: rgba(125, 235, 255, 0.5);
  --ink: #f4f7ff;  --ink-2: rgba(228, 234, 250, 0.68);  --ink-3: rgba(228, 234, 250, 0.4);
  --accent: #5eead4;  --accent-ink: #04211c;
  --warm: #8b5cf6;  --good: #4ade80;  --bad: #f87171;  --on-good: #06240f;  --on-bad: #2a0a0a;
  --shadow: 0 18px 44px -26px rgba(0, 0, 0, 0.9);
  --card-shadow: 0 0 0 transparent;
  --track: rgba(255, 255, 255, 0.08);
  --scrim: rgba(3, 4, 10, 0.72);
  --hero-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.015));
  --hero-shadow: 0 40px 110px -46px rgba(90, 110, 210, 0.42);
  --hero-ring-opacity: 0.65;
  --title-grad: linear-gradient(104deg, #eef2ff 18%, #b7c0ff 42%, #7ff0dd 58%, #eef2ff 80%);
  --cta-shadow: 0 12px 32px -8px rgba(99, 102, 241, 0.7);
  --stage:
    radial-gradient(56% 44% at 12% 4%,  rgba(99, 102, 241, 0.28), transparent 72%),
    radial-gradient(50% 40% at 90% 6%,  rgba(56, 189, 248, 0.20), transparent 72%),
    radial-gradient(46% 52% at 82% 96%, rgba(217, 70, 239, 0.16), transparent 72%);
}

body[data-mode="kid"] {
  /* KID · LIGHT */
  --bg: #faf7ff;  --bg-2: #ffffff;
  --card: #ffffff;  --card-2: #f3eefd;  --glass: rgba(255, 255, 255, 0.72);
  --line: #e9e0f7;  --line-lit: #7c3aed;
  --ink: #2a2145;  --ink-2: #665a86;  --ink-3: #968aba;
  --accent: #c2410c;  --accent-ink: #ffffff;
  --grad: linear-gradient(135deg, #a3e635, #38e0d0);
  --warm: #d97706;
  --radius: 18px;  --radius-lg: 24px;  --radius-xl: 28px;
  --font-display: "Bricolage Grotesque", var(--font);
  --track: rgba(40, 20, 70, 0.1);
  --card-shadow: 0 4px 18px -10px rgba(90, 60, 160, 0.18);
  --hero-bg: linear-gradient(160deg, rgba(255, 209, 102, 0.16), #ffffff);
  --hero-shadow: 0 24px 60px -34px rgba(150, 110, 220, 0.35);
  --hero-ring-opacity: 0.4;
  --stage: radial-gradient(70% 45% at 50% -6%, rgba(192, 132, 252, 0.08), transparent 70%);
}

:root[data-theme="dark"] body[data-mode="kid"] {
  /* KID · DARK — the "arcade" */
  --bg: #130f26;  --bg-2: #1e1740;
  --card: #1e1740;  --card-2: #281e56;  --glass: #1e1740;
  --line: #3a2c73;  --line-lit: #ffd166;
  --ink: #f4efff;  --ink-2: #c3b3ef;  --ink-3: #8b7bc0;
  --accent: #ffd166;  --accent-ink: #3a2a00;
  --warm: #ffd166;
  --track: #281e56;
  --card-shadow: 0 0 0 transparent;
  --hero-bg: linear-gradient(160deg, rgba(255, 209, 102, 0.1), rgba(30, 23, 64, 0.6));
  --hero-shadow: 0 30px 90px -40px rgba(192, 132, 252, 0.6);
  --hero-ring-opacity: 0.5;
  --stage: radial-gradient(70% 50% at 50% -8%, rgba(192, 132, 252, 0.18), transparent 70%);
}

* { box-sizing: border-box; }

/* A <button> does not inherit colour or font from its context — the UA gives it
   a system text colour. Everything dynamically built as a <button> (.line,
   .game, .pet, .chip, .world…) relies on inheriting --ink, so without this the
   text renders in the browser's default button colour: dark-on-dark here.
   Components that want their own colour (.btn, .brand) set it explicitly and
   still win on specificity. */
button { font-family: inherit; color: inherit; }

/* min-height, never height: a fixed 100% caps the body box at one viewport
   while the content keeps growing past it, which makes the sticky top bar fall
   off the bottom of its own container as soon as you scroll. */
body {
  min-height: 100%;
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  background-image: var(--stage);
  background-attachment: fixed;
  pointer-events: none;
  z-index: 0;
}

.shell { position: relative; z-index: 1; max-width: 1000px; margin: 0 auto; padding: 0 20px 90px; }

/* ---------- top bar ---------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 15px 0 11px;
  background: linear-gradient(var(--bg) 74%, transparent);
}
.brand {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 20px;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin-right: auto;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 0;
}
.brand span { color: var(--accent); }

.stat {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 13.5px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  white-space: nowrap;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.stat b { color: var(--ink); font-weight: 600; }

/* The companion stat is a way into the companion screen (home.js openCompanion). */
#stat-pet { cursor: pointer; transition: border-color 0.14s; }
#stat-pet:hover, #stat-pet:focus-visible { border-color: var(--accent); outline: none; }

/* No streak for a kid profile.
 *
 * This is not a style choice, and it must survive a redesign. The research
 * behind the Math Quest rebuild is explicit: do not show a child an accuracy
 * percentage, a streak, or an effort score. Any visible number becomes the
 * thing that gets optimised for, and any number that can *fall* functions as a
 * loss even inside a system otherwise designed never to take anything away.
 *
 * XP stays. It only ever rises, and the old game showed a running gem count in
 * the same spot, so removing it would read as something being taken away.
 *
 * Hidden until the mode is known, rather than shown and then withdrawn: the
 * page renders before home.js sets data-mode, so keying off "kid" alone would
 * flash a streak at her for one frame and then take it away. */
#stat-streak { display: none; }
body[data-mode="adult"] #stat-streak { display: inline-flex; }

.stat.pulse { animation: pop 0.45s ease; }
@keyframes pop { 0% { transform: scale(1); } 40% { transform: scale(1.16); } 100% { transform: scale(1); } }

.iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px; height: 36px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--glass);
  color: var(--ink);
  font-size: 16px;
  cursor: pointer;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.iconbtn:hover { border-color: var(--accent); }

/* ---------- headings ---------- */
h1 {
  font-family: var(--font-display);
  font-size: clamp(28px, 5vw, 40px);
  line-height: 1.08;
  letter-spacing: -0.025em;
  margin: 22px 0 8px;
  text-wrap: balance;
}
/* Section headings used to be 12px, uppercase, 0.13em tracked and in the
   faintest ink on the page — the typography of a settings-panel label, on a
   page whose job is to be inviting. Read as a group they were the reason the
   page felt like a wall of small print. Now they are ordinary headings: big
   enough to scan, dark enough to read, with an optional plain-English line
   under them doing the work the tracking was pretending to do. */
h2 {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  text-transform: none;
  color: var(--ink);
  margin: 44px 0 6px;
}
.hsub { color: var(--ink-2); font-size: 15px; margin: 0 0 18px; }
.sub { color: var(--ink-2); margin: 0 0 22px; font-size: 17px; max-width: 54ch; }

/* ---------- hero ---------- */
.hero {
  position: relative;
  isolation: isolate;
  text-align: center;
  margin: 24px 0 10px;
  padding: clamp(2.75rem, 7vw, 4.25rem) clamp(1.25rem, 5vw, 3.25rem) clamp(2.25rem, 5vw, 3rem);
  border-radius: var(--radius-xl);
  border: 1px solid var(--line);
  background: var(--hero-bg);
  -webkit-backdrop-filter: blur(24px) saturate(150%);
  backdrop-filter: blur(24px) saturate(150%);
  box-shadow: var(--hero-shadow);
}
.hero::before {
  content: "";
  position: absolute; inset: -1px; z-index: -1;
  border-radius: inherit; padding: 1px;
  background: conic-gradient(from 140deg, #6366f1, #38bdf8, #8b5cf6, #5eead4, #6366f1);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  opacity: var(--hero-ring-opacity);
}
body[data-mode="kid"] .hero::before {
  background: conic-gradient(from 120deg, #ffd166, #f472b6, #a3e635, #38e0d0, #ffd166);
}
.hero h1 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2rem, 5vw, 3.2rem);
  letter-spacing: -0.022em;
  line-height: 1.05;
  background: var(--title-grad);
  background-size: 220% 100%;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: sheen 9s linear infinite;
}
body[data-mode="kid"] .hero h1 {
  background: none; -webkit-text-fill-color: currentColor; color: var(--ink);
  animation: none; font-weight: 700;
}
body[data-mode="kid"] .hero h1 em { font-style: normal; color: var(--accent); }
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .hero h1 { -webkit-text-fill-color: var(--ink); color: var(--ink); }
}
.hero .sub { margin: 14px auto 0; max-width: 46ch; font-size: 17.5px; line-height: 1.5; text-wrap: pretty; }

/* the typed-and-deleted topic entry (adult only) */
.ask { display: flex; gap: 10px; max-width: 620px; margin: 30px auto 0; }
.ask .box {
  flex: 1; min-height: 56px; padding: 0 18px;
  display: flex; align-items: center;
  font-size: 16px; color: var(--ink); text-align: left;
  background: var(--glass); border: 1px solid var(--line); border-radius: var(--radius);
}
.ask .box.typing .real { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.ask .box .ghost { color: var(--ink-3); white-space: pre; }
.ask .box .caret {
  display: inline-block; width: 2px; height: 1.15em; margin-left: 1px;
  background: var(--accent); vertical-align: -2px;
  animation: blink 1s step-end infinite;
}
.ask input.real {
  flex: 1; min-height: 64px; padding: 0 22px; font-size: 17px; font-family: var(--font);
  color: var(--ink); background: var(--bg-2); border: 1px solid var(--line);
  border-radius: 16px; width: auto;
}
.ask .real:focus { outline: none; border-color: var(--line-lit); box-shadow: 0 0 0 4px rgba(94, 234, 212, 0.13); }
/* `button.btn` is declared later in this file with the same specificity, so
   without the extra class here it silently wins on size and radius and the CTA
   comes out shorter than the field beside it. Matched to the field's height and
   to the pill shape of the four subject buttons below it. */
.ask button.btn {
  min-height: 64px; padding: 0 34px; white-space: nowrap;
  font-family: var(--font); font-weight: 700; font-size: 17px; color: #fff;
  border: 0; border-radius: 999px; cursor: pointer;
  background: var(--grad);
  box-shadow: var(--cta-shadow);
  transition: transform 0.14s ease, filter 0.14s ease;
}
body[data-mode="kid"] .ask button { color: var(--accent-ink); }
.ask button:hover { filter: brightness(1.08); transform: translateY(-1px); }

/* One-click ways in. The label sits on its own line so the buttons form a
   single readable row instead of trailing after a caption. */
.popular { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; align-items: center; margin-top: 22px; }
.popular .plab { flex-basis: 100%; text-align: center; font-size: 13.5px; color: var(--ink-2); margin-bottom: 2px; }
.mini {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 12px 20px; border-radius: 999px; background: var(--bg-2); border: 1px solid var(--line);
  color: var(--ink); font-size: 15px; font-weight: 600; font-family: var(--font);
  cursor: pointer; transition: 0.14s; box-shadow: var(--card-shadow);
}
.mini .me { font-size: 17px; line-height: 1; }
.mini:hover { border-color: var(--line-lit); transform: translateY(-1px); }

@keyframes blink { 50% { opacity: 0; } }
@keyframes sheen { from { background-position: 220% 0; } to { background-position: -20% 0; } }

/* ---------- pill chips (subjects) ---------- */
.chips { display: flex; flex-wrap: wrap; gap: 10px; }
.chip {
  display: flex; align-items: center; gap: 9px;
  padding: 11px 16px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card);
  color: var(--ink-2); font-size: 14.5px; font-weight: 500;
  cursor: pointer; text-align: left;
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  transition: transform 0.12s ease, border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.chip .emoji { font-size: 18px; line-height: 1; }
.chip small { display: none; }
.chip:hover { border-color: var(--line-lit); color: var(--ink); background: rgba(94, 234, 212, 0.07); transform: translateY(-1px); }
.chip.on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }

/* ---------- world grid (practice) ---------- */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(252px, 1fr)); gap: 16px; }
.world {
  position: relative;
  display: flex; flex-direction: column; gap: 4px;
  padding: 22px; min-height: 168px;
  border-radius: var(--radius-lg); border: 1px solid var(--line);
  background: var(--card); color: var(--ink); box-shadow: var(--card-shadow);
  cursor: pointer; overflow: hidden; text-align: left;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  transition: transform 0.14s ease, border-color 0.14s ease, box-shadow 0.14s ease;
}
.world:hover { transform: translateY(-3px); border-color: var(--wc, rgba(139, 92, 246, 0.5)); box-shadow: 0 0 34px -10px var(--wc, rgba(139, 92, 246, 0.5)); }
.world .bar { position: absolute; inset: 0 0 auto 0; height: 4px; background: var(--wc, linear-gradient(90deg, #5eead4, #38bdf8)); }
.world .top { display: flex; align-items: center; gap: 11px; }
.world .emoji { font-size: 30px; line-height: 1; }
.world .name { font-family: var(--font-display); font-weight: 600; font-size: 18px; letter-spacing: -0.015em; }
/* The one-line description was 11.5px monospace in the palest ink — the styling
   of a debug caption. It is the only sentence on the card that says what the
   world is about, so it gets read like one. */
.world .unit { color: var(--ink-2); font-size: 14px; line-height: 1.4; margin-top: 8px; }
.world .meter { height: 5px; border-radius: 999px; background: var(--track); overflow: hidden; margin-top: 14px; }
.world .meter i { display: block; height: 100%; background: var(--wc, var(--grad)); }
.world .foot { display: flex; justify-content: space-between; font-size: 12.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; margin-top: 7px; }
/* Every tile is a button, so every tile says so. `margin-top:auto` pins it to
   the bottom edge whether or not the card carries a meter, which keeps a row
   of cards aligned. */
.world .go {
  display: inline-flex; align-items: center; align-self: flex-start;
  margin-top: auto; padding-top: 16px;
  font-family: var(--font-display); font-weight: 600; font-size: 15px;
  color: var(--accent);
}
:root[data-theme="light"] .world .go { color: var(--warm); }

/* Locked world (kid progressive unlock) — visible so the ladder reads as a
   ladder, dimmed and non-playing, with the "how to open it" line where the
   meter would be. */
.world.locked { opacity: 0.55; border-style: dashed; }
.world.locked:hover { transform: none; box-shadow: var(--card-shadow); border-color: var(--line); }
.world.locked .bar { background: var(--line); }
.world .lockhint { display: block; margin-top: 12px; font-size: 12px; color: var(--ink-3); font-family: var(--font-mono); }

/* Mystery tile — the *next* world to open, teased rather than named. Warmer
   than a plain locked tile (an invite, not a "no"); a slow pulse on the emoji
   hints something is coming without being a distraction. */
.world.mystery { opacity: 0.85; border-style: dashed; border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.world.mystery:hover { transform: none; box-shadow: var(--card-shadow); }
.world.mystery .bar { background: color-mix(in srgb, var(--accent) 30%, var(--line)); }
.world.mystery .emoji { animation: mystery-pulse 2.4s ease-in-out infinite; }
@keyframes mystery-pulse { 0%, 100% { opacity: 0.7; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .world.mystery .emoji { animation: none; } }

/* Kid worlds get more presence: bigger, rounder, a real colour of their own on
   the bar / meter / glow, and a Play affordance in the corner. */
body[data-mode="kid"] .world {
  padding: 20px; min-height: 150px; border-radius: 22px;
}
/* The kid Play affordance is absolutely positioned in the corner (below), so
   the card has to keep that corner clear — otherwise, on a world she has
   actually played, it lands on top of the "N answered / N% solid" line. */
body[data-mode="kid"] .world:not(.special) { padding-bottom: 42px; }
body[data-mode="kid"] .world .bar { height: 6px; }
body[data-mode="kid"] .world .emoji { font-size: 30px; filter: drop-shadow(0 4px 12px var(--wc, transparent)); }
body[data-mode="kid"] .world .name { font-size: 17px; }
body[data-mode="kid"] .world .meter { height: 6px; background: var(--track); margin-top: 14px; }
body[data-mode="kid"] .world:hover { transform: translateY(-4px) scale(1.01); border-color: var(--wc, var(--accent)); box-shadow: 0 20px 50px -20px var(--wc, rgba(255, 209, 102, 0.5)); }
body[data-mode="kid"] .world:not(.special) .go {
  display: block;
  position: absolute; right: 18px; bottom: 15px;
  font-family: var(--font-display); font-weight: 700; font-size: 14px;
  /* light: --wc is a colour picked against a dark ground and fails contrast as
     text on a white card (down to 1.4:1). The card already carries the world's
     colour on the bar, meter and emoji glow; the CTA just needs to be legible. */
  color: var(--ink);
}
:root[data-theme="dark"] body[data-mode="kid"] .world:not(.special) .go {
  color: var(--wc, var(--accent));
}

/* the two quieter cards after the worlds: Surprise me / More */
.world.special {
  background: var(--glass); border-style: dashed;
  align-items: center; justify-content: center; text-align: center; gap: 2px;
}
.world.special .emoji { font-size: 32px; margin-bottom: 6px; }
.world.special .name { color: var(--ink); font-family: var(--font-display); font-weight: 600; font-size: 17px; }
.world.special .cap { color: var(--ink-2); font-size: 14px; }
.world.special.boost {
  background: linear-gradient(140deg, color-mix(in srgb, var(--good) 16%, var(--card)), var(--card));
  border-color: color-mix(in srgb, var(--good) 40%, var(--line));
  border-style: solid;
}

/* ---------- kid: pick-a-game tiles ---------- */
.games { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 14px; }
.game {
  padding: 18px; border-radius: var(--radius-lg);
  background: var(--card); border: 1px solid var(--line); box-shadow: var(--card-shadow);
  cursor: pointer; text-align: left; transition: transform 0.14s ease, border-color 0.14s ease;
}
.game:hover { transform: translateY(-3px); border-color: var(--accent); }
.game .ge { font-size: 26px; }
.game .gn { font-family: var(--font-display); font-weight: 700; font-size: 16px; margin-top: 8px; }
.game .gd { color: var(--ink-3); font-size: 12.5px; margin-top: 2px; }
.game.feature { background: linear-gradient(140deg, rgba(255, 209, 102, 0.14), var(--card)); border-color: rgba(255, 209, 102, 0.4); }

/* ---------- kid: "Suggested" plays (docs/kid-mode.md) ---------- */
.plays { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 14px; }
.play-card {
  display: flex; flex-direction: column; gap: 4px;
  padding: 20px; border-radius: 20px;
  background: linear-gradient(150deg, color-mix(in srgb, var(--accent) 14%, var(--card)), var(--card));
  border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--line));
  box-shadow: var(--card-shadow);
  cursor: pointer; text-align: left;
  transition: transform 0.14s ease, border-color 0.14s ease, box-shadow 0.14s ease;
}
.play-card:hover { transform: translateY(-3px); border-color: var(--accent); box-shadow: 0 18px 44px -22px color-mix(in srgb, var(--accent) 60%, transparent); }
.play-card .pe { font-size: 30px; }
.play-card .pn { font-family: var(--font-display); font-weight: 700; font-size: 17px; }
.play-card .pt { color: var(--ink-3); font-size: 12.5px; }
@media (prefers-reduced-motion: reduce) { .play-card { transition: none; } }

/* The shell a play mounts into. Each play owns the look inside #play-root. */
#play-root { margin-top: 6px; }

/* ---------- "not sure where to start" ----------
   Lives in the hero now, directly under the two ways in it is an alternative
   to. Deliberately the quietest of the three: a third equally loud button
   would just be a third decision. */
.startpath {
  margin: 28px auto 0; max-width: 620px; width: 100%;
  padding: 14px 20px; border-radius: var(--radius-lg);
  border: 1px dashed var(--line); background: transparent;
  display: flex; align-items: center; gap: 14px; cursor: pointer;
  text-align: left; font-family: inherit; color: inherit;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.startpath:hover { border-color: var(--line-lit); background: var(--card-2); }
.startpath .big { font-size: 22px; }
.startpath .t { flex: 1; }
.startpath .t b { font-family: var(--font-display); font-weight: 600; font-size: 15px; display: block; }
.startpath .t span { color: var(--ink-3); font-size: 13px; }
.startpath .go { color: var(--accent); font-weight: 700; font-size: 18px; }

/* ---------- how it works (first visit only) ----------
   Three boxes answering "what happens if I press the button", which the page
   never said anywhere. Numbered by position, not by a badge — the arrow
   between them carries the sequence on a wide screen. */
.howto {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;
  margin-top: 30px;
}
.howto-step {
  position: relative;
  padding: 18px 18px 18px 20px;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--card); box-shadow: var(--card-shadow);
}
.howto-step .he { font-size: 24px; display: block; margin-bottom: 8px; }
.howto-step b { font-family: var(--font-display); font-weight: 600; font-size: 16px; display: block; }
.howto-step span:not(.he) { display: block; color: var(--ink-2); font-size: 14px; margin-top: 3px; line-height: 1.45; }
.howto-step + .howto-step::before {
  content: "→"; position: absolute; left: -13px; top: 50%; transform: translateY(-50%);
  color: var(--ink-3); font-size: 14px;
}

/* ---------- the subject long tail, behind one click ---------- */
.disclose {
  display: flex; align-items: center; gap: 10px; width: 100%;
  margin-top: 44px; padding: 16px 20px;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--card); box-shadow: var(--card-shadow);
  cursor: pointer; text-align: left;
  transition: border-color 0.15s ease;
}
.disclose:hover { border-color: var(--line-lit); }
.disclose-t { font-family: var(--font-display); font-weight: 600; font-size: 17px; }
.disclose-c { color: var(--ink-3); font-size: 14px; margin-right: auto; }
/* Drawn, not typed: ▾ renders as a near-invisible speck in Inter on Windows,
   which is exactly the kind of unreadable micro-glyph this pass is removing. */
.disclose .cav {
  width: 9px; height: 9px; margin: -4px 4px 0 0; flex: none;
  border-right: 2px solid var(--accent); border-bottom: 2px solid var(--accent);
  transform: rotate(45deg); transition: transform 0.18s ease;
}
:root[data-theme="light"] .disclose .cav { border-color: var(--warm); }
.disclose.open .cav { margin: 2px 4px 0 0; transform: rotate(-135deg); }
#subjects { margin-top: 14px; }

/* ---------- generic surfaces ---------- */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px;
  box-shadow: var(--card-shadow);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.spread { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.muted { color: var(--ink-2); }
.dim { color: var(--ink-3); font-size: 13px; }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

button.btn {
  font-family: var(--font);
  font-size: 15px;
  font-weight: 600;
  padding: 11px 18px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--card-2);
  color: var(--ink);
  cursor: pointer;
}
button.btn:hover { border-color: var(--accent); }
button.btn.primary { background: var(--grad); color: #fff; border-color: transparent; box-shadow: var(--cta-shadow); }
body[data-mode="kid"] button.btn.primary { color: var(--accent-ink); }
button.btn.primary:hover { filter: brightness(1.08); }
button.btn.ghost { background: transparent; color: var(--ink-2); }
button.btn:disabled { opacity: 0.5; cursor: default; }

input[type="text"], input[type="email"], input[type="password"], textarea {
  width: 100%;
  font-family: var(--font);
  font-size: 15px;
  padding: 11px 13px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--bg-2);
  color: var(--ink);
}
input:focus, textarea:focus { outline: none; border-color: var(--accent); }
textarea { min-height: 90px; resize: vertical; line-height: 1.5; }
label.field { display: block; margin-bottom: 12px; }
label.field span { display: block; font-size: 13px; color: var(--ink-2); margin-bottom: 5px; }

/* ---------- the question card ---------- */
.run { max-width: 640px; margin: 0 auto; }
.runhead { display: flex; align-items: center; gap: 10px; margin: 8px 0 16px; }
.runhead .skill { font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-3); }
.runhead .count { font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-3); }
.runhead .band, .runhead .count { margin-left: auto; }
/* "· why?" — a kid-only, always-available reveal of the one honest sentence on
   why a skill matters (docs/kid-mode.md half-one item 2). One sentence, no expansion. */
.whybtn {
  font-family: var(--font-mono); font-size: 12px; line-height: 1;
  color: var(--ink-3); background: none; border: 0; padding: 2px 4px;
  cursor: pointer; border-radius: 6px;
}
.whybtn:hover, .whybtn:focus-visible { color: var(--accent); outline: none; }
.whytext {
  margin: 0 0 18px; padding: 10px 13px; border-radius: var(--radius);
  background: color-mix(in srgb, var(--accent) 7%, var(--card));
  border: 1px solid color-mix(in srgb, var(--accent) 22%, var(--line));
  color: var(--ink-2); font-size: 13.5px; line-height: 1.5;
}
.band { display: inline-flex; gap: 3px; }
.band i { width: 6px; height: 6px; border-radius: 50%; background: var(--line); }
.band i.on { background: var(--accent); }

/* Boss chip — the optional "3 hard ones and you're done here" offer on the
   first question of a kid world run (docs/kid-mode.md build #3). */
.bosschip {
  display: block; width: 100%; margin: -6px 0 16px;
  padding: 11px 15px; border-radius: 14px; text-align: left;
  font-family: var(--font-display); font-weight: 600; font-size: 13.5px;
  color: var(--ink);
  background: linear-gradient(120deg, color-mix(in srgb, var(--accent) 18%, var(--card)), var(--card));
  border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--line));
  cursor: pointer; transition: transform .12s ease, border-color .12s ease;
}
.bosschip:hover { transform: translateY(-1px); border-color: var(--accent); }

/* The three-way "not into this one" pick (kid). */
.reasons { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.reasons .btn { font-size: 13px; padding: 7px 12px; }
@media (prefers-reduced-motion: reduce) { .bosschip { transition: none; } }

.q {
  font-size: clamp(19px, 3.2vw, 24px);
  line-height: 1.4;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.015em;
  margin: 0 0 20px;
  text-wrap: pretty;
}
body[data-mode="kid"] .q { font-size: clamp(21px, 4vw, 28px); }
.q b { color: var(--accent); font-weight: 700; }

/* Boost's "pet asks first" comic panel — a companion character offering help
   on one missed skill at a time, instead of a plain "1 of 6" walkthrough list
   (that count read as a tally of failures, not an invite). Thick outline +
   hard offset shadow + a speech-bubble tail is the cheapest comic-book
   read without needing real artwork. */
.boost-scene { display: flex; align-items: flex-start; gap: 14px; }
.boost-avatar {
  flex: 0 0 auto; width: 58px; height: 58px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 30px; background: var(--card-2);
  border: 3px solid var(--ink); box-shadow: 3px 3px 0 var(--ink);
}
.boost-bubble {
  position: relative; flex: 1 1 auto; min-width: 0;
  padding: 16px 18px; border-radius: var(--radius-lg);
  background: var(--card); border: 3px solid var(--ink);
  box-shadow: 4px 4px 0 var(--ink);
}
.boost-bubble::before {
  content: ""; position: absolute; left: -13px; top: 18px;
  width: 0; height: 0; border-style: solid;
  border-width: 8px 13px 8px 0;
  border-color: transparent var(--ink) transparent transparent;
}
.boost-bubble::after {
  content: ""; position: absolute; left: -9px; top: 20px;
  width: 0; height: 0; border-style: solid;
  border-width: 6px 10px 6px 0;
  border-color: transparent var(--card) transparent transparent;
}
.boost-say {
  margin: 0 0 8px; font-family: var(--font-display); font-weight: 700;
  font-size: clamp(17px, 3vw, 20px); line-height: 1.3; color: var(--ink);
}
.boost-topic {
  display: inline-block; margin: 0 0 12px; padding: 3px 10px;
  border-radius: 999px; font-size: 12px; font-weight: 600;
  color: var(--accent-ink); background: var(--accent);
}
.boost-q {
  margin: 0 0 16px; padding: 12px 14px; border-radius: 10px;
  background: var(--card-2); font-family: var(--font-display);
  font-weight: 600; font-size: clamp(17px, 3vw, 21px); color: var(--ink);
}
.boost-choices { display: flex; gap: 10px; flex-wrap: wrap; }

.choices { display: grid; gap: 10px; }
.choice {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 15px 17px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink);
  font-size: 16.5px;
  text-align: left;
  cursor: pointer;
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  transition: border-color 0.12s ease, background 0.12s ease, transform 0.12s ease;
}
.choice:hover:not(:disabled) { border-color: var(--accent); transform: translateX(2px); }
.choice .key {
  flex: none;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border-radius: 8px;
  background: var(--card-2);
  color: var(--ink-3);
  font-family: var(--font-mono);
  font-size: 12px;
}
.choice.right { border-color: var(--good); background: rgba(74, 222, 128, 0.12); }
.choice.right .key { background: var(--good); color: var(--on-good); }
.choice.wrong { border-color: var(--bad); background: rgba(248, 113, 113, 0.12); }
.choice.wrong .key { background: var(--bad); color: var(--on-bad); }
.choice:disabled { cursor: default; }

.verdict { margin-top: 18px; padding: 15px 17px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--card); }
.verdict.right { border-color: rgba(74, 222, 128, 0.5); }
.verdict.wrong { border-color: rgba(248, 113, 113, 0.45); }
/* Kid mode: a miss is a "here's something to learn" moment, not an alarm — a
   warm accent border and a soft tinted fill, no red. */
body[data-mode="kid"] .verdict.wrong {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line));
  background: color-mix(in srgb, var(--accent) 7%, var(--card));
}
body[data-mode="kid"] .verdict.wrong h4 { color: var(--accent); }
.verdict h4 { margin: 0 0 6px; font-family: var(--font-display); font-size: 15px; }
.verdict p { margin: 0; color: var(--ink-2); font-size: 15px; line-height: 1.55; }
.verdict b { color: var(--ink); }

.gain {
  position: fixed;
  left: 50%;
  top: calc(64px + var(--gain-slot, 0) * 44px);
  transform: translateX(-50%);
  padding: 9px 16px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 700;
  font-size: 15px;
  z-index: 40;
  pointer-events: none;
  animation: rise 1.1s ease forwards;
}
@keyframes rise {
  0% { opacity: 0; transform: translate(-50%, -12px); }
  18% { opacity: 1; transform: translate(-50%, 0); }
  75% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -10px); }
}

/* ---------- companions ---------- */
.pets { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; }
.pet { padding: 16px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--card); text-align: center; cursor: pointer; }
.pet.active { border-color: var(--accent); }
.pet .glyph { font-size: 34px; line-height: 1.2; }
.pet .name { font-family: var(--font-display); font-weight: 600; margin-top: 4px; }
.pet .meter { height: 5px; border-radius: 999px; background: var(--track); overflow: hidden; margin: 9px 0 6px; }
.pet .meter i { display: block; height: 100%; background: var(--warm); }
.pet .stages { font-size: 15px; letter-spacing: 3px; opacity: 0.4; }

/* ---------- onboarding sheet ("not sure where to start") ---------- */
.sheet {
  position: fixed; inset: 0; z-index: 50;
  display: none; place-items: center; padding: 20px;
  background: var(--scrim);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.sheet.on { display: grid; }
.sheet .panel {
  max-width: 460px; width: 100%; padding: 30px;
  border-radius: var(--radius-xl); border: 1px solid var(--line);
  background: var(--bg-2);
  box-shadow: var(--shadow);
}
.sheet .step { font-family: var(--font-display); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); }
.sheet h3 { font-family: var(--font-display); font-weight: 600; font-size: 21px; margin: 10px 0 18px; letter-spacing: -0.01em; }
.sheet .opt {
  display: block; width: 100%; text-align: left;
  padding: 14px 16px; margin-bottom: 9px;
  border-radius: 12px; border: 1px solid var(--line);
  background: var(--glass); color: var(--ink);
  font-size: 15px; font-family: var(--font); cursor: pointer; transition: 0.12s;
}
.sheet .opt:hover { border-color: var(--accent); background: rgba(94, 234, 212, 0.08); }

/* ---------- misc ---------- */
.hidden { display: none !important; }
.err { color: var(--bad); font-size: 14px; margin: 8px 0 0; }
.ok { color: var(--good); font-size: 14px; margin: 8px 0 0; }
.list { display: flex; flex-direction: column; gap: 8px; }
.line { display: flex; justify-content: space-between; gap: 12px; padding: 11px 14px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); box-shadow: var(--card-shadow); font-size: 14.5px; }
.line b { font-variant-numeric: tabular-nums; font-weight: 600; }
.line b.ok { color: var(--good); }
.line b.bad { color: var(--bad); }

.done-h { font-family: var(--font-display); font-size: 22px; letter-spacing: -0.02em; margin: 6px 0 16px; text-transform: none; color: var(--ink); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
  .hero h1 { animation: none; background-position: 0 0; }
  .ask .box .caret { animation: none; }
  .gain { animation: none; }
  .stat.pulse { animation: none; }
  .chip, .world, .choice, .game, .mini { transition: none; }
}

@media (max-width: 640px) {
  .shell { padding: 0 14px 100px; }
  .grid { grid-template-columns: 1fr 1fr; }
  .games { grid-template-columns: 1fr 1fr; }
  /* `.plays` kept its 230px minimum on a 375px screen, so three suggested plays
     stacked into three full-width cards and ate the whole first screen: measured
     on a 375x812 phone, "Your worlds" sat at y=767 and the first world tile ran
     800-950, so twelve pixels of it were visible. The hero says "Pick a world.
     Play." and the worlds were below the fold. Two-up and tighter, like the
     other grids here. */
  .plays { grid-template-columns: 1fr 1fr; gap: 10px; }
  .play-card { padding: 13px; border-radius: 16px; gap: 2px; }
  .play-card .pe { font-size: 22px; }
  .play-card .pn { font-size: 15px; }
  .play-card .pt { font-size: 11.5px; line-height: 1.3; }
  /* Adult tiles carry a real sentence and a Start button now, so 165px-wide
     columns would shred them; kid tiles stay two-up (docs/kid-mode.md: she should
     not have to scroll to reach the thing the page just told her to do). */
  .grid { grid-template-columns: 1fr; gap: 12px; }
  /* One column, but no fixed height: a 168px card holding a name, one line and
     a link is mostly air, and nine of them is a long thumb-scroll to reach the
     bottom of a list the visitor is meant to skim. */
  .world { min-height: 0; padding: 16px 18px; }
  .world .emoji { font-size: 26px; }
  .world .unit { margin-top: 6px; }
  .world .go { padding-top: 12px; }
  body[data-mode="kid"] .grid { grid-template-columns: 1fr 1fr; }
  body[data-mode="kid"] .world { min-height: 132px; padding: 16px; }
  body[data-mode="kid"] .world .unit { display: none; }
  .hero { padding: 2.25rem 1.1rem 1.9rem; }
  .ask { flex-direction: column; gap: 12px; }
  .ask input.real, .ask .box { width: 100%; }
  .ask button { width: 100%; }
  .howto { grid-template-columns: 1fr; gap: 10px; }
  .howto-step { padding: 14px 16px; }
  .howto-step .he { font-size: 20px; margin-bottom: 5px; }
  .howto-step + .howto-step::before { content: none; }
  .mini { padding: 11px 16px; font-size: 14.5px; }
  h2 { font-size: 20px; }
}

/* The way back to the five-minute collection, on the adult home page. */
/* The way back to the five-minute collection, on the adult home page. It used
   to be a heading plus a thin bordered box; the heading only repeated what the
   box already said, so the box absorbed it and became a real card. */
#try-block { margin-top: 30px; }
.trycard {
  display: flex; align-items: center; gap: 16px;
  padding: 20px 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--card);
  box-shadow: var(--card-shadow);
  text-decoration: none;
  color: inherit;
  transition: border-color .15s ease, transform .15s ease;
}
.trycard:hover { border-color: var(--line-lit); transform: translateY(-2px); }
.trycard-e { font-size: 28px; line-height: 1; }
.trycard-x { flex: 1; }
.trycard-t { display: block; font-family: var(--font-display); font-weight: 600; font-size: 17px; }
.trycard-s { display: block; margin-top: 3px; color: var(--ink-2); font-size: 14.5px; }
.trycard-go { color: var(--accent); font-weight: 700; font-size: 18px; }
:root[data-theme="light"] .trycard-go { color: var(--warm); }
