/* ═══ Quick Brain! — playful game styles ═══ */

/* ── Bundled fonts (self-hosted woff2, latin subset — offline, cross-platform). SIL OFL.
   Fredoka = display; Baloo 2 = UI/keys; Nunito = body. See docs/quick-brain-style-guide.md ── */
@font-face { font-family:"Fredoka"; font-style:normal; font-weight:500; font-display:swap; src:url("../fonts/fredoka-500.woff2") format("woff2"); }
@font-face { font-family:"Fredoka"; font-style:normal; font-weight:600; font-display:swap; src:url("../fonts/fredoka-600.woff2") format("woff2"); }
@font-face { font-family:"Fredoka"; font-style:normal; font-weight:700; font-display:swap; src:url("../fonts/fredoka-700.woff2") format("woff2"); }
@font-face { font-family:"Baloo 2"; font-style:normal; font-weight:500 800; font-display:swap; src:url("../fonts/baloo2.woff2") format("woff2"); } /* variable */
@font-face { font-family:"Nunito"; font-style:normal; font-weight:400; font-display:swap; src:url("../fonts/nunito-400.woff2") format("woff2"); }
@font-face { font-family:"Nunito"; font-style:normal; font-weight:700; font-display:swap; src:url("../fonts/nunito-700.woff2") format("woff2"); }
@font-face { font-family:"Nunito"; font-style:normal; font-weight:800; font-display:swap; src:url("../fonts/nunito-800.woff2") format("woff2"); }

* { margin: 0; padding: 0; box-sizing: border-box; }

/* ── "2b" light-pastel design system — docs/quick-brain-style-guide.md is the source of truth.
   Legacy token names are kept mapped to their new role so existing rules update for free. ── */
:root {
  --bg: linear-gradient(165deg, #fdf0f7, #eaf3ff); /* screen background */
  --bg-solid: #f4eef9;                              /* anti-flash base */
  --surface: #ffffff;
  --card: #ffffff;                                  /* legacy name → white card */
  --card-hi: #f6f2ff;                               /* selected / hover tint */
  --ink: #5b4a7d;                                   /* primary text */
  --ink-dim: #a99fc4;                               /* secondary text */
  --text-status: #9a8fb8;

  --lilac: #b8a4f0;   --pink: #e0559a;   --pink-soft: #ff9ec4;
  --peach: #ffc59e;   --sky: #9cd3ff;    --cube: #7cb8f5;

  --mint: #86e0c0;    --mint-dark: #5fc9a3;
  --good: #86e0c0;    /* legacy name → mint (correct/confirm) */
  --bad: #e0559a;     /* legacy name → pink (incorrect) */
  --gold: #f0a93c;    --flame: #ff7a3c;
  --yellow: #ffe08a;  --yellow-dark: #e6c256;  --yellow-text: #8a6a00;
  --accent: #f0a93c;  /* legacy name → gold (scores / highlights) */

  --card-shadow: rgba(160, 130, 210, 0.16);
  --key-shadow: #e4dbf5;
  --shadow: 0 5px 0 var(--key-shadow);         /* signature chunky 3D key/button */
  --soft-shadow: 0 8px 18px var(--card-shadow); /* soft candy card shadow */

  --radius: 22px;  --r-card: 22px;  --r-btn: 16px;  --r-pill: 999px;

  --font-display: "Fredoka", ui-rounded, "SF Pro Rounded", "Segoe UI", system-ui, sans-serif;
  --font-ui: "Baloo 2", ui-rounded, "SF Pro Rounded", "Segoe UI", system-ui, sans-serif;
  --font-body: "Nunito", ui-rounded, "SF Pro Rounded", "Segoe UI", system-ui, sans-serif;
}

html, body { height: 100%; }
/* Solid light base so scrolled / over-scrolled areas never flash a dark edge. */
html { background: var(--bg-solid); }

body {
  font-family: var(--font-body);
  font-synthesis: none;
  /* `fixed` anchors the gradient to the viewport so it doesn't rescale to the full
     scroll height on long screens. */
  background: var(--bg) fixed;
  background-color: var(--bg-solid);
  color: var(--ink);
  -webkit-user-select: none;
  user-select: none;
  overflow-x: hidden;
  /* Native app feel inside a WebView: no rubber-band scroll, no long-press
     callout, no double-tap zoom / tap-highlight. Harmless in a browser. */
  overscroll-behavior: none;
  -webkit-touch-callout: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

/* ── Icon system (inline SVG sprite) ───────────────────────────────────
   `.ic` is the default inline glyph: it flows with text at the current
   font size. Chrome/UI icons inherit `currentColor`; content icons carry
   their own fills. Bigger contexts (mode cards, type grid, numpad) size
   the <svg> up via more specific rules below. */
.ic {
  width: 1em;
  height: 1em;
  vertical-align: -0.14em;
  flex: none;
  fill: currentColor;
}

/* Confetti burst overlay (JS-created, self-removing) for a new personal best. */
.confetti-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 9999;
}

#app {
  max-width: 560px;
  margin: 0 auto;
  /* Pad by the notch / status bar / home indicator on phones; the vertical pads
     shrink on short screens so gameplay fits, but never go below the safe-area inset. */
  padding: max(clamp(12px, 2.5vh, 20px), env(safe-area-inset-top)) max(16px, env(safe-area-inset-right))
           max(clamp(16px, 4vh, 32px), env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  /* Fixed viewport height so screens scroll INTERNALLY (an app-like layout) —
     this lets Practice pin its Start button while the type list scrolls under it. */
  height: 100dvh;
  display: flex;
  flex-direction: column;
}

.hidden { display: none !important; }

/* Font roles (docs/quick-brain-style-guide.md §1): Nunito body is the default.
   Fredoka = big display moments (logo, titles, the question prompt, large numbers).
   Baloo 2 = UI chrome (keys, questions' answer tiles, section labels, pills). */
.logo, h1, h2, h3, .q-prompt,
.over-score span, .stat span, #countdown-num { font-family: var(--font-display); }

.btn, .mode-name, .hud-score, .numpad-display, .np-key,
.compare-panel, .answer-btn, .odd-item, .level-pill, .fpill,
.section-label, .lock-toggle-title { font-family: var(--font-ui); }

/* ── screens ── */
.screen { display: none; flex: 1; min-height: 0; flex-direction: column; gap: clamp(10px, 2vh, 16px); }
/* Tall screens (home, progress, band…) scroll within themselves; Practice overrides
   this to pin its footer (see #screen-practice). */
.screen.active { display: flex; overflow-y: auto; overflow-x: hidden; animation: screen-in 0.25s ease; }
@keyframes screen-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

.screen-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.screen-head h2 { font-size: 1.4rem; }

.section-label {
  color: var(--ink-dim);
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* ── home ── */
.logo {
  font-size: clamp(2.2rem, 9vw, 3.2rem);
  font-weight: 700;
  color: var(--pink);
  letter-spacing: -0.01em;
  text-align: center;
  margin-top: 0.3rem;
}
.tagline { text-align: center; color: var(--ink-dim); font-size: 1.1rem; font-weight: 700; }

/* ── Bolt the bunny mascot (see www/img/mascot/README.md) ── */
.mascot { display: block; pointer-events: none; }
.mascot-hero {
  width: clamp(120px, 38vw, 180px);
  height: auto;
  margin: 4vh auto 0;
  filter: drop-shadow(0 10px 14px rgba(150, 120, 200, 0.32));
  animation: mascot-bob 3.4s ease-in-out infinite;
}
.mascot-result {
  /* Floor low enough that a 320px phone fits level-up + best + coins + the
     rewarded-ad button without the screen scrolling. */
  width: clamp(76px, 24vw, 130px);
  height: auto;
  margin: 0 auto;
  filter: drop-shadow(0 8px 12px rgba(150, 120, 200, 0.3));
  position: relative; z-index: 1; /* in front of the defeated boss */
}
/* Results heroes row: the mascot centered; after beating a world's boss, its
   defeated (slumped) portrait sits beside them — the art carries the mood, so
   no extra tilt/desaturation. */
.over-heroes { position: relative; display: flex; justify-content: center; }
.over-boss {
  position: absolute; z-index: 0;
  width: clamp(62px, 19vw, 100px); height: auto;
  left: calc(50% + clamp(26px, 8.5vw, 48px)); bottom: -2px;
  filter: drop-shadow(0 6px 10px rgba(90, 70, 130, 0.3));
}
/* Greeting row on the mode-select screen: winking Bolt beside "Hi, <name>!" */
.greet { display: flex; align-items: center; justify-content: center; gap: 6px; margin: -2px 0 6px; }
.mascot-greet {
  width: clamp(84px, 26vw, 112px); height: auto;
  filter: drop-shadow(0 8px 10px rgba(150, 120, 200, 0.3));
  animation: mascot-bob 3s ease-in-out infinite;
}
.greet-text h2 { font-family: var(--font-display); font-size: clamp(1.5rem, 7vw, 1.9rem); color: var(--ink); line-height: 1; }
.greet-sub { color: var(--ink-dim); font-weight: 700; font-size: 0.9rem; margin-top: 3px; }
/* Tap the greeting mascot to change avatar (little gear badge hints at it). */
.avatar-edit { position: relative; background: none; border: none; padding: 0; cursor: pointer; line-height: 0; }
.avatar-edit .mascot-greet { display: block; }
.avatar-edit-badge {
  position: absolute; right: 0; bottom: 4px;
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--lilac); color: #fff;
  border: 2px solid var(--surface);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 3px 8px rgba(160, 130, 210, 0.4);
}
.avatar-edit-badge .ic { width: 19px; height: 19px; }
/* Small header mascot (practice / progress) */
.mascot-mini { width: 40px; height: auto; filter: drop-shadow(0 4px 6px rgba(150, 120, 200, 0.3)); }

/* ── avatar selection ── */
/* Header stays pinned; the grid scrolls in its own region underneath
   (same pattern as #screen-practice). */
#screen-avatar { overflow: hidden; }
.avatar-scroll {
  flex: 1 1 auto;
  min-height: 0;          /* let the flex child actually scroll */
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-bottom: 6px;
}
.avatar-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
.avatar-card {
  position: relative;
  background: var(--surface);
  border: 3px solid transparent;
  border-radius: var(--r-card);
  box-shadow: var(--soft-shadow);
  cursor: pointer;
  padding: 12px 8px 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  transition: transform 0.1s;
}
.avatar-card:active { transform: scale(0.97); }
.avatar-card.selected { border-color: var(--lilac); background: var(--card-hi); }
.avatar-card-img {
  width: clamp(96px, 34vw, 150px); height: clamp(96px, 34vw, 150px);
  display: flex; align-items: flex-end; justify-content: center;
}
.avatar-card-img img { max-width: 100%; max-height: 100%; filter: drop-shadow(0 6px 8px rgba(150, 120, 200, 0.28)); }
.avatar-card-name { font-family: var(--font-ui); font-weight: 800; font-size: 1.05rem; color: var(--ink); }
.avatar-card-check {
  position: absolute; top: 8px; right: 8px;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--mint); color: #fff;
  display: flex; align-items: center; justify-content: center;
}
.avatar-card-check .ic { width: 16px; height: 16px; }

