/* ============ Synapse — Brain Training MVP ============ */

/* ---------- Tokens ---------- */
:root {
  /* Type scale (mobile-first, fluid) */
  --text-xs: clamp(0.75rem, 0.7rem + 0.25vw, 0.8125rem);
  --text-sm: clamp(0.875rem, 0.8rem + 0.3vw, 0.9375rem);
  --text-base: 1rem;
  --text-lg: clamp(1.0625rem, 1rem + 0.5vw, 1.25rem);
  --text-xl: clamp(1.375rem, 1.2rem + 1vw, 1.75rem);
  --text-2xl: clamp(1.875rem, 1.5rem + 1.5vw, 2.5rem);
  --text-num: clamp(3rem, 2rem + 8vw, 4.5rem);

  /* Spacing (4px base) */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;

  /* Radius */
  --radius-sm: 0.625rem;
  --radius-md: 0.875rem;
  --radius-lg: 1.125rem;
  --radius-xl: 1.375rem;
  --radius-full: 9999px;

  /* Transitions */
  --ease-snap: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
  --t-fast: 140ms;
  --t-med: 240ms;

  /* Game accent hues */
  --memory: #3b82f6;
  --memory-soft: #dbeafe;
  --attention: #f43f5e;
  --attention-soft: #ffe4e6;
  --math: #22c55e;
  --math-soft: #dcfce7;
  --logic: #a855f7;
  --logic-soft: #f3e8ff;
  --reaction: #eab308;
  --reaction-soft: #fef9c3;
  --signals: #06b6d4;
  --signals-soft: #cffafe;
  --oddone: #ec4899;
  --oddone-soft: #fce7f3;
  --ghosts: #7c5cff;
  --ghosts-soft: #e9e3ff;
  --passball: #16a34a;
  --passball-soft: #dcfce7;
  --secret: #0d9488;
  --secret-soft: #ccfbf1;
  --affirm: #14b8a6;
  --affirm-soft: #d1faf4;
  --crime: #b13a63;
  --crime-soft: #f6d9e4;
  --identical: #e0568a;
  --identical-soft: #fcdcea;
  --audit: #c2410c;
  --audit-soft: #fde4d3;
  --operator: #b1345a;
  --operator-soft: #f9d7e1;
  --phone: #f59e0b;
  --phone-soft: #fdecc8;
  --hanoi: #8b5cf6;
  --hanoi-soft: #e9defb;
  --basicmath: #d1495b;
  --basicmath-soft: #f7d7dc;
  --fractions: #e8873a;
  --fractions-soft: #fde6cf;
  --anagram: #159a9c;
  --anagram-soft: #d0f0ee;
  --treasure: #e0568a;
  --treasure-soft: #fcdcea;
  --missnum: #ef5a6e;
  --missnum-soft: #fcdadf;
  --patterns: #7d4fa8;
  --patterns-soft: #ece0f5;
  --numbermatch: #6b57d6;
  --numbermatch-soft: #e2ddf8;
  --mathchain: #2f9e8f;
  --mathchain-soft: #cdece7;
  --crossmath: #c98a2e;
  --crossmath-soft: #f6e6c8;
  --taparrows: #4f7bd8;
  --taparrows-soft: #dbe6fb;

  --maxw: 480px;
}

/* Light mode (default) — Warm Peach */
:root,
[data-theme="light"] {
  --bg: #fbeae0;
  --surface: #fff6f0;
  --surface-2: #fdeee6;
  --surface-offset: #f3ddd0;
  --border: #f0d9cb;
  --text: #2b2018;
  --text-muted: #8a7a6f;
  --text-faint: #b7a99e;
  --primary: #ff8a4c;
  --primary-hover: #f5793a;
  --primary-soft: #ffe6d6;
  --accent: #18786e;
  --accent-soft: #d9efe9;
  --hero-teal: #1f6f66;
  --hero-teal-2: #134e48;
  --success: #2fa56a;
  --danger: #e35d4f;
  --shadow-sm: 0 1px 2px rgba(120, 70, 40, 0.07), 0 1px 3px rgba(120, 70, 40, 0.05);
  --shadow-md: 0 6px 20px rgba(120, 70, 40, 0.10), 0 2px 6px rgba(120, 70, 40, 0.06);
  --shadow-lg: 0 14px 40px rgba(120, 70, 40, 0.16), 0 5px 14px rgba(120, 70, 40, 0.09);
  --shadow-press: inset 0 2px 6px rgba(120, 70, 40, 0.14);
  /* warm-tinted soft chips for game accents on peach */
  --memory-soft: #e2ecfb;
  --attention-soft: #ffe1e2;
  --math-soft: #d8f3e2;
  --logic-soft: #f0e4fb;
  --reaction-soft: #fdf2c8;
  --signals-soft: #d4f1f4;
  --oddone-soft: #fce0ef;
  --affirm-soft: #ccf3ec;
  --crime-soft: #f6d9e4;
  --identical-soft: #fcdcea;
  --audit-soft: #fde4d3;
  --operator-soft: #f9d7e1;
  --phone-soft: #fdecc8;
  --hanoi-soft: #e9defb;
  --basicmath-soft: #f7d7dc;
  --fractions-soft: #fbe4cb;
  --anagram-soft: #cdeeec;
  --treasure-soft: #fcdcea;
  --missnum-soft: #fcdadf;
}

[data-theme="dark"] {
  --bg: #14110f;
  --surface: #201b18;
  --surface-2: #28221e;
  --surface-offset: #1a1512;
  --border: #362e29;
  --text: #f3ece4;
  --text-muted: #aa9d92;
  --text-faint: #6e655c;
  --primary: #ff9c63;
  --primary-hover: #ffb285;
  --primary-soft: #3a2417;
  --accent: #3fb3a4;
  --accent-soft: #123630;
  --hero-teal: #1f6f66;
  --hero-teal-2: #103e39;
  --success: #4ade80;
  --danger: #f87171;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 12px 36px rgba(0, 0, 0, 0.55);
  --shadow-press: inset 0 2px 6px rgba(0, 0, 0, 0.4);
  --memory-soft: #18243f;
  --attention-soft: #3a1620;
  --math-soft: #11301d;
  --logic-soft: #2a1740;
  --reaction-soft: #322a0c;
  --signals-soft: #082c33;
  --oddone-soft: #401429;
  --ghosts-soft: #241a44;
  --passball-soft: #0c2e1c;
  --secret-soft: #06302c;
  --affirm-soft: #08302b;
  --crime-soft: #3a2035;
  --identical-soft: #3d1f30;
  --audit-soft: #3a2113;
  --operator-soft: #3a1c28;
  --phone-soft: #3a2a10;
  --hanoi-soft: #241a3d;
  --basicmath-soft: #3d1620;
  --fractions-soft: #3a2411;
  --anagram-soft: #0e2f30;
  --treasure-soft: #3a1626;
  --missnum-soft: #3a1620;
  --patterns-soft: #2a1c3d;
  --crossmath-soft: #33260f;
  --taparrows-soft: #16233d;
  --primary-glow: rgba(129, 140, 248, 0.35);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --bg: #0e0e16;
    --surface: #1a1a26;
    --surface-2: #20202e;
    --surface-offset: #14141f;
    --border: #2c2c3c;
    --text: #ecedf5;
    --text-muted: #9a9bb2;
    --text-faint: #62647d;
    --primary: #818cf8;
    --primary-hover: #a5b0ff;
    --primary-soft: #232347;
    --accent: #fbbf24;
    --accent-soft: #3a2e10;
    --success: #4ade80;
    --danger: #f87171;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 12px 36px rgba(0, 0, 0, 0.55);
    --shadow-press: inset 0 2px 6px rgba(0, 0, 0, 0.4);
    --memory-soft: #18243f;
    --attention-soft: #3a1620;
    --math-soft: #11301d;
    --logic-soft: #2a1740;
    --reaction-soft: #322a0c;
    --signals-soft: #082c33;
    --oddone-soft: #401429;
    --affirm-soft: #08302b;
    --crime-soft: #3a2035;
    --identical-soft: #3d1f30;
    --audit-soft: #3a2113;
    --operator-soft: #3a1c28;
    --phone-soft: #3a2a10;
    --hanoi-soft: #241a3d;
    --basicmath-soft: #3d1620;
    --fractions-soft: #3a2411;
    --anagram-soft: #0e2f30;
    --treasure-soft: #3a1626;
    --missnum-soft: #3a1620;
  }
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  font-family: "Satoshi", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: var(--text-base);
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  min-height: 100dvh;
  overscroll-behavior-y: none;
  -webkit-tap-highlight-color: transparent;
}

img, svg { display: block; max-width: 100%; }

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
  background: none;
  border: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: var(--radius-sm); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ---------- App shell ---------- */
#app {
  max-width: var(--maxw);
  margin: 0 auto;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  position: relative;
  background: var(--bg);
}

.screen {
  flex: 1;
  display: none;
  flex-direction: column;
  /* max(): if the WebView ever reports no safe-area inset, keep a floor so the
     header can never slide under the status bar. */
  padding: calc(var(--space-6) + max(env(safe-area-inset-top), 26px)) var(--space-5)
           calc(var(--space-10) + env(safe-area-inset-bottom));
  animation: screenIn var(--t-med) var(--ease-out);
}
/* Clear the fixed bottom nav on scrollable screens (nav ≈ 73px) */
body.nav-on .screen:not(.game-screen) {
  padding-bottom: calc(88px + var(--space-6) + env(safe-area-inset-bottom));
}
.screen.active { display: flex; }

@keyframes screenIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* game screens fill height, no scroll, locked selection */
.screen.game-screen {
  padding: calc(var(--space-4) + max(env(safe-area-inset-top), 26px)) var(--space-5)
           calc(var(--space-6) + env(safe-area-inset-bottom));
  user-select: none;
  -webkit-user-select: none;
}

/* ---------- Typography helpers ---------- */
.greeting { font-size: var(--text-sm); color: var(--text-muted); font-weight: 500; }
.h-title { font-size: var(--text-2xl); font-weight: 700; letter-spacing: -0.02em; line-height: 1.1; }
.page-title { font-size: var(--text-xl); font-weight: 700; letter-spacing: -0.02em; }
.section-label {
  font-size: var(--text-xs); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--text-muted);
}
.muted { color: var(--text-muted); }
.num-big { font-size: var(--text-num); font-weight: 800; letter-spacing: -0.03em; line-height: 1; }

/* ---------- Top bar ---------- */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--space-6);
}
.brand { display: flex; align-items: center; gap: var(--space-2); }
.brand .logo { width: 30px; height: 30px; object-fit: contain; display: block; }
.brand .name { font-size: var(--text-lg); font-weight: 800; letter-spacing: -0.02em; }

.iconbtn {
  width: 44px; height: 44px; border-radius: var(--radius-full);
  display: grid; place-items: center; color: var(--text-muted);
  background: var(--surface); box-shadow: var(--shadow-sm);
  transition: transform var(--t-fast) var(--ease-snap), color var(--t-fast);
}
.iconbtn:active { transform: scale(0.9); }

/* ---------- Cards ---------- */
.card {
  background: var(--surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-md);
  padding: var(--space-5);
}

/* streak chip */
.streak-row { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-6); }
.streak-chip {
  display: inline-flex; align-items: center; gap: var(--space-2);
  background: var(--accent-soft); color: var(--accent);
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-full);
  font-weight: 700; font-size: var(--text-sm); box-shadow: var(--shadow-sm);
}
.streak-chip .flame { animation: flicker 2.4s ease-in-out infinite; }
@keyframes flicker {
  0%, 100% { transform: scale(1) rotate(-2deg); }
  50% { transform: scale(1.12) rotate(2deg); }
}

/* ---------- Daily workout ---------- */
.workout-card {
  background: linear-gradient(140deg, var(--primary), var(--primary-hover));
  color: #fff;
  border-radius: var(--radius-xl);
  padding: var(--space-5);
  box-shadow: var(--shadow-lg);
  margin-bottom: var(--space-6);
  position: relative;
  overflow: hidden;
}
.workout-card::after {
  content: ""; position: absolute; right: -40px; top: -40px;
  width: 160px; height: 160px; border-radius: 50%;
  background: rgba(255,255,255,0.12);
}
.workout-card .wo-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: var(--space-4); position: relative; z-index: 1; }
.workout-card .wo-label { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.08em; opacity: 0.85; font-weight: 700; }
.workout-card .wo-title { font-size: var(--text-lg); font-weight: 700; margin-top: 2px; }
.wo-games { display: flex; flex-direction: column; gap: var(--space-2); position: relative; z-index: 1; }
.wo-game {
  display: flex; align-items: center; gap: var(--space-3);
  background: rgba(255,255,255,0.15);
  border-radius: var(--radius-md); padding: var(--space-3);
  transition: transform var(--t-fast) var(--ease-snap), background var(--t-fast);
  text-align: left; width: 100%;
}
.wo-game:active { transform: scale(0.97); background: rgba(255,255,255,0.25); }
.wo-game .wo-emoji { font-size: 1.4rem; width: 40px; height: 40px; display: grid; place-items: center; background: rgba(255,255,255,0.2); border-radius: var(--radius-sm); }
.wo-game .wo-info { flex: 1; min-width: 0; }
.wo-game .wo-name { font-weight: 700; font-size: var(--text-sm); }
.wo-game .wo-skill { font-size: var(--text-xs); opacity: 0.8; }
.wo-game .wo-chev { opacity: 0.7; }

/* ---------- Skill snapshot (bars) ---------- */
.skills-card { margin-bottom: var(--space-6); }
.skills-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--space-4); }
.skill-list { display: flex; flex-direction: column; gap: var(--space-4); }
.skill-row { display: flex; align-items: center; gap: var(--space-3); }
.skill-name { width: 78px; font-size: var(--text-sm); font-weight: 600; flex-shrink: 0; }
.skill-track { flex: 1; height: 10px; background: var(--surface-offset); border-radius: var(--radius-full); overflow: hidden; }
.skill-fill {
  height: 100%; border-radius: var(--radius-full); width: 0;
  transition: width 900ms var(--ease-out);
  /* Two defects fixed here. 1) .skill-fill is a <span>, i.e. an inline
     element, so `width`/`height` were ignored and it rendered 0px wide.
     2) The markup sets --fill-accent per skill on .skill-row, but no
     background was ever declared, so it had no colour either. Together these
     made every skill-level bar on Home and Profile appear permanently empty. */
  display: block;
  background: var(--fill-accent, var(--primary));
}
.skill-lvl { width: 30px; text-align: right; font-size: var(--text-sm); font-weight: 700; color: var(--text-muted); flex-shrink: 0; }

/* ---------- Games grid ---------- */
.games-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.game-tile {
  background: var(--surface); border-radius: var(--radius-lg);
  padding: var(--space-4); box-shadow: var(--shadow-sm);
  text-align: left; position: relative;
  border: 1.5px solid transparent;
  transition: transform var(--t-fast) var(--ease-snap), box-shadow var(--t-fast), border-color var(--t-fast);
  min-height: 112px; display: flex; flex-direction: column; justify-content: space-between;
}
.game-tile:active { transform: scale(0.95); box-shadow: var(--shadow-md); }
.game-tile .gt-emoji {
  width: 46px; height: 46px; border-radius: var(--radius-md);
  display: grid; place-items: center; font-size: 1.5rem; margin-bottom: var(--space-2);
}
.game-tile .gt-name { font-weight: 700; font-size: var(--text-sm); letter-spacing: -0.01em; }
.game-tile .gt-skill { font-size: var(--text-xs); color: var(--text-muted); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  padding: var(--space-4) var(--space-5); border-radius: var(--radius-md);
  font-weight: 700; font-size: var(--text-base);
  transition: transform var(--t-fast) var(--ease-snap), background var(--t-fast), box-shadow var(--t-fast);
  min-height: 52px; width: 100%;
}
.btn:active { transform: scale(0.96); }
.btn-primary { background: var(--primary); color: #fff; box-shadow: var(--shadow-md); }
.btn-primary:active { background: var(--primary-hover); }
.btn-ghost { background: var(--surface); color: var(--text); box-shadow: var(--shadow-sm); }
.btn-soft { background: var(--surface-offset); color: var(--text); }
.btn-row { display: flex; flex-direction: column; gap: var(--space-3); margin-top: var(--space-6); }

/* ---------- Game header (in-game) ---------- */
.game-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  margin-bottom: var(--space-5);
}
.game-head .back {
  width: 42px; height: 42px; border-radius: var(--radius-full); display: grid; place-items: center;
  background: var(--surface); box-shadow: var(--shadow-sm); color: var(--text-muted);
  transition: transform var(--t-fast) var(--ease-snap);
}
.game-head .back:active { transform: scale(0.9); }
.game-head .gh-title { font-weight: 700; font-size: var(--text-base); }
.game-head .gh-score { font-weight: 800; font-size: var(--text-lg); color: var(--accent); font-variant-numeric: tabular-nums; }
/* Current-level chip: shown in every in-game header so the player always knows
   which difficulty they're playing at. */
.gh-level {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 11px; font-weight: 800; letter-spacing: 0.04em;
  padding: 3px 9px; border-radius: 999px;
  background: var(--primary-soft); color: var(--primary-hover);
  white-space: nowrap;
}
.gh-level.mastered { background: linear-gradient(180deg, #fff4d6, #ffe6a8); color: #a9791f; }
[data-theme="dark"] .gh-level.mastered { background: rgba(240,200,100,0.18); color: #ffd766; }

/* timer bar */
.timer-wrap { height: 8px; background: var(--surface-offset); border-radius: var(--radius-full); overflow: hidden; margin-bottom: var(--space-5); }
.timer-fill { height: 100%; border-radius: var(--radius-full); width: 100%; background: var(--primary); transition: width 1s linear, background var(--t-med); }

.game-body { flex: 1; display: flex; flex-direction: column; }

/* generic feedback flashes */
.flash-correct { animation: flashGreen 380ms var(--ease-out); }
.flash-wrong { animation: shake 360ms var(--ease-out); }
@keyframes flashGreen { 0% { box-shadow: 0 0 0 0 var(--success); } 100% { box-shadow: 0 0 0 0 transparent; } }
@keyframes shake {
  0%,100%{transform:translateX(0);} 20%{transform:translateX(-8px);} 40%{transform:translateX(8px);}
  60%{transform:translateX(-5px);} 80%{transform:translateX(5px);}
}
@keyframes pulse { 0%{transform:scale(1);} 50%{transform:scale(1.06);} 100%{transform:scale(1);} }

/* ============ Shopping List ============ */
.mem-stage { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-5); }
.mem-prompt { font-weight: 600; color: var(--text-muted); font-size: var(--text-sm); text-align: center; }
.mem-show-card {
  background: var(--surface); border-radius: var(--radius-xl); box-shadow: var(--shadow-lg);
  padding: var(--space-6); display: grid; gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(56px, 1fr)); width: 100%;
  border: 2px solid var(--memory);
}
.mem-show-card .item { font-size: 2.4rem; text-align: center; animation: pop var(--t-med) var(--ease-snap) backwards; }
@keyframes pop { from { transform: scale(0); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.mem-countdown { font-size: var(--text-2xl); font-weight: 800; color: var(--memory); font-variant-numeric: tabular-nums; }
.mem-grid { display: grid; gap: var(--space-3); width: 100%; }
.mem-cell {
  aspect-ratio: 1; border-radius: var(--radius-md); background: var(--surface);
  box-shadow: var(--shadow-sm); font-size: 1.9rem; display: grid; place-items: center;
  border: 2.5px solid transparent;
  transition: transform var(--t-fast) var(--ease-snap), border-color var(--t-fast), background var(--t-fast);
}
.mem-cell:active { transform: scale(0.92); }
.mem-cell.selected { border-color: var(--memory); background: var(--memory-soft); }
.mem-cell.correct { border-color: var(--success); background: var(--math-soft); }
.mem-cell.missed { border-color: var(--success); background: transparent; opacity: 0.55; }
.mem-cell.wrong { border-color: var(--danger); background: var(--attention-soft); }
.round-dots { display: flex; gap: var(--space-2); justify-content: center; }
.round-dots .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--surface-offset); }
.round-dots .dot.done { background: var(--memory); }
.round-dots .dot.active { background: var(--memory); transform: scale(1.4); }

/* ============ Arrows ============ */
.arrow-stage { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: space-between; padding: var(--space-4) 0; }
.combo-pill {
  font-weight: 800; font-size: var(--text-sm); padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-full); background: var(--attention-soft); color: var(--attention);
  font-variant-numeric: tabular-nums; transition: transform var(--t-fast) var(--ease-snap);
}
.combo-pill.bump { animation: pulse 320ms var(--ease-snap); }
.arrow-display {
  flex: 1; display: grid; place-items: center; width: 100%;
}
.arrow-big {
  width: 130px; height: 130px;
  transition: transform var(--t-fast) var(--ease-snap), color var(--t-fast);
}
.arrow-big.show { animation: pop 220ms var(--ease-snap); }
.dpad { display: grid; grid-template-columns: repeat(3, 70px); grid-template-rows: repeat(3, 70px); gap: var(--space-2); }
.dpad-btn {
  border-radius: var(--radius-md); background: var(--surface); box-shadow: var(--shadow-sm);
  display: grid; place-items: center; color: var(--text);
  transition: transform var(--t-fast) var(--ease-snap), background var(--t-fast);
}
.dpad-btn:active { transform: scale(0.88); background: var(--attention-soft); }
.dpad-up { grid-column: 2; grid-row: 1; }
.dpad-left { grid-column: 1; grid-row: 2; }
.dpad-right { grid-column: 3; grid-row: 2; }
.dpad-down { grid-column: 2; grid-row: 3; }

/* ============ Math ============ */
.math-stage { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-8); }
.math-eq { font-size: clamp(2.5rem, 12vw, 3.5rem); font-weight: 800; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.math-eq.shake { animation: shake 360ms var(--ease-out); }
.math-opts { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); width: 100%; }
.math-opt {
  padding: var(--space-5); border-radius: var(--radius-lg); background: var(--surface);
  box-shadow: var(--shadow-sm); font-size: var(--text-xl); font-weight: 800; font-variant-numeric: tabular-nums;
  transition: transform var(--t-fast) var(--ease-snap), background var(--t-fast), color var(--t-fast);
  min-height: 64px;
}
.math-opt:active { transform: scale(0.95); }
.math-opt.correct { background: var(--math); color: #fff; }
.math-opt.wrong { background: var(--danger); color: #fff; animation: shake 360ms; }
.math-tier { font-size: var(--text-xs); font-weight: 700; color: var(--math); text-transform: uppercase; letter-spacing: 0.06em; }

/* ============ Robotic Flows (Logic) ============ */
.flow-meta { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--space-4); }
.flow-board-wrap { flex: 1; display: grid; place-items: center; }
.flow-board {
  display: grid; gap: 5px; background: var(--surface-offset); padding: 6px;
  border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
  touch-action: none; width: 100%; max-width: 360px; aspect-ratio: 1;
}
.flow-cell {
  border-radius: 8px; background: var(--surface); display: grid; place-items: center;
  position: relative; transition: background var(--t-fast);
}
.flow-cell.path { /* path color set inline */ }
.flow-dot {
  width: 70%; height: 70%; border-radius: 50%;
  box-shadow: 0 2px 6px rgba(0,0,0,0.18); z-index: 2;
}
.flow-puzzle-pick { display: flex; flex-direction: column; gap: var(--space-3); }
.puzzle-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-4); border-radius: var(--radius-md); background: var(--surface); box-shadow: var(--shadow-sm);
  transition: transform var(--t-fast) var(--ease-snap);
}
.puzzle-item:active { transform: scale(0.97); }
.puzzle-stars { color: var(--logic); letter-spacing: 2px; }
/* Toolbar under a puzzle board. Uses an auto-fitting grid so the buttons share
   the width evenly and wrap to a new row when they don't fit — a 4-button
   toolbar (e.g. Twins Connect) becomes a clean 2×2 on phones instead of
   overflowing off the right edge. */
.flow-tools {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--space-3);
  margin-top: var(--space-4);
}
.flow-tools .btn { min-height: 48px; min-width: 0; white-space: nowrap; padding-left: var(--space-3); padding-right: var(--space-3); }

/* ============ Twins Connect (Logic) ============ */
.twins-board { max-width: 380px; }
.twins-cell { transition: background var(--t-fast), box-shadow var(--t-fast); }
.twins-endpoint {
  display: grid; place-items: center; z-index: 2;
  box-shadow: 0 2px 6px rgba(0,0,0,0.22);
}
.twins-endpoint svg {
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.35));
  pointer-events: none;
}