/* Locked (not yet unlocked) avatars: dimmed art, a lock, and the coin price. */
.avatar-card.locked .avatar-card-img img { filter: grayscale(0.5) opacity(0.75) drop-shadow(0 6px 8px rgba(150, 120, 200, 0.2)); }
.avatar-card.locked .avatar-card-name { color: var(--ink-dim); }
.avatar-card-lock {
  position: absolute; top: 8px; right: 8px;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--surface); color: var(--lilac);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 6px rgba(160, 130, 210, 0.25);
}
.avatar-card-lock .ic { width: 15px; height: 15px; }
.avatar-card-price {
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--font-ui); font-weight: 800; font-size: 0.95rem; color: var(--gold);
  background: #fff7e6; border-radius: 999px; padding: 3px 12px;
}
.avatar-card-price .ic { width: 1em; height: 1em; }
.avatar-card.shake { animation: shake 0.4s; }
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20%, 60% { transform: translateX(-6px); }
  40%, 80% { transform: translateX(6px); }
}

/* Coin balance pill (headers) + the gold coin icon anywhere. */
.coin-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-ui); font-weight: 800; font-size: 0.95rem; color: var(--gold);
  background: var(--surface); border-radius: 999px; padding: 5px 12px;
  box-shadow: 0 3px 8px rgba(160, 130, 210, 0.16);
  white-space: nowrap;
}
.coin-chip .ic { width: 1.05rem; height: 1.05rem; }
/* The menu wallet is a button (tap it to shop for avatars). */
button.coin-chip { border: none; cursor: pointer; font: inherit; font-weight: 800; color: var(--gold); }
button.coin-chip:active { transform: scale(0.96); }

.avatar-msg { text-align: center; color: var(--ink-dim); font-weight: 700; min-height: 1.2em; font-size: 0.95rem; }

/* Purchase-confirm bar pinned at the bottom of the avatar screen. */
.avatar-confirm {
  position: fixed; left: 50%; bottom: max(16px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  width: min(520px, calc(100% - 32px));
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--surface); border-radius: var(--r-card);
  box-shadow: 0 12px 28px rgba(150, 120, 200, 0.3);
  padding: 12px 14px; z-index: 45;
}
.avatar-confirm-text { font-weight: 700; color: var(--ink); }
.avatar-confirm-text .ic { width: 1em; height: 1em; vertical-align: -0.14em; }
.avatar-confirm-btns { display: flex; gap: 8px; flex: none; }
.avatar-confirm-btns .btn { padding: 9px 16px; }

/* Results: coins earned line (gold, like the trophy banner). */
.over-coins {
  color: var(--gold); font-family: var(--font-ui); font-weight: 800; font-size: 1.1rem;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  animation: pop 0.5s ease;
}
.over-coins .ic { width: 1.3rem; height: 1.3rem; }

@keyframes mascot-bob {
  0%, 100% { transform: translateY(0) rotate(-2deg); }
  50%      { transform: translateY(-8px) rotate(2deg); }
}
@media (prefers-reduced-motion: reduce) {
  .mascot-hero, .mascot-greet { animation: none; }
}

/* ── reward toast (pops in on a correct answer) ── */
.toast {
  position: fixed; top: 32vh; left: 50%;
  /* Resting transform is the centered state, so the toast stays put after the
     pop finishes (animation-fill-mode defaults to none → it would otherwise
     drop the translateX(-50%) and jump right for the rest of its life). */
  transform: translateX(-50%) rotate(-3deg);
  display: flex; align-items: center; gap: 8px;
  background: var(--surface); border-radius: 999px; padding: 8px 18px;
  box-shadow: 0 10px 22px rgba(255, 150, 200, 0.32);
  font-family: var(--font-ui); font-weight: 800; font-size: 1.05rem; color: var(--ink);
  white-space: nowrap; pointer-events: none; z-index: 40;
  animation: toast-pop 0.5s ease-out;
}
.toast-star {
  width: 22px; height: 22px; background: var(--yellow); flex: none;
  clip-path: polygon(50% 0, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0 50%, 40% 40%);
}
.toast-streak { color: var(--flame); display: inline-flex; align-items: center; gap: 2px; }
@keyframes toast-pop {
  0%   { transform: translateX(-50%) scale(0.6) rotate(-6deg); opacity: 0; }
  60%  { transform: translateX(-50%) scale(1.08) rotate(-3deg); opacity: 1; }
  100% { transform: translateX(-50%) scale(1) rotate(-3deg); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }

.card {
  background: var(--surface);
  border-radius: var(--r-card);
  box-shadow: var(--soft-shadow);
  padding: 18px 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.card h2 { font-family: var(--font-ui); font-weight: 800; font-size: 1.2rem; }

.profile-list { display: flex; flex-direction: column; gap: 10px; }
.profile-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  background: linear-gradient(90deg, #f3ecff, #fff0f7);
  border: none;
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 1.1rem;
  font-weight: 700;
  padding: 9px 14px;
  border-radius: 18px;
  cursor: pointer;
  transition: transform 0.1s;
}
.profile-row:active { transform: scale(0.98); }
.profile-row-main {
  display: flex; align-items: center; gap: 12px;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Round avatar chip with the mascot's face peeking up. */
.profile-row .px {
  width: 40px; height: 40px; flex: none; border-radius: 50%;
  background: #ffe1ef; overflow: hidden;
  display: flex; align-items: flex-end; justify-content: center;
}
.profile-row .px img { width: 44px; height: 44px; object-fit: cover; object-position: center 18%; }
.profile-row-go { color: var(--lilac); font-size: 1.3rem; flex: none; display: inline-flex; }
.profile-row-go .ic { width: 1.2rem; height: 1.2rem; }

.band-help { color: var(--ink-dim); font-size: 0.95rem; line-height: 1.4; }
.band-card .mode-icon svg { width: 27px; height: 27px; }

/* Level-lock toggle switch */
.lock-toggle {
  display: flex; align-items: center; gap: 12px;
  margin-top: 16px; padding: 14px 16px;
  background: var(--surface); border-radius: var(--r-card);
  box-shadow: var(--soft-shadow); cursor: pointer;
}
.lock-toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.lock-toggle-track {
  flex: none; position: relative; width: 48px; height: 28px;
  background: #e2d7fb; border-radius: 999px; transition: background 0.15s;
}
.lock-toggle-track::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 22px; height: 22px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 3px rgba(120, 90, 170, 0.35);
  transition: transform 0.15s;
}
.lock-toggle input:checked + .lock-toggle-track { background: var(--mint); }
.lock-toggle input:checked + .lock-toggle-track::after { transform: translateX(20px); }
.lock-toggle input:focus-visible + .lock-toggle-track { outline: 2px solid var(--lilac); outline-offset: 2px; }
.lock-toggle-text { display: flex; flex-direction: column; gap: 2px; }
.lock-toggle-title { font-weight: 800; }
.lock-toggle-desc { color: var(--ink-dim); font-size: 0.85rem; line-height: 1.3; }

/* Debug overlay (Survival / Time Attack level-progression readout) */
/* Debug "set coins" tool */
.debug-tool { margin-top: 16px; display: flex; flex-direction: column; gap: 8px; }
.debug-coin-row { display: flex; gap: 8px; }
.debug-coin-row input,
.debug-coin-row select {
  flex: 1 1 auto; min-width: 0;
  font: inherit; font-weight: 700; font-size: 1.05rem;
  padding: 11px 14px; border-radius: var(--r-btn);
  border: 2px solid #e2d7fb; background: #f6f2ff; color: var(--ink); outline: none;
}
.debug-coin-row select { flex: 0 1 auto; max-width: 45%; }
#debug-minlevel { flex: 1 1 auto; max-width: none; } /* alone in its row */
#debug-story-stage { flex: 1 1 auto; max-width: none; }
.debug-btn-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.debug-btn-row .btn { flex: 0 0 auto; }
.debug-mini-label { color: var(--ink-dim); font-weight: 800; font-size: 0.85rem; }
.btn-mini { padding: 8px 14px; font-size: 1rem; min-width: 40px; }
.debug-coin-row input:focus,
.debug-coin-row select:focus { border-color: var(--lilac); }
.debug-coin-row .btn { flex: none; }

.debug-hud {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.9rem;
  color: var(--accent);
  text-align: center;
  padding: 3px 6px;
  margin-top: 2px;
  opacity: 0.85;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.profile-form { display: flex; gap: 8px; }
.profile-form input {
  flex: 1 1 auto;
  min-width: 0; /* let the field shrink so the Add button stays on-screen in portrait */
  font: inherit;
  font-weight: 700;
  font-size: 1.05rem;
  padding: 11px 14px;
  border-radius: var(--r-btn);
  border: 2px solid #e2d7fb;
  background: #f6f2ff;
  color: var(--ink);
  outline: none;
}
.profile-form input::placeholder { color: #b3a8d4; }
.profile-form input:focus { border-color: var(--lilac); }
.profile-form .btn { flex: none; } /* keep its size; never get pushed off the row */

.profile-error { color: var(--bad); font-size: 0.85rem; min-height: 1.1em; margin-top: -6px; }

/* ── buttons ── */
/* Primary CTA: chunky 3D yellow key (guide §4). :active squishes down. */
.btn {
  font-family: var(--font-ui);
  font-weight: 800;
  font-size: 1rem;
  color: var(--yellow-text);
  background: var(--yellow);
  border: none;
  border-radius: var(--r-btn);
  padding: 11px 18px;
  cursor: pointer;
  box-shadow: 0 5px 0 var(--yellow-dark);
  transition: transform 0.08s, box-shadow 0.08s;
}
.btn:active { transform: translateY(4px); box-shadow: 0 1px 0 var(--yellow-dark); }
.btn-big { font-size: 1.35rem; padding: 16px 24px; margin-top: auto; }
/* Destructive action (e.g. delete account) — heart-red family. */
.btn-danger { background: #f5566a; color: #fff; box-shadow: 0 5px 0 #b1122f; }
.btn-danger:active { transform: translateY(4px); box-shadow: 0 1px 0 #b1122f; }
.btn-ghost {
  background: transparent;
  color: var(--lilac);
  box-shadow: none;
  font-weight: 800;
  font-size: 1.05rem;
  padding: 8px 10px;
}
.btn-ghost:active { transform: none; }
/* Round white chip buttons (quit ✕ in the HUD, mute 🔊 + settings ⚙ in the header). */
#btn-quit, #btn-mute, #btn-settings {
  background: var(--surface);
  color: var(--ink-dim);
  width: 36px; height: 36px; padding: 0;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 10px rgba(160, 130, 210, 0.2);
}
#btn-quit .ic, #btn-mute .ic, #btn-settings .ic { width: 1.15rem; height: 1.15rem; }

/* ── onboarding intro + naming ── */
.intro-card { gap: 16px; }
.intro-blurb {
  text-align: center; color: var(--ink-dim);
  font-weight: 700; font-size: 1.05rem; line-height: 1.45;
}
#screen-intro .btn-big, #screen-name .btn-big { margin-top: 0; }

/* ── Landing screen (title screen) ─────────────────────────────────────────
   Full-bleed story-map art washed with semi-transparent white, then Bolt +
   the two-tone sticker wordmark, tagline, blurb and a pink/white pill Play. */
#screen-intro { position: relative; text-align: center; padding-bottom: clamp(16px, 4vh, 34px); }
/* Fixed backdrop covers the whole viewport (under #app's safe-area padding). */
#screen-intro::before {
  content: ""; position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(rgba(255, 255, 255, 0.62), rgba(255, 255, 255, 0.72)),
              url("../img/story/bg-map.jpg") center / cover no-repeat;
}
#screen-intro > * { position: relative; z-index: 1; }
/* Fade-only entrance: a transform on the screen would re-anchor the fixed
   backdrop to it and make it jump during the animation. */
#screen-intro.active { animation: fade-in 0.25s ease; }

/* Bolt the hero — big and front-and-centre (~2× the standard hero size). */
#screen-intro .mascot-hero { width: clamp(240px, 76vw, 360px); margin-top: 3vh; }

/* Two-tone sticker wordmark: bright-pink "Bolt's" over lilac "Adventures", white outline. */
.intro-logo {
  font-size: clamp(2.5rem, 12vw, 3.7rem); line-height: 1; margin: 0.4rem 0 0;
  -webkit-text-stroke: 5px #fff; paint-order: stroke fill;
  filter: drop-shadow(0 4px 2px rgba(150, 120, 200, 0.28));
}
.intro-logo span { display: block; }
.intro-logo .lg-bolt { color: #ff5b9e; }
.intro-logo .lg-adv { color: var(--lilac); }
/* Subtext + description sit darker than default so they read over the art. */
.intro-tagline { color: #6b4fb0; font-weight: 800; font-size: 1.15rem; }
#screen-intro .intro-blurb { color: var(--ink); }

/* Description + Play sit lower on the page (pushed toward the bottom third). */
#screen-intro .intro-card { background: none; box-shadow: none; padding: 0; margin-top: auto; }

/* Pink/white pill Play button (mirrors the concept). */
#screen-intro .btn-play {
  align-self: center; margin-top: clamp(8px, 2vh, 18px);
  display: inline-flex; align-items: center; justify-content: center; gap: 12px;
  background: #ff5b9e; color: #fff;
  border: 3px solid #fff; border-radius: 999px; padding: 16px 48px;
  box-shadow: 0 6px 0 #d13a7c, 0 12px 18px rgba(220, 70, 140, 0.3);
}
#screen-intro .btn-play:active { transform: translateY(4px); box-shadow: 0 2px 0 #d13a7c, 0 6px 10px rgba(220, 70, 140, 0.3); }
#screen-intro .btn-play .ic { width: 1.2em; height: 1.2em; }

/* ── player settings hub ── */
/* Big centered avatar doubles as the "change avatar" tap-target (gear badge). */
.settings-who { display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; }
.settings-avatar .mascot-greet { width: clamp(120px, 40vw, 172px); }
.settings-avatar .avatar-edit-badge {
  right: 6px; bottom: 8px; width: 40px; height: 40px;
}
.settings-avatar .avatar-edit-badge .ic { width: 23px; height: 23px; }
.settings-who h3 { font-family: var(--font-display); font-size: 1.7rem; color: var(--ink); line-height: 1.1; }
.settings-list { display: flex; flex-direction: column; gap: 12px; margin-top: 8px; }
.btn-settings-row {
  display: flex; align-items: center; justify-content: flex-start; gap: 12px;
  width: 100%; text-align: left;
  background: var(--surface); color: var(--ink);
  box-shadow: var(--soft-shadow);
  font-size: 1.15rem; padding: 15px 18px; border-radius: 18px;
}
.btn-settings-row .ic { color: var(--lilac); width: 1.4rem; height: 1.4rem; flex: none; }
.btn-settings-row:active { transform: scale(0.98); }
/* Destructive row (delete account): red text/icon, nudged down to separate it. */
.settings-row-danger { color: #d63a5a; margin-top: 6px; }
.settings-row-danger .ic { color: #d63a5a; }

/* ── about & credits ── */
.credits-scroll {
  flex: 1 1 auto; min-height: 0;
  margin-top: clamp(8px, 1.6vh, 14px);
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.credits-scroll::-webkit-scrollbar { display: none; }
.credits-body {
  background: var(--surface);
  border-radius: var(--r-card);
  box-shadow: var(--soft-shadow);
  padding: 16px 18px 20px;
  color: var(--ink);
  font-weight: 600;
  line-height: 1.5;
}
.credits-body h3 {
  font-family: var(--font-ui); font-weight: 800; font-size: 1rem;
  color: var(--lilac); margin: 16px 0 4px;
}
.credits-body p { font-size: 0.9rem; color: var(--ink-dim); margin: 4px 0; }
.credits-lead { font-size: 1rem !important; color: var(--ink) !important; }
.credits-list { list-style: none; margin: 4px 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.credits-list li { font-size: 0.9rem; color: var(--ink-dim); }
.credits-mit { font-size: 0.78rem !important; font-style: italic; }
.credits-analytics {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 8px; margin-top: 18px !important; color: var(--ink-dim); font-size: 0.85rem;
}
.credits-analytics-label { font-weight: 800; }
#credits-analytics-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.8rem;
  color: var(--ink); background: var(--card-hi); border-radius: 8px;
  padding: 3px 8px; word-break: break-all; max-width: 100%;
}
.credits-copy {
  border: none; cursor: pointer; font-family: var(--font-ui); font-weight: 800;
  font-size: 0.8rem; color: var(--pink); background: none; padding: 3px 6px;
  border-radius: 8px;
}
.credits-copy:active { transform: scale(0.94); }
.credits-privacy { text-align: center; margin-top: 20px !important; }
.credits-privacy a { color: var(--lilac); font-family: var(--font-ui); font-weight: 800; text-decoration: underline; text-underline-offset: 2px; }
.credits-foot { text-align: center; margin-top: 12px !important; color: var(--pink) !important; font-weight: 800; }

/* ── mode select ── */
.mode-cards { display: flex; flex-direction: column; gap: 12px; }
.mode-card {
  display: grid;
  grid-template-columns: 48px 1fr;
  grid-template-areas: "icon name" "icon desc" "icon best";
  align-items: center;
  column-gap: 14px;
  text-align: left;
  background: var(--surface);
  border: none;
  border-radius: var(--r-card);
  color: var(--ink);
  font: inherit;
  padding: 14px 15px;
  cursor: pointer;
  box-shadow: var(--soft-shadow);
  transition: transform 0.1s;
}
.mode-card:active { transform: scale(0.985); }
/* Icon sits in a rounded pastel "chip" (guide §2 icon-chip tints). */
.mode-icon {
  grid-area: icon; width: 48px; height: 48px; border-radius: 15px;
  display: flex; align-items: center; justify-content: center;
  background: var(--card-hi);
}
.mode-icon svg { width: 27px; height: 27px; }
.mode-name { grid-area: name; font-family: var(--font-ui); font-size: 1.2rem; font-weight: 700; }
.mode-desc { grid-area: desc; color: var(--ink-dim); font-size: 0.9rem; font-weight: 700; }
.mode-best { grid-area: best; color: var(--gold); font-family: var(--font-ui); font-size: 0.85rem; font-weight: 800; margin-top: 2px; }
/* Per-card chip tints */
.mode-card[data-mode="survival"] .mode-icon { background: #ffe1ea; }
.mode-card[data-mode="timed"]    .mode-icon { background: #dcefff; }
.mode-card[data-mode="practice"] .mode-icon { background: #e3ffef; }
.mode-card-progress .mode-icon { background: #efe7ff; }
.band-card:nth-child(1) .mode-icon { background: #e3ffef; }
.band-card:nth-child(2) .mode-icon { background: #dcefff; }
.band-card:nth-child(3) .mode-icon { background: #efe7ff; }
.band-card:nth-child(4) .mode-icon { background: #fff2cf; }

/* ── practice config ── */
.type-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.type-card {
  background: var(--surface);
  border: 2px solid transparent;
  border-radius: 18px;
  box-shadow: 0 6px 14px rgba(160, 130, 210, 0.13);
  color: var(--ink);
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 0.78rem;
  line-height: 1.1;
  padding: 13px 5px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  text-align: center;
}
/* Each type icon rides in its own rounded pastel chip (tint cycles across the grid). */
.type-card .ticon {
  width: 40px; height: 40px; padding: 8px; border-radius: 12px;
  background: #efe7ff; vertical-align: 0;
}
.type-card:nth-child(5n+1) .ticon { background: #efe7ff; }
.type-card:nth-child(5n+2) .ticon { background: #fff2cf; }
.type-card:nth-child(5n+3) .ticon { background: #dcefff; }
.type-card:nth-child(5n+4) .ticon { background: #ffe1ea; }
.type-card:nth-child(5n+5) .ticon { background: #e3ffef; }
.type-card.selected { border-color: var(--lilac); background: var(--card-hi); }
/* "All Types" is a special mode → it spans the whole first row, laid out wide. */
.type-card[data-type="all"] {
  grid-column: 1 / -1;
  flex-direction: row;
  justify-content: center;
  gap: 12px;
  padding: 11px;
  font-size: 0.95rem;
}

.level-row { display: flex; gap: 8px; flex-wrap: wrap; }
.level-pill {
  flex: 1;
  min-width: 0;
  background: var(--surface);
  border: 2px solid transparent;
  border-radius: 999px;
  box-shadow: 0 3px 8px rgba(160, 130, 210, 0.12);
  color: var(--ink);
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 0.9rem;
  padding: 10px 4px;
  cursor: pointer;
  white-space: nowrap;
}
.level-pill[data-level="auto"] { flex-basis: 100%; }
.level-pill.selected { border-color: transparent; background: var(--lilac); color: #fff; }

.practice-preview {
  color: var(--ink-dim);
  text-align: center;
  min-height: 1.4em;
  font-size: 1.05rem;
}

/* Practice layout: the type/difficulty content scrolls, while "Start Practice"
   stays pinned at the bottom so it's always one tap away. */
/* row-gap 0 so the footer's negative margin overlaps the list exactly (the
   default .screen gap would push it back down); the header keeps its spacing
   via the scroll area's own margin. */
#screen-practice { overflow: hidden; row-gap: 0; }
.practice-scroll {
  flex: 1 1 auto;
  min-height: 0;          /* let the flex child actually scroll */
  margin-top: clamp(10px, 2vh, 16px);  /* the spacing .screen's gap used to give */
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: clamp(8px, 1.6vh, 14px);
  /* enough tail that the last row can scroll up past the fade zone */
  padding-bottom: 14px;
  scrollbar-width: none;  /* no visible scrollbar on web — it still scrolls */
}
.practice-scroll::-webkit-scrollbar { display: none; }
.practice-foot {
  flex: none;
  position: relative;
  display: flex;
  flex-direction: column;
  /* Overlap the scroll area by the fade height: the list really scrolls
     underneath the gradient, clipping only at the button's top edge. */
  margin-top: -21px;
  padding-top: 21px;      /* the fade zone lives in this padding strip */
  /* room for the chunky 0 5px 0 button shadow — the screen's overflow:hidden
     would crop it flush against the bottom edge otherwise */
  padding-bottom: 6px;
  pointer-events: none;   /* the fade strip must not block scrolling… */
  z-index: 1;
}
.practice-foot .btn-big { width: 100%; margin-top: 0; pointer-events: auto; } /* …but the button still taps */
/* Fade sitting immediately above the button: the scrolling list melts into
   the page background (the gradient is ~#eaf3ff this close to the bottom). */
.practice-foot::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 21px;
  background: linear-gradient(to top, #eaf3ff, rgba(234, 243, 255, 0));
  pointer-events: none;
}

/* ── HUD ── */
.hud {
  display: flex;
  align-items: center;
  gap: clamp(6px, 2vw, 12px);
  font-size: clamp(1rem, 3.6vw, 1.15rem);
  font-weight: 800;
}
.hud-item { white-space: nowrap; display: inline-flex; align-items: center; gap: 3px; }
#hud-lives { gap: 4px; }
#hud-correct { color: var(--mint-dark); }
#hud-streak { color: var(--flame); }
.hud-ic { width: 1.15em; height: 1.15em; }
/* Lost lives read as faint outlines; alive ones keep the icon's own red. */
.hud-ic.life.lost { opacity: 0.3; filter: grayscale(0.55); }
.hud-score { margin-left: auto; font-family: var(--font-ui); font-weight: 800; font-size: clamp(1.25rem, 4.5vw, 1.5rem); color: var(--gold); }

/* ── question timer bar ── */
.qtimer {
  height: 12px;
  border-radius: 999px;
  background: #e6ddf5;
  overflow: hidden;
}
#qtimer-bar {
  height: 100%;
  width: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--mint), var(--yellow));
}

/* ── question card ── */
.question-card {
  position: relative;
  background: var(--surface);
  box-shadow: var(--soft-shadow);
  border-radius: var(--r-card);
  min-height: clamp(150px, 22vh, 210px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(6px, 1.5vh, 10px);
  padding: clamp(10px, 3vw, 16px);
  text-align: center;
}
.question-card.flash-good { animation: flash-good 0.5s; }
.question-card.flash-bad { animation: flash-bad 0.5s; }
@keyframes flash-good { 0%, 60% { box-shadow: 0 0 0 5px var(--good) inset; } }
@keyframes flash-bad {
  0%, 60% { box-shadow: 0 0 0 5px var(--bad) inset; }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
}

.q-prompt {
  font-size: clamp(2.4rem, 11vw, 3.6rem);
  font-weight: 900;
  letter-spacing: 0.03em;
}
.q-prompt.q-prompt-small { font-size: clamp(1.3rem, 6vw, 1.7rem); color: var(--ink); }
/* Directional arrows drawn as SVG (Arrow Snap / Arrow Path). Explicit square
   size — inline SVG height:auto falls back to the 150px default otherwise. */
/* Inline glyph inside feedback / debug text (arrows, shapes, small icons). */
.fb-ic { width: 1.35em; height: 1.35em; vertical-align: -0.3em; }
.arrow-glyph { vertical-align: middle; }
.arrow-big { width: clamp(2.6rem, 13vw, 3.6rem); height: clamp(2.6rem, 13vw, 3.6rem); }
.arrow-seq { width: clamp(1.6rem, 7.5vw, 2.2rem); height: clamp(1.6rem, 7.5vw, 2.2rem); }

.q-feedback {
  min-height: 1.5em;
  font-size: 1.15rem;
  font-weight: 800;
}
.q-feedback.good { color: var(--good); }
.q-feedback.bad { color: var(--bad); }

/* ── cubes canvas ── */
.q-canvas {
  position: relative;
  width: min(100%, 380px);
  height: clamp(116px, 20vh, 190px); /* shrink on short screens so the numpad still fits */
}
.q-canvas.dice-row { height: auto; } /* a row of dice only needs its own height */
.cube {
  position: absolute;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: linear-gradient(150deg, #bfe0ff, #7cb8f5);
  box-shadow: 0 4px 0 #5c98d8;
}
.cube.moving { animation: drift var(--dur, 1.6s) ease-in-out infinite alternate; }
@keyframes drift { to { transform: translate(var(--dx, 20px), var(--dy, 12px)); } }
.q-canvas.covered .cube { visibility: hidden; }
.q-canvas.covered .die { visibility: hidden; }
.q-canvas.covered .clock { visibility: hidden; }

.shape {
  position: absolute;
  font-size: 26px;
  line-height: 0;
}
.shape .shape-ic { width: 28px; height: 28px; display: block; }

.q-canvas.dice-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
}
.die {
  /* renderDice() sets an explicit square width/height (px) to fit the row; these
     are just fallbacks. Fixed square size = never squished. */
  flex: none;
  width: 52px;
  height: 52px;
  background: linear-gradient(150deg, #ffffff, #f0eaff);
  border-radius: 15px;
  /* renderDice() sets width/height/padding/--pip in px, proportional to the die,
     so the 3×3 grid fills and pips spread more as the die grows. (`padding: %`
     resolves against the container width, not the die — do NOT use it here.) */
  padding: 7px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  box-shadow: 0 5px 0 #ddd2f2;
}
.die .pip {
  width: var(--pip, 9px);
  height: var(--pip, 9px);
  background: var(--ink);
  border-radius: 50%;
  align-self: center;
  justify-self: center;
}

.q-canvas .clock { height: 100%; display: block; margin: 0 auto; }

.q-canvas.pattern-mode {
  display: flex;
  align-items: center;
  justify-content: center;
  height: auto;
  min-height: 190px;
}
.pattern-grid { display: grid; gap: 6px; }
.pcell {
  /* ~15% bigger than the original 40px, easing down on narrow phones so the
     widest boards (6×6 Arrow Path, 4-wide Number Hunt) still fit the card. */
  width: clamp(38px, 11.7vw, 46px);
  height: clamp(38px, 11.7vw, 46px);
  border: none;
  border-radius: 11px;
  background: #efe7ff;
  color: var(--ink);
  font-family: var(--font-ui);
  font-weight: 800;
  cursor: pointer;
  padding: 0;
  font-size: clamp(20px, 6.1vw, 24px);
  line-height: 1;
  transition: background 0.1s;
}
.pcell.lit { background: var(--yellow); color: var(--ink); }
.pcell.wrong { background: var(--bad); color: #fff; }
.pcell .ic { width: clamp(28px, 8.7vw, 34px); height: clamp(28px, 8.7vw, 34px); vertical-align: middle; }

/* what-changed scatter items */
.shape-btn {
  position: absolute;
  background: transparent;
  border: none;
  font-size: 31px; /* ~20% larger than before for readability */
  line-height: 0;
  padding: 4px;
  cursor: pointer;
}
.shape-btn .shape-ic { width: 33px; height: 33px; display: block; }
.shape-btn.lit { outline: 3px solid var(--good); border-radius: 8px; }
.shape-btn.wrong-pick { outline: 3px solid var(--bad); border-radius: 8px; }
.q-canvas.blink > * { visibility: hidden; }

/* Tile selection (make-the-target pairs, arrow sequences): the same mint
   "picked" state the compare panels / answer buttons show on a tap, so every
   mode signals selection with one colour. (.correct/.incorrect are defined
   later, so end-of-question feedback still overrides this.) */
.odd-item.selected {
  background: var(--mint);
  box-shadow: 0 5px 0 var(--mint-dark);
  color: #14532d;
}

/* seesaw */
.q-canvas.seesaw-mode {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* Compact + responsive so up to 4 scales (Master) plus the answer tiles still
     fit on small portrait screens instead of pushing the options off the bottom. */
  /* Floors are generous so short viewports (phones, where vh resolves small)
     still get real spacing between scales — not just the tall desktop window. */
  gap: clamp(22px, 2.8vh, 38px);
  height: auto;
  min-height: 0;
  padding: 2px 0;
  /* Breathing room from the question text above and the answer tiles below. */
  margin: clamp(18px, 2.6vh, 28px) 0;
}
.seesaw-wrap { display: flex; flex-direction: column; align-items: center; padding-top: clamp(24px, 5vw, 40px); }
/* Master mode (4 scales): 2×2 grid instead of a tall single column. */
.q-canvas.seesaw-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: clamp(6px, 2vw, 18px);
  align-items: start;
  justify-items: center;
}
.q-canvas.seesaw-grid .seesaw-bar { width: min(150px, 40vw); }
.seesaw-bar {
  position: relative;
  width: min(210px, 58vw);
  height: 9px;
  background: #c4b3ec;
  border-radius: 6px;
}
.seesaw-bar.tilt-left { transform: rotate(-8deg); }
.seesaw-bar.tilt-right { transform: rotate(8deg); }
.crate { position: absolute; bottom: 6px; line-height: 0; }
/* Explicit square size — `height: auto` on an inline SVG falls back to the
   150px replaced-element default here instead of the 1:1 viewBox ratio. */
.crate-ic { width: clamp(30px, 9vw, 44px); height: clamp(30px, 9vw, 44px); }
.crate-left { left: 6px; }
.crate-right { right: 6px; }
.fulcrum { line-height: 0; margin-top: -3px; }
.fulcrum svg { width: clamp(15px, 4.4vw, 21px); height: clamp(15px, 4.4vw, 21px); display: block; }
.q-canvas.covered::after {
  content: "?";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 4rem;
  font-weight: 900;
  color: var(--ink-dim);
}

/* ── compare panels ── */
.q-compare {
  display: flex;
  align-items: stretch;
  gap: 10px;
  width: 100%;
}
.compare-panel {
  flex: 1;
  /* Lilac tint (not white) so the tiles read as buttons against the white
     question card they sit inside — a bare-white tile disappears on it. */
  background: #efe7ff;
  border: none;
  border-radius: 14px;
  color: var(--ink);
  font: inherit;
  font-size: clamp(1.6rem, 7vw, 2.4rem);
  font-weight: 900;
  padding: 28px 8px;
  cursor: pointer;
  box-shadow: 0 5px 0 #d9cbf5;
  transition: transform 0.08s, box-shadow 0.08s;
}
.compare-panel:active { transform: translateY(4px); box-shadow: 0 1px 0 #d9cbf5; }
.compare-vs {
  align-self: center;
  font-weight: 900;
  color: var(--ink-dim);
}

/* ── odd-one-out grid ── */
.q-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 150px));
  gap: clamp(8px, 2vw, 12px);
  justify-content: center;
  width: 100%;
}
.odd-item {
  /* Lilac tint (not white) so the tiles read as buttons against the white
     question card they sit inside — a bare-white tile disappears on it. */
  background: #efe7ff;
  border: none;
  border-radius: 14px;
  color: var(--ink);
  font: inherit;
  /* Shrink on small screens so rows of tiles don't push the layout off-screen. */
  font-size: clamp(1.5rem, 6.5vw, 2.2rem);
  font-weight: 900;
  /* Height comes from a viewport-scaled min-height with a solid floor (not from
     vw-based padding, which collapsed to a squished ~49px on narrow phones while
     wide desktop hit the 22px ceiling at ~92px). Content is centered. */
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: clamp(66px, 18vw, 92px);
  padding: 10px 8px;
  min-width: 0;
  cursor: pointer;
  box-shadow: 0 5px 0 #d9cbf5;
  transition: transform 0.08s, box-shadow 0.08s;
}
.odd-item:active { transform: translateY(4px); box-shadow: 0 1px 0 #d9cbf5; }
.odd-item .grid-ic { width: clamp(34px, 11vw, 52px); height: clamp(34px, 11vw, 52px); }
.odd-item.color-tile { font-size: 1.05rem; letter-spacing: 0.04em; }
.odd-item.color-tile.correct { outline: 4px solid var(--good); }
.odd-item.color-tile.incorrect { outline: 4px solid var(--bad); }

.q-caption {
  color: var(--ink-dim);
  font-size: clamp(1.3rem, 6vw, 1.7rem);
  font-weight: 800;
}

/* ── answer choice buttons ── */
.answers {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
.answer-btn {
  background: var(--card);
  border: none;
  border-radius: 16px;
  color: var(--ink);
  font: inherit;
  font-size: 1.9rem;
  font-weight: 900;
  padding: 20px 8px;
  cursor: pointer;
  box-shadow: var(--shadow);
  transition: transform 0.1s;
}
.answer-btn:active { transform: translateY(3px); box-shadow: none; }
.answer-btn.correct, .compare-panel.correct, .odd-item.correct {
  background: var(--mint);
  box-shadow: 0 5px 0 var(--mint-dark);
  color: #14532d;
}
.answer-btn.incorrect, .compare-panel.incorrect, .odd-item.incorrect {
  background: var(--bad);
  box-shadow: 0 5px 0 #b83b76;
  color: #fff;
}

/* ── numpad ── */
.numpad { display: flex; flex-direction: column; gap: clamp(5px, 1.3vh, 10px); }
.numpad-display {
  background: var(--surface);
  border: 2px dashed #d9cff0;
  border-radius: var(--r-btn);
  color: var(--ink);
  font-size: clamp(1.4rem, 5vw, 2rem);
  font-weight: 800;
  text-align: center;
  padding: clamp(4px, 1vh, 8px);
  min-height: clamp(2.2rem, 5.5vh, 3.2rem);
  letter-spacing: 0.1em;
  display: flex; align-items: center; justify-content: center;
}
.numpad-display:empty::before { content: ""; }
.numpad-keys {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(6px, 1.6vw, 8px);
}
.np-key {
  background: var(--card);
  border: none;
  border-radius: 12px;
  color: var(--ink);
  font: inherit;
  font-size: clamp(1.2rem, 4.5vw, 1.6rem);
  font-weight: 900;
  padding: clamp(6px, 1.6vh, 14px);
  cursor: pointer;
  box-shadow: var(--shadow);
  transition: transform 0.08s;
}
.np-key:active { transform: translateY(4px); box-shadow: 0 1px 0 var(--key-shadow); }
.np-back { background: #efe7ff; box-shadow: 0 5px 0 #d9cbf5; color: var(--lilac); }
.np-back:active { box-shadow: 0 1px 0 #d9cbf5; }
.np-blank { visibility: hidden; } /* empty bottom-left cell (no submit key — answers auto-check) */
.np-key .ic { width: 1.3em; height: 1.3em; vertical-align: -0.28em; }

/* ── countdown overlay ── */
.countdown {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(253, 240, 247, 0.9);
  z-index: 50;
}
#countdown-num {
  /* inline-block + centered origin so the pop scale is applied consistently
     across engines (a bare inline <span> can transform differently on WebKit). */
  display: inline-block;
  transform-origin: center center;
  font-family: var(--font-display);
  font-size: clamp(6rem, 30vw, 10rem);
  font-weight: 700;
  color: var(--pink);
  text-shadow: 0 4px 0 rgba(224, 85, 154, 0.18);
}
#countdown-num.pop { animation: pop 0.4s ease; }
@keyframes pop {
  from { transform: scale(1.6); opacity: 0.3; }
  to   { transform: scale(1); opacity: 1; }
}

/* ── results ── */
/* Kept vertically tight: with level-up + new-best + coins all showing, the
   screen must still fit a phone without scrolling. */
#screen-over { position: relative; text-align: center; justify-content: center; gap: clamp(6px, 1.4vh, 12px); }
/* Wallet chip pinned top-center, same chip the mode screen shows. The "+N"
   coin float is JS-anchored to this chip's rect, so it follows automatically. */
.over-coin-chip { position: absolute; top: 0; left: 50%; transform: translateX(-50%); z-index: 2; }
/* "+N" that rises past the wallet chip and fades. Fixed + JS-anchored to the
   chip's rect so the screen's overflow can't clip it. */
.coin-float {
  position: fixed;
  z-index: 9500;
  color: var(--gold);
  font-family: var(--font-ui); font-weight: 800; font-size: 1.15rem;
  text-shadow: 0 1px 0 #fff;
  pointer-events: none;
  animation: coin-float 1.5s ease-out forwards;
}
@keyframes coin-float {
  0%   { opacity: 0; transform: translate(-50%, 10px); }
  18%  { opacity: 1; transform: translate(-50%, 0); }
  100% { opacity: 0; transform: translate(-50%, -42px); }
}
#over-title { font-size: clamp(1.5rem, 6vw, 1.9rem); }
.newbest {
  color: var(--accent);
  font-size: 1.15rem;
  font-weight: 900;
  line-height: 1.3; /* stacked banners: keep the block short on small phones */
  animation: pop 0.5s ease;
}
/* Banners stack, one centered line each — sharing a line left whichever
   banner landed next to the coins line visibly off-center. */
.over-banners {
  display: flex; flex-direction: column; align-items: center;
}
/* Long lines (e.g. level-up) must wrap inside the row, not spill off-screen. */
.over-banners > * { max-width: 100%; min-width: 0; }
.over-score {
  display: flex; flex-direction: row; align-items: baseline; justify-content: center; gap: 8px;
}
.over-score span { font-size: clamp(2.6rem, 10vw, 3.4rem); font-weight: 900; color: var(--accent); line-height: 1.1; }
.over-score small { color: var(--ink-dim); font-size: 1rem; }
.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
}
.stat {
  background: var(--surface);
  border-radius: var(--r-btn);
  box-shadow: 0 6px 14px rgba(160, 130, 210, 0.12);
  padding: 9px 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.stat span { font-family: var(--font-display); font-size: 1.5rem; font-weight: 700; }
.stat label { color: var(--ink-dim); font-size: 0.8rem; }
.over-buttons { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }

/* Opt-in rewarded-ad button on the results screen: gold accent, quieter than
   the Play Again CTA. */
.btn-reward {
  background: #fff7e6;
  color: var(--gold);
  box-shadow: 0 5px 0 #eeddba;
}
.btn-reward .ic { width: 1.2em; height: 1.2em; }
.btn-reward:disabled { opacity: 0.75; }

/* "Time's up!" toast: Time Attack freezes for a beat before the results. */
.timesup-toast {
  position: fixed; left: 50%; top: 38%;
  z-index: 9000;
  display: flex; align-items: center; gap: 10px;
  background: var(--surface); color: var(--ink);
  font-family: var(--font-display); font-weight: 700; font-size: 1.7rem;
  padding: 16px 30px; border-radius: 999px;
  white-space: nowrap; /* left:50% halves the shrink-to-fit width — don't wrap */
  box-shadow: 0 14px 32px rgba(160, 130, 210, 0.4);
  pointer-events: none;
  animation: timesup-in 0.35s ease forwards;
}
.timesup-toast .ic { width: 1.7rem; height: 1.7rem; }
@keyframes timesup-in {
  from { opacity: 0; transform: translate(-50%, 18px) scale(0.6); }
  60%  { opacity: 1; transform: translate(-50%, 0)   scale(1.08); }
  to   { opacity: 1; transform: translate(-50%, 0)   scale(1); }
}

/* Coin toast: pops over the results screen when rewarded-ad coins arrive. */
.coin-toast {
  position: fixed; left: 50%; top: 26%;
  z-index: 9000;
  display: flex; align-items: center; gap: 8px;
  background: #fff7e6; color: var(--gold);
  font-family: var(--font-ui); font-weight: 800; font-size: 1.35rem;
  padding: 12px 24px; border-radius: 999px;
  white-space: nowrap;
  box-shadow: 0 10px 26px rgba(160, 130, 210, 0.35), 0 0 0 3px #ffe08a inset;
  pointer-events: none;
  animation: coin-toast 1.9s ease forwards;
}
.coin-toast .ic { width: 1.5rem; height: 1.5rem; }
@keyframes coin-toast {
  0%   { opacity: 0; transform: translate(-50%, 16px) scale(0.5); }
  12%  { opacity: 1; transform: translate(-50%, 0)   scale(1.12); }
  20%  { transform: translate(-50%, 0) scale(1); }
  76%  { opacity: 1; transform: translate(-50%, 0)   scale(1); }
  100% { opacity: 0; transform: translate(-50%, -30px) scale(0.94); }
}

/* Fake full-screen ad (web preview of the between-game interstitial). */
/* Pre-interstitial "Good job!" interlude: a full-screen scrim (blocks every
   control) with a celebratory pill, shown for a beat before the ad appears.
   Sits just below the ad overlay so the ad covers it on the way in. */
.ad-interlude {
  position: fixed; inset: 0; z-index: 9990;
  background: rgba(35, 28, 62, 0.55);
  display: flex; align-items: center; justify-content: center;
  animation: fade-in 0.2s ease-out;
}
.ad-interlude-toast {
  display: flex; align-items: center; gap: 10px;
  background: var(--surface); border-radius: 999px; padding: 14px 26px;
  box-shadow: 0 12px 28px rgba(35, 28, 62, 0.35);
  font-family: var(--font-display); font-size: 1.5rem; color: var(--ink);
  animation: interlude-pop 0.5s ease-out;
}
.ad-interlude-toast .ai-star { width: 30px; height: 30px; color: var(--gold); }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes interlude-pop {
  0%   { transform: scale(0.6); opacity: 0; }
  60%  { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .ad-interlude, .ad-interlude-toast { animation: none; }
}

/* ── Main-menu guided tour ────────────────────────────────────────────────
   A spotlight (a transparent box whose huge box-shadow dims everything else)
   steps across the menu, with a tip card explaining each control. */
.tour { position: fixed; inset: 0; z-index: 10050; }
.tour.hidden { display: none; }
.tour-scrim { position: fixed; inset: 0; } /* transparent — captures/blocks taps */
.tour-spot {
  position: fixed; border-radius: 18px; pointer-events: none;
  box-shadow: 0 0 0 9999px rgba(45, 35, 75, 0.58);
  transition: left 0.28s ease, top 0.28s ease, width 0.28s ease, height 0.28s ease;
}
.tour-tip {
  position: fixed; width: min(300px, 82vw);
  background: var(--surface); border-radius: var(--r-card); box-shadow: var(--soft-shadow);
  padding: 15px 17px; animation: interlude-pop 0.28s ease-out;
}
.tour-title { font-family: var(--font-display); color: var(--ink); font-size: 1.15rem; margin-bottom: 3px; }
.tour-body { color: var(--ink-dim); font-weight: 700; font-size: 0.95rem; line-height: 1.4; }
.tour-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 13px; }
.tour-skip { background: none; border: none; cursor: pointer; color: var(--ink-dim); font-family: var(--font-ui); font-weight: 800; font-size: 0.85rem; padding: 4px; }
.tour-dots { display: inline-flex; gap: 6px; }
.tour-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--key-shadow); }
.tour-dot.on { background: var(--pink); }
@media (prefers-reduced-motion: reduce) {
  .tour-spot { transition: none; }
  .tour-tip { animation: none; }
}

.fake-ad {
  position: fixed; inset: 0; z-index: 10000;
  background: rgba(35, 28, 62, 0.93);
  display: flex; align-items: center; justify-content: center;
}

/* ── "rate the app" prompt ── */
.review-modal {
  position: fixed; inset: 0; z-index: 10001;
  background: rgba(35, 28, 62, 0.55);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  animation: review-fade 0.2s ease-out;
}
@keyframes review-fade { from { opacity: 0; } to { opacity: 1; } }
.review-card {
  background: var(--surface);
  border-radius: var(--r-card);
  box-shadow: var(--soft-shadow);
  padding: 20px 20px 22px;
  width: min(360px, 100%);
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  text-align: center;
  animation: pop 0.3s ease;
}
.review-mascot { width: clamp(96px, 32vw, 128px); height: auto; margin-top: -4px;
  filter: drop-shadow(0 8px 12px rgba(150, 120, 200, 0.3)); }
.review-title { font-family: var(--font-display); font-size: 1.5rem; color: var(--ink); line-height: 1.15; }
.review-body { color: var(--ink-dim); font-weight: 700; font-size: 1rem; line-height: 1.4; }
.review-buttons { display: flex; flex-direction: column; gap: 10px; width: 100%; margin-top: 4px; }
.review-buttons .btn-big { margin-top: 0; width: 100%; }

/* ── Sound-settings sliders ── */
.vol-row { width: 100%; display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.vol-label { display: flex; align-items: center; gap: 8px; font-family: var(--font-ui);
  font-weight: 800; font-size: 1rem; color: var(--ink); }
.vol-label .ic { width: 22px; height: 22px; color: var(--pink); flex: none; }
.vol-val { margin-left: auto; color: var(--ink-dim); font-variant-numeric: tabular-nums;
  font-weight: 800; font-size: 0.9rem; min-width: 3ch; text-align: right; }
.vol-slider { -webkit-appearance: none; appearance: none; width: 100%; height: 10px;
  border-radius: var(--r-pill); background: #ece3fb; outline: none; cursor: pointer; }
.vol-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none;
  width: 26px; height: 26px; border-radius: 50%; background: var(--pink);
  border: 3px solid #fff; box-shadow: 0 3px 0 rgba(176, 60, 122, 0.55); cursor: pointer; }
.vol-slider::-moz-range-thumb { width: 22px; height: 22px; border-radius: 50%;
  background: var(--pink); border: 3px solid #fff; box-shadow: 0 3px 0 rgba(176, 60, 122, 0.55); cursor: pointer; }
.vol-slider:focus-visible { box-shadow: 0 0 0 3px var(--pink-soft); }
.review-buttons .btn-ghost { color: var(--ink-dim); }
.fake-ad-box {
  background: var(--surface);
  border-radius: var(--r-card);
  padding: 24px 22px;
  width: min(420px, calc(100% - 48px));
  display: flex; flex-direction: column; gap: 14px;
  text-align: center;
}
.fake-ad-tag {
  color: var(--ink-dim); font-size: 0.78rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: 0.08em;
}
.fake-ad-body {
  font-family: var(--font-display); font-size: 1.5rem; font-weight: 700;
  color: var(--ink-dim);
  padding: 44px 0;
  border-radius: 14px;
  background: repeating-linear-gradient(45deg, #f6f2ff, #f6f2ff 14px, #efe7ff 14px, #efe7ff 28px);
}

/* ── progress screen ── */
.kpi-row { grid-template-columns: repeat(3, 1fr); }
/* Center the number + label within each KPI card. */
.kpi-row .stat { align-items: center; text-align: center; }
/* Playful per-KPI colors (guide progress screen). */
#kpi-correct { color: var(--pink); }
#kpi-best { color: var(--gold); }
#kpi-games { color: var(--mint-dark); }

.filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: space-between;
}
.pill-group { display: flex; gap: 6px; flex-wrap: wrap; }
.fpill {
  background: var(--surface);
  border: 2px solid transparent;
  border-radius: 999px;
  box-shadow: 0 3px 8px rgba(160, 130, 210, 0.12);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 0.85rem;
  font-weight: 700;
  padding: 6px 13px;
  cursor: pointer;
}
.fpill.selected { border-color: transparent; background: var(--lilac); color: #fff; box-shadow: none; }

.chart-card {
  background: var(--surface);
  border-radius: var(--r-card);
  box-shadow: var(--soft-shadow);
  padding: 14px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.chart-title { color: var(--ink-dim); font-size: 0.9rem; font-weight: 700; }
.chart-wrap { position: relative; }
#chart { width: 100%; height: auto; display: block; }
.chart-tip {
  position: absolute;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid #eadff5;
  border-radius: 10px;
  padding: 6px 10px;
  font-size: 0.85rem;
  line-height: 1.4;
  pointer-events: none;
  white-space: nowrap;
  box-shadow: 0 6px 16px rgba(160, 130, 210, 0.28);
}
.chart-empty { color: var(--ink-dim); text-align: center; padding: 24px 0; }

.runs-table-wrap { overflow-x: auto; }
.runs-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}
.runs-table th {
  color: var(--ink-dim);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-align: left;
  padding: 6px 8px;
}
.runs-table td {
  padding: 9px 8px;
  border-top: 1px solid #f2ecfa;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.runs-table th { border-bottom: 1px solid #eadff5; }
.runs-table td:nth-child(4), .runs-table td:nth-child(5) { font-family: var(--font-ui); }
.runs-table td:nth-child(4), .runs-table td:nth-child(5),
.runs-table th:nth-child(4), .runs-table th:nth-child(5) { text-align: right; }
.runs-table .cell-ic { width: 1.25rem; height: 1.25rem; vertical-align: -0.28em; }

@media (max-width: 420px) {
  /* Results stats stay one 4-across row (saves a row of height); shrink to fit. */
  .stats-grid { gap: 6px; }
  .stats-grid.kpi-row { grid-template-columns: repeat(3, 1fr); }
  .stat span { font-size: 1.2rem; }
  .stat label { font-size: 0.68rem; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   STORY MODE — world select, map, stage detail, boss, results & dialog
   ═══════════════════════════════════════════════════════════════════════════ */

/* Mode card + results chip */
.mode-card[data-mode="story"] .mode-icon { background: #efe6ff; }
.over-stars { display: flex; justify-content: center; gap: 8px; margin-top: -2px; }
.story-star { width: 38px; height: 38px; }
.goal-star:not(.on), .node-star:not(.on), .story-star:not(.on) { opacity: 0.26; filter: grayscale(1); }
/* Results: earned stars pop in one-by-one (celebrateStars). `prep` hides a star
   until its turn; `pop` springs it in with a cheerful overshoot. */
.story-star.prep { transform: scale(0); opacity: 0; }
.story-star.pop { animation: star-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both; }
@keyframes star-pop {
  0% { transform: scale(0); opacity: 0; }
  60% { transform: scale(1.18); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
/* Sprite-star sparks radiating from a landing star (starBurst). */
.spark { position: fixed; z-index: 10000; width: 16px; height: 16px; margin: -8px 0 0 -8px; pointer-events: none; }
.spark .ic { width: 100%; height: 100%; }
@keyframes spark-out {
  0% { transform: translate(0, 0) scale(0.3); opacity: 0; }
  25% { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(1); opacity: 0; }
}
.spark { animation: spark-out 0.7s ease-out forwards; }

/* Shared scroll bodies + pinned footer (mirrors the practice screen) */
#screen-worlds, #screen-story, #screen-stage, #screen-boss { overflow: hidden; row-gap: 0; }
.worlds-scroll, .story-scroll, .stage-scroll, .boss-scroll {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
  display: flex; flex-direction: column; gap: 12px;
  margin-top: clamp(10px, 2vh, 16px); padding-bottom: 14px; scrollbar-width: none;
}
/* Children keep their natural height — overflow scrolls instead of squashing
   fixed-height pieces (the boss scene was shrinking to a sliver when the body
   grew taller than the screen). */
.worlds-scroll > *, .story-scroll > *, .stage-scroll > *, .boss-scroll > * { flex: none; }
.worlds-scroll::-webkit-scrollbar, .story-scroll::-webkit-scrollbar,
.stage-scroll::-webkit-scrollbar, .boss-scroll::-webkit-scrollbar { display: none; }
.stage-foot { flex: none; padding-top: 10px; padding-bottom: 6px; }
.stage-foot .btn-big { width: 100%; margin-top: 0; }
.head-spacer { width: 44px; flex: none; }

/* Total-stars chip in the headers */
.world-stars {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-ui); font-weight: 800; color: var(--gold);
  background: var(--surface); padding: 6px 12px; border-radius: var(--r-pill);
  box-shadow: var(--soft-shadow); font-size: 0.95rem;
}
.chip-star { width: 18px; height: 18px; }

/* World Select cards */
.world-card {
  display: grid; grid-template-columns: 52px 1fr auto;
  grid-template-areas: "icon name badge" "icon desc desc" "prog prog prog";
  gap: 3px 14px; align-items: center;
  background: var(--surface); border: none; border-radius: var(--r-card);
  box-shadow: var(--soft-shadow); padding: 14px 16px;
  text-align: left; color: var(--ink); font: inherit; cursor: pointer;
  transition: transform 0.1s;
}
.world-card:active { transform: scale(0.985); }
.world-card .mode-icon { grid-area: icon; }
/* world cards: the icon chip is a peek of the world's own map art */
.world-thumb { background-size: cover; background-position: center; }
.world-card.locked .world-thumb { filter: grayscale(0.55); }
.world-card .mode-name { grid-area: name; font-family: var(--font-ui); font-size: 1.15rem; font-weight: 800; }
.world-card .mode-desc { grid-area: desc; color: var(--ink-dim); font-size: 0.85rem; font-weight: 700; }
.world-card.locked { opacity: 0.72; cursor: default; }
.world-badge { grid-area: badge; display: inline-flex; align-items: center; gap: 4px;
  color: var(--gold); font-family: var(--font-ui); font-weight: 800; font-size: 0.85rem; }
.world-badge .ic { width: 16px; height: 16px; }
.world-lock { grid-area: prog; display: flex; align-items: center; gap: 6px;
  color: var(--ink-dim); font-weight: 800; font-size: 0.85rem; margin-top: 4px; }
.world-lock .ic { width: 18px; height: 18px; }
.world-prog { grid-area: prog; height: 8px; border-radius: var(--r-pill);
  background: var(--card-hi); overflow: hidden; margin-top: 8px; }
.world-prog-bar { display: block; height: 100%; border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--pink-soft), var(--pink)); }

/* Story-complete dialog: the grand reward chip sits centered under the body. */
.story-done-reward { justify-content: center; font-size: 1.5rem; margin: 2px 0 4px; }

/* World Select: greeter, card entrance, completed badge, new-world flourish */
.worlds-greet { display: flex; align-items: center; gap: 10px; margin-top: 4px; }
.worlds-mascot { width: clamp(52px, 15vw, 66px); height: auto; flex: none;
  filter: drop-shadow(0 6px 10px rgba(150, 120, 200, 0.3)); animation: mascot-bob 3s ease-in-out infinite; }
.worlds-sub { color: var(--ink-dim); font-family: var(--font-ui); font-weight: 800; font-size: 1rem; }
.world-card { position: relative; animation: card-in 0.4s ease-out backwards; animation-delay: var(--in, 0s); }
@keyframes card-in { 0% { opacity: 0; transform: translateY(14px); } 100% { opacity: 1; transform: none; } }
.world-done-badge { position: absolute; top: 8px; left: 8px; width: 21px; height: 21px; border-radius: 50%;
  background: var(--mint-dark); color: #fff; display: flex; align-items: center; justify-content: center; z-index: 1; }
.world-done-badge .ic { width: 14px; height: 14px; }
/* the world you just unlocked pulses a gold ring for a beat */
.world-card.just-unlocked { animation: card-in 0.4s ease-out backwards, world-glow 1.1s ease-out 0.4s 2; }
@keyframes world-glow { 0%, 100% { box-shadow: var(--soft-shadow); } 50% { box-shadow: 0 0 0 3px var(--gold), var(--soft-shadow); } }
/* Story toasts carry full sentences ("Memory Mountain unlocked — …"), so unlike
   the base .toast they wrap onto a second line instead of overflowing narrow
   phones; the pill relaxes into a rounded card when it does. */
.story-toast {
  z-index: 10002;
  white-space: normal;
  box-sizing: border-box; /* max-width includes the pill padding */
  max-width: min(92vw, 400px);
  width: max-content;
  text-align: center;
  border-radius: 20px;
  line-height: 1.3;
}
.story-toast .ic { flex: none; }
@media (prefers-reduced-motion: reduce) {
  .worlds-mascot { animation: none; }
  .world-card, .world-card.just-unlocked { animation: none; }
}

/* Story Map */
/* The map is the whole device: .story-stage is fixed to the viewport (the shell's
   padding doesn't apply), the art covers it, and the header floats on top. Node
   `pos` percentages are therefore percentages OF THE SCREEN — keep them well
   inside [15,85]×[16,84] so nodes clear the floating header, the level pill and
   the screen edges on any aspect ratio (see tools/level-editor.html). */
.story-stage { position: fixed; inset: 0; z-index: 0; }
/* The default screen-in animation transforms the screen, which would briefly make
   it the fixed map's containing block (positioning the map inside the padded
   shell, then snapping out) — fade this screen in without moving it. */
#screen-story.active { animation: screen-fade 0.25s ease; }
@keyframes screen-fade { from { opacity: 0; } to { opacity: 1; } }
#screen-story .screen-head { position: relative; z-index: 2; }
#screen-story .screen-head h2 { color: #fff; text-shadow: 0 2px 10px rgba(0, 0, 0, 0.45); }
/* the ghost back button is invisible over bright map art — make it a round
   white chip like the header's mute/settings buttons */
#screen-story .screen-head .btn-ghost {
  background: var(--surface); color: var(--ink);
  width: 36px; height: 36px; padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 10px rgba(160, 130, 210, 0.2);
}
.story-map-box { position: absolute; inset: 0; overflow: hidden; }
/* Blurred fill behind the letterbox so the aspect-locked map doesn't sit on
   bare bars when the webview isn't the authoring aspect ratio. */
.story-map-box::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background-image: var(--map-bg); background-size: cover; background-position: center;
  filter: blur(22px) brightness(0.82); transform: scale(1.12);
}
.story-map {
  /* width/height are set in JS to a 390:844 box — the exact frame the level
     editor authors against — then contain-fitted + centered here (inset:0;
     margin:auto). Keeping `cover`/center means authored node & dot percentages
     land on the SAME cropped image at any webview size. */
  position: absolute; inset: 0; margin: auto; overflow: hidden; z-index: 1;
  background-size: cover; background-position: center;
}
/* Trail connecting consecutive stage nodes (drawn under them): a smooth curve
   through the stages, rendered as mini stage-styled dots (white, colored ring). */
.map-path { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; }
.map-path .trail-dot { fill: #fff; stroke: var(--mint-dark); stroke-width: 2.5; }
/* The player's face bobbing over the stage they're currently on. */
.map-hero {
  position: absolute; z-index: 2; pointer-events: none;
  width: 46px; height: 46px; border-radius: 50%;
  /* sits just above the node face it marks; --lift grows for the larger boss node */
  transform: translate(-50%, calc(-50% - var(--lift, 43px)));
  border: 3px solid #fff; background: var(--card-hi); overflow: hidden;
  box-shadow: var(--soft-shadow);
  animation: hero-bob 2.4s ease-in-out infinite;
}
.map-hero img {
  width: 100%; height: 100%; object-fit: cover; object-position: center 12%;
  transform: scale(1.45); transform-origin: 50% 18%;
}
@keyframes hero-bob {
  0%, 100% { margin-top: 0; }
  50% { margin-top: -6px; }
}
/* Level entry point on the map (opens the difficulty picker). The map is the
   whole screen, so drop below the floating header (its stars chip owns the
   top-right corner) and clear the notch. */
.map-level-btn {
  position: absolute; right: 12px; z-index: 3;
  top: calc(max(clamp(12px, 2.5vh, 20px), env(safe-area-inset-top)) + 52px);
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-ui); font-weight: 800; font-size: 0.9rem;
  color: var(--ink); background: rgba(255, 255, 255, 0.92);
  border: none; border-radius: var(--r-pill); padding: 7px 13px;
  box-shadow: var(--soft-shadow); cursor: pointer;
}
.map-level-btn .ic { width: 18px; height: 18px; }
.map-level-btn:active { transform: scale(0.96); }
.map-node {
  position: absolute; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  border: none; background: none; padding: 0; cursor: pointer;
}
.map-node.locked { cursor: default; }
.map-node:not(.locked):active { transform: translate(-50%, -50%) scale(0.94); }
.node-face {
  width: 46px; height: 46px; border-radius: 50%; border: 3px solid #fff;
  background: var(--surface); box-shadow: var(--soft-shadow);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-size: 1.3rem; font-weight: 700; color: var(--ink);
}
.node-face .ic { width: 22px; height: 22px; }
.map-node.done .node-face { color: var(--pink); border-color: var(--mint-dark); }
.map-node.locked .node-face { background: var(--card-hi); color: var(--ink-dim); box-shadow: var(--soft-shadow); }
.map-node.boss .node-face { width: 58px; height: 58px;
  background: linear-gradient(160deg, #ffd7e6, #ffb0cf); overflow: hidden; }
.map-node.boss .node-face .ic { width: 30px; height: 30px; }
/* the world boss's face fills the round boss node; locked = a dimmed tease */
.node-boss { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.map-node.locked .node-boss { filter: grayscale(0.7) brightness(0.92); opacity: 0.85; }
.node-stars { display: flex; gap: 1px; }
.node-star { width: 14px; height: 14px; }
.map-node.locked .node-stars { visibility: hidden; }

/* ── Living map: entrance, current-stage pulse, boss glow, unlock flourish, twinkles.
   `backwards` fill hides a node during its stagger delay, then reverts after so the
   :active press-scale still works. All decorative loops off under reduced motion. ── */
.map-node { animation: node-in 0.42s cubic-bezier(0.34, 1.56, 0.64, 1) backwards; animation-delay: var(--in, 0s); }
@keyframes node-in {
  0%   { transform: translate(-50%, -50%) scale(0); opacity: 0; }
  70%  { transform: translate(-50%, -50%) scale(1.12); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}
.node-face { position: relative; }
.map-node.current .node-face::after {
  content: ""; position: absolute; inset: -5px; border-radius: 50%;
  border: 3px solid var(--mint-dark); animation: node-pulse 1.7s ease-out infinite;
}
@keyframes node-pulse { 0% { transform: scale(1); opacity: 0.85; } 100% { transform: scale(1.55); opacity: 0; } }
.map-node.boss .node-face { animation: boss-glow 1.9s ease-in-out infinite; }
@keyframes boss-glow {
  0%, 100% { box-shadow: var(--soft-shadow); }
  50% { box-shadow: 0 0 15px 3px rgba(255, 122, 60, 0.6), var(--soft-shadow); }
}
.map-node.unlocked-now .node-face::before {
  content: ""; position: absolute; inset: -5px; border-radius: 50%;
  border: 4px solid var(--gold); animation: unlock-ring 0.8s ease-out 0.35s 2 both;
}
@keyframes unlock-ring { 0% { transform: scale(0.8); opacity: 1; } 100% { transform: scale(1.75); opacity: 0; } }
.map-twinkle { position: absolute; width: 15px; height: 15px; transform: translate(-50%, -50%);
  pointer-events: none; opacity: 0; animation: twinkle 3.6s ease-in-out infinite; }
.map-twinkle .ic { width: 100%; height: 100%; }
@keyframes twinkle {
  0%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }
  50% { opacity: 0.8; transform: translate(-50%, -50%) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .map-node { animation: none; }
  .map-node.current .node-face::after, .map-node.unlocked-now .node-face::before { display: none; }
  .map-node.boss .node-face { animation: none; }
  .map-twinkle { animation: none; } /* stays opacity:0 → hidden */
}

/* Panels shared by stage detail + boss */
.panel { background: var(--surface); border-radius: var(--r-card);
  box-shadow: var(--soft-shadow); padding: 14px 16px; display: flex; flex-direction: column; gap: 8px; }
.goal-row { display: flex; align-items: center; gap: 12px; }
.goal-ic { width: 34px; height: 34px; border-radius: 12px; background: var(--card-hi);
  display: flex; align-items: center; justify-content: center; flex: none; }
.goal-ic .ic { width: 20px; height: 20px; }
.goal-text { flex: 1; font-weight: 700; color: var(--ink); font-size: 0.98rem; }
.goal-star { width: 24px; height: 24px; flex: none; }
.reward-panel { flex-direction: row; justify-content: space-around; text-align: center; }
.reward-col { display: flex; flex-direction: column; gap: 4px; align-items: center; }
.reward-col .section-label { margin: 0; }
.reward-coins { color: var(--gold); font-family: var(--font-ui); font-weight: 800;
  display: inline-flex; align-items: center; gap: 5px; font-size: 1.05rem; }
.reward-coins .ic { width: 22px; height: 22px; }

/* Stage detail hero + boosters */
.stage-hero { display: flex; gap: 12px; align-items: center; }
.stage-thumb { width: 96px; height: 72px; border-radius: 16px; flex: none;
  background-size: cover; background-position: center; box-shadow: var(--soft-shadow); }
.stage-hero-txt h3 { font-family: var(--font-display); font-size: 1.25rem; color: var(--ink); }
.stage-hero-txt p { color: var(--ink-dim); font-weight: 700; font-size: 0.9rem; line-height: 1.35; }
.stage-banner { width: 100%; height: clamp(96px, 15vh, 130px); border-radius: var(--r-card);
  background-size: cover; background-position: center; box-shadow: var(--soft-shadow); }
.stage-avatar { width: 78px; height: auto; flex: none;
  filter: drop-shadow(0 6px 10px rgba(150, 120, 200, 0.3)); animation: mascot-bob 3.2s ease-in-out infinite; }
/* Boss boosters: one compact row of three pick-one cards (tap toggles;
   .selected marks the choice), with the pick's description shown beneath. */
.booster-row { display: flex; gap: 8px; }
.booster-card {
  flex: 1 1 0; min-width: 0; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 9px 4px 8px; border-radius: 14px; border: 2.5px solid transparent;
  background: var(--card-hi); font: inherit; transition: border-color 0.12s;
}
.booster-card .mode-icon { background: #fff; width: 38px; height: 38px; border-radius: 12px; }
.booster-card .mode-icon svg { width: 22px; height: 22px; }
.booster-card b { color: var(--ink); font-family: var(--font-ui); font-size: 0.74rem; line-height: 1.1; text-align: center; }
.booster-card.selected { border-color: var(--gold); background: #fff; }
.booster-desc { color: var(--ink-dim); font-weight: 700; font-size: 0.85rem; text-align: center; min-height: 1.25em; margin-top: 2px; }

/* Boss Challenge */
.boss-scene { width: 100%; height: clamp(118px, 19vh, 168px); background-size: cover; background-position: center;
  border-radius: var(--r-card); box-shadow: var(--soft-shadow); position: relative; overflow: hidden;
  animation: boss-scene-glow 3.4s ease-in-out infinite; }
/* the world boss looms on the scene, gently bobbing; a name plate sits below-left */
.boss-art { position: absolute; right: 5%; bottom: 4%; height: 88%; width: auto;
  filter: drop-shadow(0 5px 10px rgba(90, 70, 130, 0.4)); animation: fog-bob 3.6s ease-in-out infinite; }
.boss-plate {
  position: absolute; left: 10px; bottom: 10px;
  padding: 4px 12px; border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.92); color: var(--ink);
  font-family: var(--font-ui); font-weight: 800; font-size: 0.9rem;
  box-shadow: var(--soft-shadow);
}
@keyframes fog-bob { 0%, 100% { transform: translateY(0) rotate(-2deg); } 50% { transform: translateY(-6px) rotate(2deg); } }
@keyframes boss-scene-glow { 0%, 100% { box-shadow: var(--soft-shadow); } 50% { box-shadow: 0 0 18px 2px rgba(150, 120, 200, 0.45), var(--soft-shadow); } }
.boss-name { font-family: var(--font-display); font-size: 1.4rem; color: var(--ink); text-align: center; }
.boss-dialog { display: flex; gap: 12px; align-items: center; background: var(--surface);
  border-radius: var(--r-card); box-shadow: var(--soft-shadow); padding: 14px; }
.boss-mascot { width: 72px; height: auto; flex: none;
  filter: drop-shadow(0 6px 10px rgba(150, 120, 200, 0.3)); animation: mascot-bob 3.2s ease-in-out infinite; }
.boss-dialog p { color: var(--ink); font-weight: 700; font-size: 0.95rem; line-height: 1.4; }
.btn-boss { background: linear-gradient(90deg, var(--pink-soft), var(--pink)); color: #fff; box-shadow: 0 5px 0 #b83a7d; }
.btn-boss:active { transform: translateY(4px); box-shadow: 0 1px 0 #b83a7d; }

/* Stage/boss body: panels fade + rise in, staggered, on entry. */
#stage-body > *, #boss-body > * { animation: panel-in 0.4s ease-out backwards; }
#stage-body > *:nth-child(1), #boss-body > *:nth-child(1) { animation-delay: 0.03s; }
#stage-body > *:nth-child(2), #boss-body > *:nth-child(2) { animation-delay: 0.09s; }
#stage-body > *:nth-child(3), #boss-body > *:nth-child(3) { animation-delay: 0.15s; }
#stage-body > *:nth-child(4), #boss-body > *:nth-child(4) { animation-delay: 0.21s; }
#stage-body > *:nth-child(5), #boss-body > *:nth-child(5) { animation-delay: 0.27s; }
@keyframes panel-in { 0% { opacity: 0; transform: translateY(12px); } 100% { opacity: 1; transform: none; } }
/* Start button: an expanding glow ring inviting the tap (a pseudo-element, so it
   never fights the button's own :active press transform/shadow). */
#btn-stage-start, #btn-boss-start { position: relative; }
#btn-stage-start::after, #btn-boss-start::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
}
#btn-stage-start::after { animation: btn-glow-gold 2.1s ease-out infinite; }
#btn-boss-start::after { animation: btn-glow-pink 2.1s ease-out infinite; }
@keyframes btn-glow-gold { 0% { box-shadow: 0 0 0 0 rgba(240, 169, 60, 0.5); } 100% { box-shadow: 0 0 0 12px rgba(240, 169, 60, 0); } }
@keyframes btn-glow-pink { 0% { box-shadow: 0 0 0 0 rgba(224, 85, 154, 0.5); } 100% { box-shadow: 0 0 0 12px rgba(224, 85, 154, 0); } }
@media (prefers-reduced-motion: reduce) {
  .stage-avatar, .boss-mascot, .boss-art, .boss-scene { animation: none; }
  #stage-body > *, #boss-body > * { animation: none; }
  #btn-stage-start::after, #btn-boss-start::after { display: none; }
}

/* In-game themed backdrop — set on <body> (already a fixed, full-viewport layer)
   during Story gameplay, so it spans the whole screen including the safe-area
   padding / notch / nav bar. #app is transparent, so the scene shows through the
   gaps around the question card. applyGameBackdrop() sets/clears it inline. */

/* Unlock-harder dialog */
.hard-options { display: flex; flex-direction: column; gap: 10px; width: 100%; margin-top: 4px; }
.hard-tier { display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; background: var(--card-hi); color: var(--ink);
  box-shadow: 0 5px 0 var(--key-shadow); } /* lilac key-shadow, matching the rest of the app */
.hard-tier:active { transform: translateY(4px); box-shadow: 0 1px 0 var(--key-shadow); }
.hard-tier .ic { width: 22px; height: 22px; }
.hard-tier.selected { outline: 3px solid var(--gold); outline-offset: -3px; }
.hard-lock { width: 100%; text-align: left; margin-top: 0; background: var(--card-hi); }
/* Round ✕ to dismiss a dialog (top-left of the card). Every card that carries a
   .dialog-close must be positioned so the ✕ anchors to the card, not the overlay. */
#hard-modal .review-card, #story-done-modal .review-card,
#rename-modal .review-card, #sound-modal .review-card { position: relative; }
.dialog-close {
  position: absolute; top: 10px; left: 10px; z-index: 1; padding: 0;
  width: 34px; height: 34px; border-radius: 50%; border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  background: var(--card-hi); color: var(--ink-dim);
}
.dialog-close .ic { width: 18px; height: 18px; }
.dialog-close:active { transform: scale(0.94); }

/* ═══════════════════════════════════════════════════════════════════════════
   HOW TO PLAY — question-type tutorial popup (looping mini-demo storyboard)
   ═══════════════════════════════════════════════════════════════════════════ */
#howto-modal .review-card { position: relative; }
.howto-eyebrow {
  color: var(--gold); font-family: var(--font-ui); font-weight: 800;
  font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.09em; margin-bottom: -6px;
}
.howto-title { display: flex; align-items: center; gap: 9px; font-size: 1.35rem; }
.howto-title .howto-ic { width: 30px; height: 30px; }
.howto-body { min-height: 2.6em; }
#howto-go { width: 100%; margin-top: 0; }

/* The demo stage: 2–3 absolutely-stacked frames cross-fading in a loop.
   Frame delay/duration are set inline by renderHowtoDemo; data-n picks the
   visible fraction (each frame holds ~2s of the cycle). */
.howto-demo {
  position: relative; width: 100%; height: 208px;
  background: var(--card-hi); border-radius: 16px; overflow: hidden;
  display: flex; flex-direction: column;
}
/* the hint text is pinned above the storyboard for the whole loop */
.howto-demo > .ht-caption { padding: 10px 12px 0; }
.ht-stage { position: relative; flex: 1 1 auto; min-height: 0; }
.ht-frame {
  position: absolute; inset: 0; opacity: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 9px; padding: 10px;
  animation-timing-function: ease-in-out; animation-iteration-count: infinite;
}
.howto-demo[data-n="1"] .ht-frame { opacity: 1; }
.howto-demo[data-n="2"] .ht-frame { animation-name: ht-c2; }
.howto-demo[data-n="3"] .ht-frame { animation-name: ht-c3; }
@keyframes ht-c2 { 0%, 44% { opacity: 1; } 50%, 94% { opacity: 0; } 100% { opacity: 1; } }
@keyframes ht-c3 { 0%, 29% { opacity: 1; } 33%, 96% { opacity: 0; } 100% { opacity: 1; } }

.ht-prompt { font-family: var(--font-display); font-size: 1.7rem; color: var(--ink); display: flex; align-items: center; gap: 6px; }
.ht-prompt.small { font-size: 1.15rem; }
.ht-dots { color: var(--ink-dim); letter-spacing: 0.2em; }
.ht-caption { color: var(--ink-dim); font-weight: 800; font-size: 0.8rem; text-align: center; }
.ht-row { display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; }

.ht-tile {
  position: relative; min-width: 42px; height: 42px; padding: 0 8px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface); border-radius: 11px; box-shadow: 0 3px 0 var(--key-shadow);
  font-family: var(--font-ui); font-weight: 800; font-size: 1.15rem; color: var(--ink);
}
.ht-tile.gl .ic, .ht-tile.gl svg { width: 24px; height: 24px; }
.ht-tile.gl2 svg { width: 24px; height: 24px; }
.ht-tile.ht-panel { min-width: 56px; height: 52px; font-size: 1.35rem; }
.ht-tile.sw { min-width: 34px; height: 34px; }
.sw-red { background: #ef4444; } .sw-blue { background: #3b82f6; }
.sw-green { background: #22c55e; } .sw-yellow { background: #eab308; }
.ht-vsrow { display: flex; align-items: center; gap: 12px; }
.ht-vs { color: var(--ink-dim); font-family: var(--font-ui); font-weight: 800; font-size: 0.85rem; }

/* The tap ring pulses ONCE per storyboard cycle (duration = --cycle), delayed
   by its frame's start (--fs) + its own stagger (--d) — so multi-tap sequences
   always fire 1st → 2nd → 3rd from the moment their frame first shows, and
   never drift out of phase with the frames. Keyframes are % of the cycle. */
.ht-tap::after {
  content: ""; position: absolute; inset: -5px; border-radius: inherit;
  border: 3px solid var(--mint-dark); opacity: 0;
  animation: ht-ring var(--cycle, 2s) ease-out infinite;
  animation-delay: calc(var(--fs, 0s) + var(--d, 0s) + 0.35s);
}
@keyframes ht-ring {
  0% { transform: scale(0.72); opacity: 0; }
  4% { opacity: 1; }
  24% { transform: scale(1.22); opacity: 0; }
  100% { opacity: 0; }
}

/* mini numpad + answer chip */
.ht-keys .ht-key { min-width: 36px; height: 36px; font-size: 1.05rem; background: #f6f2ff; }
.ht-answer {
  margin-top: 2px; padding: 4px 16px; border-radius: 999px;
  background: var(--mint); color: #1c5c44; font-family: var(--font-ui); font-weight: 800;
}

/* mini cell boards (pattern / chimp / simon / hunt / twins / path) */
.ht-grid { display: grid; gap: 5px; }
.ht-grid .ht-cell {
  position: relative; width: 34px; height: 34px; border-radius: 9px;
  background: #efe9fb; display: flex; align-items: center; justify-content: center;
  font-family: var(--font-ui); font-weight: 800; font-size: 1rem; color: var(--ink);
}
.ht-cell.lit { background: var(--mint); } /* statically lit (the pattern "peek") */
/* lights up in sequence (simon "watch"): one mint glow per cycle, --dp stagger */
.ht-cell.pulse { animation: ht-glow var(--cycle, 2s) ease-in-out infinite; animation-delay: calc(var(--fs, 0s) + var(--dp, 0s)); }
@keyframes ht-glow { 0% { background: #efe9fb; } 6% { background: var(--mint); } 16%, 100% { background: #efe9fb; } }
.ht-cell.down { background: #d9cdf2; }
.ht-cell .ic { width: 18px; height: 18px; }

/* one-off stimuli */
.ht-die { width: 46px; height: 46px; }
.ht-clock { width: 72px; height: 72px; }
.ht-cubes { gap: 5px; }
.ht-cube { width: 19px; height: 19px; border-radius: 5px; box-shadow: inset 0 -3px 0 rgba(0,0,0,0.15); }
.ht-glyph svg { width: 28px; height: 28px; }
.ht-arr { width: 22px; height: 22px; }
.ht-arr-big { width: 36px; height: 36px; }
.ht-rps { width: 38px; height: 38px; }
.ht-rps-s { width: 26px; height: 26px; }
/* heavy left side down (bar tilts counterclockwise); both items sit ON the bar */
.ht-seesaw { position: relative; width: 150px; height: 68px; }
.ht-seesaw .ht-bar { position: absolute; left: 12px; right: 12px; top: 36px; height: 6px; border-radius: 999px; background: #b8a4f0; transform: rotate(-8deg); }
.ht-seesaw .ht-pivot { position: absolute; left: 50%; bottom: 2px; transform: translateX(-50%); }
.ht-seesaw .ht-pivot .ic { width: 26px; height: 26px; }
.ht-seesaw .ht-see-item { position: absolute; }
.ht-seesaw .ht-see-item .ic { width: 26px; height: 26px; }
.ht-seesaw .ht-see-item.l { left: 10px; top: 19px; }
.ht-seesaw .ht-see-item.r { right: 10px; top: 1px; }

/* ⓘ badge on practice type cards */
.type-card { position: relative; }
.type-info {
  position: absolute; top: 4px; right: 4px; width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--card-hi); color: var(--ink-dim);
}
.type-info .ic { width: 15px; height: 15px; }

/* reduced motion: no loop — show the answer frame statically, rings frozen on */
@media (prefers-reduced-motion: reduce) {
  .ht-frame { animation: none !important; opacity: 0; }
  .ht-frame:last-child { opacity: 1; }
  .ht-tap::after { animation: none; opacity: 1; transform: none; }
  .ht-cell.pulse { animation: none; background: var(--mint); }
}