/* Twins level picker (100-level campaign) */
.twins-progress {
  display: flex; justify-content: space-between; align-items: center;
  font-size: var(--text-sm); margin: 4px 0 14px;
}
.twins-progress b { color: var(--logic); }
.twins-band { margin-bottom: 18px; }
.twins-band-head {
  display: flex; justify-content: space-between; align-items: baseline;
  font-weight: 700; font-size: var(--text-sm); margin-bottom: 8px;
}
.twins-lvl-grid {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px;
}
.twins-lvl {
  position: relative; aspect-ratio: 1; border: none; cursor: pointer;
  border-radius: var(--radius-md, 12px);
  background: var(--logic-soft, #ece4fb);
  color: var(--ink, #2a2320);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; transition: transform var(--t-fast), box-shadow var(--t-fast);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.05);
}
.twins-lvl:active { transform: scale(0.94); }
.twins-lvl.is-done {
  background: var(--logic, #a855f7); color: #fff;
  box-shadow: 0 2px 8px rgba(168,85,247,0.35);
}
.twins-lvl-n { font-weight: 800; font-size: var(--text-base, 16px); line-height: 1; }
.twins-lvl-s { font-size: 9px; line-height: 1; color: #ffd54a; min-height: 9px; letter-spacing: -1px; }
.twins-lvl.is-open {
  box-shadow: inset 0 0 0 2px var(--logic, #a855f7);
}
.twins-lvl.is-locked {
  background: rgba(0,0,0,0.05); color: rgba(0,0,0,0.3);
  cursor: not-allowed; box-shadow: none;
}
.twins-lvl.is-locked:active { transform: none; }
.twins-lock { font-size: var(--text-base, 16px); opacity: 0.55; }

/* ============ Lost & Found (Attention) ============ */
.lf-rules { text-align: center; padding: var(--space-6) var(--space-3); display: flex; flex-direction: column; align-items: center; gap: 10px; }
.lf-rules-icon {
  width: 92px; height: 92px; border-radius: 24px; padding: 20px;
  background: var(--attention, #f59e0b); box-shadow: 0 8px 24px rgba(245,158,11,0.35);
  margin-bottom: 6px;
}
.lf-rules h2 { font-size: var(--text-xl, 24px); font-weight: 800; }
.lf-rules .btn { margin-top: 14px; min-width: 180px; }

.lf-body { display: flex; flex-direction: column; height: 100%; }
.lf-progress { height: 6px; background: rgba(0,0,0,0.08); border-radius: 99px; overflow: hidden; margin-bottom: 10px; }
.lf-progress-fill { height: 100%; background: var(--attention, #f59e0b); border-radius: 99px; transition: width var(--t-med, .3s); }
.lf-prompt {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: rgba(30,22,28,0.92); color: #fff; border-radius: 16px;
  padding: 12px 16px; font-weight: 700; font-size: var(--text-sm, 14px);
}
.lf-target { width: 34px; height: 34px; flex: 0 0 34px; display: grid; place-items: center; }
.lf-target svg { width: 100%; height: 100%; animation: lf-pop .3s ease; }
@keyframes lf-pop { from { transform: scale(.5); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.lf-meta { display: flex; justify-content: space-between; font-size: var(--text-sm, 14px); font-weight: 700; margin: 10px 2px 8px; }
#lf-time.lf-low { color: #ef4444; }
.lf-field {
  position: relative; flex: 1; min-height: 440px; border-radius: 18px; padding: 12px 8px;
  display: grid; grid-template-columns: repeat(6, 1fr); gap: 2px;
  align-content: space-evenly; justify-items: center;
  overflow: hidden;
}
.lf-item {
  width: 100%; aspect-ratio: 1; max-width: 56px; border: none; background: transparent;
  cursor: pointer; padding: 6px;
  display: grid; place-items: center; transition: transform .12s, opacity .25s;
  transform: rotate(var(--lf-rot, 0deg));
}
.lf-item:active { transform: scale(0.85); }
.lf-item.is-correct { animation: lf-correct .3s ease; }
.lf-item.is-correct::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: rgba(34,197,94,0.35); z-index: -1;
}
@keyframes lf-correct { 0%{transform:scale(1)} 50%{transform:scale(1.4)} 100%{transform:scale(1)} }
.lf-item.is-wrong { animation: lf-wrong .3s ease; }
@keyframes lf-wrong { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-4px)} 75%{transform:translateX(4px)} }
.lf-item.lf-hide { opacity: 0; pointer-events: none; transform: scale(0); }
.lf-wave-done { grid-column: 1 / -1; text-align: center; color: #fff; font-weight: 800; font-size: var(--text-lg, 20px); padding: 60px 20px; line-height: 1.6; }
.lf-field.lf-shuffling { animation: lf-fieldshake .26s ease; }
.lf-field.lf-shuffling .lf-item { opacity: 0; transition: opacity .18s; }
@keyframes lf-fieldshake { 0%,100%{transform:translateX(0)} 20%{transform:translateX(-6px)} 60%{transform:translateX(6px)} }
.lf-field.lf-shuffled-in .lf-item { animation: lf-pop .32s ease backwards; }

/* ============ One Man Out (Attention) ============ */
.omo-rules { text-align: center; padding: var(--space-6) var(--space-3); display: flex; flex-direction: column; align-items: center; gap: 10px; }
.omo-rules-face { width: 108px; height: 108px; border-radius: 24px; padding: 6px; background: var(--attention-soft, #fde9c8); box-shadow: 0 8px 24px rgba(0,0,0,0.12); margin-bottom: 6px; }
.omo-rules h2 { font-size: var(--text-xl, 24px); font-weight: 800; }
.omo-rules .btn { margin-top: 14px; min-width: 180px; }

.omo-body { display: flex; flex-direction: column; height: 100%; }
.omo-progress { display: flex; gap: 6px; margin-bottom: 12px; }
.omo-seg { flex: 1; height: 6px; border-radius: 99px; background: rgba(0,0,0,0.1); transition: background var(--t-med,.3s); }
.omo-seg.done { background: var(--attention, #f59e0b); }
.omo-seg.cur { background: var(--attention, #f59e0b); opacity: 0.55; }
.omo-meta { display: flex; justify-content: space-between; align-items: center; font-size: var(--text-sm, 14px); font-weight: 700; margin-bottom: 14px; color: var(--ink, #2a2320); }
.omo-meta > span:nth-child(2) { color: var(--muted, #8a7f77); font-weight: 600; }
.omo-grid {
  display: grid; gap: 16px 12px;
  align-content: space-evenly; justify-items: center; align-items: center;
  flex: 1; width: 100%; max-width: 460px; margin: 0 auto; padding: 8px 0;
}
.omo-face {
  width: 100%; aspect-ratio: 1; border: none; background: transparent; cursor: pointer; padding: 4px;
  border-radius: 16px; transition: transform .12s, background .2s;
}
/* smaller faces on 3-col grids look better a touch larger; bigger grids get more gap */
.omo-grid[style*="repeat(5"] { gap: 14px 8px; }
.omo-face:active { transform: scale(0.92); }
.omo-face:hover { background: rgba(0,0,0,0.03); }
.omo-face.omo-correct { animation: omo-correct .5s ease; background: rgba(34,197,94,0.22); box-shadow: 0 0 0 3px #22c55e; }
@keyframes omo-correct { 0%{transform:scale(1)} 45%{transform:scale(1.12)} 100%{transform:scale(1)} }
.omo-face.omo-wrong { animation: omo-wrong .35s ease; box-shadow: 0 0 0 3px #ef4444; border-radius: 16px; }
@keyframes omo-wrong { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-5px)} 75%{transform:translateX(5px)} }
.omo-grid.omo-shuffling { animation: omo-gridshake .34s ease; }
.omo-grid.omo-shuffling .omo-face { opacity: 0.15; transition: opacity .2s; }
@keyframes omo-gridshake { 0%,100%{transform:translateX(0)} 20%{transform:translateX(-7px)} 60%{transform:translateX(7px)} }
.omo-grid.omo-shuffled-in .omo-face { animation: omo-correct .32s ease backwards; }
.omo-face.omo-removed { opacity: 0; transform: scale(0.4); pointer-events: none; transition: opacity .3s, transform .3s; }
.omo-tools { display: flex; justify-content: center; margin-top: var(--space-4); }
.omo-tools .btn { min-height: 46px; min-width: 200px; }
.omo-tools .btn:disabled { opacity: 0.5; }

/* ============ Find color (Speed) ============ */
.fc-rules { text-align: center; padding: var(--space-6) var(--space-3); display: flex; flex-direction: column; align-items: center; gap: 10px; }
.fc-swatches-preview { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; width: 150px; margin-bottom: 8px; }
.fc-swatches-preview span { aspect-ratio: 1; border-radius: 10px; box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08); }
.fc-rules h2 { font-size: var(--text-xl, 24px); font-weight: 800; }
.fc-rules .btn { margin-top: 14px; min-width: 180px; }

.fc-body { display: flex; flex-direction: column; height: 100%; }
.fc-timerbar { height: 8px; background: rgba(0,0,0,0.08); border-radius: 99px; overflow: hidden; margin-bottom: 10px; }
.fc-timerfill { height: 100%; width: 100%; background: var(--reaction, #eab308); border-radius: 99px; transition: width 1s linear; }
.fc-meta { display: flex; justify-content: space-between; align-items: center; font-size: var(--text-base, 16px); font-weight: 800; margin-bottom: 16px; }
.fc-meta .muted { font-weight: 600; font-size: var(--text-sm, 14px); }
#fc-time.fc-low { color: #ef4444; }
.fc-word {
  background: #33302f; color: #fff; text-align: center; font-weight: 800;
  font-size: var(--text-xl, 24px); padding: 18px; border-radius: 14px; margin-bottom: 18px;
  letter-spacing: 0.5px;
}
.fc-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; align-content: start; }
.fc-swatch {
  aspect-ratio: 1.3; border: none; border-radius: 16px; cursor: pointer;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.1), 0 2px 6px rgba(0,0,0,0.12);
  transition: transform .1s;
}
.fc-swatch:active { transform: scale(0.94); }
.fc-swatch.fc-correct { animation: fc-correct .35s ease; box-shadow: 0 0 0 4px #22c55e; }
@keyframes fc-correct { 0%{transform:scale(1)} 45%{transform:scale(1.08)} 100%{transform:scale(1)} }
.fc-swatch.fc-wrong { animation: fc-wrong .35s ease; box-shadow: 0 0 0 4px #ef4444; }
@keyframes fc-wrong { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-5px)} 75%{transform:translateX(5px)} }

/* ============ Swipes (Speed) ============ */
.sw-rules { text-align: center; padding: var(--space-6) var(--space-3); display: flex; flex-direction: column; align-items: center; gap: 10px; }
.sw-rules-arrow { width: 84px; height: 84px; color: var(--reaction, #eab308); margin-bottom: 6px; }
.sw-rules h2 { font-size: var(--text-xl, 24px); font-weight: 800; }
.sw-rules .btn { margin-top: 14px; min-width: 180px; }

.sw-body { display: flex; flex-direction: column; height: 100%; }
.sw-timerbar { height: 8px; background: rgba(0,0,0,0.08); border-radius: 99px; overflow: hidden; margin-bottom: 10px; }
.sw-timerfill { height: 100%; width: 100%; background: var(--reaction, #eab308); border-radius: 99px; transition: width 1s linear; }
.sw-meta { display: flex; justify-content: space-between; align-items: center; font-size: var(--text-base, 16px); font-weight: 800; margin-bottom: 14px; }
.sw-meta .muted { font-weight: 600; font-size: var(--text-sm, 14px); }
#sw-time.sw-low { color: #ef4444; }
.sw-area {
  position: relative; flex: 1; min-height: 420px; border-radius: 22px;
  border: 2px solid rgba(0,0,0,0.18);
  display: grid; place-items: center; overflow: hidden;
  touch-action: none; user-select: none; -webkit-user-select: none;
  cursor: grab; background: transparent;
}
.sw-area:active { cursor: grabbing; }
.sw-prompt { display: flex; flex-direction: column; align-items: center; gap: 6px; pointer-events: none; }
.sw-arrow { width: 96px; height: 96px; color: var(--ink, #3a2a20); }
.sw-word { font-size: 52px; font-weight: 900; color: var(--ink, #3a2a20); }
.sw-word-small { font-size: 30px; opacity: 0.85; }
.sw-twist { gap: 2px; }
.sw-twist-hint { font-size: var(--text-xs, 12px); font-weight: 700; color: var(--reaction, #b8860b); text-transform: uppercase; letter-spacing: 1px; margin-top: 4px; }
.sw-feedback { position: absolute; inset: 0; pointer-events: none; }
.sw-area.sw-ok { animation: sw-ok .28s ease; }
@keyframes sw-ok { 0%{background:rgba(34,197,94,0)} 40%{background:rgba(34,197,94,0.28)} 100%{background:rgba(34,197,94,0)} }
.sw-area.sw-bad { animation: sw-bad .3s ease; }
@keyframes sw-bad { 0%,100%{background:rgba(239,68,68,0);transform:translateX(0)} 30%{background:rgba(239,68,68,0.22);transform:translateX(-6px)} 70%{transform:translateX(6px)} }

/* ============ Reaction ============ */
.react-stage {
  position: absolute; inset: 0; display: grid; place-items: center;
  border-radius: 0; text-align: center; color: #fff; padding: var(--space-6);
  transition: background var(--t-med);
}
.react-fullwrap { flex: 1; position: relative; border-radius: var(--radius-xl); overflow: hidden; box-shadow: var(--shadow-md); }
.react-wait { background: #dc2626; }
.react-go { background: #16a34a; }
/* Decoy flash used from level 5: clearly NOT the green go signal, but a change big
   enough to catch anyone tapping on movement rather than on colour. */
.react-decoy { background: #d97706; }
.react-idle { background: var(--reaction); color: #1a1505; }
.react-early { background: #b91c1c; }
.react-big { font-size: var(--text-2xl); font-weight: 800; }
.react-sub { font-size: var(--text-base); opacity: 0.9; margin-top: var(--space-2); }
.react-rounds { display: flex; gap: var(--space-2); justify-content: center; margin-top: var(--space-4); }
.react-rounds .rdot { width: 11px; height: 11px; border-radius: 50%; background: var(--surface-offset); }
.react-rounds .rdot.done { background: var(--reaction); }

/* ============ Results ============ */
.results-screen { align-items: center; justify-content: center; text-align: center; }
.results-emoji { font-size: 3.5rem; margin-bottom: var(--space-3); animation: pop 400ms var(--ease-snap); }
.results-title { font-size: var(--text-xl); font-weight: 700; }
.results-score { font-size: var(--text-num); font-weight: 800; letter-spacing: -0.03em; color: var(--primary); margin: var(--space-2) 0; font-variant-numeric: tabular-nums; }
.results-delta { font-size: var(--text-sm); font-weight: 700; display: inline-flex; align-items: center; gap: 4px; padding: var(--space-2) var(--space-3); border-radius: var(--radius-full); }
.delta-up { background: var(--math-soft); color: var(--success); }
.delta-down { background: var(--attention-soft); color: var(--danger); }
.delta-same { background: var(--surface-offset); color: var(--text-muted); }
.xp-card { margin-top: var(--space-6); width: 100%; }
.xp-row { display: flex; align-items: center; justify-content: space-between; }
.xp-skill { display: flex; align-items: center; gap: var(--space-2); font-weight: 600; }
.xp-amount { font-weight: 800; color: var(--accent); font-variant-numeric: tabular-nums; }
.xp-bar { height: 8px; background: var(--surface-offset); border-radius: var(--radius-full); overflow: hidden; margin-top: var(--space-3); }
.xp-fill { height: 100%; background: var(--accent); border-radius: var(--radius-full); transition: width 900ms var(--ease-out); }

/* ============ Profile ============ */
.stat-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--space-3); margin-bottom: var(--space-6); }
.stat-box { background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); padding: var(--space-4); text-align: center; }
.stat-box .sv { font-size: var(--text-xl); font-weight: 800; font-variant-numeric: tabular-nums; }
.stat-box .sl { font-size: var(--text-xs); color: var(--text-muted); margin-top: 2px; }
.bestlist { display: flex; flex-direction: column; gap: var(--space-2); }
.best-row { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3); border-radius: var(--radius-md); background: var(--surface); box-shadow: var(--shadow-sm); }
.best-row .be { width: 38px; height: 38px; border-radius: var(--radius-sm); display: grid; place-items: center; font-size: 1.2rem; }
.best-row .bn { flex: 1; font-weight: 600; font-size: var(--text-sm); }
.best-row .bv { font-weight: 800; font-variant-numeric: tabular-nums; }
.profile-screen { user-select: text; -webkit-user-select: text; }

/* allow selection in profile */
.stack { display: flex; flex-direction: column; }
.mb-6 { margin-bottom: var(--space-6); }
.mt-4 { margin-top: var(--space-4); }
.center { text-align: center; }
.hidden { display: none !important; }

/* ========== Strange Signals — Impulse-style sequence memory ========== */
.sig2-shell {
  --sig2-bg: #2d4a4e;          /* dark sea-green */
  --sig2-bg-2: #38595e;
  --sig2-cell: #1a2d2f;        /* darker square cells */
  --sig2-cell-border: rgba(255,255,255,0.05);
  --sig2-text: #f4eee0;
  --sig2-chip-bg: rgba(0,0,0,0.42);
  --sig2-correct: #a3e635;     /* lime green */
  --sig2-wrong: #fb7185;       /* coral red */
  --sig2-lit: #fff4c2;         /* warm cream */
  --sig2-lit-glow: #ffd97a;
  --sig2-bulb-off: #5d6d6d;    /* grey-green for off bulb */
  --sig2-bulb-cap: #b8b1a3;
  position: relative;
  flex: 1; display: flex; flex-direction: column;
  background: radial-gradient(120% 80% at 50% 0%, var(--sig2-bg-2), var(--sig2-bg) 75%);
  border-radius: 24px;
  overflow: hidden;
  min-height: 70vh;
  margin: 0 -2px;
  box-shadow: 0 12px 40px rgba(20, 35, 35, 0.4);
}

.sig2-topbar {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 14px 8px;
  position: relative; z-index: 3;
}
.sig2-bar {
  flex: 1;
  /* Two children now (round, score) since the duplicate level chip was removed.
     `space-between` would fling them to opposite ends of a wide pill; centre with a
     gap so the bar still reads as a single grouped readout. */
  display: flex; align-items: center; justify-content: center; gap: 22px;
  padding: 9px 22px;
  background: var(--sig2-chip-bg);
  color: var(--sig2-text);
  border-radius: var(--radius-full);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
.sig2-bar .sig2-round { font-size: 15px; }
.sig2-bar .sig2-score { font-size: 15px; }

.sig2-iconbtn {
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--sig2-chip-bg);
  color: var(--sig2-text);
  border: 0;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: transform 100ms var(--ease-out), background 200ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.sig2-iconbtn:hover { background: rgba(0,0,0,0.6); }
.sig2-iconbtn:active { transform: scale(0.92); }

/* Stage holds background art + message + grid */
.sig2-stage {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 8px 10px 18px;
  min-width: 0;
}
.sig2-bg-art {
  position: absolute; inset: 0;
  background-image: url("signals_room_bg.png");
  background-size: cover;
  background-position: center bottom;
  opacity: 0.55;
  pointer-events: none;
}
.sig2-bg-art::after {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(120% 60% at 50% 30%, transparent, rgba(20,35,35,0.6) 80%);
  pointer-events: none;
}

.sig2-message {
  position: relative;
  z-index: 2;
  margin: 0 auto 14px;
  background: rgba(0,0,0,0.32);
  color: var(--sig2-text);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.01em;
  padding: 12px 22px;
  border-radius: var(--radius-full);
  text-align: center;
  max-width: 92%;
  line-height: 1.25;
}

/* Grid of cells */
.sig2-grid {
  position: relative;
  z-index: 2;
  display: grid;
  gap: 8px;
  /* Container-relative (NOT viewport-relative): the grid sits inside the
     screen padding + shell + stage padding, so 92vw overflowed and got
     clipped by .sig2-shell's overflow:hidden on narrow phones. */
  width: 100%;
  max-width: 420px;
  box-sizing: border-box;
  margin: 0 auto;
  align-self: center;
  justify-self: center;
}
.sig2-cell {
  appearance: none;
  border: 1px solid var(--sig2-cell-border);
  background: var(--sig2-cell);
  border-radius: 6px;
  padding: 8px;
  aspect-ratio: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 220ms var(--ease-out), transform 100ms var(--ease-out), box-shadow 220ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.sig2-cell:disabled { cursor: default; }
.sig2-cell:active:not(:disabled) { transform: scale(0.95); }

.sig2-cell.lit {
  /* bulb glows but cell stays dark — only during show phase */
}
.sig2-cell.correct {
  background: var(--sig2-correct);
  box-shadow: 0 0 24px rgba(163, 230, 53, 0.5);
  border-color: rgba(255,255,255,0.18);
}
.sig2-cell.wrong {
  background: var(--sig2-wrong);
  box-shadow: 0 0 24px rgba(251, 113, 133, 0.55);
  border-color: rgba(255,255,255,0.2);
  animation: sig2-shake 320ms var(--ease-out);
}
@keyframes sig2-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

/* Bulb SVG inside each cell */
.sig2-bulb-svg {
  width: 78%;
  height: 78%;
  overflow: visible;
  transition: filter 220ms var(--ease-out), transform 220ms var(--ease-out);
}

/* Default OFF colors */
.sig2-cap { fill: var(--sig2-bulb-cap); }
.sig2-cap-band { fill: #8c8475; }
.sig2-wire { stroke: var(--sig2-bulb-cap); opacity: 0.5; }
.sig2-glass {
  fill: var(--sig2-bulb-off);
  stroke: rgba(0,0,0,0.25);
  stroke-width: 1;
  transition: fill 200ms var(--ease-out);
}
.sig2-shine { stroke: rgba(255,255,255,0.4); opacity: 0; transition: opacity 200ms var(--ease-out); }

/* Lit state: warm bulb */
.sig2-cell.lit .sig2-glass {
  fill: var(--sig2-lit);
}
.sig2-cell.lit .sig2-bulb-svg {
  filter: drop-shadow(0 0 10px var(--sig2-lit-glow)) drop-shadow(0 0 18px rgba(255,217,122,0.55));
  transform: scale(1.05);
}
.sig2-cell.lit .sig2-shine { opacity: 0.7; }

/* `flash` class is added each time a bulb lights during the show phase, then
   removed. Forces a fresh pop animation so back-to-back flashes at the same
   cell are visually distinguishable. */
.sig2-cell.flash .sig2-bulb-svg {
  animation: sig2-pop 220ms var(--ease-out);
}
@keyframes sig2-pop {
  0%   { transform: scale(0.86); }
  60%  { transform: scale(1.14); }
  100% { transform: scale(1.05); }
}

/* When correctly tapped: cell green + bulb stays lit */
.sig2-cell.correct .sig2-glass { fill: var(--sig2-lit); }
.sig2-cell.correct .sig2-bulb-svg {
  filter: drop-shadow(0 0 8px rgba(255,255,255,0.5));
}

/* hint reveal for missed bulb on wrong tap */
.sig2-cell.lit.hint {
  background: var(--sig2-cell);
  animation: sig2-pulse 600ms var(--ease-out) 2;
}
@keyframes sig2-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.04); }
}

/* Broken bulb */
.sig2-glass-broken {
  fill: var(--sig2-bulb-off);
  stroke: rgba(0,0,0,0.35);
  stroke-width: 1;
}
.sig2-shard { fill: var(--sig2-bulb-off); }
.sig2-cell.wrong .sig2-glass-broken { fill: rgba(255,255,255,0.85); }
.sig2-cell.wrong .sig2-shard { fill: rgba(255,255,255,0.7); }
.sig2-cell.wrong .sig2-cap { fill: rgba(255,255,255,0.8); }
.sig2-cell.wrong .sig2-cap-band { fill: rgba(255,255,255,0.55); }

/* Floating "+95" score popup */
.sig2-floater {
  position: absolute;
  pointer-events: none;
  transform: translate(-50%, 0);
  font-weight: 800;
  font-size: 18px;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0,0,0,0.5);
  animation: sig2-float 800ms var(--ease-out) forwards;
  z-index: 4;
}
@keyframes sig2-float {
  0%   { opacity: 0; transform: translate(-50%, 8px); }
  20%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -32px); }
}

/* Pause + howto overlays */
.sig2-paused, .sig2-howto {
  position: absolute; inset: 0;
  background: rgba(10, 25, 28, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center;
  z-index: 5;
  padding: 24px;
}
.sig2-paused[hidden], .sig2-howto[hidden] { display: none; }
.sig2-card {
  background: var(--surface);
  border-radius: 22px;
  padding: 22px 22px 18px;
  max-width: 320px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.45);
  text-align: center;
}
.sig2-card h3 { font-size: var(--text-xl); font-weight: 800; margin: 0 0 6px; color: var(--text); }
.sig2-card p { margin: 4px 0; color: var(--text); font-size: var(--text-base); line-height: 1.45; }
.sig2-card p.sig2-mini { color: var(--text-muted); font-size: var(--text-sm); margin-top: 8px; }
.sig2-card .btn { margin-top: 14px; }

@media (prefers-reduced-motion: reduce) {
  .sig2-cell, .sig2-cell.wrong, .sig2-bulb-svg, .sig2-floater { animation: none !important; transition: none !important; }
}


/* ========== Hidden Ghosts — spooky memory grid ========== */
.gh2-shell {
  --gh2-bg: #20203a;
  --gh2-bg-2: #2c2a52;
  --gh2-cell: #2a2a46;
  --gh2-cell-border: rgba(255,255,255,0.06);
  --gh2-text: #efeaff;
  --gh2-chip-bg: rgba(0,0,0,0.40);
  --gh2-reveal: #7fd8e6;
  --gh2-correct: #5fd36a;
  --gh2-wrong: #f0596b;
  position: relative;
  flex: 1; display: flex; flex-direction: column;
  background: radial-gradient(125% 85% at 50% 0%, var(--gh2-bg-2), var(--gh2-bg) 78%);
  border-radius: 24px;
  overflow: hidden;
  min-height: 72vh;
  margin: 0 -2px;
  box-shadow: 0 12px 40px rgba(15, 12, 35, 0.45);
}
.gh2-topbar { display: flex; align-items: center; gap: 10px; padding: 14px 14px 8px; position: relative; z-index: 3; }
.gh2-bar {
  /* See .sig2-bar: two children now, so centre + gap rather than space-between. */
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 22px;
  padding: 9px 22px; background: var(--gh2-chip-bg); color: var(--gh2-text);
  border-radius: var(--radius-full); font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
}
.gh2-bar .gh2-round, .gh2-bar .gh2-score { font-size: 15px; }
.gh2-iconbtn {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--gh2-chip-bg); color: var(--gh2-text); border: 0;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  transition: transform 100ms var(--ease-out), background 200ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.gh2-iconbtn:hover { background: rgba(0,0,0,0.6); }
.gh2-iconbtn:active { transform: scale(0.92); }
.gh2-stage { position: relative; flex: 1; display: flex; flex-direction: column; justify-content: center; padding: 8px 10px 18px; }
.gh2-bg-art {
  position: absolute; inset: 0;
  background:
    radial-gradient(60% 40% at 20% 12%, rgba(124,92,255,0.20), transparent 60%),
    radial-gradient(50% 35% at 85% 18%, rgba(127,216,230,0.12), transparent 60%);
  pointer-events: none;
}
.gh2-bg-art::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(120% 60% at 50% 35%, transparent, rgba(15,12,35,0.55) 82%);
  pointer-events: none;
}
.gh2-message {
  position: relative; z-index: 2; margin: 0 auto 14px;
  background: rgba(0,0,0,0.34); color: var(--gh2-text);
  font-weight: 700; font-size: 17px; letter-spacing: 0.01em;
  padding: 11px 22px; border-radius: var(--radius-full);
  text-align: center; max-width: 92%; line-height: 1.25;
  transition: background 200ms var(--ease-out), color 200ms var(--ease-out);
}
.gh2-message.warn { background: rgba(240,89,107,0.22); color: #ffd9de; }
.gh2-grid {
  position: relative; z-index: 2; display: grid; gap: 7px;
  width: 100%; max-width: 340px; margin: 0 auto; align-self: center;
  box-sizing: border-box;
}
.gh2-cell {
  appearance: none; border: 1px solid var(--gh2-cell-border);
  background: var(--gh2-cell); border-radius: 7px; padding: 0;
  aspect-ratio: 1; cursor: pointer; position: relative;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  transition: background 200ms var(--ease-out), transform 90ms var(--ease-out), box-shadow 220ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.gh2-cell:disabled { cursor: default; }
.gh2-cell:active:not(:disabled) { transform: scale(0.94); }
.gh2-ghost { display: flex; align-items: center; justify-content: center; width: 72%; height: 72%; line-height: 1; opacity: 0; transform: scale(0.6); transition: opacity 180ms var(--ease-out), transform 180ms var(--ease-snap); filter: drop-shadow(0 2px 4px rgba(0,0,0,0.35)); }
.gh2-ghost svg { width: 100%; height: 100%; display: block; }
.gh2-cell.reveal { background: var(--gh2-reveal); border-color: rgba(255,255,255,0.25); box-shadow: 0 0 18px rgba(127,216,230,0.4); }
.gh2-cell.reveal .gh2-ghost { opacity: 1; transform: scale(1); animation: gh2-pop 220ms var(--ease-snap); }
.gh2-cell.reveal.missed { background: var(--gh2-reveal); opacity: 0.85; }
.gh2-cell.correct { background: var(--gh2-correct); border-color: rgba(255,255,255,0.22); box-shadow: 0 0 18px rgba(95,211,106,0.45); }
.gh2-cell.correct .gh2-ghost { opacity: 1; transform: scale(1); animation: gh2-pop 220ms var(--ease-snap); }
.gh2-cell.wrong { background: var(--gh2-wrong); border-color: rgba(255,255,255,0.24); box-shadow: 0 0 18px rgba(240,89,107,0.5); animation: gh2-shake 320ms var(--ease-out); }
.gh2-cell.wrong .gh2-ghost { opacity: 0; }
.gh2-cell.wrong::after { content: "\2715"; position: absolute; color: #fff; font-size: 1.4rem; font-weight: 800; opacity: 0.92; }
@keyframes gh2-pop { 0% { transform: scale(0.6);} 60% { transform: scale(1.18);} 100% { transform: scale(1);} }
@keyframes gh2-shake { 0%,100% { transform: translateX(0);} 25% { transform: translateX(-4px);} 75% { transform: translateX(4px);} }
.gh2-floater {
  position: absolute; top: 4px; left: 50%; transform: translateX(-50%);
  font-weight: 800; font-size: 13px; color: #fff; pointer-events: none;
  text-shadow: 0 1px 3px rgba(0,0,0,0.5);
  animation: gh2-float 800ms var(--ease-out) forwards;
}
@keyframes gh2-float { 0% { opacity: 0; transform: translate(-50%, 6px);} 25% { opacity: 1;} 100% { opacity: 0; transform: translate(-50%, -18px);} }
.gh2-overlay {
  position: absolute; inset: 0;
  background: rgba(16, 14, 35, 0.58);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center; z-index: 5; padding: 24px;
}
.gh2-overlay[hidden] { display: none; }
.gh2-card {
  background: var(--surface); border-radius: 22px; padding: 22px 22px 18px;
  max-width: 320px; box-shadow: 0 20px 60px rgba(0,0,0,0.45); text-align: center;
}
.gh2-card h3 { font-size: var(--text-xl); font-weight: 800; margin: 0 0 6px; color: var(--text); }
.gh2-card p { margin: 4px 0; color: var(--text); font-size: var(--text-base); line-height: 1.45; }
.gh2-card p.gh2-mini { color: var(--text-muted); font-size: var(--text-sm); margin-top: 8px; }
.gh2-card .btn { margin-top: 14px; }
@media (prefers-reduced-motion: reduce) {
  .gh2-cell, .gh2-cell.wrong, .gh2-ghost, .gh2-floater { animation: none !important; transition: none !important; }
}

/* ========== Pass the Ball: memorize blockers, then draw a path ==========
   Green field stage. Memorize phase shows helmet blockers on red tiles;
   recall phase: drag a path between two footballs avoiding the blockers. */
.pb-shell {
  --pb-bg: #143a28;
  --pb-bg-2: #1c4d35;
  --pb-cell: #1d4733;
  --pb-cell-border: rgba(255,255,255,0.07);
  --pb-text: #eafff2;
  --pb-chip-bg: rgba(0,0,0,0.40);
  --pb-block: #ef5350;
  --pb-path: #fcd34d;
  --pb-correct: #5fd36a;
  --pb-wrong: #f0596b;
  position: relative;
  flex: 1; display: flex; flex-direction: column;
  background: radial-gradient(125% 85% at 50% 0%, var(--pb-bg-2), var(--pb-bg) 78%);
  border-radius: 24px; overflow: hidden; min-height: 72vh; margin: 0 -2px;
  box-shadow: 0 12px 40px rgba(8, 28, 18, 0.5);
}
.pb-topbar { display: flex; align-items: center; gap: 10px; padding: 14px 14px 8px; position: relative; z-index: 3; }
.pb-bar {
  /* See .sig2-bar: two children now, so centre + gap rather than space-between. */
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 22px;
  padding: 9px 22px; background: var(--pb-chip-bg); color: var(--pb-text);
  border-radius: var(--radius-full); font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
}
.pb-bar .pb-round, .pb-bar .pb-score { font-size: 15px; }
.pb-iconbtn {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--pb-chip-bg); color: var(--pb-text); border: 0;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  transition: transform 100ms var(--ease-out), background 200ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.pb-iconbtn:hover { background: rgba(0,0,0,0.6); }
.pb-iconbtn:active { transform: scale(0.92); }
.pb-bg-art {
  position: absolute; inset: 0; pointer-events: none; opacity: 0.5;
  background:
    repeating-linear-gradient(90deg, transparent 0 11.11%, rgba(255,255,255,0.05) 11.11% calc(11.11% + 2px)),
    linear-gradient(180deg, rgba(255,255,255,0.04), transparent 40%);
}
.pb-stage { position: relative; flex: 1; display: flex; flex-direction: column; align-items: center; padding: 8px 14px 18px; z-index: 2; }
.pb-message {
  align-self: stretch; text-align: center; margin: 6px auto 12px; max-width: 340px;
  background: var(--pb-chip-bg); color: var(--pb-text); border-radius: var(--radius-full);
  padding: 9px 16px; font-weight: 700; font-size: var(--text-sm); line-height: 1.3;
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.pb-message.warn { color: #ffd9d9; }
.pb-message .pb-inline { width: 22px; height: 22px; border-radius: 5px; background: var(--pb-block); display: inline-flex; align-items: center; justify-content: center; padding: 2px; }
.pb-message .pb-inline svg, .pb-message .pb-inline img { width: 100%; height: 100%; object-fit: contain; }
.pb-gridwrap { position: relative; width: 100%; max-width: 340px; margin: 0 auto; align-self: center; }
.pb-grid { display: grid; gap: 8px; width: 100%; box-sizing: border-box; touch-action: none; }
.pb-svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 4; }
.pb-cell {
  appearance: none; border: 1px solid var(--pb-cell-border);
  background: var(--pb-cell); border-radius: 8px; padding: 0;
  aspect-ratio: 1; position: relative;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  transition: background 180ms var(--ease-out), box-shadow 200ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.pb-icon { width: 72%; height: 72%; opacity: 0; transform: scale(0.6); transition: opacity 180ms var(--ease-out), transform 180ms var(--ease-snap); filter: drop-shadow(0 2px 4px rgba(0,0,0,0.35)); }
.pb-icon svg, .pb-icon img { width: 100%; height: 100%; display: block; object-fit: contain; -webkit-user-drag: none; user-select: none; }
.pb-cell.block { background: var(--pb-block); border-color: rgba(255,255,255,0.22); box-shadow: 0 0 14px rgba(239,83,83,0.4); }
.pb-cell.block .pb-icon { opacity: 1; transform: scale(1); animation: gh2-pop 220ms var(--ease-snap); }
.pb-cell.ball .pb-icon { opacity: 1; transform: scale(1); }
.pb-cell.ball { box-shadow: inset 0 0 0 2px rgba(252,211,77,0.55); }
.pb-cell.path { background: rgba(252,211,77,0.22); box-shadow: inset 0 0 0 2px rgba(252,211,77,0.5); }
.pb-cell.path.ball { background: rgba(252,211,77,0.34); }
.pb-cell.solved { background: var(--pb-correct); border-color: rgba(255,255,255,0.22); box-shadow: 0 0 16px rgba(95,211,106,0.45); }
.pb-cell.hit { background: var(--pb-wrong); animation: gh2-shake 320ms var(--ease-out); }
.pb-floater {
  position: absolute; top: 4px; left: 50%; transform: translateX(-50%);
  font-weight: 800; font-size: 13px; color: #fff; pointer-events: none;
  text-shadow: 0 1px 3px rgba(0,0,0,0.5); animation: gh2-float 800ms var(--ease-out) forwards;
}
.pb-overlay {
  position: absolute; inset: 0; background: rgba(8, 24, 16, 0.6);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center; z-index: 6; padding: 24px;
}
.pb-overlay[hidden] { display: none; }
.pb-card {
  background: var(--surface); border-radius: 22px; padding: 22px 22px 18px;
  max-width: 320px; box-shadow: 0 20px 60px rgba(0,0,0,0.45); text-align: center;
  display: flex; flex-direction: column; align-items: center;
}
.pb-card h3 { font-size: var(--text-xl); font-weight: 800; margin: 0 0 6px; color: var(--text); }
.pb-card p { margin: 4px 0; color: var(--text); font-size: var(--text-base); line-height: 1.45; }
.pb-card p.pb-mini { color: var(--text-muted); font-size: var(--text-sm); margin-top: 8px; }
.pb-card .btn { margin-top: 14px; align-self: stretch; }
@media (prefers-reduced-motion: reduce) {
  .pb-cell, .pb-icon { animation: none !important; transition: none !important; }
}

/* ========== Secret code: memorize numbers, tap them in ascending order ==========
   Teal "vault" stage. Memorize phase shows numbers on cream keypad tiles; they
   flip blank; the player taps them in ascending order from memory. Correct tap
   turns the tile green (revealing its number); wrong tap flashes red. */
.sc-shell {
  --sc-bg: #1f4d49;
  --sc-bg-2: #2a615b;
  --sc-text: #eafff7;
  --sc-chip-bg: rgba(0,0,0,0.34);
  --sc-tile: #f6e3da;          /* cream keypad tile */
  --sc-tile-edge: #e2cdc2;
  --sc-tile-num: #4a3a33;      /* dark number */
  --sc-correct: #66bb6a;
  --sc-wrong: #ef5350;
  position: relative;
  flex: 1; display: flex; flex-direction: column;
  background: radial-gradient(125% 85% at 50% 0%, var(--sc-bg-2), var(--sc-bg) 80%);
  border-radius: 24px; overflow: hidden; min-height: 72vh; margin: 0 -2px;
  box-shadow: 0 12px 40px rgba(8, 32, 28, 0.5);
}
.sc-topbar { display: flex; align-items: center; gap: 10px; padding: 14px 14px 8px; position: relative; z-index: 3; }
.sc-bar {
  /* See .sig2-bar: two children now, so centre + gap rather than space-between. */
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 22px;
  padding: 9px 22px; background: var(--sc-chip-bg); color: var(--sc-text);
  border-radius: var(--radius-full); font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
}
.sc-bar .sc-round, .sc-bar .sc-score { font-size: 15px; }
.sc-iconbtn {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--sc-chip-bg); color: var(--sc-text); border: 0;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  transition: transform 100ms var(--ease-out), background 200ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.sc-iconbtn:hover { background: rgba(0,0,0,0.55); }
.sc-iconbtn:active { transform: scale(0.92); }
.sc-bg-art {
  position: absolute; inset: 0; pointer-events: none; opacity: 0.5;
  background:
    radial-gradient(circle at 18% 60%, rgba(255,255,255,0.05) 0 12%, transparent 13%),
    radial-gradient(circle at 82% 30%, rgba(255,255,255,0.04) 0 16%, transparent 17%),
    linear-gradient(180deg, rgba(255,255,255,0.04), transparent 40%);
}
.sc-stage { position: relative; flex: 1; display: flex; flex-direction: column; align-items: center; padding: 8px 14px 18px; z-index: 2; }
.sc-message {
  align-self: stretch; text-align: center; margin: 6px auto 4px; max-width: 340px;
  background: var(--sc-chip-bg); color: var(--sc-text); border-radius: var(--radius-full);
  padding: 9px 16px; font-weight: 700; font-size: var(--text-sm); line-height: 1.3;
}
.sc-message.warn { color: #ffd9d9; }
.sc-board { position: relative; width: 100%; max-width: 340px; flex: 1; margin: 8px auto 0; align-self: center; }
.sc-tile {
  position: absolute; box-sizing: border-box;
  border: 0; padding: 0; cursor: pointer;
  background: var(--sc-tile); border-radius: 14px;
  box-shadow: 0 4px 0 var(--sc-tile-edge), 0 8px 14px rgba(0,0,0,0.28);
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; color: var(--sc-tile-num);
  font-variant-numeric: tabular-nums;
  transition: transform 120ms var(--ease-snap), background 160ms var(--ease-out), box-shadow 160ms var(--ease-out), opacity 160ms var(--ease-out);
  -webkit-tap-highlight-color: transparent; user-select: none;
}
.sc-tile:active { transform: scale(0.95); }
.sc-tile .sc-num { transition: opacity 150ms var(--ease-out); }
/* decorative keypad dots shown when the number is hidden */
.sc-tile .sc-dots {
  position: absolute; right: 8px; bottom: 7px; width: 16px; height: 12px; opacity: 0.35;
  background-image: radial-gradient(currentColor 1px, transparent 1.4px);
  background-size: 5px 5px; color: var(--sc-tile-num);
}
.sc-tile .sc-abc {
  position: absolute; right: 8px; top: 6px; font-size: 9px; font-weight: 800;
  letter-spacing: 1px; opacity: 0.25; color: var(--sc-tile-num);
}
.sc-tile.hidden-num .sc-num { opacity: 0; }
.sc-tile.correct {
  background: var(--sc-correct); color: #fff;
  box-shadow: 0 4px 0 #4d9b51, 0 8px 16px rgba(95,180,90,0.4);
}
.sc-tile.correct .sc-num { opacity: 1; }
.sc-tile.correct .sc-dots, .sc-tile.correct .sc-abc { opacity: 0; }
.sc-tile.wrong {
  background: var(--sc-wrong); color: #fff;
  box-shadow: 0 4px 0 #c44; animation: sc-shake 320ms var(--ease-out);
}
.sc-tile.wrong .sc-num { opacity: 1; }
.sc-tile.wrong .sc-dots, .sc-tile.wrong .sc-abc { opacity: 0; }
.sc-xmark {
  position: absolute; z-index: 5; width: 34px; height: 34px; border-radius: 50%;
  background: #ef5350; color: #fff; display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 10px rgba(0,0,0,0.35); pointer-events: none;
  transform: translate(-50%, -50%) scale(0); animation: sc-pop 260ms var(--ease-snap) forwards;
}
@keyframes sc-pop { to { transform: translate(-50%, -50%) scale(1); } }
@keyframes sc-shake {
  0%,100% { transform: translateX(0); } 20% { transform: translateX(-4px); }
  40% { transform: translateX(4px); } 60% { transform: translateX(-3px); } 80% { transform: translateX(3px); }
}
.sc-floater {
  position: absolute; font-weight: 800; font-size: 13px; color: #eafff7; pointer-events: none;
  text-shadow: 0 1px 3px rgba(0,0,0,0.5); animation: gh2-float 800ms var(--ease-out) forwards; z-index: 6;
}
.sc-overlay {
  position: absolute; inset: 0; background: rgba(10, 32, 28, 0.6);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center; z-index: 7; padding: 24px;
}
.sc-overlay[hidden] { display: none; }
.sc-card {
  background: var(--surface); border-radius: 22px; padding: 22px 22px 18px;
  max-width: 320px; box-shadow: 0 20px 60px rgba(0,0,0,0.45); text-align: center;
  display: flex; flex-direction: column; align-items: center;
}
.sc-card h3 { font-size: var(--text-xl); font-weight: 800; margin: 0 0 6px; color: var(--text); }
.sc-card p { margin: 4px 0; color: var(--text); font-size: var(--text-base); line-height: 1.45; }
.sc-card p.sc-mini { color: var(--text-muted); font-size: var(--text-sm); margin-top: 8px; }
.sc-card .btn { margin-top: 14px; align-self: stretch; }
@media (prefers-reduced-motion: reduce) {
  .sc-tile, .sc-xmark { animation: none !important; transition: none !important; }
}


/* ========== The Odd One — immersive pattern-spotting ==========
   Themed dark plum stage with teal shapes. Some shapes carry a textured fill
   (dots / diagonal stripes) — those are the targets. */
.odd2-shell {
  --odd2-bg: #3a1d3b;       /* plum */
  --odd2-bg-2: #50204c;     /* slightly lighter plum for blob */
  --odd2-accent: #38c4c1;   /* teal = rgb(56,196,193) */
  /* Odd-one shade variations: SAME teal hue, lighter by a clearly noticeable
     (but not glaring) amount so the odd one is findable by scanning rather than
     by guessing. Difficulty = how much lighter (strong → soft). */
  --odd2-tint-strong: #6fe0dd;  /* rgb(111,224,221) — clearly lighter, ~70 delta */
  --odd2-tint-mid:    #5cd6d3;  /* rgb(92,214,211) — noticeably lighter, ~45 delta */
  --odd2-tint-soft:   #4ecfcc;  /* rgb(78,207,204) — subtle but perceptible, ~28 delta */
  --odd2-text: #f4e6f1;
  --odd2-chip-bg: rgba(0,0,0,0.42);
  position: relative;
  flex: 1; display: flex; flex-direction: column;
  background: radial-gradient(120% 80% at 50% 0%, var(--odd2-bg-2), var(--odd2-bg) 70%);
  border-radius: 24px;
  overflow: hidden;
  min-height: 70vh;
  margin: 0 -2px;
  box-shadow: 0 12px 40px rgba(35, 10, 35, 0.35);
}
[data-theme="dark"] .odd2-shell {
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.55);
}

.odd2-topbar {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 14px 8px;
  position: relative; z-index: 3;
}
.odd2-bar {
  position: relative;
  flex: 1;
  display: flex; align-items: center; justify-content: center; gap: 9px;
  padding: 9px 14px;
  background: var(--odd2-chip-bg);
  color: var(--odd2-text);
  border-radius: var(--radius-full);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  font-size: 14px;
  overflow: hidden;
}
/* Progress fill inside the pill — grows left to right with elapsed time */
.odd2-bar-fill {
  position: absolute;
  left: 0; top: 0; bottom: 0; width: 0%;
  background: rgba(0,0,0,0.55);
  z-index: 0;
  transition: width 200ms linear;
  pointer-events: none;
}
.odd2-bar > *:not(.odd2-bar-fill) { position: relative; z-index: 1; }
.odd2-bar .odd2-divider {
  width: 1px; height: 14px; background: rgba(255,255,255,0.18);
}
.odd2-toast {
  position: absolute; top: 14px; left: 50%; transform: translateX(-50%);
  z-index: 4; background: rgba(251,113,133,0.92); color: #fff;
  font-weight: 800; font-size: 14px; letter-spacing: 0.02em;
  padding: 8px 18px; border-radius: var(--radius-full);
  box-shadow: 0 6px 18px rgba(0,0,0,0.3);
  animation: odd2-toast-in 180ms var(--ease-out);
}
.odd2-toast[hidden] { display: none; }
@keyframes odd2-toast-in { from { opacity: 0; transform: translate(-50%, -6px);} to { opacity: 1; transform: translate(-50%, 0);} }
.odd2-bar .odd2-time { min-width: 42px; text-align: center; }
.odd2-bar .odd2-progress { min-width: 30px; text-align: center; opacity: 0.95; }
.odd2-bar .odd2-score { min-width: 26px; text-align: right; }

.odd2-iconbtn {
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--odd2-chip-bg);
  color: var(--odd2-text);
  border: 0;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: transform 100ms var(--ease-out), background 200ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.odd2-iconbtn:hover { background: rgba(0,0,0,0.6); }
.odd2-iconbtn:active { transform: scale(0.92); }

.odd2-stage {
  flex: 1;
  position: relative;
  display: flex; align-items: stretch; justify-content: stretch;
  padding: 8px 6px 18px;
}
/* Studio illustration background — dim, atmospheric */
.odd2-bg-art {
  position: absolute; inset: 0;
  background-image: url("odd_studio_bg.png");
  background-size: cover;
  background-position: center bottom;
  opacity: 0.55;
  pointer-events: none;
}
.odd2-bg-art::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(120% 60% at 50% 25%, transparent, rgba(58,29,59,0.65) 75%);
  pointer-events: none;
}

.odd2-shapes {
  position: relative;
  width: 100%; height: 100%;
  display: block;
}

.odd2-shape {
  filter: drop-shadow(0 2px 0 rgba(0,0,0,0.25));
  transition: transform 160ms var(--ease-out), opacity 220ms var(--ease-out), filter 220ms var(--ease-out);
  transform-box: fill-box;
  transform-origin: center;
}
.odd2-shape.found {
  animation: odd2-pop 420ms var(--ease-out) forwards;
}
.odd2-shape.miss {
  animation: odd2-shake 320ms var(--ease-out);
}
/* Green flash, hold briefly so the player clearly sees the success, then
   shrink-and-fade. The fill itself is swapped to solid green in JS. */
@keyframes odd2-pop {
  0%   { transform: scale(1);    opacity: 1; filter: drop-shadow(0 0 0 rgba(163,230,53,0)); }
  25%  { transform: scale(1.22); opacity: 1; filter: drop-shadow(0 0 14px rgba(163,230,53,0.95)); }
  55%  { transform: scale(1.14); opacity: 1; filter: drop-shadow(0 0 12px rgba(163,230,53,0.8)); }
  80%  { transform: scale(1.05); opacity: 1; filter: drop-shadow(0 0 6px rgba(163,230,53,0.4)); }
  100% { transform: scale(0.2);  opacity: 0; filter: drop-shadow(0 0 0 rgba(163,230,53,0)); }
}
@keyframes odd2-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-3px) rotate(-4deg); }
  75% { transform: translateX(3px) rotate(4deg); }
}
@media (prefers-reduced-motion: reduce) {
  .odd2-shape.found, .odd2-shape.miss { animation: none !important; }
  .odd2-shape.found { opacity: 0; transform: scale(0); }
}

/* Floating point feedback */
.odd2-floater {
  position: absolute;
  pointer-events: none;
  transform: translate(-50%, 0);
  font-weight: 800;
  font-size: 16px;
  letter-spacing: 0.02em;
  text-shadow: 0 1px 2px rgba(0,0,0,0.4);
  animation: odd2-float 700ms var(--ease-out) forwards;
}
.odd2-floater.ok { color: #b5f3d1; }
.odd2-floater.miss { color: #ffb4b4; }
@keyframes odd2-float {
  0% { opacity: 0; transform: translate(-50%, 6px); }
  20% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -28px); }
}

/* Modal-style overlays for help + paused */
.odd2-howto, .odd2-paused {
  position: absolute; inset: 0;
  background: rgba(20, 6, 22, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center;
  z-index: 5;
  padding: 24px;
}
.odd2-howto[hidden], .odd2-paused[hidden] { display: none; }
.odd2-card {
  background: var(--surface);
  border-radius: 22px;
  padding: 22px 22px 18px;
  max-width: 320px;
  width: 100%;
  box-shadow: 0 20px 60px rgba(0,0,0,0.4);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}
.odd2-card .btn { display: flex; width: 100%; text-align: center; }
.odd2-card h3 { font-size: var(--text-xl); font-weight: 800; margin: 0 0 6px; color: var(--text); }
.odd2-card p { margin: 4px 0; color: var(--text); font-size: var(--text-base); line-height: 1.45; }
.odd2-card p.odd2-mini { color: var(--text-muted); font-size: var(--text-sm); margin-top: 8px; }
.odd2-card .btn { margin-top: 14px; }

/* ============================================================ */
/* ============ WARM PEACH REDESIGN ADDITIONS ================= */
/* ============================================================ */

/* --- Ambient atmosphere (warm peach glows, home only) --- */
.atmos { position: fixed; inset: 0; z-index: -2; overflow: hidden; pointer-events: none; opacity: 0; transition: opacity 600ms var(--ease-out); }
.grain { position: fixed; inset: 0; z-index: -1; pointer-events: none; opacity: 0; }
body.at-home .atmos { opacity: 1; }
.aurora { position: absolute; border-radius: 50%; filter: blur(70px); opacity: 0.5; }
.aurora-1 { width: 320px; height: 320px; background: var(--primary-soft); top: -120px; right: -80px; }
.aurora-2 { width: 280px; height: 280px; background: #ffd9c2; bottom: 8%; left: -90px; opacity: 0.4; }
.aurora-3 { width: 240px; height: 240px; background: var(--accent-soft); top: 40%; right: -60px; opacity: 0.35; }
[data-theme="dark"] .aurora { opacity: 0.22; }
[data-theme="dark"] .aurora-1 { background: #4a2a18; }
[data-theme="dark"] .aurora-2 { background: #2a1810; }
[data-theme="dark"] .aurora-3 { background: #123630; }

/* --- Bottom nav (lean tab bar) --- */
#bottom-nav {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: 0; width: 100%; max-width: var(--maxw); z-index: 40;
  display: none;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-6) calc(var(--space-3) + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--surface) 86%, transparent);
  backdrop-filter: blur(16px) saturate(1.4); -webkit-backdrop-filter: blur(16px) saturate(1.4);
  border-top: 1px solid var(--border);
  box-shadow: 0 -6px 24px rgba(120,70,40,0.08);
}
body.nav-on #bottom-nav { display: grid; }
.nav-btn {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  padding: var(--space-2) 0; border-radius: var(--radius-md);
  color: var(--text-faint); font-size: 11px; font-weight: 700; letter-spacing: 0.02em;
  transition: color var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-snap);
}
.nav-btn span { line-height: 1; }
.nav-btn:active { transform: scale(0.92); }
.nav-btn.active { color: var(--primary); }

/* leave room above the fixed nav so content never hides behind it (nav ≈ 88px) */
body.nav-on #screen-home,
body.nav-on #screen-profile,
body.nav-on #screen-intro { padding-bottom: calc(88px + var(--space-8) + env(safe-area-inset-bottom)); }
body.nav-on #screen-results { padding-bottom: calc(88px + var(--space-8) + env(safe-area-inset-bottom)); }

/* --- Brand wordmark uses warm primary --- */
.brand .logo { color: var(--primary); }

/* --- GAME OF THE DAY hero banner --- */
.hero-card {
  position: relative; overflow: hidden;
  border-radius: var(--radius-xl);
  background: linear-gradient(135deg, var(--hero-teal), var(--hero-teal-2));
  padding: var(--space-5) var(--space-6);
  box-shadow: var(--shadow-lg);
  margin-bottom: var(--space-8);
  color: #f3efe6;
  display: flex; align-items: center; gap: var(--space-4);
  min-height: 132px;
}
.hero-card::before {
  content: ""; position: absolute; right: -30px; bottom: -50px;
  width: 180px; height: 180px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,0.10), transparent 70%);
}
.hero-text { flex: 1; min-width: 0; position: relative; z-index: 1; }
.hero-label { font-size: var(--text-xs); font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: rgba(243,239,230,0.72); }
.hero-name { font-size: var(--text-xl); font-weight: 800; letter-spacing: -0.02em; margin: 4px 0 var(--space-4); color: #fffaf2; line-height: 1.1; }
.hero-play {
  display: inline-flex; align-items: center; gap: var(--space-2);
  background: var(--primary); color: #fff;
  padding: var(--space-3) var(--space-5); border-radius: var(--radius-full);
  font-weight: 800; font-size: var(--text-sm); letter-spacing: 0.04em; text-transform: uppercase;
  box-shadow: 0 6px 16px rgba(255,138,76,0.4);
  transition: transform var(--t-fast) var(--ease-snap), background var(--t-fast);
}
.hero-play:active { transform: scale(0.95); background: var(--primary-hover); }
.hero-glyph {
  font-size: 4.6rem; line-height: 1; position: relative; z-index: 1;
  filter: drop-shadow(0 4px 10px rgba(0,0,0,0.3));
  flex-shrink: 0;
}

/* --- Category sections + 2-col game cards --- */
.cat-section { margin-bottom: var(--space-6); }
.cat-head { font-size: var(--text-lg); font-weight: 800; letter-spacing: -0.01em; margin-bottom: var(--space-4); color: var(--text); }
.cat-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
.gcard {
  background: var(--surface); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md); overflow: hidden; text-align: left;
  border: 1px solid var(--border);
  transition: transform var(--t-fast) var(--ease-snap), box-shadow var(--t-med);
}
.gcard:active { transform: scale(0.96); }
.gcard-thumb {
  position: relative; aspect-ratio: 16 / 11;
  display: grid; place-items: center; font-size: 2.6rem;
  background: var(--tile-soft); color: var(--tile-accent);
}
.gcard-thumb .glyph { filter: drop-shadow(0 2px 4px rgba(120,70,40,0.18)); }

/* Custom image game icons (replace emoji where g.icon is set) */
.game-img-icon { display: block; object-fit: contain; max-width: 100%; -webkit-user-drag: none; user-select: none; filter: drop-shadow(0 2px 5px rgba(0,0,0,0.22)); }
/* Safety cap so a game icon can never render at full natural size if a size rule is missing */
.hero-glyph img { width: 84px; height: 84px; }
.hero-glyph { max-width: 84px; max-height: 84px; overflow: hidden; }
.wo-emoji .glyph-wo { width: 30px; height: 30px; }
.hero-glyph .glyph-hero { width: 84px; height: 84px; border-radius: 16px; }
.gcard-thumb .glyph-card { width: 58px; height: 58px; }
.cat-grid.solo .gcard-thumb .glyph-card { width: 56px; height: 56px; }
.best-row .be .glyph-best { width: 30px; height: 30px; }
.intro-glyph .glyph-intro { width: 92px; height: 92px; margin: 0 auto; }
.xp-skill .glyph-xp { width: 22px; height: 22px; display: inline-block; vertical-align: middle; }
.gcard-lvl {
  position: absolute; top: 6px; left: 6px;
  display: inline-flex; align-items: center; width: auto; max-width: none;
  white-space: nowrap; line-height: 1; box-sizing: border-box;
  font-size: 7px; font-weight: 800; letter-spacing: 0.03em; text-transform: uppercase;
  background: rgba(43,32,24,0.62); color: #fff;
  padding: 2px 5px; border-radius: var(--radius-full);
}
.gcard-new {
  position: absolute; top: 6px; right: 6px;
  display: inline-flex; align-items: center; width: auto; max-width: none;
  white-space: nowrap; line-height: 1; box-sizing: border-box;
  font-size: 7px; font-weight: 800; letter-spacing: 0.03em; text-transform: uppercase;
  background: var(--success); color: #fff;
  padding: 2px 5px; border-radius: var(--radius-full);
}
.gcard-name { padding: var(--space-3) var(--space-4) var(--space-4); font-weight: 700; font-size: var(--text-sm); letter-spacing: -0.01em; color: var(--text); }

/* Solo category: single game spans full width as a horizontal card */
/* A section with a single game keeps the SAME vertical card layout as multi-game
   sections (large centered icon on top, name below) — just half width so it
   lines up with the left column of the 2-up grid. */
.cat-grid.solo { grid-template-columns: 1fr 1fr; }

/* --- INTRO screen --- */
#screen-intro { padding-top: 0; padding-left: 0; padding-right: 0; }
.intro-hero {
  position: relative; overflow: hidden;
  padding: calc(var(--space-6) + max(env(safe-area-inset-top), 26px)) var(--space-5) var(--space-8);
  background: linear-gradient(160deg, var(--intro-accent), var(--intro-accent-2));
  color: #fffaf4;
  border-radius: 0 0 var(--radius-xl) var(--radius-xl);
}
.intro-hero::after {
  content: ""; position: absolute; right: -40px; top: -30px;
  width: 220px; height: 220px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,0.16), transparent 70%);
}
.intro-topbar { display: flex; align-items: center; justify-content: space-between; position: relative; z-index: 2; margin-bottom: var(--space-6); }
.intro-iconbtn {
  width: 42px; height: 42px; border-radius: 50%;
  background: rgba(0,0,0,0.18); color: #fff;
  display: grid; place-items: center;
  transition: transform var(--t-fast) var(--ease-snap), background var(--t-fast);
}
.intro-iconbtn:active { transform: scale(0.9); background: rgba(0,0,0,0.3); }
.intro-glyph { text-align: center; font-size: 5rem; line-height: 1; position: relative; z-index: 2; filter: drop-shadow(0 6px 14px rgba(0,0,0,0.28)); margin-bottom: var(--space-5); }
/* .intro-eyebrow removed 2026-08-18 - the "FREE GAMES" kicker sat above every game
   title on the intro screen and said nothing a player needed. Rule deleted with it so
   it does not linger as dead CSS. */
.intro-name { font-size: var(--text-2xl); font-weight: 800; letter-spacing: -0.02em; line-height: 1.05; margin-top: 4px; position: relative; z-index: 2; text-align: center; }

/* ---- Intro level ladder ----
   Renders the FULL ladder (1..maxLevel for the game), not a 5-rung preview. With 15
   rungs this always overflows a phone width, so the strip scrolls horizontally and JS
   centres the current rung on open. Fading edges signal there is more in both
   directions; the scrollbar itself is hidden because a WebView draws it as a chunky
   grey bar over the hero art. */
.intro-ladder-wrap { position: relative; z-index: 2; margin-top: var(--space-6); }
.intro-levels {
  display: flex; align-items: center; gap: var(--space-2);
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* The inline padding must be at least as wide as the mask fade below, otherwise
     scrolling to either end leaves the first/last rung sitting under the fade and it
     renders as a half-faded pill rather than a crisp one. */
  padding: 2px 20px 6px;
  /* Fade the strip out at both ends so a clipped rung reads as "scrollable"
     rather than as a rendering glitch. */
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 18px, #000 calc(100% - 18px), transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 18px, #000 calc(100% - 18px), transparent 100%);
}
.intro-levels::-webkit-scrollbar { display: none; }
.intro-ladder-caption {
  margin-top: var(--space-2); padding: 0 20px;
  font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: #fff; opacity: 0.72;
}
.intro-lv-main {
  flex-shrink: 0; display: inline-flex; align-items: center; gap: var(--space-2);
  background: rgba(255,255,255,0.92); color: var(--intro-accent-2);
  padding: var(--space-2) var(--space-3) var(--space-2) var(--space-2); border-radius: var(--radius-full);
  font-weight: 800; white-space: nowrap;
  /* Lifts the current rung out of a long row of otherwise identical pips. */
  box-shadow: 0 4px 14px rgba(0,0,0,0.22);
}
.intro-lv-main .play { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; background: var(--intro-accent); color: #fff; flex-shrink: 0; }
.intro-lv-pip {
  flex-shrink: 0; min-width: 34px; height: 34px; padding: 0 var(--space-2);
  display: grid; place-items: center; border-radius: var(--radius-full);
  background: rgba(255,255,255,0.16); color: rgba(255,255,255,0.85);
  font-size: var(--text-xs); font-weight: 700; font-variant-numeric: tabular-nums;
}
/* Cleared rungs read as solid and "filled in"; rungs ahead stay ghosted. */
.intro-lv-pip.is-done {
  background: rgba(255,255,255,0.58); color: var(--intro-accent-2);
}
.intro-lv-pip.is-ahead {
  background: rgba(255,255,255,0.13); color: rgba(255,255,255,0.6);
  border: 1px dashed rgba(255,255,255,0.28);
}

.intro-body { padding: var(--space-6) var(--space-5) var(--space-4); }
.intro-skills-label { font-size: var(--text-xs); font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted); margin-bottom: var(--space-4); }
.skill-trained { display: flex; align-items: flex-start; gap: var(--space-3); margin-bottom: var(--space-5); }
.skill-trained-icon {
  width: 40px; height: 40px; border-radius: var(--radius-md); flex-shrink: 0;
  display: grid; place-items: center; font-size: 1.3rem;
  background: var(--intro-soft); color: var(--intro-accent);
}
.skill-trained-text { flex: 1; min-width: 0; }
.skill-trained-name { display: block; font-weight: 800; font-size: var(--text-base); color: var(--text); }
.skill-trained-desc { display: block; }
.skill-trained-desc { font-size: var(--text-sm); color: var(--text-muted); line-height: 1.4; margin-top: 2px; }

.intro-start-wrap { padding: 0 var(--space-5); }
.intro-start { background: var(--primary); color: #fff; box-shadow: 0 8px 22px rgba(255,138,76,0.38); }
.intro-start:active { background: var(--primary-hover); }

/* --- In-game chrome refinements (CSS only) --- */
.game-head .gh-title { color: var(--text); font-weight: 800; letter-spacing: -0.01em; flex: 1; text-align: center; }
.game-head .gh-score { color: var(--primary); }
.game-head .back { background: var(--surface); color: var(--text-muted); border: 1px solid var(--border); }
.timer-fill { background: var(--primary); }

/* games on the warm default surface get a clean panel feel */
.math-opt, .dpad-btn, .mem-cell { border: 1px solid var(--border); }
.math-opt.correct, .math-opt.wrong { border-color: transparent; }
.mem-cell.selected, .mem-cell.correct, .mem-cell.missed, .mem-cell.wrong { border-width: 2.5px; }

/* puzzle-pick (flows) cards warm */
.puzzle-item { border: 1px solid var(--border); }

/* dark game shells: keep their own dark theming, ensure rounded margin works */
.sig2-shell, .odd2-shell { margin-top: var(--space-2); }

/* --- level chip on skill rows (Home + Profile) --- */
.lvl-chip {
  flex-shrink: 0; min-width: 44px; text-align: center;
  font-size: var(--text-xs); font-weight: 800;
  color: var(--text-muted); background: var(--surface-offset);
  padding: 3px 9px; border-radius: var(--radius-full);
}
/* on the dark workout-card the skill rows aren't used; chip lives on light cards */

/* --- workout-card completion states --- */
.wo-game .wo-check { display: none; color: #fff; opacity: 0.9; }
.wo-game.done { background: rgba(255,255,255,0.28); }
.wo-game.done .wo-chev { display: none; }
.wo-game.done .wo-check { display: inline-flex; }

/* --- Profile section spacing polish --- */
.profile-screen .page-title { font-weight: 800; }
.stat-box .sv { color: var(--text); }
.prof-skills { padding: var(--space-6) var(--space-5); }

/* --- results buttons warm --- */
.results-score { color: var(--primary); }
.xp-amount { color: var(--accent); }

/* --- workout-card Start pill (keep on one line) --- */
.wo-start {
  display: inline-flex; align-items: center; gap: 6px;
  flex-shrink: 0; white-space: nowrap;
  background: rgba(255,255,255,0.95); color: var(--primary-hover);
  font-weight: 800; font-size: var(--text-sm);
  padding: var(--space-2) var(--space-4); border-radius: var(--radius-full);
  box-shadow: 0 4px 12px rgba(0,0,0,0.12);
  transition: transform var(--t-fast) var(--ease-snap);
}
.wo-start:active { transform: scale(0.94); }
.wo-start svg { fill: var(--primary-hover); }

/* ============ Per-game difficulty level chips ============ */
/* In-game level chip (light game headers using gameHeader) */

/* Per-game difficulty level banner on the results screen */
.results-gamelvl { margin-top: var(--space-3); font-weight: 800; font-size: var(--text-base); display: inline-flex; align-items: center; gap: 6px; padding: var(--space-2) var(--space-4); border-radius: var(--radius-full); }
.results-gamelvl.up { color: var(--success, #16a34a); background: color-mix(in srgb, var(--success, #16a34a) 14%, transparent); }
.results-gamelvl.down { color: var(--text-muted); background: var(--surface-offset); font-weight: 700; }
.results-gamelvl.same { color: var(--text-muted); background: var(--surface-offset); font-weight: 700; font-size: var(--text-sm); }

/* ================= Silent Space (affirmations) ================= */
.silent-wrap {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-5);
  padding: var(--space-4);
  background: radial-gradient(120% 90% at 50% 20%, var(--affirm-soft), var(--surface));
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-md);
  position: relative;
  overflow: hidden;
}
.silent-stage {
  position: relative;
  width: 100%;
  min-height: 240px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  border-radius: var(--radius-lg);
  transition: background 0.4s ease;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.silent-ring {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 168px;
  height: 168px;
  margin: -84px 0 0 -84px;
  border-radius: 50%;
  border: 3px solid color-mix(in srgb, var(--affirm) 55%, transparent);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--affirm) 25%, transparent);
  transform: scale(1);
  opacity: 0.9;
  pointer-events: none;
}
/* Resting: gentle idle pulse */
.silent-ring-rest { animation: silentRest 4s ease-in-out infinite; }
@keyframes silentRest {
  0%, 100% { transform: scale(0.92); opacity: 0.6; }
  50% { transform: scale(1.0); opacity: 0.9; }
}
/* Breathe: the silent gap — ring contracts inward over the gap duration */
.silent-ring-breathe {
  animation: silentBreathe var(--gap-ms, 1400ms) ease-in-out forwards;
}
@keyframes silentBreathe {
  0% { transform: scale(1.12); opacity: 0.85; border-color: color-mix(in srgb, var(--affirm) 55%, transparent); }
  100% { transform: scale(0.72); opacity: 0.45; border-color: color-mix(in srgb, var(--affirm) 30%, transparent); }
}
/* Open: word just appeared — a soft expansion */
.silent-ring-open { animation: silentOpen 0.6s ease-out forwards; }
@keyframes silentOpen {
  0% { transform: scale(0.72); opacity: 0.5; box-shadow: 0 0 0 0 color-mix(in srgb, var(--affirm) 30%, transparent); }
  40% { transform: scale(1.14); opacity: 1; box-shadow: 0 0 0 14px color-mix(in srgb, var(--affirm) 12%, transparent); }
  100% { transform: scale(1.0); opacity: 0.9; box-shadow: 0 0 0 0 transparent; }
}
.silent-word {
  position: relative;
  z-index: 2;
  font-size: clamp(1.9rem, 8vw, 2.6rem);
  font-weight: 800;
  color: var(--text);
  letter-spacing: -0.01em;
  text-align: center;
  min-height: 1.2em;
}
.silent-word-in { animation: silentWordIn 0.42s cubic-bezier(0.2, 0.9, 0.2, 1); }
@keyframes silentWordIn {
  0% { opacity: 0; transform: translateY(8px) scale(0.96); filter: blur(3px); }
  100% { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
}
.silent-hint {
  position: relative;
  z-index: 2;
  font-size: var(--text-base);
  color: var(--text-muted);
  text-align: center;
  max-width: 22rem;
  padding: 0 var(--space-3);
  min-height: 1.4em;
  transition: color 0.3s ease;
}
.silent-hint-affirm {
  font-size: var(--text-lg);
  font-weight: 700;
  font-style: italic;
  color: var(--affirm);
}
.silent-line {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.3em 0.45em;
  max-width: 26rem;
  min-height: 1.6em;
  font-size: var(--text-lg);
  line-height: 1.3;
}
.sline-word {
  opacity: 0.9;
  transition: color 0.25s ease, opacity 0.25s ease;
}
.sline-word.hit { color: var(--affirm); font-weight: 700; }
.sline-word.miss { color: var(--text-faint); text-decoration: line-through; opacity: 0.6; }
.silent-progress { display: flex; gap: 8px; }
.silent-progress .sdot {
  width: 9px; height: 9px; border-radius: 50%;
  background: color-mix(in srgb, var(--affirm) 25%, transparent);
  transition: all 0.3s ease;
}
.silent-progress .sdot.cur { background: var(--affirm); transform: scale(1.25); }
.silent-progress .sdot.done { background: var(--affirm); }
.silent-begin { min-width: 160px; }

/* Feedback flashes on the stage */
.silent-stage.st-present { animation: stPresent 0.5s ease; }
@keyframes stPresent { 0% { background: color-mix(in srgb, var(--affirm) 22%, transparent); } 100% { background: transparent; } }
.silent-stage.st-restless { animation: stRestless 0.45s ease; }
@keyframes stRestless { 0% { background: color-mix(in srgb, var(--danger) 18%, transparent); } 100% { background: transparent; } }
.silent-stage.st-drift { animation: stDrift 0.5s ease; }
@keyframes stDrift { 0% { background: color-mix(in srgb, var(--text-faint) 16%, transparent); } 100% { background: transparent; } }

/* Header icon buttons reused by Silent Space */
.gh-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%;
  border: none; background: var(--surface-2); color: var(--text-muted);
  cursor: pointer; margin-left: 6px;
}
.gh-icon:hover { background: var(--border); color: var(--text); }

/* Overlays (pause / how-to) for Silent Space */
.pause-overlay, .howto-overlay {
  position: absolute; inset: 0; z-index: 20;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(4px);
  padding: var(--space-5);
}
.pause-overlay[hidden], .howto-overlay[hidden] { display: none; }
.pause-card, .howto-card {
  background: var(--surface); border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg); padding: var(--space-6);
  max-width: 22rem; width: 100%; text-align: center;
  display: flex; flex-direction: column; gap: var(--space-3);
}
.pause-title, .howto-title { font-size: var(--text-xl); font-weight: 800; }
.howto-card p { font-size: var(--text-base); color: var(--text-muted); line-height: 1.5; }

/* Pause menu (Continue / Restart / How to play / Leave game) */
/* Ensure any paused overlay (whatever its game-specific class) centres the menu. */
[id$="-paused"][data-menu="1"] {
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-5);
}
/* Critical: when hidden, stay hidden — otherwise the overlay keeps intercepting
   taps and the game appears frozen after Continue. Must beat the rule above. */
[id$="-paused"][data-menu="1"][hidden] { display: none !important; }
.pause-card[data-menu="1"] {
  gap: var(--space-3); padding: var(--space-4);
  background: transparent; box-shadow: none;
  max-width: 22rem; width: 100%;
  display: flex; flex-direction: column;
}
.pausemenu-btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  position: relative;
  width: 100%; padding: 16px 20px;
  border: none; border-radius: 999px; cursor: pointer;
  font-size: var(--text-lg); font-weight: 800; letter-spacing: 0.01em;
  transition: transform 0.1s ease, filter 0.2s ease;
}
.pausemenu-btn .pm-ic { position: absolute; left: 22px; display: inline-flex; align-items: center; }
.pausemenu-btn:active { transform: scale(0.97); }
.pausemenu-btn.pm-continue { background: #7ac943; color: #fff; box-shadow: 0 4px 14px rgba(122,201,67,0.4); }
.pausemenu-btn.pm-continue:hover { filter: brightness(1.05); }
.pausemenu-btn.pm-dark { background: #3a2e2b; color: #f3ece8; }
[data-theme="light"] .pausemenu-btn.pm-dark { background: #4a3b37; color: #fff; }
.pausemenu-btn.pm-dark:hover { filter: brightness(1.12); }

/* Silent Space closing message */
.silent-done-title {
  display: inline-block;
  font-size: var(--text-xl);
  font-weight: 800;
  color: var(--affirm);
  margin-bottom: 0.2em;
}

/* ================= Crime Scene ================= */
.crime-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3);
  border-radius: var(--radius-xl);
  background:
    linear-gradient(180deg, rgba(46,36,54,0.86), rgba(32,24,40,0.94)),
    url("crime_scene_bg.png") center/cover no-repeat;
  box-shadow: var(--shadow-md);
  overflow: hidden;
}
/* HUD in the header. Defaults are readable on the light peach background used by
   most games; the Crime scene / Math audit games have their own dark HUD block
   that overrides these to white below. */
.crime-hud { display: inline-flex; align-items: center; gap: 10px; }
.crime-timer {
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  font-size: var(--text-base);
  color: var(--text);
  background: var(--surface-offset);
  padding: 3px 10px; border-radius: 999px;
  min-width: 52px; text-align: center;
}
.crime-timer.low { color: #fff; background: var(--danger); }
.crime-round {
  font-weight: 700; font-size: var(--text-sm); color: var(--text-muted);
}
.crime-hud .gh-score { color: var(--primary); }

/* Banner */
.crime-banner {
  margin-top: var(--space-2);
  padding: 10px 22px;
  border-radius: 999px;
  background: rgba(20,14,26,0.72);
  color: #fff;
  font-weight: 800;
  font-size: var(--text-lg);
  box-shadow: var(--shadow-sm);
  text-align: center;
  transition: transform 0.2s ease;
}
.crime-banner.demote { color: #ffd3d3; animation: crimeShake 0.5s ease; }
.crime-banner.cleared { color: #d1ffe0; background: rgba(22,101,52,0.7); }
@keyframes crimeShake {
  0%,100% { transform: translateX(0); }
  20% { transform: translateX(-8px); }
  40% { transform: translateX(8px); }
  60% { transform: translateX(-5px); }
  80% { transform: translateX(5px); }
}

/* Honeycomb grid: explicit rows of pointy-top hexes.
   Rows interlock via a controlled negative margin (NOT a transform), and
   offset rows shift half a hex sideways, so cells never overlap. */
.crime-grid {
  /* pointy-top hex: height = width / (sqrt(3)/2) = width * 1.1547.
     For a seamless honeycomb, rows overlap vertically by exactly 1/4 of the
     hex height, and hexes in a row sit edge-to-edge (tiny gap), with offset
     rows shifted half a hex. */
  --hex-w: 74px;
  --hex-h: calc(var(--hex-w) * 1.1547);
  --hex-gap: 12px;
  flex: 1;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--space-2) 0 var(--space-4);
  max-width: 460px;
}
/* Fixed hex sizes per row count so the half-shifted offset rows still fit
   the phone width without clipping. Smaller hexes when more per row. */
.crime-grid[data-per-row="3"] { --hex-w: 80px; --hex-gap: 14px; }
.crime-grid[data-per-row="4"] { --hex-w: 70px; --hex-gap: 12px; }
.crime-grid[data-per-row="5"] { --hex-w: 58px; --hex-gap: 10px; }
.hexrow {
  display: flex;
  justify-content: center;
  gap: var(--hex-gap);
}
/* Row spacing: a small negative margin keeps the offset rows nesting into the
   notches, but looser than a tight honeycomb so there's clear space between rows. */
.hexrow + .hexrow { margin-top: calc(var(--hex-h) * -0.14); }
/* shift offset rows sideways by half a hex + half a gap so they nest in the notch */
.hexrow.offset { margin-left: calc(var(--hex-w) * 0.5 + var(--hex-gap) * 0.5); }
.hexrow.offset { margin-right: calc(var(--hex-w) * 0.5 + var(--hex-gap) * 0.5); }
.hexcell {
  width: var(--hex-w);
  height: var(--hex-h);
  border: none;
  background: transparent;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  animation: hexPop 0.32s cubic-bezier(0.2,0.9,0.2,1) both;
}
@keyframes hexPop { 0% { opacity: 0; transform: scale(0.6); } 100% { opacity: 1; transform: scale(1); } }
.hexface {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%;
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
  background: linear-gradient(180deg, #fbf3ec, #efe2d6);
  box-shadow: inset 0 -3px 6px rgba(0,0,0,0.08);
  transition: transform 0.12s ease, filter 0.2s ease;
}
.hexemoji { width: 82%; height: 78%; object-fit: contain; filter: drop-shadow(0 2px 2px rgba(0,0,0,0.22)); pointer-events: none; user-select: none; }
/* invisible spacer hex to keep the last row nesting cleanly */
.hexcell.placeholder { visibility: hidden; pointer-events: none; animation: none; }
.hexcell:active .hexface { transform: scale(0.92); }
.hexcell.found .hexface {
  background: linear-gradient(180deg, #7fd8a6, #34a56f);
  animation: hexFound 0.4s ease;
}
.hexcell.found .hexemoji { filter: none; opacity: 0.35; }
@keyframes hexFound { 0% { transform: scale(1); } 45% { transform: scale(1.18); } 100% { transform: scale(1); } }
.hexcell.wrong .hexface {
  background: linear-gradient(180deg, #f0879a, #c0344f);
  animation: hexWrong 0.4s ease;
}
@keyframes hexWrong { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-5px);} 75% { transform: translateX(5px);} }

@media (max-width: 380px) { .crime-grid { --hex-w: 66px; --hex-gap: 6px; } }

/* Compact header when the Crime Scene HUD is present */
.game-head:has(.crime-hud) { gap: 6px; margin-bottom: var(--space-3); }
.game-head:has(.crime-hud) .gh-title {
  flex: 0 0 auto;
  font-size: var(--text-lg);
  white-space: nowrap;
}
.game-head:has(.crime-hud) .back { width: 36px; height: 36px; }
.game-head:has(.crime-hud) .gh-icon { width: 32px; height: 32px; margin-left: 0; }
.game-head:has(.crime-hud) .crime-hud { margin-left: auto; gap: 8px; }
.game-head:has(.crime-hud) .crime-timer { font-size: var(--text-sm); padding: 3px 8px; min-width: 46px; }

/* ================= Math audit ================= */
.audit-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3);
  border-radius: var(--radius-xl);
  background: radial-gradient(120% 80% at 50% 0%, var(--audit-soft), var(--surface));
  box-shadow: var(--shadow-md);
}
.audit-clip {
  position: relative;
  width: 100%;
  max-width: 340px;
  flex: 1;
  margin-top: var(--space-4);
  background: linear-gradient(180deg, #f6a94a, #ef8f2e);
  border-radius: 22px;
  padding: 16px;
  box-shadow: var(--shadow-lg);
  display: flex;
}
.audit-clip-top {
  position: absolute;
  top: -18px; left: 50%; transform: translateX(-50%);
  width: 92px; height: 30px;
  background: #f5b74f;
  border-radius: 10px 10px 8px 8px;
  box-shadow: inset 0 -3px 4px rgba(0,0,0,0.12);
}
.audit-clip-top::after {
  content: ""; position: absolute; top: 9px; left: 20px;
  width: 34px; height: 6px; border-radius: 3px; background: rgba(255,255,255,0.6);
}
.audit-paper {
  position: relative;
  flex: 1;
  background: repeating-linear-gradient(#fdf0e6, #fdf0e6 30px, #f3e2d4 31px, #fdf0e6 32px);
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.25s ease, box-shadow 0.25s ease;
  border: 3px solid transparent;
}
.audit-paper.aud-flash-ok { background: #dff5e2; border-color: #2fa34e; }
.audit-paper.aud-flash-bad { background: #fadfe0; border-color: #d9433f; }
/* big pass/fail banner over the clipboard */
.aud-verdict-banner {
  position: absolute;
  top: 16px; left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: 8px;
  padding: 8px 18px; border-radius: 999px;
  font-size: var(--text-sm); font-weight: 800; color: #fff;
  white-space: nowrap; text-align: center; justify-content: center;
  animation: audVerdictPop 0.32s cubic-bezier(0.2,0.9,0.2,1) both;
  box-shadow: var(--shadow-md);
}
.aud-verdict-banner.ok { background: #2fa34e; }
.aud-verdict-banner.bad { background: #d9433f; }
.aud-verdict-icon { font-size: 1.3em; line-height: 1; }
@keyframes audVerdictPop { 0% { opacity: 0; transform: translate(-50%, -8px) scale(0.8); } 100% { opacity: 1; transform: translate(-50%, 0) scale(1); } }
.audit-eq {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  color: #4a3327; font-weight: 800;
}
.audit-line { font-size: clamp(1.8rem, 8vw, 2.4rem); line-height: 1.1; }
.audit-eqsign { opacity: 0.7; }
.audit-answer { font-size: clamp(2.1rem, 9vw, 2.8rem); color: #b1345a; }
.audit-verdict { margin-top: 8px; font-size: var(--text-sm); font-weight: 700; color: #a04; }
.audit-actions {
  display: flex; gap: var(--space-4); width: 100%; max-width: 340px; padding-bottom: var(--space-2);
}
.audit-btn {
  flex: 1; height: 68px; border: none; border-radius: var(--radius-lg);
  display: grid; place-items: center; cursor: pointer;
  transition: transform 0.1s ease, filter 0.15s ease;
  box-shadow: var(--shadow-md);
}
.audit-btn:active { transform: scale(0.94); }
.audit-no { background: #fbe0e2; color: #d9433f; }
.audit-yes { background: #dcf5e0; color: #2fa34e; }

/* ================= Missing operator ================= */
.operator-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3);
  border-radius: var(--radius-xl);
  background: radial-gradient(120% 80% at 50% 0%, var(--operator-soft), var(--surface));
  box-shadow: var(--shadow-md);
}
.op-paper {
  position: relative;
  flex: 1;
  width: 100%;
  max-width: 360px;
  margin-top: var(--space-3);
  background: #fdf0e6;
  border-radius: 18px;
  box-shadow: var(--shadow-md);
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-4) var(--space-2);
  border: 3px solid transparent;
  transition: background 0.25s ease, border-color 0.25s ease;
  overflow: hidden;
}
.op-paper.op-paper-ok { background: #dff5e2; border-color: #2fa34e; }
.op-paper.op-paper-bad { background: #fadfe0; border-color: #d9433f; }
/* filled-slot result colors */
.op-slot.slot-ok { border-color: #2fa34e !important; background: #d4f3da !important; color: #1e7a3a !important; }
.op-slot.slot-bad { border-color: #d9433f !important; background: #fbd9da !important; color: #b32f2c !important; }
/* big pass/fail banner */
.op-verdict {
  position: absolute;
  top: 14px; left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: 8px;
  padding: 8px 18px; border-radius: 999px;
  font-size: var(--text-lg); font-weight: 800; color: #fff;
  white-space: nowrap;
  animation: opVerdictPop 0.32s cubic-bezier(0.2,0.9,0.2,1) both;
  box-shadow: var(--shadow-md);
}
.op-verdict.ok { background: #2fa34e; }
.op-verdict.bad { background: #d9433f; }
.op-verdict-icon { font-size: 1.25em; line-height: 1; }
@keyframes opVerdictPop { 0% { opacity: 0; transform: translate(-50%, -8px) scale(0.8); } 100% { opacity: 1; transform: translate(-50%, 0) scale(1); } }
.op-eq {
  position: relative;
  display: flex; flex-wrap: nowrap; align-items: center; justify-content: center;
  gap: 8px; max-width: 100%;
  color: #4a3327; font-weight: 800;
  transition: transform 0.15s ease;
}
.op-num { font-size: clamp(1.4rem, 6.4vw, 2.3rem); flex: 0 0 auto; }
.op-eqsign { opacity: 0.7; }
.op-result { color: #b1345a; }
.op-slot {
  flex: 0 0 auto;
  width: 44px; height: 44px; border-radius: 50%;
  border: 3px dashed #c9a98f; background: transparent;
  font-size: 1.4rem; font-weight: 800; color: #4a3327;
  cursor: pointer; display: grid; place-items: center;
  transition: all 0.15s ease;
}
/* tighter sizing when there are more terms (3 slots) so it never clips */
.op-eq:has(.op-slot:nth-of-type(3)) { gap: 5px; }
.op-eq:has(.op-slot:nth-of-type(3)) .op-num { font-size: clamp(1.2rem, 5.6vw, 2rem); }
.op-eq:has(.op-slot:nth-of-type(3)) .op-slot { width: 40px; height: 40px; font-size: 1.2rem; }
.op-slot.filled { border-style: solid; border-color: var(--operator); background: #fff; }
.op-slot.active { border-color: #e6a53a; box-shadow: 0 0 0 4px rgba(230,165,58,0.25); }
.op-eq.op-ok { animation: opOk 0.5s ease; }
.op-eq.op-bad { animation: opBad 0.5s ease; }
@keyframes opOk { 0%,100%{transform:scale(1);} 45%{transform:scale(1.06);} }
@keyframes opBad { 0%,100%{transform:translateX(0);} 25%{transform:translateX(-8px);} 75%{transform:translateX(8px);} }
.op-demote { position: absolute; bottom: -30px; left: 0; right: 0; text-align: center; font-size: var(--text-sm); font-weight: 700; color: #b1345a; }
.op-pad {
  display: flex; gap: 10px; width: 100%; max-width: 360px; justify-content: center;
}
.op-key {
  flex: 1; height: 60px; border: none; border-radius: var(--radius-md);
  background: var(--surface-2); color: var(--text);
  font-size: 1.6rem; font-weight: 800; cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform 0.1s ease, background 0.15s ease;
}
.op-key:active { transform: scale(0.92); }
.op-key:hover { background: var(--border); }
.op-ac { background: #f2607e; color: #fff; font-size: 1.2rem; }
.op-check { width: 100%; max-width: 360px; }
.op-check.op-shake { animation: opBad 0.4s ease; }

/* ================= Phone number ================= */
.phone-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3);
  border-radius: var(--radius-xl);
  background: radial-gradient(120% 80% at 50% 0%, var(--phone-soft), var(--surface));
  box-shadow: var(--shadow-md);
}
.ph-prompt {
  margin-top: var(--space-3);
  padding: 8px 20px; border-radius: 999px;
  background: rgba(20,20,26,0.28); color: var(--text);
  font-weight: 700; font-size: var(--text-base);
}
.ph-card {
  position: relative;
  width: 100%; max-width: 340px;
  background: linear-gradient(160deg, #35c4cf, #17a2b8);
  border-radius: 20px;
  padding: var(--space-5) var(--space-4);
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  box-shadow: var(--shadow-lg);
  color: #fff;
  transition: box-shadow 0.25s ease, transform 0.15s ease;
}
.ph-card.ph-ok { box-shadow: 0 0 0 4px rgba(47,163,78,0.6), var(--shadow-lg); }
.ph-card.ph-bad { box-shadow: 0 0 0 4px rgba(217,67,63,0.6), var(--shadow-lg); animation: phShake 0.4s ease; }
@keyframes phShake { 0%,100%{transform:translateX(0);} 25%{transform:translateX(-7px);} 75%{transform:translateX(7px);} }
.ph-avatar {
  width: 60px; height: 60px; border-radius: 50%;
  background: rgba(255,255,255,0.25); color: rgba(255,255,255,0.85);
  display: grid; place-items: center; overflow: hidden;
}
.ph-name { font-weight: 800; font-size: var(--text-lg); opacity: 0.92; }
.ph-job { font-size: var(--text-sm); opacity: 0.7; margin-bottom: 6px; }
.ph-number {
  font-size: clamp(1.8rem, 8vw, 2.6rem); font-weight: 800;
  letter-spacing: 0.08em; min-height: 1.2em;
}
/* while memorizing, name/job are faint; number is bold. When hidden, blur it out */
.ph-card.ph-hidden .ph-number { visibility: hidden; }
.ph-card.ph-hidden .ph-name, .ph-card.ph-hidden .ph-job { opacity: 0.35; }

.ph-entry { width: 100%; max-width: 360px; display: flex; flex-direction: column; align-items: center; gap: var(--space-4); }
.ph-typed { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; min-height: 44px; }
.ph-slot {
  width: 30px; height: 42px; border-radius: 8px;
  background: var(--surface-2); display: grid; place-items: center;
  font-size: 1.4rem; font-weight: 800; color: var(--text);
  border-bottom: 3px solid var(--border);
}
.ph-slot.filled { border-bottom-color: var(--phone); }
.ph-slot.cur { box-shadow: 0 0 0 2px rgba(245,158,11,0.4); }
.ph-typed.ph-shake { animation: phShake 0.4s ease; }
.ph-pad {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; width: 100%;
}
.ph-key {
  height: 58px; border: none; border-radius: var(--radius-md);
  background: var(--surface-2); color: var(--text);
  font-size: 1.5rem; font-weight: 800; cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform 0.1s ease, background 0.15s ease;
}
.ph-key:active { transform: scale(0.93); }
.ph-key:hover { background: var(--border); }
.ph-back { font-size: 1.3rem; }
.ph-submit { font-size: 1rem; font-weight: 700; background: var(--phone); color: #fff; }

/* ================= Tower of Hanoi ================= */
.hanoi-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3);
  border-radius: var(--radius-xl);
  background: radial-gradient(120% 80% at 50% 0%, var(--hanoi-soft), var(--surface));
  box-shadow: var(--shadow-md);
}
.hn-goal {
  margin-top: var(--space-2);
  padding: 8px 18px; border-radius: 999px;
  background: rgba(20,14,26,0.22); color: var(--text);
  font-weight: 700; font-size: var(--text-sm); text-align: center;
}
.hn-goal.hn-win { background: rgba(22,101,52,0.75); color: #fff; }
.hn-board {
  flex: 1; width: 100%; max-width: 440px;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
  align-items: stretch;
}
.hn-peg {
  position: relative;
  display: flex; flex-direction: column; justify-content: flex-end; align-items: center;
  border-radius: 16px;
  background: rgba(120,90,160,0.10);
  padding: 10px 4px 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.15s ease;
}
.hn-peg.sel { background: rgba(139,92,246,0.20); }
.hn-peg.bad { animation: hnBad 0.4s ease; }
@keyframes hnBad { 0%,100%{transform:translateX(0);} 25%{transform:translateX(-6px);} 75%{transform:translateX(6px);} }
.hn-rod {
  position: absolute; bottom: 26px; left: 50%; transform: translateX(-50%);
  width: 8px; height: calc(100% - 40px); border-radius: 4px;
  background: linear-gradient(180deg, #f3e0d0, #e2cbb6);
}
.hn-peg.target .hn-rod { background: linear-gradient(180deg, #4ade80, #22c55e); }
.hn-disks {
  position: relative; z-index: 2;
  display: flex; flex-direction: column-reverse; align-items: center; gap: 4px;
  width: 100%; padding-bottom: 4px;
}
.hn-base {
  width: 100%; height: 10px; border-radius: 6px;
  background: linear-gradient(180deg, #f3e0d0, #dcc4ad);
  z-index: 2;
}
.hn-peg.target .hn-base { background: linear-gradient(180deg, #4ade80, #22c55e); }
.hn-label { padding: 6px 0 8px; font-weight: 800; color: var(--text-muted); }
.hn-peg.target .hn-label { color: #22a04e; }
.hn-disk {
  height: 26px; border-radius: 8px;
  display: grid; place-items: center;
  color: #fff; font-weight: 800; font-size: 0.85rem;
  box-shadow: inset 0 -3px 5px rgba(0,0,0,0.18), 0 1px 2px rgba(0,0,0,0.15);
  transition: transform 0.12s ease;
}
.hn-disk.lifted { transform: translateY(-6px) scale(1.04); box-shadow: inset 0 -3px 5px rgba(0,0,0,0.18), 0 4px 10px rgba(0,0,0,0.3); }

/* Tutorial */
.hn-howto-card { max-width: 24rem; }
.hn-tut { display: flex; flex-direction: column; align-items: center; gap: var(--space-4); }
.hn-tut-text { font-size: var(--text-base); color: var(--text-muted); text-align: center; line-height: 1.5; }
.hn-tboard { display: grid; grid-template-columns: repeat(3,1fr); gap: 10px; width: 100%; max-width: 260px; }
.hn-tpeg { position: relative; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 120px; }
.hn-trod { position: absolute; bottom: 8px; width: 6px; height: 100px; border-radius: 3px; background: #e2cbb6; }
.hn-tpeg.g .hn-trod { background: #22c55e; }
.hn-tstack { position: relative; z-index: 2; display: flex; flex-direction: column-reverse; align-items: center; gap: 3px; }
.hn-tbase { width: 100%; height: 6px; border-radius: 4px; background: #e2cbb6; z-index: 2; }
.hn-tpeg.g .hn-tbase { background: #22c55e; }
.hn-tdisk { height: 20px; border-radius: 6px; display: grid; place-items: center; color: #fff; font-weight: 800; font-size: 0.75rem; }
.hn-tarc { position: relative; }
.hn-tut-dots { display: flex; gap: 8px; justify-content: center; }
.hn-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border); }
.hn-dot.on { background: var(--hanoi); }

/* Intro "Level stats" panel (Tower of Hanoi) */
.intro-stats { margin-bottom: var(--space-4); padding-bottom: var(--space-3); border-bottom: 1px solid var(--border); }
.intro-stats-label { font-size: var(--text-sm); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-faint); margin-bottom: var(--space-3); }
.intro-stat { display: flex; gap: var(--space-3); align-items: flex-start; padding: var(--space-2) 0; }
.intro-stat-ic { font-size: 1.4rem; line-height: 1.4; }
.intro-stat-t { font-size: var(--text-sm); color: var(--text-muted); line-height: 1.5; }
.intro-stat-t b { color: var(--text); }

/* ================= Basic math ================= */
.basicmath-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--space-3);
  border-radius: var(--radius-xl);
  background: radial-gradient(120% 80% at 50% 0%, var(--basicmath-soft), var(--surface));
  box-shadow: var(--shadow-md);
}
.bm-board {
  width: 100%; max-width: 360px;
  aspect-ratio: 4 / 3;
  background: linear-gradient(160deg, #2f8f6f, #237a5c);
  border: 10px solid #d9a44e;
  border-radius: 14px;
  box-shadow: var(--shadow-lg), inset 0 0 40px rgba(0,0,0,0.15);
  display: flex; align-items: center; justify-content: center;
}
.bm-eq {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  color: #fdf3e6; font-weight: 800;
  text-shadow: 0 1px 2px rgba(0,0,0,0.2);
}
.bm-num { font-size: clamp(2.6rem, 13vw, 3.6rem); line-height: 1; }
.bm-op { font-size: clamp(1.8rem, 8vw, 2.4rem); opacity: 0.9; }
.bm-eqsign { font-size: 2rem; font-weight: 800; color: var(--text-muted); }
.bm-options {
  display: flex; flex-wrap: wrap; gap: 10px; justify-content: center;
  width: 100%; max-width: 400px;
}
.bm-opt {
  flex: 1 1 0; min-width: 70px;
  height: 64px; border: none; border-radius: var(--radius-md);
  background: var(--surface-2); color: var(--text);
  font-size: 1.6rem; font-weight: 800; cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform 0.1s ease, background 0.2s ease;
}
.bm-opt:active { transform: scale(0.94); }
.bm-opt:hover { background: var(--border); }
.bm-opt.ok { background: #2fa34e; color: #fff; animation: bmPop 0.4s ease; }
.bm-opt.bad { background: #d9433f; color: #fff; animation: bmBad 0.4s ease; }
.bm-opt.reveal { background: #2fa34e; color: #fff; }
@keyframes bmPop { 0%,100%{transform:scale(1);} 45%{transform:scale(1.1);} }
@keyframes bmBad { 0%,100%{transform:translateX(0);} 25%{transform:translateX(-6px);} 75%{transform:translateX(6px);} }

/* ========== Tasty Fractions ========== */
.fractions-body {
  display: flex; flex-direction: column; align-items: center;
  justify-content: flex-start;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-xl);
  background: radial-gradient(120% 80% at 50% 0%, var(--fractions-soft), var(--surface));
  box-shadow: var(--shadow-md);
}
.fr-note {
  position: relative;
  width: 100%; max-width: 360px;
  min-height: 128px;
  margin-top: var(--space-2);
  padding: 26px 30px;
  display: flex; align-items: center; justify-content: center;
  background: repeating-linear-gradient(#fbf1df 0 30px, #f4e6cf 30px 31px);
  border-radius: 12px;
  border: 1px solid #e6d3b3;
  border-left: 6px solid #d1495b;
  box-shadow: var(--shadow-md);
  transition: box-shadow 0.25s ease, transform 0.2s ease;
}
.fr-note::before {
  content: ""; position: absolute; left: 14px; top: 12px; bottom: 12px;
  width: 2px; background: rgba(209, 73, 91, 0.25);
}
.fr-note-ok { box-shadow: var(--shadow-md), 0 0 0 3px rgba(47, 165, 106, 0.6); }
.fr-note-bad { box-shadow: var(--shadow-md), 0 0 0 3px rgba(227, 93, 79, 0.6); animation: frShake 0.4s ease; }
@keyframes frShake { 0%,100%{transform:translateX(0);} 25%{transform:translateX(-6px);} 75%{transform:translateX(6px);} }
.fr-eq {
  display: flex; align-items: center; justify-content: center; gap: 16px;
  color: #3a2a1a; font-weight: 800;
}
.fr-frac { display: inline-flex; flex-direction: column; align-items: center; line-height: 1; }
.fr-num, .fr-den { font-size: clamp(1.9rem, 9vw, 2.6rem); }
.fr-bar { width: 100%; min-width: 34px; height: 4px; border-radius: 3px; background: currentColor; margin: 4px 0; }
.fr-of { font-size: clamp(1rem, 5vw, 1.4rem); font-weight: 700; color: #159a9c; }
.fr-N { font-size: clamp(2.4rem, 12vw, 3.4rem); }
.fr-eqsign { font-size: 1.8rem; font-weight: 800; color: var(--text-muted); }
.fr-answer {
  min-width: 120px; height: 66px;
  display: flex; align-items: center; justify-content: center; gap: 2px;
  padding: 0 18px;
  background: var(--surface-2);
  border: 2px solid var(--border);
  border-radius: var(--radius-md);
  font-size: 2.2rem; font-weight: 800; color: var(--text);
  box-shadow: var(--shadow-sm);
}
.fr-answer.fr-ok { border-color: #2fa56a; background: color-mix(in srgb, #2fa56a 14%, var(--surface-2)); }
.fr-answer.fr-bad { border-color: #e35d4f; background: color-mix(in srgb, #e35d4f 12%, var(--surface-2)); }
.fr-typed { color: var(--text); }
.fr-typed.fr-wrong { color: #e35d4f; text-decoration: line-through; opacity: 0.7; }
.fr-reveal { color: #2fa56a; margin-left: 10px; }
.fr-placeholder { color: var(--text-faint); font-weight: 800; }
.fr-answer.fr-empty { border-style: dashed; border-color: var(--fractions); }
.fr-pad {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
  width: 100%; max-width: 320px;
}
.fr-key {
  height: 58px; border: none; border-radius: var(--radius-md);
  background: var(--surface-2); color: var(--text);
  font-size: 1.7rem; font-weight: 800; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-sm);
  transition: transform 0.1s ease, background 0.2s ease;
}
.fr-key:active { transform: scale(0.94); }
.fr-key:hover { background: var(--border); }
.fr-del { color: var(--danger); }
.fr-enter { background: var(--fractions); color: #fff; }
.fr-enter:hover { background: color-mix(in srgb, var(--fractions) 88%, #000); }

/* ========== Spy Anagrams ========== */
.anagram-body {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--space-4);
  padding: var(--space-3);
  border-radius: var(--radius-xl);
  background: radial-gradient(120% 80% at 50% 0%, var(--anagram-soft), var(--surface));
  box-shadow: var(--shadow-md);
}
.ag-monitor {
  position: relative;
  width: 100%; max-width: 360px;
  aspect-ratio: 16 / 10;
  margin-top: var(--space-2);
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(160deg, #123a3b, #0c2829);
  border: 2px solid rgba(21, 154, 156, 0.55);
  border-radius: 14px;
  box-shadow: var(--shadow-lg), inset 0 0 40px rgba(0,0,0,0.35), 0 0 22px rgba(21,154,156,0.25);
  overflow: hidden;
}
.ag-corner { position: absolute; width: 26px; height: 26px; border: 3px solid var(--anagram); }
.ag-corner.tl { top: 8px; left: 8px; border-right: none; border-bottom: none; border-radius: 6px 0 0 0; }
.ag-corner.tr { top: 8px; right: 8px; border-left: none; border-bottom: none; border-radius: 0 6px 0 0; }
.ag-corner.bl { bottom: 8px; left: 8px; border-right: none; border-top: none; border-radius: 0 0 0 6px; }
.ag-corner.br { bottom: 8px; right: 8px; border-left: none; border-top: none; border-radius: 0 0 6px 0; }
.ag-word {
  font-size: clamp(2.2rem, 12vw, 3rem); font-weight: 800; letter-spacing: 0.02em;
  color: #6ee7ea; text-shadow: 0 0 16px rgba(110, 231, 234, 0.6);
  transition: opacity 0.4s ease, filter 0.4s ease;
}
.ag-options {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  width: 100%; max-width: 380px;
}
/* 5 options: last one spans both columns so there's no lonely gap. */
.ag-options.opt-5 .ag-opt:nth-child(5) { grid-column: 1 / -1; }
.ag-opt {
  min-height: 60px; padding: 6px 8px; border: none; border-radius: var(--radius-md);
  background: var(--surface-2); color: var(--text);
  font-size: clamp(1rem, 4.6vw, 1.4rem); font-weight: 800; letter-spacing: 0.03em;
  cursor: pointer; box-shadow: var(--shadow-sm);
  display: flex; align-items: center; justify-content: center;
  word-break: break-all; line-height: 1.1;
  transition: transform 0.1s ease, background 0.2s ease;
}
.ag-opt:active { transform: scale(0.95); }
.ag-opt:hover { background: var(--border); }
.ag-opt.ok { background: #2fa34e; color: #fff; animation: agPop 0.4s ease; }
.ag-opt.bad { background: #d9433f; color: #fff; animation: agBad 0.4s ease; }
.ag-opt.reveal { background: #2fa34e; color: #fff; }
@keyframes agPop { 0%,100%{transform:scale(1);} 45%{transform:scale(1.08);} }
@keyframes agBad { 0%,100%{transform:translateX(0);} 25%{transform:translateX(-5px);} 75%{transform:translateX(5px);} }

/* ========== Mastery badges ========== */
/* Results screen "Mastered" banner */
.results-gamelvl.mastered {
  color: #a9791f;
  background: linear-gradient(180deg, #fff4d6, #ffe6a8);
  border: 1px solid #f0cf7a;
  font-weight: 800;
}
[data-theme="dark"] .results-gamelvl.mastered { color: #ffd766; background: rgba(240, 200, 100, 0.14); border-color: rgba(240, 200, 100, 0.4); }

/* Full-screen mastery celebration overlay */
.mastery-overlay {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-5);
  background: rgba(20, 12, 8, 0.62);
  backdrop-filter: blur(6px);
  opacity: 0; transition: opacity 0.3s ease;
}
.mastery-overlay.show { opacity: 1; }
.mastery-card {
  position: relative;
  width: 100%; max-width: 340px;
  padding: 30px 26px 26px;
  text-align: center;
  background: var(--surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg), 0 0 0 1px var(--border);
  transform: translateY(16px) scale(0.96);
  transition: transform 0.35s cubic-bezier(0.16,1,0.3,1);
  overflow: hidden;
}
.mastery-overlay.show .mastery-card { transform: translateY(0) scale(1); }
.mastery-rays {
  position: absolute; top: -30%; left: 50%; width: 300px; height: 300px;
  transform: translateX(-50%);
  background: conic-gradient(from 0deg, transparent 0 12deg, color-mix(in srgb, var(--m-accent) 22%, transparent) 12deg 24deg, transparent 24deg 36deg, color-mix(in srgb, var(--m-accent) 22%, transparent) 36deg 48deg);
  opacity: 0.5;
  animation: masterySpin 14s linear infinite;
  pointer-events: none;
  /* A conic gradient rotating forever directly behind a backdrop-filtered overlay is
     the most expensive thing on this screen. Promoting it to its own layer keeps the
     rotation on the compositor instead of repainting the gradient every frame. */
  will-change: transform;
  backface-visibility: hidden;
}
@keyframes masterySpin { to { transform: translateX(-50%) rotate(360deg); } }

/* Respect the OS setting explicitly. The global reduced-motion rule collapses every
   animation to 0.01ms, which for an INFINITE animation means it restarts thousands of
   times a second and pins a core rather than stopping. */
@media (prefers-reduced-motion: reduce) {
  .mastery-badge-float, .mastery-rays { animation: none !important; }
}
.mastery-eyebrow {
  position: relative;
  font-size: var(--text-xs); font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--m-accent); margin-bottom: var(--space-3);
}
/* Three nested elements, one job each. See the long comment in showMasteryOverlay()
   for why: two animations were fighting over one `transform`, and the filtered <img>
   was animating its own transform (an Android WebView re-raster trap that reads as a
   vibration on a phone but not on a desktop).

     .mastery-badge-wrap   entrance transform, from JS
     .mastery-badge-float  infinite bob, from CSS
     .mastery-badge        the drop-shadow, and nothing that moves
*/
.mastery-badge-wrap {
  position: relative;
  width: 168px; height: 168px;
  margin: 0 auto var(--space-3);
  will-change: transform, opacity;
}
.mastery-badge-float {
  width: 100%; height: 100%;
  animation: masteryFloat 3.2s ease-in-out infinite;
  /* Promote to its own layer: the drop-shadow inside is then rasterized once and this
     layer is only translated, instead of the shadow being re-rendered every frame. */
  will-change: transform;
}
.mastery-badge {
  display: block;
  width: 100%; height: 100%; object-fit: contain;
  filter: drop-shadow(0 8px 20px rgba(0,0,0,0.28));
  /* Deliberately no animation here. Moving a filtered element by transforming the
     element ITSELF is what caused the shake on device. */
}
@keyframes masteryFloat { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-7px); } }
.mastery-title { position: relative; font-size: 1.7rem; font-weight: 900; color: var(--text); margin-bottom: var(--space-2); }
.mastery-sub { position: relative; font-size: var(--text-sm); color: var(--text-muted); line-height: 1.5; margin-bottom: var(--space-5); }
.mastery-close { position: relative; width: 100%; }

/* Profile badge shelf */
.badge-count {
  display: inline-block; margin-left: 6px;
  font-size: var(--text-xs); font-weight: 800; color: var(--primary);
  background: var(--primary-soft); padding: 2px 8px; border-radius: 999px;
  vertical-align: middle;
}
.badge-shelf {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3);
  margin-bottom: var(--space-2);
}
.badge-slot {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: var(--space-3) var(--space-2);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.badge-slot.earned { border-color: color-mix(in srgb, #f0cf7a 70%, var(--border)); background: linear-gradient(180deg, color-mix(in srgb, #fff4d6 40%, var(--surface)), var(--surface)); }
.badge-img-wrap { position: relative; width: 74px; height: 74px; display: flex; align-items: center; justify-content: center; }
.badge-img { width: 100%; height: 100%; object-fit: contain; }
.badge-slot.locked .badge-img { filter: grayscale(1) brightness(0.7) opacity(0.5); }
.badge-lock {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--text-faint);
}
.badge-slot.earned .badge-img { filter: drop-shadow(0 3px 8px rgba(0,0,0,0.2)); }
.badge-name { font-size: 0.7rem; font-weight: 700; color: var(--text-muted); text-align: center; line-height: 1.15; }
.badge-slot.earned .badge-name { color: var(--text); }

/* ========== Treasure Hunt ========== */
/* Dark aubergine board with a honeycomb of gems on it (matches the reference art). */
.treasure-body {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-3) var(--space-3);
  border-radius: var(--radius-xl);
  background: linear-gradient(180deg, #3b2f4a, #2a2038);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}
.tr-tip {
  width: 100%; max-width: 380px;
  padding: 10px 16px;
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 12px;
  color: #f4ecf8; font-weight: 700; font-size: var(--text-sm);
  text-align: center;
  box-shadow: inset 0 -2px 6px rgba(0,0,0,0.15);
}
.tr-grid {
  --hex-w: 62px;
  --hex-h: calc(var(--hex-w) * 1.1547);
  --hex-gap: 8px;
  flex: 1;
  width: 100%; max-width: 460px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: var(--space-2) 0;
}
/* Hex tile size scales with how many gems fit per row so the whole board fits
   the phone width. */
.tr-grid[data-per-row="3"] { --hex-w: 84px; --hex-gap: 12px; }
.tr-grid[data-per-row="4"] { --hex-w: 70px; --hex-gap: 10px; }
.tr-grid[data-per-row="5"] { --hex-w: 58px; --hex-gap: 8px; }
.tr-grid[data-per-row="6"] { --hex-w: 50px; --hex-gap: 6px; }

/* No tile behind each gem — gems float directly on the aubergine board. The
   .hexface element is kept for layout/clip-path but its fill is transparent. */
.tr-face {
  position: relative;
  background: transparent !important;
  box-shadow: none !important;
}
.gem-svg {
  width: 90%; height: 90%;
  filter: drop-shadow(0 2px 2px rgba(0,0,0,0.5));
}
.gem-sym {
  position: absolute; bottom: 12%; left: 50%; transform: translateX(-50%);
  font-size: 0.75rem; font-weight: 900; color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,0.9); pointer-events: none;
}
.tr-cell { cursor: default; }
.tr-cell:active .hexface { transform: none; }

.tr-controls { width: 100%; max-width: 420px; display: flex; flex-direction: column; gap: var(--space-3); align-items: center; padding-top: var(--space-2); }
.tr-cb-row { width: 100%; display: flex; justify-content: center; }
.tr-cb {
  display: inline-flex; align-items: center; gap: 10px; cursor: pointer;
  font-size: var(--text-sm); font-weight: 700; color: rgba(255,255,255,0.72);
  user-select: none;
}
.tr-cb input { position: absolute; opacity: 0; width: 0; height: 0; }
.tr-switch {
  width: 42px; height: 24px; border-radius: 999px; background: rgba(255,255,255,0.18);
  position: relative; transition: background 0.2s ease; flex-shrink: 0;
}
.tr-switch::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px;
  border-radius: 50%; background: #fff; box-shadow: var(--shadow-sm);
  transition: transform 0.2s ease;
}
.tr-cb input:checked + .tr-switch { background: var(--treasure); }
.tr-cb input:checked + .tr-switch::after { transform: translateX(18px); }

/* Flat square colour buttons, like the reference art. */
.tr-buttons {
  display: flex; gap: 8px 8px; justify-content: center; align-items: center;
  width: 100%; max-width: 400px; flex-wrap: wrap;
}
.tr-btn {
  width: 44px; height: 44px; border-radius: 6px;
  border: none; cursor: pointer;
  background: var(--tr-c);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 3px 0 rgba(0,0,0,0.25);
  transition: transform 0.1s ease, box-shadow 0.1s ease;
}
.tr-buttons[data-n="3"] .tr-btn, .tr-buttons[data-n="4"] .tr-btn { width: 52px; height: 52px; }
.tr-btn:active { transform: translateY(2px); box-shadow: 0 1px 0 rgba(0,0,0,0.25); }
.tr-btn-sym { font-size: 1.3rem; font-weight: 900; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,0.35); }
.tr-btn.ok { outline: 3px solid #2fa34e; outline-offset: 2px; animation: trPop 0.4s ease; }
.tr-btn.bad { outline: 3px solid #d9433f; outline-offset: 2px; animation: trBad 0.4s ease; }
.tr-btn.reveal { outline: 3px solid #2fa34e; outline-offset: 2px; }
@keyframes trPop { 0%,100%{transform:scale(1);} 45%{transform:scale(1.1);} }
@keyframes trBad { 0%,100%{transform:translateX(0);} 25%{transform:translateX(-5px);} 75%{transform:translateX(5px);} }

/* ========== Missing Number ========== */
.missnum-body {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--space-4);
  padding: var(--space-3);
  border-radius: var(--radius-xl);
  background: radial-gradient(120% 80% at 50% 0%, var(--missnum-soft), var(--surface));
  box-shadow: var(--shadow-md);
}
.mn-grid {
  --hex-w: 74px;
  --hex-h: calc(var(--hex-w) * 1.1547);
  --hex-gap: 12px;
  flex: 1;
  width: 100%; max-width: 460px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: var(--space-3) 0;
}
.mn-grid[data-per-row="3"] { --hex-w: 84px; --hex-gap: 14px; }
.mn-grid[data-per-row="4"] { --hex-w: 72px; --hex-gap: 12px; }
.mn-grid[data-per-row="5"] { --hex-w: 60px; --hex-gap: 10px; }
.mn-grid[data-per-row="6"] { --hex-w: 52px; --hex-gap: 8px; }
/* Cream tiles with bold blue numbers (matches the reference art). */
.mn-face {
  background: linear-gradient(180deg, #fbf3ec, #efe2d6) !important;
  box-shadow: inset 0 -3px 6px rgba(0,0,0,0.08);
}
.mn-num {
  font-size: clamp(1.2rem, 6vw, 1.9rem); font-weight: 800; color: #2f7bd6;
  text-shadow: 0 1px 0 rgba(255,255,255,0.6);
}
.mn-cell { cursor: default; }
.mn-cell:active .hexface { transform: none; }

.mn-options {
  display: flex; flex-wrap: wrap; gap: 10px 12px; justify-content: center;
  width: 100%; max-width: 380px;
}
.mn-opt {
  flex: 0 1 auto; width: 72px; height: 62px;
  border: none; border-radius: var(--radius-md);
  background: var(--surface-2); color: var(--text);
  font-size: 1.6rem; font-weight: 800; cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform 0.1s ease, background 0.2s ease;
}
/* With 3-4 options, keep them wider for easy tapping. */
.mn-options[data-n="3"] .mn-opt, .mn-options[data-n="4"] .mn-opt { width: 80px; height: 66px; }
.mn-opt:active { transform: scale(0.94); }
.mn-opt:hover { background: var(--border); }
.mn-opt.ok { background: #2fa34e; color: #fff; animation: mnPop 0.4s ease; }
.mn-opt.bad { background: #d9433f; color: #fff; animation: mnBad 0.4s ease; }
.mn-opt.reveal { background: #2fa34e; color: #fff; }
@keyframes mnPop { 0%,100%{transform:scale(1);} 45%{transform:scale(1.1);} }
@keyframes mnBad { 0%,100%{transform:translateX(0);} 25%{transform:translateX(-6px);} 75%{transform:translateX(6px);} }

/* ===== Tricky Patterns ===== */
.patterns-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
  padding-top: var(--space-4);
}
.tp-tip {
  text-align: center;
  font-weight: 700;
  font-size: 1.02rem;
  color: var(--text);
  max-width: 320px;
  line-height: 1.35;
}
.tp-panels {
  display: flex;
  gap: var(--space-4);
  width: 100%;
  max-width: 380px;
  justify-content: center;
}
.tp-panel {
  flex: 1 1 0;
  max-width: 168px;
  aspect-ratio: 1 / 1;
  background: #2c1c3d;
  border-radius: 22px;
  box-shadow: inset 0 2px 10px rgba(0, 0, 0, 0.35), 0 4px 14px rgba(0, 0, 0, 0.15);
  padding: 8px;
  display: flex;
}
.tp-svg { width: 100%; height: 100%; display: block; }
.tp-svg circle { filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.35)); }

.tp-buttons {
  display: flex;
  gap: var(--space-4);
  width: 100%;
  max-width: 380px;
  justify-content: center;
}
.tp-btn {
  flex: 1 1 0;
  max-width: 168px;
  padding: 18px 0;
  border: none;
  border-radius: 18px;
  font-size: 1.35rem;
  font-weight: 800;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}
.tp-btn:active { transform: scale(0.96); }
.tp-no {
  background: #2c1c3d;
  color: #f6ecff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
}
.tp-yes {
  background: #2c1c3d;
  color: #f6ecff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
}
.tp-btn.ok { background: #58c15a !important; color: #fff !important; box-shadow: 0 0 0 4px rgba(88, 193, 90, 0.4); }
.tp-btn.bad { background: var(--danger) !important; color: #fff !important; box-shadow: 0 0 0 4px rgba(233, 79, 95, 0.35); animation: tp-shake 0.35s ease; }
@keyframes tp-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-6px); }
  75% { transform: translateX(6px); }
}

/* purple game chrome to match the reference */
.game-head:has(#tp-timer) .gh-title,
.patterns-body .crime-round { color: var(--patterns); }
#tp-timer { background: var(--patterns-soft); color: var(--patterns); }

/* ===== Math Crossword ===== */
.crossmath-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  padding-top: var(--space-3);
}
.cm-tip {
  text-align: center;
  font-weight: 700;
  font-size: 0.98rem;
  color: var(--text);
  max-width: 320px;
  line-height: 1.35;
}
.cm-grid-wrap {
  width: 100%;
  max-width: 340px;
  display: flex;
  justify-content: center;
}
.cm-grid {
  display: grid;
  gap: 4px;
  width: 100%;
}
.cm-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;
  border-radius: 9px;
  font-weight: 800;
  font-size: clamp(0.9rem, 4.6vw, 1.35rem);
  user-select: none;
}
.cm-empty { background: transparent; }
.cm-num {
  background: #f3e2bd;
  color: #4a3413;
  box-shadow: inset 0 -2px 0 rgba(0,0,0,0.08);
}
.cm-op, .cm-eq {
  background: #efd9ae;
  color: #8a6320;
}
.cm-blank {
  background: #fff8ec;
  color: #4a3413;
  border: 2px dashed #d9b877;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.1s ease, border-color 0.15s ease;
}
.cm-blank:active { transform: scale(0.94); }
.cm-blank.filled {
  background: #ffe9b8;
  border-style: solid;
  border-color: var(--crossmath);
}
.cm-blank.ok { background: #bfe6c0 !important; border-color: #4caf50 !important; color: #1f5a25 !important; }
.cm-blank.bad { background: #f3c2c2 !important; border-color: var(--danger) !important; animation: cm-shake 0.35s ease; }
@keyframes cm-shake {
  0%,100% { transform: translateX(0); }
  25% { transform: translateX(-5px); }
  75% { transform: translateX(5px); }
}

.cm-tray {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  max-width: 340px;
  padding: 10px 12px;
  background: var(--card, rgba(0,0,0,0.03));
  border-radius: 16px;
}
.cm-tile {
  min-width: 46px;
  padding: 10px 12px;
  border: none;
  border-radius: 12px;
  background: #f3e2bd;
  color: #3f7d3f;
  font-size: 1.2rem;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0,0,0,0.12), inset 0 -2px 0 rgba(0,0,0,0.08);
  transition: transform 0.1s ease, box-shadow 0.15s ease, background 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}
.cm-tile:active { transform: scale(0.92); }
.cm-tile.sel {
  background: var(--crossmath);
  color: #fff;
  box-shadow: 0 0 0 3px rgba(201,138,46,0.4);
  transform: translateY(-2px);
}
.cm-tile.used {
  opacity: 0.28;
  pointer-events: none;
  text-decoration: line-through;
}

/* purple/amber game chrome */
#cm-timer { background: var(--crossmath-soft); color: var(--crossmath); }

/* ===== Tap Away Arrows ===== */
.taparrows-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  padding-top: var(--space-3);
}
.ta-tip {
  text-align: center;
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--text);
  max-width: 320px;
  line-height: 1.35;
}
.ta-lives { font-size: 0.95rem; letter-spacing: 1px; }
.ta-grid-wrap {
  width: 100%;
  max-width: 360px;
  display: flex;
  justify-content: center;
}
.ta-grid {
  position: relative;
  display: grid;
  gap: 6px;
  width: 100%;
  aspect-ratio: 1 / 1;
}
.ta-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  aspect-ratio: 1 / 1;
  font-size: clamp(1.1rem, 6vw, 1.8rem);
  font-weight: 900;
}
.ta-dot {
  background: transparent;
  position: relative;
}
.ta-dot::after {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: rgba(120,120,140,0.28);
  display: block;
}
.ta-arrow {
  border: none;
  cursor: pointer;
  background: var(--taparrows-soft);
  color: var(--taparrows);
  box-shadow: 0 3px 8px rgba(0,0,0,0.12), inset 0 -2px 0 rgba(0,0,0,0.08);
  transition: transform 0.12s ease, background 0.15s ease, box-shadow 0.15s ease, opacity 0.25s ease;
  -webkit-tap-highlight-color: transparent;
  line-height: 1;
}
.ta-arrow:hover { filter: brightness(1.04); }
.ta-arrow:active { transform: scale(0.9); }
.ta-arrow.blocked {
  background: #f3c2c2;
  color: var(--danger);
  animation: ta-shake 0.38s ease;
}
@keyframes ta-shake {
  0%,100% { transform: translateX(0); }
  20% { transform: translateX(-5px); }
  40% { transform: translateX(5px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}
.ta-arrow.firing {
  transform: translate(var(--fx,0), var(--fy,0)) scale(0.4);
  opacity: 0;
}
.ta-shot {
  position: absolute;
  height: 4px;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--taparrows), rgba(79,123,216,0.1));
  transform-origin: 0 50%;
  pointer-events: none;
  z-index: 3;
  animation: ta-shot-fade 0.45s ease forwards;
}
@keyframes ta-shot-fade {
  0% { opacity: 0.9; }
  100% { opacity: 0; }
}


/* ========== Color match (Stroop) ========== */
.cm-body { display: flex; flex-direction: column; align-items: center; padding-top: 8px; }
.cm-question {
  text-align: center; font-weight: 700; font-size: 1.05rem; color: var(--text);
  max-width: 340px; margin: 8px auto 22px; line-height: 1.35;
}
.cm-cards { position: relative; width: 100%; max-width: 340px; margin: 0 auto; }
.cm-card {
  background: var(--surface); border-radius: 18px;
  box-shadow: 0 6px 18px rgba(120,70,40,0.12);
  height: 120px; display: flex; align-items: center; justify-content: center;
  margin: 22px 0; transition: transform .12s ease, background .15s ease;
}
.cm-word { font-size: 2.6rem; font-weight: 800; letter-spacing: -0.01em; text-transform: lowercase; }
.cm-tag {
  position: relative; z-index: 2; margin: 0 auto; width: max-content;
  background: color-mix(in srgb, var(--text) 12%, transparent);
  color: var(--text-soft); font-size: 12px; font-weight: 700;
  padding: 4px 12px; border-radius: 8px; text-transform: lowercase;
}
.cm-tag-top { margin-bottom: -8px; }
.cm-tag-bottom { margin-top: -8px; }
.cm-flash-ok { animation: cmOk .5s ease; }
.cm-flash-bad { animation: cmBad .5s ease; }
@keyframes cmOk { 0%,100%{ box-shadow:0 6px 18px rgba(120,70,40,0.12);} 50%{ box-shadow:0 0 0 4px var(--success);} }
@keyframes cmBad { 0%,100%{ transform:translateX(0);} 20%{transform:translateX(-7px);} 40%{transform:translateX(7px);} 60%{transform:translateX(-5px);} 80%{transform:translateX(5px);} }
.cm-actions {
  display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
  width: 100%; max-width: 340px; margin: 28px auto 0;
}
.cm-btn {
  border: 0; border-radius: 16px; padding: 18px 0; cursor: pointer;
  font-size: 1.15rem; font-weight: 800; letter-spacing: 0.03em; color: #fff;
  transition: transform .12s ease, filter .15s ease;
}
.cm-btn:active { transform: scale(0.96); }
.cm-no  { background: #e5352b; }
.cm-yes { background: #2fa14e; }
.cm-verdict {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  display: flex; align-items: center; gap: 8px; z-index: 5;
  background: rgba(43,32,24,0.9); color: #fff; font-weight: 800;
  padding: 10px 18px; border-radius: 999px; font-size: 0.95rem; white-space: nowrap;
  box-shadow: 0 8px 24px rgba(0,0,0,0.25); pointer-events: none;
}
.cm-verdict.ok  { background: rgba(47,161,78,0.95); }
.cm-verdict.bad { background: rgba(229,53,43,0.95); }
.cm-verdict-icon { font-size: 1.1rem; }

/* ========== Color recall (memory grid) ========== */
.cr-shell { display: flex; flex-direction: column; height: 100%; padding: 0 4px 12px; }
.cr-topbar { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 4px 10px; }
.cr-iconbtn {
  width: 40px; height: 40px; border: 0; border-radius: 50%; cursor: pointer;
  background: var(--surface); color: var(--text);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 3px 10px rgba(120,70,40,0.12);
}
.cr-bar { display: flex; align-items: center; gap: 14px; font-weight: 800; }
.cr-timer { color: var(--memory, #7a5cff); min-width: 44px; text-align: center; }
.cr-timer.low { color: #e5352b; }
.cr-round { color: var(--text-soft); }
.cr-score { color: var(--text); }
.cr-stage { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px; padding: 8px 0; }
.cr-message { font-weight: 700; font-size: 1.05rem; color: var(--text); text-align: center; min-height: 1.4em; }
.cr-message.warn { color: #e5352b; }
.cr-grid {
  display: grid; gap: 12px; width: 100%; max-width: 340px; aspect-ratio: 1 / 1;
}
.cr-cell {
  border: 0; border-radius: 14px; cursor: pointer;
  background: color-mix(in srgb, var(--text) 8%, var(--surface));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.4), 0 2px 6px rgba(120,70,40,0.08);
  transition: transform .1s ease, background .18s ease, box-shadow .18s ease;
  aspect-ratio: 1 / 1; min-height: 0;
}
.cr-cell:not(:disabled):active { transform: scale(0.94); }
.cr-cell.lit { box-shadow: 0 0 0 3px rgba(255,255,255,0.5), 0 6px 16px rgba(0,0,0,0.18); }
.cr-cell.correct { box-shadow: 0 0 0 3px var(--success); }
.cr-cell.hinted { box-shadow: 0 0 0 3px #f5b301; }
.cr-cell.wrong { background: #e5352b !important; animation: crShake .4s ease; }
.cr-cell.missed { outline: 3px dashed rgba(255,255,255,0.7); outline-offset: -6px; }
@keyframes crShake { 0%,100%{transform:translateX(0);} 25%{transform:translateX(-5px);} 75%{transform:translateX(5px);} }
.cr-hint {
  display: inline-flex; align-items: center; gap: 8px;
  border: 0; border-radius: 999px; cursor: pointer; padding: 10px 18px;
  background: var(--surface); color: var(--text); font-weight: 800;
  box-shadow: 0 3px 10px rgba(120,70,40,0.14);
}
.cr-hint:disabled { opacity: 0.4; cursor: default; }
.cr-hint-count {
  background: #f5b301; color: #2b2118; border-radius: 999px;
  min-width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; padding: 0 6px;
}
.cr-overlay {
  position: absolute; inset: 0; z-index: 20; display: flex; align-items: center; justify-content: center;
  background: rgba(43,32,24,0.45); backdrop-filter: blur(3px);
}
.cr-overlay[hidden] { display: none; }
.cr-card {
  background: var(--surface); border-radius: 20px; padding: 26px 24px; max-width: 320px; text-align: center;
  box-shadow: 0 18px 50px rgba(0,0,0,0.25);
}
.cr-card h3 { margin: 0 0 10px; }
.cr-card p { color: var(--text-soft); margin: 0 0 12px; }
.cr-card .cr-mini { font-size: 14px; }



/* ========== Fingerprints (Simon-style sequence memory) ========== */
.fp-shell { display: flex; flex-direction: column; height: 100%; padding: 0 4px 12px; }
.fp-topbar { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 4px 8px; }
.fp-iconbtn { width: 40px; height: 40px; border: 0; border-radius: 50%; cursor: pointer; background: var(--surface); color: var(--text); display: flex; align-items: center; justify-content: center; box-shadow: 0 3px 10px rgba(120,70,40,0.12); }
.fp-bar { display: flex; align-items: center; gap: 14px; font-weight: 800; }
.fp-timer { color: var(--memory, #7a5cff); min-width: 44px; text-align: center; }
.fp-timer.low { color: #e5352b; }
.fp-round { color: var(--text-soft); }
.fp-score { color: var(--text); }
.fp-message { text-align: center; font-weight: 700; font-size: 1.05rem; color: var(--text); min-height: 1.4em; margin-top: 4px; }
.fp-progress { display: flex; justify-content: center; gap: 6px; min-height: 12px; margin: 10px 0 2px; }
.fp-dot { width: 8px; height: 8px; border-radius: 50%; background: color-mix(in srgb, var(--text) 18%, transparent); transition: background .15s ease; }
.fp-dot.done { background: var(--success); }
.fp-board { position: relative; width: 100%; max-width: 340px; margin: 8px auto 0; aspect-ratio: 3 / 4; }
.fp-tile {
  position: absolute; transform: translate(-50%, -50%);
  width: 24%; aspect-ratio: 1/1; border: 0; border-radius: 18px; cursor: pointer;
  background: color-mix(in srgb, var(--text) 10%, var(--surface));
  color: transparent;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.35), 0 4px 10px rgba(120,70,40,0.10);
  display: flex; align-items: center; justify-content: center;
  transition: transform .1s ease, background .16s ease, color .16s ease, box-shadow .16s ease;
}
.fp-tile:not(:disabled):active { transform: translate(-50%, -50%) scale(0.94); }
.fp-tile .fp-svg { width: 56%; height: 56%; opacity: 0; transition: opacity .12s ease; }
.fp-tile.lit {
  background: var(--memory, #7a5cff); color: #fff;
  box-shadow: 0 0 0 3px rgba(255,255,255,0.5), 0 8px 20px rgba(0,0,0,0.22);
}
.fp-tile.lit .fp-svg { opacity: 1; }
.fp-tile.wrong { background: #e5352b !important; color:#fff; animation: crShake .4s ease; }
.fp-tile.wrong .fp-svg { opacity: 1; }
.fp-hint {
  align-self: center; display: inline-flex; align-items: center; gap: 8px;
  border: 0; border-radius: 999px; cursor: pointer; padding: 10px 18px; margin-top: 8px;
  background: var(--surface); color: var(--text); font-weight: 800;
  box-shadow: 0 3px 10px rgba(120,70,40,0.14);
}
.fp-hint:disabled { opacity: 0.4; cursor: default; }
.fp-hint-count { background: #f5b301; color: #2b2118; border-radius: 999px; min-width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center; font-size: 12px; padding: 0 6px; }

/* Fingerprints — get-ready countdown */
.fp-countdown {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  font-size: 5rem; font-weight: 900; color: var(--memory, #7a5cff);
  pointer-events: none; opacity: 0; z-index: 5;
  text-shadow: 0 4px 16px rgba(0,0,0,0.15);
}
.fp-countdown.show { animation: fpCount .75s ease-out; }
@keyframes fpCount {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(1.6); }
  30%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(0.8); }
}

/* ============ Colored cells (Speed) ============ */
.cc-rules { text-align: center; padding: var(--space-6) var(--space-3); display: flex; flex-direction: column; align-items: center; gap: 10px; }
.cc-preview { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; width: 168px; margin-bottom: 8px; }
.cc-preview .cc-cell { aspect-ratio: 1; border-radius: 8px; }
.cc-rules h2 { font-size: var(--text-xl, 24px); font-weight: 800; }
.cc-rules .btn { margin-top: 14px; min-width: 180px; }

.cc-body { display: flex; flex-direction: column; height: 100%; }
.cc-timerbar { height: 8px; background: rgba(0,0,0,0.08); border-radius: 99px; overflow: hidden; margin-bottom: 10px; }
.cc-timerfill { height: 100%; width: 100%; background: var(--reaction, #eab308); border-radius: 99px; transition: width 1s linear; }
.cc-meta { display: flex; justify-content: space-between; align-items: center; font-size: var(--text-base, 16px); font-weight: 800; margin-bottom: 16px; }
.cc-meta .muted { font-weight: 600; font-size: var(--text-sm, 14px); }
#cc-time.cc-low { color: #ef4444; }

.cc-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; align-content: start; margin-bottom: 22px; }
.cc-cell {
  aspect-ratio: 1; border-radius: 16px; display: block;
  box-shadow: 0 2px 6px rgba(0,0,0,0.12);
}
.cc-cell.cc-g { background: #5f8f3e; }
.cc-cell.cc-r { background: #e5352b; }
.cc-cell.cc-e { background: var(--surface, #fae7db); box-shadow: inset 0 0 0 2px rgba(0,0,0,0.16); }

/* Column count is set inline by the game: the number of answer choices rises with the
   level (3 up to 5), and five 24px buttons will not fit at the three-option padding. */
.cc-options { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: auto; }
.cc-opt {
  padding: clamp(14px, 22px, 22px) 0; border-radius: 16px; cursor: pointer;
  background: var(--surface, #fae7db); color: var(--ink, #33302f);
  font-size: clamp(17px, 5vw, 24px); font-weight: 800;
  border: none; box-shadow: inset 0 0 0 2px rgba(0,0,0,0.14), 0 2px 6px rgba(0,0,0,0.1);
  transition: transform .1s;
}
.cc-opt:active { transform: scale(0.95); }
.cc-opt.cc-correct { animation: cc-correct .35s ease; box-shadow: 0 0 0 4px #22c55e; }
@keyframes cc-correct { 0%{transform:scale(1)} 45%{transform:scale(1.08)} 100%{transform:scale(1)} }
.cc-opt.cc-wrong { animation: cc-wrong .35s ease; box-shadow: 0 0 0 4px #ef4444; }
@keyframes cc-wrong { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-5px)} 75%{transform:translateX(5px)} }

/* ============ Schulte table (Speed) ============ */
.st-rules { text-align: center; padding: var(--space-6) var(--space-3); display: flex; flex-direction: column; align-items: center; gap: 10px; }
.st-preview { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; width: 176px; margin-bottom: 8px; }
.st-pcell {
  aspect-ratio: 1; border-radius: 8px; display: flex; align-items: center; justify-content: center;
  background: var(--surface, #fae7db); color: var(--ink, #33302f);
  font-weight: 800; font-size: clamp(9px, 13px, 13px); box-shadow: inset 0 0 0 2px rgba(0,0,0,0.12);
  /* The preview grid is a fixed 176px wide but its column count now varies with the
     level, so let the digits shrink rather than overflow their cell. */
  overflow: hidden;
}
.st-rules h2 { font-size: var(--text-xl, 24px); font-weight: 800; }
.st-rules .btn { margin-top: 14px; min-width: 180px; }

.st-body { display: flex; flex-direction: column; height: 100%; }
.st-timerbar { height: 8px; background: rgba(0,0,0,0.08); border-radius: 99px; overflow: hidden; margin-bottom: 10px; }
.st-timerfill { height: 100%; width: 100%; background: var(--reaction, #eab308); border-radius: 99px; transition: width 1s linear; }
.st-meta { display: flex; justify-content: space-between; align-items: center; font-size: var(--text-base, 16px); font-weight: 800; margin-bottom: 12px; }
.st-meta .muted { font-weight: 600; font-size: var(--text-sm, 14px); }
#st-time.st-low { color: #ef4444; }
.st-prompt { text-align: center; font-size: var(--text-2xl, 30px); font-weight: 600; color: var(--muted, #8a7f78); margin-bottom: 18px; }
.st-prompt b { font-weight: 800; color: var(--ink, #33302f); }

/* The column count and --st-cols are set inline by the game, because the table now
   grows with the level (3x3 at L1 up to 6x6 at L9+). Gap, radius and font size scale
   down with it - a 6x6 board at the 4x4 tile size would run off a phone screen, and at
   the 4x4 font size two-digit numbers in a 36-tile grid would not fit. */
.st-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); align-content: start;
  --st-cols: 4;
  gap: clamp(5px, calc(26px - var(--st-cols) * 3px), 12px);
}
.st-tile {
  aspect-ratio: 1; cursor: pointer;
  border-radius: clamp(8px, calc(32px - var(--st-cols) * 4px), 16px);
  background: var(--surface, #fae7db); color: var(--ink, #33302f);
  font-size: clamp(13px, calc(42px - var(--st-cols) * 4.5px), 24px); font-weight: 800;
  border: none; box-shadow: inset 0 0 0 2px rgba(0,0,0,0.14), 0 2px 6px rgba(0,0,0,0.1);
  transition: transform .1s, opacity .2s, background .2s;
  font-variant-numeric: tabular-nums;
  padding: 0;
}
.st-tile:active { transform: scale(0.95); }
.st-tile.st-done { opacity: 0.4; box-shadow: inset 0 0 0 2px rgba(0,0,0,0.08); cursor: default; }
.st-tile.st-wrong { animation: st-wrong .35s ease; box-shadow: 0 0 0 4px #ef4444; }
@keyframes st-wrong { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-5px)} 75%{transform:translateX(5px)} }

/* ============ Disjunction (Speed) ============ */
.dj-rules { text-align: center; padding: var(--space-6) var(--space-3); display: flex; flex-direction: column; align-items: center; gap: 10px; }
.dj-preview { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.dj-preview .dj-mini { width: 56px; height: 56px; }
.dj-plus { font-size: 22px; font-weight: 800; color: var(--muted, #8a7f78); }
.dj-rules h2 { font-size: var(--text-xl, 24px); font-weight: 800; }
.dj-rules .btn { margin-top: 14px; min-width: 180px; }

.dj-body { display: flex; flex-direction: column; height: 100%; }
.dj-timerbar { height: 8px; background: rgba(0,0,0,0.08); border-radius: 99px; overflow: hidden; margin-bottom: 10px; }
.dj-timerfill { height: 100%; width: 100%; background: var(--reaction, #eab308); border-radius: 99px; transition: width 1s linear; }
.dj-meta { display: flex; justify-content: space-between; align-items: center; font-size: var(--text-base, 16px); font-weight: 800; margin-bottom: 8px; }
.dj-meta .muted { font-weight: 600; font-size: var(--text-sm, 14px); }
#dj-time.dj-low { color: #ef4444; }

/* the mini 4x4 grid used everywhere in this game */
.dj-mini {
  display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(4, 1fr);
  gap: 3px; padding: 6px; border-radius: 12px; aspect-ratio: 1;
  background: var(--surface, #fae7db); box-shadow: inset 0 0 0 2px rgba(0,0,0,0.16);
}
.dj-mini span { border-radius: 3px; background: transparent; }
.dj-green span.on { background: #3f9d5f; }
.dj-blue span.on { background: #6a7ee0; }

/* question row: three green inputs, operators, and the unknown box */
.dj-question { display: flex; align-items: center; justify-content: center; gap: 8px; flex: 1; }
.dj-question .dj-mini { width: 68px; height: 68px; flex: 0 0 auto; }
.dj-op { font-size: 22px; font-weight: 800; color: var(--ink, #33302f); }
.dj-unknown {
  display: flex; align-items: center; justify-content: center;
  background: transparent; box-shadow: none;
  border: 2px dashed var(--ink, #33302f); width: 68px; height: 68px; grid-template-columns: none; grid-template-rows: none;
}
.dj-unknown .dj-q { font-size: 30px; font-weight: 800; color: var(--ink, #33302f); }

/* answer options: three larger blue grids */
.dj-options { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: auto; padding-bottom: 6px; }
.dj-opt {
  padding: 8px; border-radius: 18px; cursor: pointer; border: none;
  background: #6a7ee0; box-shadow: 0 3px 8px rgba(0,0,0,0.15);
  transition: transform .1s;
}
.dj-opt .dj-mini { background: #eee; box-shadow: none; width: 100%; height: auto; }
.dj-opt .dj-blue span { background: rgba(255,255,255,0.55); }
.dj-opt .dj-blue span.on { background: #6a7ee0; }
.dj-opt:active { transform: scale(0.95); }
.dj-opt.dj-correct { animation: dj-correct .35s ease; box-shadow: 0 0 0 4px #22c55e; }
@keyframes dj-correct { 0%{transform:scale(1)} 45%{transform:scale(1.06)} 100%{transform:scale(1)} }
.dj-opt.dj-wrong { animation: dj-wrong .35s ease; box-shadow: 0 0 0 4px #ef4444; }
@keyframes dj-wrong { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-5px)} 75%{transform:translateX(5px)} }

/* ============ Debug log (testing builds) ============ */
/* Debug FAB: docked bottom-LEFT and translucent so it never sits on top of
   game content (it used to cover the bottom-right cell of the Signals grid). */
#dbg-log-fab {
  position: fixed;
  left: max(8px, env(safe-area-inset-left)); z-index: 99999;
  bottom: calc(8px + env(safe-area-inset-bottom));
  width: 38px; height: 38px; border-radius: 50%;
  background: rgba(30,30,34,0.45); color: rgba(255,255,255,0.75); border: none;
  font-size: 9px; font-weight: 800; letter-spacing: 0.5px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.25); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  opacity: 0.5;
  transition: opacity 160ms ease, background 160ms ease;
}
#dbg-log-fab:hover, #dbg-log-fab:focus-visible { opacity: 1; background: rgba(30,30,34,0.85); }
#dbg-log-fab:active { transform: scale(0.92); opacity: 1; }
#dbg-log-badge {
  transform: scale(0.85);
  position: absolute; top: -4px; right: -4px; min-width: 18px; height: 18px;
  padding: 0 4px; border-radius: 9px; background: #ef4444; color: #fff;
  font-size: 10px; font-weight: 800; display: flex; align-items: center; justify-content: center;
}

#dbg-log-overlay {
  position: fixed; inset: 0; z-index: 100000;
  background: rgba(0,0,0,0.5); display: flex; align-items: flex-end;
}
#dbg-log-overlay[hidden] { display: none !important; }
.dbg-log-panel {
  width: 100%; max-height: 80vh; display: flex; flex-direction: column;
  background: #14151a; color: #e8e8ea; border-top-left-radius: 16px; border-top-right-radius: 16px;
  box-shadow: 0 -8px 30px rgba(0,0,0,0.5); font-family: ui-monospace, Menlo, Consolas, monospace;
}
.dbg-log-head {
  display: flex; align-items: center; gap: 8px; padding: 12px 14px;
  border-bottom: 1px solid rgba(255,255,255,0.1);
}
.dbg-log-title { font-weight: 800; font-size: 15px; font-family: system-ui, sans-serif; }
.dbg-log-count { font-size: 11px; color: #9aa0aa; }
.dbg-log-actions { margin-left: auto; display: flex; gap: 6px; }
.dbg-log-actions button {
  background: #2a2c34; color: #e8e8ea; border: none; border-radius: 8px;
  padding: 7px 10px; font-size: 12px; font-weight: 700; cursor: pointer; font-family: system-ui, sans-serif;
}
.dbg-log-actions button:active { transform: scale(0.94); }
#dbg-log-clear { background: #5a2130; color: #ffd7d7; }
.dbg-log-filters {
  display: flex; gap: 12px; padding: 8px 14px; flex-wrap: wrap;
  border-bottom: 1px solid rgba(255,255,255,0.08); font-family: system-ui, sans-serif;
}
.dbg-log-filters label { font-size: 12px; color: #c4c8d0; display: flex; align-items: center; gap: 4px; }
.dbg-log-body {
  overflow-y: auto; padding: 8px 10px 20px; font-size: 11.5px; line-height: 1.45;
  -webkit-overflow-scrolling: touch;
}
.dbg-row {
  display: grid; grid-template-columns: auto auto auto 1fr; gap: 6px; align-items: start;
  padding: 3px 4px; border-bottom: 1px solid rgba(255,255,255,0.05); white-space: pre-wrap; word-break: break-word;
}
.dbg-t { color: #7d838f; }
.dbg-lvl { font-weight: 800; }
.dbg-tag { color: #7fd1ff; }
.dbg-msg { color: #e8e8ea; }
.dbg-error .dbg-lvl { color: #ff6b6b; }
.dbg-error .dbg-msg { color: #ffb3b3; }
.dbg-warn  .dbg-lvl { color: #ffcf5c; }
.dbg-warn  .dbg-msg { color: #ffe6a8; }
.dbg-event .dbg-lvl { color: #6ee787; }
.dbg-info  .dbg-lvl, .dbg-log .dbg-lvl { color: #9aa0aa; }

/* Universal pause menu (Back button in games without a built-in pause) */
#universal-paused {
  position: fixed; inset: 0; z-index: 10000;
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-5);
}
#universal-paused[hidden] { display: none !important; }

/* Generic "How to play" overlay (Back-menu > How to play for Speed games) */
#generic-howto {
  position: fixed; inset: 0; z-index: 10001;
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-5);
  background: color-mix(in srgb, var(--bg) 80%, transparent);
  backdrop-filter: blur(4px);
}
#generic-howto[hidden] { display: none !important; }
#generic-howto .howto-card { max-width: 22rem; width: 100%; text-align: center; }
#generic-howto .howto-body {
  font-size: var(--text-base); color: var(--text-muted); line-height: 1.55;
  margin: 0;
}
#generic-howto .btn { margin-top: var(--space-2); }

/* ============ Pattern Compare (Speed) ============ */
.pc-rules { text-align: center; padding: var(--space-6) var(--space-3); display: flex; flex-direction: column; align-items: center; gap: 10px; }
.pc-preview { display: flex; gap: 10px; margin-bottom: 8px; }
.pc-preview .pc-grid { width: 96px; }
.pc-rules h2 { font-size: var(--text-xl, 24px); font-weight: 800; }
.pc-rules .btn { margin-top: 14px; min-width: 200px; }

.pc-body { display: flex; flex-direction: column; height: 100%; }
.pc-timerbar { height: 8px; background: rgba(0,0,0,0.08); border-radius: 99px; overflow: hidden; margin-bottom: 10px; }
.pc-timerfill { height: 100%; width: 100%; background: var(--reaction, #eab308); border-radius: 99px; transition: width 1s linear; }
.pc-meta { display: flex; flex-direction: column; align-items: center; gap: 12px; margin-bottom: 8px; }
#pc-time { font-size: var(--text-2xl, 30px); font-weight: 800; }
#pc-time.pc-low { color: #ef4444; }
.pc-q { background: var(--reaction, #a855f7); color: #fff; font-weight: 800; font-size: var(--text-base, 16px); padding: 10px 20px; border-radius: 99px; box-shadow: 0 4px 12px rgba(0,0,0,0.12); }

.pc-boards { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-content: center; flex: 1; }
.pc-card { background: var(--surface, #fae7db); border-radius: 16px; padding: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); }
.pc-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; width: 100%; }
.pc-cell { aspect-ratio: 1; border-radius: 4px; box-shadow: 0 1px 2px rgba(0,0,0,0.12); }
.pc-cell.empty { background: transparent !important; box-shadow: none; }

.pc-options { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: auto; padding-bottom: 6px; }
.pc-opt {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 16px 0; border-radius: 16px; cursor: pointer; border: none;
  background: var(--surface, #fae7db); color: var(--ink, #33302f);
  box-shadow: inset 0 0 0 2px rgba(0,0,0,0.12), 0 2px 6px rgba(0,0,0,0.1);
  transition: transform .1s;
}
.pc-opt .pc-sym { font-size: 22px; font-weight: 800; }
.pc-opt .pc-lbl { font-size: var(--text-sm, 14px); font-weight: 700; }
.pc-opt:active { transform: scale(0.96); }
.pc-opt.pc-correct { background: #22c55e; color: #fff; box-shadow: 0 0 0 3px rgba(34,197,94,0.4); }
.pc-opt.pc-wrong { background: #ef4444; color: #fff; animation: pc-shake .35s ease; }
/* After a wrong answer, briefly outline the button that WAS correct. */
.pc-opt.pc-reveal { box-shadow: 0 0 0 3px #22c55e; }
@keyframes pc-shake { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-5px)} 75%{transform:translateX(5px)} }

/* ============ Profile: Backup / restore ============ */
.prof-backup { display: flex; flex-direction: column; gap: var(--space-4); }
.backup-note {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: 1.45;
}
.backup-actions { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.backup-actions .btn {
  flex: 1 1 0; width: auto; min-width: 112px;
  white-space: nowrap;              /* "Save backup" must never wrap */
  font-size: var(--text-sm);
  padding-left: var(--space-3); padding-right: var(--space-3);
}
.backup-status {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: 600;
  color: #1f8a54;
  line-height: 1.4;
}
.backup-status.is-error { color: #c2374f; }

/* ============================================================================
   Large screens and landscape
   ----------------------------------------------------------------------------
   The app was locked to portrait, which Google Play flags as a resizability /
   orientation restriction. With the lock removed the layout has to cope with
   short, wide viewports too. Two problems had to be solved:

     1. The game shells declare min-height: 70-72vh. In portrait that fills the
        screen nicely; in landscape it made the shell taller than the viewport
        (measured +324px on a 915x412 phone, +376px at 740x360), forcing the
        player to scroll while playing.
     2. Square game boards were sized only against WIDTH, so on a short viewport
        they ran off the bottom.

   Fixes below cap the boards against the viewport HEIGHT as well, and relax the
   vertical rhythm when height is scarce.
   ========================================================================== */

/* ---- Short viewports (landscape phones, split screen) ---- */
@media (max-height: 560px) {
  /* Shells must never be taller than the screen. */
  .sig2-shell, .gh2-shell, .pb-shell, .sc-shell, .odd2-shell {
    min-height: 0;
  }

  /* Reclaim vertical space. */
  .screen {
    padding-top: calc(var(--space-3) + max(env(safe-area-inset-top), 12px));
    padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom));
  }
  .game-head { margin-bottom: var(--space-2); }
  .sig2-stage, .gh2-stage { padding-top: 4px; padding-bottom: 8px; }

  /* Square boards: fit the smaller of width and remaining height. */
  .sig2-grid {
    max-width: min(420px, calc(100dvh - 190px));
  }

  /* Message pills and headings tighten up. */
  .sig2-message, .gh2-message { padding: 8px 16px; font-size: var(--text-sm); }
}

/* ---- Very short (e.g. 320px tall split screen) ---- */
@media (max-height: 400px) {
  .screen { padding-top: calc(var(--space-2) + env(safe-area-inset-top)); }
  .sig2-grid { max-width: min(420px, calc(100dvh - 150px)); }
  .game-head { margin-bottom: 2px; }
}

/* ============================================================================
   TABLET LAYOUT
   ----------------------------------------------------------------------------
   Previously this section was two lines that nudged --maxw from 480px to 560px
   and then 620px. That is not a tablet layout - it is a phone layout centred on a
   big screen, with two fat empty margins and a 36-tile game list running two
   columns wide down a strip in the middle.

   The design now splits in two:

     * BROWSE surfaces (home, profile) go genuinely wide and multi-column. There is
       real content to spread out: 36 game cards, 36 mastery badges, five skill bars.
     * PLAY surfaces (game, results, intro) stay on a capped, phone-width column.
       All 36 boards are hand-tuned for a ~480px column - Schulte tables, Hanoi pegs,
       flow grids. Stretching them to 1000px would not make them better, it would
       make them a scattering of tiny widgets in a huge field. This is a deliberate
       split, not an oversight.

   --maxw       = the app shell width (browse surfaces)
   --maxw-play  = the capped column for anything you actually play in
   ========================================================================== */

:root { --maxw-play: 480px; }

/* Below the tablet breakpoint the profile column wrappers are transparent, so the
   blocks inside them lay out in the phone flex stack exactly as they always have.
   They only become real columns at 900px+ (see below). */
.prof-col { display: contents; }

/* Play surfaces never exceed the phone column, at any screen size. Centred inside
   whatever the shell width happens to be. */
#screen-game > .stack,
#screen-results > .stack,
#screen-intro > .stack {
  width: 100%;
  max-width: var(--maxw-play);
  margin-inline: auto;
}

/* ---- Small tablets / large phones in landscape (600-899px) ---- */
@media (min-width: 600px) {
  :root { --maxw: 720px; }

  /* Three across instead of two: at 720px a 2-column grid gives 340px-wide cards
     for a 58px glyph, which looks like a list of banners rather than a game grid. */
  .cat-grid, .cat-grid.solo { grid-template-columns: repeat(3, 1fr); }

  .stat-grid { gap: var(--space-4); }
}

/* ---- Tablets proper (800px+) ----
   800px is deliberate, not a round number: it is the portrait width of essentially
   every 10" Android tablet. A 900px threshold would have left the single most common
   tablet orientation on the phone layout, which is exactly the bug being fixed. */
@media (min-width: 800px) {
  :root { --maxw: 960px; }

  /* Home becomes a two-column board. The page-level items (greeting, section heads,
     game grids) still span the full width; only the hero and the workout card pair
     up, because side by side they read as "pick one of these two ways to start". */
  #home-content {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: var(--space-6);
    align-content: start;
    /* Cards keep their natural height. Stretching the short hero card to match the
       tall workout card left a large empty void under "Play" and made the hero read
       as a broken/unfinished panel. */
    align-items: start;
  }
  #home-content > .topbar,
  #home-content > .greeting,
  #home-content > .h-title,
  #home-content > .streak-row,
  #home-content > .skills-card,
  #home-content > .cat-section { grid-column: 1 / -1; }
  #home-content > .hero-card    { grid-column: 1; margin-bottom: var(--space-6); }
  #home-content > .workout-card { grid-column: 2; }

  /* Profile: header and stats across the top, then two columns.
     Left  = skill levels + mastery badges (the visual, browsable stuff)
     Right = best scores + backup (the reference list and the utility)
     Each block is a <section> wrapping its own heading, so a heading can never be
     auto-placed into a different cell from the content it labels. */
  #profile-content {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: var(--space-6);
    align-content: start;
    align-items: start;
  }
  #profile-content > .game-head,
  #profile-content > .stat-grid,
  #profile-content > .app-version { grid-column: 1 / -1; }

  /* The wrappers stop being transparent and become the actual columns. */
  #profile-content > .prof-col {
    display: flex;
    flex-direction: column;
    min-width: 0;
  }
  #profile-content > .prof-col-a { grid-column: 1; }
  #profile-content > .prof-col-b { grid-column: 2; }

  /* The badge shelf is half as wide now, so drop it from 3 tiles across to 2 rather
     than letting the tiles shrink until the names truncate. */
  #profile-content .badge-shelf { grid-template-columns: repeat(2, 1fr); }

  /* Best Scores is the first thing in the right column and its heading carries a
     top margin meant to separate it from a block above. There is nothing above it
     here, so that margin would push the column out of alignment with the left one. */
  #profile-content > .prof-block-best > .sec-best { margin-top: 0 !important; }

  /* The intro hero is a full-bleed banner, so it spans; the ladder inside it now has
     room to show every rung of a 15-level game without scrolling. */
  .intro-levels { justify-content: center; }
}

/* Game tiles only go to 4 across once there is width to spare. At 800px a 4-column
   grid inside a two-column page gives ~175px cards, which squeezes the longer game
   names onto three lines. */
@media (min-width: 1000px) {
  .cat-grid, .cat-grid.solo { grid-template-columns: repeat(4, 1fr); }
}

/* ---- Large tablets and desktop (1200px+) ---- */
@media (min-width: 1200px) {
  :root { --maxw: 1120px; }
  .cat-grid, .cat-grid.solo { grid-template-columns: repeat(5, 1fr); }
}

/* The bottom nav is pinned and inherits --maxw, so on a tablet it would stretch into
   a 1120px-wide bar with two tiny icons marooned at the centre. Cap it and keep it
   centred: a thumb-reachable pill, not a full-width toolbar. */
@media (min-width: 800px) {
  #bottom-nav {
    max-width: 520px;
    left: 50%;
    transform: translateX(-50%);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  }
}

/* ---- Landscape / short viewports ----
   These 36 games are laid out for portrait. On a 412px-tall landscape phone most
   boards simply cannot fit, and shrinking the column further backfires: text
   wraps onto more lines and the content grows taller again (measured).

   So rather than pretend it fits, we make landscape reliably USABLE: the column
   is capped against the available height to shrink boards where that helps, the
   game screen scrolls when content is genuinely taller than the screen, and the
   header stays pinned so Back / pause / timer are always reachable. Nothing is
   ever clipped or unreachable. A proper per-game landscape layout is a separate
   piece of work. */
@media (orientation: landscape) and (max-height: 620px) {
  /* Keep the column at a phone-like width. Squeezing it against the viewport
     height sounded clever but backfired: at ~226px the header row could not fit
     and the Back button was crushed to 2px wide, and body text wrapped onto so
     many extra lines that total height grew rather than shrank. */
  :root { --maxw: 420px; }

  /* Header controls must never be compressed away. */
  #screen-game .game-head { flex-wrap: wrap; row-gap: 6px; }
  #screen-game .game-head > .back {
    flex: 0 0 auto;
    min-width: 40px;
    min-height: 40px;
  }

  /* The DOCUMENT is the scroller here. Do not make #screen-game a scroll
     container: it is not height-constrained, so it would never scroll itself and
     it would become the containing block for position:sticky, which stopped the
     header sticking at all. */

  /* Keep the controls reachable while scrolling. */
  #screen-game .game-head {
    position: sticky;
    top: 0;
    z-index: 30;
    background: linear-gradient(to bottom, var(--bg) 72%, transparent);
    padding-bottom: 6px;
  }

  /* Mild vertical tightening (aggressive squeezing made wrapping worse). */
  #screen-game .card { padding: 12px 14px; }

  /* Intro / pause overlays are position:absolute inset:0, i.e. anchored to the
     game stage. When the stage is taller than a short viewport they centre on the
     STAGE, pushing the card (and its Start button) below the fold. Anchor them to
     the viewport instead and let long text scroll inside the card. */
  .pause-overlay, .howto-overlay, .sig2-howto, .sig2-paused,
  .odd2-howto, .odd2-paused, #generic-howto, .cr-overlay {
    position: fixed;
    inset: 0;
  }
  .pause-card, .howto-card, .hn-howto-card, .modal-card, .cr-overlay > * {
    max-height: 84dvh;
    overflow-y: auto;
  }
}


/* Version footer at the bottom of Profile. Deliberately quiet - it exists so a bug
   report can say which build it came from, not to compete with the content. */
.app-version {
  margin: var(--space-6) 0 var(--space-4);
  text-align: center;
  font-size: 12px;
  line-height: 1.4;
  color: var(--text-muted);
  opacity: 0.85;
  letter-spacing: 0.01em;
}

/* ============================================================================
   Unlock / billing UI  (one-time purchase: levels 6-15)
   ==========================================================================*/

/* Locked rungs on the intro level ladder. Deliberately quieter than .is-ahead
   (which is a level you can reach) but still legible - a lock the player cannot
   read is just a gap in the ladder. */
.intro-lv-pip.is-locked {
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.16);
}
.intro-lv-pip.is-locked svg { opacity: 0.85; }

/* Inline CTA inside the ladder caption. The caption is uppercase 700 on the hero,
   so this matches it and reads as part of the sentence rather than a stray button. */
.ladder-unlock {
  display: inline-flex; align-items: center;
  padding: 3px var(--space-2);
  margin-left: 2px;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.92);
  color: var(--intro-accent-2, #1a120c);
  font: inherit; font-weight: 800;
  letter-spacing: 0.06em; text-transform: uppercase;
  cursor: pointer;
  transition: transform var(--t-fast) var(--ease-snap);
}
.ladder-unlock:active { transform: scale(0.95); }

/* ---------- The unlock sheet ---------- */
.unlock-backdrop {
  position: fixed; inset: 0; z-index: 1100;   /* above mastery-overlay's 1000 */
  display: flex; align-items: flex-end; justify-content: center;
  background: rgba(20, 12, 8, 0.62);
  backdrop-filter: blur(6px);
  animation: unlock-fade 220ms var(--ease-out) both;
}
@keyframes unlock-fade { from { opacity: 0; } to { opacity: 1; } }

.unlock-sheet {
  position: relative;
  width: 100%; max-width: var(--maxw-play, 480px);
  background: var(--surface);
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  box-shadow: var(--shadow-lg);
  padding: var(--space-8) var(--space-5) calc(var(--space-6) + env(safe-area-inset-bottom));
  text-align: center;
  animation: unlock-rise 320ms var(--ease-snap) both;
}
@keyframes unlock-rise { from { transform: translateY(24px); } to { transform: none; } }

/* Honour the OS setting - this sheet can appear right after a purchase, which is
   exactly when a motion-sensitive user least wants a surprise animation. */
@media (prefers-reduced-motion: reduce) {
  .unlock-backdrop, .unlock-sheet { animation: none; }
}

.unlock-close {
  position: absolute; top: var(--space-3); right: var(--space-3);
  width: 36px; height: 36px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface-2); color: var(--text-muted);
  cursor: pointer;
}
.unlock-icon { font-size: 34px; line-height: 1; margin-bottom: var(--space-3); }
.unlock-title {
  font-size: var(--text-xl); font-weight: 800; color: var(--text);
  margin-bottom: var(--space-2);
}
.unlock-sub {
  font-size: var(--text-sm); color: var(--text-muted);
  line-height: 1.5; margin-bottom: var(--space-5);
}
.unlock-points {
  text-align: left; margin: 0 auto var(--space-5);
  max-width: 300px; padding: 0; list-style: none;
}
.unlock-points li {
  position: relative; padding-left: var(--space-6);
  margin-bottom: var(--space-2);
  font-size: var(--text-sm); font-weight: 600; color: var(--text);
}
.unlock-points li::before {
  content: ""; position: absolute; left: 2px; top: 0.42em;
  width: 9px; height: 5px;
  border-left: 2.5px solid var(--accent);
  border-bottom: 2.5px solid var(--accent);
  transform: rotate(-45deg);
}
.unlock-priceline {
  font-size: var(--text-sm); color: var(--text-muted);
  margin-bottom: var(--space-4);
}
.unlock-price { font-weight: 800; color: var(--text); }
.unlock-buy {
  background: var(--primary); color: #fff; box-shadow: var(--shadow-md);
  margin-bottom: var(--space-2);
}
.unlock-buy:active { background: var(--primary-hover); }
.unlock-restore {
  width: 100%; min-height: 44px;
  font-size: var(--text-sm); font-weight: 700;
  color: var(--text-muted); cursor: pointer;
  background: none;
}
.unlock-note {
  font-size: var(--text-sm); color: var(--text-muted);
  line-height: 1.5; padding: var(--space-3) 0;
}

/* ---------- Toast for billing results ---------- */
.billing-toast {
  position: fixed; z-index: 1200;
  left: 50%; transform: translateX(-50%);
  bottom: calc(var(--space-8) + env(safe-area-inset-bottom));
  max-width: min(420px, calc(100vw - 32px));
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-full);
  background: rgba(20, 12, 8, 0.92); color: #fff;
  font-size: var(--text-sm); font-weight: 600; text-align: center;
  box-shadow: var(--shadow-lg);
  animation: unlock-fade 200ms var(--ease-out) both;
}
@media (prefers-reduced-motion: reduce) { .billing-toast { animation: none; } }

/* ---------- Level-up goal ---------- */
.intro-goal {
  margin-top: var(--space-2); padding: 0 20px;
  font-size: var(--text-xs); font-weight: 600;
  color: #fff; opacity: 0.85;
}
.intro-goal b { font-weight: 800; opacity: 1; }

.results-goal {
  margin-top: var(--space-2);
  font-size: var(--text-sm); font-weight: 700;
}
.results-goal.hit { color: var(--success); }
.results-goal.miss { color: var(--text-muted); }

/* ============================================================================
   Peripheral Vision (Attention)
   ==========================================================================*/
.pv-rules { text-align: center; padding: var(--space-6) var(--space-5); }
.pv-preview {
  display: flex; align-items: center; justify-content: center; gap: var(--space-4);
  margin-bottom: var(--space-5);
}
.pv-preview-card {
  width: 64px; height: 64px; border-radius: var(--radius-md);
  display: grid; place-items: center;
  background: var(--surface-2); box-shadow: var(--shadow-sm);
  font-size: var(--text-lg); font-weight: 800; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.pv-preview-dot { width: 14px; height: 14px; border-radius: 50%; background: var(--danger); }
.pv-rule-catch { margin-top: calc(var(--space-2) * -1); }

.pv-body { display: flex; flex-direction: column; }
.pv-timerbar {
  height: 6px; border-radius: var(--radius-full);
  background: rgba(0, 0, 0, 0.08); overflow: hidden; margin-bottom: var(--space-2);
}
.pv-timerfill {
  height: 100%; width: 100%; background: var(--primary);
  border-radius: var(--radius-full); transition: width 1s linear;
}
.pv-meta {
  display: flex; justify-content: space-between; align-items: center;
  font-size: var(--text-sm); font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.pv-meta .muted { color: var(--text-muted); font-weight: 600; }
.pv-low { color: var(--danger); }

.pv-banner {
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--accent-soft); color: var(--accent);
  font-size: var(--text-sm); font-weight: 800; text-align: center;
}

/* The stage is deliberately tall and empty. Nothing should sit near the dot and
   compete for the fixation the whole game depends on. */
/* Grows to fill whatever is left below the banner so the dot lands near the optical
   centre of the screen. A fixation target parked in the upper third is uncomfortable
   to hold for a 30-second session. */
.pv-stage {
  position: relative;
  flex: 1 1 auto;
  min-height: 220px;
  margin-top: var(--space-6);
}
.pv-body { min-height: 68vh; }
.pv-card {
  position: absolute; top: 50%; transform: translateY(-50%);
  /* Shrinks on narrow phones so there is room to push the cards outward. The JS
     clamp below still has the final say. */
  width: clamp(62px, 21vw, 88px);
  height: clamp(62px, 21vw, 88px);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  border: 1.5px solid var(--border);
  display: grid; place-items: center;
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast);
}
/* --pv-ecc is the gap from the centre line to the inner edge of each card, set per
   level. Bigger means the numbers land further into the periphery. */
.pv-card.pv-left  { right: calc(50% + var(--pv-ecc, 60px)); }
.pv-card.pv-right { left:  calc(50% + var(--pv-ecc, 60px)); }
.pv-num {
  font-size: var(--text-xl); font-weight: 800; color: var(--text);
  font-variant-numeric: tabular-nums; line-height: 1;
}
.pv-card.pv-correct { background: var(--success); border-color: var(--success); }
.pv-card.pv-correct .pv-num { color: #fff; }
.pv-card.pv-wrong { background: var(--danger); border-color: var(--danger); }
.pv-card.pv-wrong .pv-num { color: #fff; }

.pv-dot {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--danger);
  cursor: pointer;
  /* No transition on background: a catch trial has to appear instantly or the cue
     outlasts the flash and stops testing fixation. */
}
.pv-dot.pv-catch { background: #2f74d0; }
.pv-dot.pv-correct { box-shadow: 0 0 0 8px color-mix(in srgb, var(--success) 45%, transparent); }
.pv-dot.pv-wrong { box-shadow: 0 0 0 8px color-mix(in srgb, var(--danger) 45%, transparent); }

/* The dot is a 18px tap target, which is below the 44px minimum. Grow the touch area
   without growing the visible dot, or catch trials become a dexterity test. */
.pv-dot::after {
  content: ""; position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 48px; height: 48px; border-radius: 50%;
}

/* ---------------- Math Chain (mathchain) ---------------- */
.mc-body { display: flex; flex-direction: column; align-items: center; padding: 4px 16px 20px; }

.mc-progress {
  width: 100%; max-width: 420px; height: 8px; border-radius: 999px; margin-top: 6px;
  background: color-mix(in srgb, var(--text) 12%, transparent); overflow: hidden;
}
.mc-progress-fill {
  height: 100%; width: 0%; border-radius: 999px; background: var(--mathchain);
  transition: width .35s var(--ease-out);
}
.mc-round { align-self: flex-end; font-weight: 800; font-size: 1.25rem; color: var(--text); margin: 6px 2px 0; }
.mc-round span { font-size: 0.85rem; color: var(--text-soft); }

/* The stage keeps a fixed height so the board does not jump between a two-character
   token ("+2") and a three-character one ("\00d73"), or when it is briefly empty. */
.mc-stage {
  flex: 1 1 auto; width: 100%; min-height: 220px;
  display: flex; align-items: center; justify-content: center;
}
.mc-token {
  font-size: clamp(3.5rem, 2rem + 14vw, 6rem); font-weight: 800; line-height: 1;
  color: var(--text); font-variant-numeric: tabular-nums;
  animation: mc-pop .18s var(--ease-snap);
}
.mc-token.mc-op { color: var(--mathchain); }
@keyframes mc-pop { from { opacity: 0; transform: scale(.82); } to { opacity: 1; transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { .mc-token { animation: none; } }

.mc-ask { font-weight: 800; font-size: 1.15rem; color: var(--text); margin-bottom: 14px; text-align: center; }
.mc-ask[hidden] { display: none; }

.mc-options {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;
  width: 100%; max-width: 420px;
}
.mc-opt {
  border: 0; border-radius: var(--radius-lg); cursor: pointer;
  padding: 18px 4px; font-size: 1.5rem; font-weight: 800;
  font-variant-numeric: tabular-nums;
  background: color-mix(in srgb, var(--mathchain) 14%, var(--surface));
  color: var(--text);
  transition: transform .12s var(--ease-snap), background .15s ease;
}
.mc-opt:active { transform: scale(.95); }
.mc-opt.ok { background: var(--success); color: #fff; }
.mc-opt.bad { background: #e5352b; color: #fff; }
.mc-opt.reveal { background: var(--success); color: #fff; }

/* Four wide chips do not fit a narrow phone; drop to two rows instead of shrinking
   the digits to an unreadable size. */
@media (max-width: 360px) {
  .mc-options { grid-template-columns: repeat(2, 1fr); }
}

/* ---------------- Number Match (numbermatch) ---------------- */
.nm-body { display: flex; flex-direction: column; height: 100%; padding: 4px 10px 12px; }

.nm-hud { display: flex; align-items: center; justify-content: space-between; padding: 2px 4px; font-weight: 800; }
.nm-timer { color: var(--numbermatch); font-variant-numeric: tabular-nums; }
.nm-timer.low { color: #e5352b; }
.nm-left { color: var(--text-soft); font-size: 0.9rem; }
.nm-msg { min-height: 1.2em; text-align: center; font-weight: 700; font-size: 0.9rem; color: var(--text-soft); }

/* The board scrolls rather than shrinking. Nine columns of 9px digits is unreadable,
   and Add can make the grid taller than the screen by design. */
/* The padding is load-bearing, not decoration. A selected cell scales to 1.06 and a
   hinted cell draws a 2px outline, both of which paint OUTSIDE the cell box. This
   element scrolls, and a scroll container cannot have overflow-x: visible - CSS forces
   it to auto once the other axis is auto - so anything painted past the content edge is
   clipped. Without the padding the leftmost and rightmost columns had a visibly flat,
   shaved edge when selected: measured at 1.34px on a 390px phone. 6px clears the 1.34px
   of scale and the 2px outline with room to spare. */
.nm-boardwrap {
  flex: 1 1 auto; overflow-y: auto; overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  padding: 6px;
}
.nm-board {
  display: grid; grid-template-columns: repeat(var(--nm-cols, 9), 1fr);
  gap: 3px; width: 100%; max-width: 460px; margin: 0 auto;
}
.nm-cell {
  aspect-ratio: 1 / 1; border: 0; cursor: pointer; padding: 0;
  border-radius: 8px; font-weight: 700; line-height: 1;
  font-size: clamp(0.95rem, 0.4rem + 2.6vw, 1.4rem);
  font-variant-numeric: tabular-nums;
  background: var(--surface); color: var(--text);
  transition: transform .1s var(--ease-snap), background .15s ease;
}
.nm-cell.sel { background: var(--numbermatch); color: #fff; transform: scale(1.06); }
.nm-cell.hint { background: var(--numbermatch-soft); outline: 2px solid var(--numbermatch); }
.nm-cell.bad { background: #e5352b; color: #fff; }
/* A cleared cell keeps its slot so the grid geometry - and therefore every
   adjacency rule - stays intact. It must not be tappable or focusable. */
.nm-cell.gone { background: transparent; pointer-events: none; opacity: .18; }

.nm-tools { display: flex; gap: 10px; justify-content: center; padding-top: 10px; }
.nm-tool {
  position: relative; border: 0; cursor: pointer;
  padding: 12px 22px; border-radius: var(--radius-full);
  font-weight: 800; font-size: 0.95rem;
  background: color-mix(in srgb, var(--numbermatch) 16%, var(--surface));
  color: var(--text);
}
.nm-tool:disabled { opacity: .4; cursor: default; }
.nm-tool:not(:disabled):active { transform: scale(.96); }
.nm-badge {
  position: absolute; top: -6px; right: -6px; min-width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 5px; border-radius: 999px;
  background: var(--numbermatch); color: #fff; font-size: 0.7rem; font-weight: 800;
}

/* ========== Number Hunt (Speed) ========== */
.nh-body { display: flex; flex-direction: column; min-height: 0; }

.nh-prompt {
  text-align: center;
  font-size: 1.35rem;
  font-weight: 700;
  margin: 6px 0 8px;
  color: var(--text);
}
.nh-prompt b {
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
  color: var(--reaction);
}

/* The grid has to hold up to 6 x 12 cells of three-digit numbers on a 320px phone.
   Cell size is driven by the wrapper rather than by the font, and the font is then
   derived from the cell, so the tallest board shrinks to fit instead of pushing the
   page into a scroll. */
/* The grid is absolutely positioned inside this wrapper on purpose.

   The first attempt sized it with `aspect-ratio`, which derives HEIGHT from width - so a
   12-row board computed a height taller than the screen and pushed the page into a
   216px vertical scroll on a 320px phone. In a game where you scan for one odd cell,
   part of the board being below the fold is not a cosmetic problem: the target can be
   somewhere you cannot see.

   An absolutely positioned child contributes no intrinsic height, so the wrapper's
   height is whatever flex leaves over and nothing can push it. The grid then fills
   exactly that box, however many rows it has. */
.nh-gridwrap {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  padding: 2px 4px 6px;
}
.nh-grid {
  position: absolute;
  /* `justify-self: center` here made the box shrink-to-fit instead of spanning the
     insets, collapsing four columns into 17px each. Auto inline margins centre it
     without touching the used width. */
  top: 2px; bottom: 6px; left: 4px; right: 4px;
  width: auto;
  max-width: 520px;
  margin-inline: auto;
  display: grid;
  gap: 4px;
  grid-template-rows: repeat(var(--nh-rows, 8), minmax(0, 1fr));
}
.nh-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: var(--reaction-soft);
  color: var(--reaction);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  /* set from the measured cell by fitDigits(); the clamp is only a pre-layout fallback */
  font-size: var(--nh-font, clamp(11px, 3.6vw, 26px));
  line-height: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s ease, background .12s ease;
}
.nh-cell:active { transform: scale(.94); }

.nh-hit {
  background: var(--good, #3f9a4e) !important;
  color: #fff !important;
  transform: scale(1.08);
}
.nh-wrong {
  background: var(--bad, #d7392f) !important;
  color: #fff !important;
  animation: nh-shake .34s ease;
}
@keyframes nh-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-4px); }
  40% { transform: translateX(4px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(3px); }
}

/* intro preview strip */
.nh-preview {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  max-width: 190px;
  margin: 0 auto 14px;
}
.nh-preview span {
  padding: 8px 0;
  border-radius: 8px;
  background: var(--reaction-soft);
  color: var(--reaction);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.nh-preview-odd { outline: 2px solid var(--reaction); }
