@import "./fonts/fonts.css";

/* =============================================================================
   MOCHI — Visual System
   "Frosted luminous soft-sculpture gallery."
   The whole app's emotional state is carried by GLOW TEMPERATURE.
   Warm amber = excited (gameplay).  Cool jade, dimming to slate = quiet (focus).
   Nothing here shouts. Warmth is a feeling, not decoration.
   ========================================================================== */

/* ---------- 1. DESIGN TOKENS ---------- */
:root {
  /* Type */
  --font-display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --font-ui: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace;

  /* Warm greige surface palette (light / default) — calm, drawn from the
     M1 character's studio backdrop (#C5BBB2 family) rather than a cool grey. */
  --porcelain:   #E8E2D7;
  --porcelain-2: #DED7CA;
  --mist:        #D1C9BB;
  --surface:     rgba(249, 246, 240, 0.62);   /* translucent frosted card */
  --surface-2:   rgba(252, 250, 245, 0.72);
  --ink:         #2A2621;   /* primary text — warm charcoal */
  --ink-soft:    #5C544A;
  --ink-faint:   #8E8678;
  --line:        rgba(42, 38, 33, 0.09);
  --line-strong: rgba(42, 38, 33, 0.16);

  /* The glow engine — reassigned per mood (see §3) */
  --glow-warm:      #F0A860;   /* amber */
  --glow-warm-deep: #E4633A;   /* ember */
  --glow-cool:      #6FC9B0;   /* jade */
  --glow-cool-deep: #3F9E8C;

  /* Live mood variables — the scene + Mochi read from these. */
  --glow:        var(--glow-warm);        /* current accent */
  --glow-deep:   var(--glow-warm-deep);
  --glow-soft:   rgba(240, 168, 96, 0.30);
  --glow-rgb:    240, 168, 96;
  --aura-size:   62vmin;                  /* radius of the ambient light behind Mochi */
  --aura-alpha:  0.34;
  /* Off-white with a hint of sage. The two stops are deliberately spread so the
     #scene gradient reads as a soft luminous horizon, not a flat slab — and the
     faint green ground is restful while letting Mochi's warm aura pop. */
  --scene-bg-1:  #FAFBF6;                  /* near-white top (the horizon glow) */
  --scene-bg-2:  #E6E9DC;                  /* off-white + a whisper of sage below */
  --scene-ink:   var(--ink);
  --scene-ink-soft: var(--ink-soft);

  /* Spacing scale (4px base) */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px; --s-5: 20px;
  --s-6: 24px; --s-7: 32px; --s-8: 40px; --s-9: 48px; --s-10: 64px; --s-11: 88px;

  /* Radius — soft, organic, mochi-like */
  --r-sm: 10px; --r-md: 16px; --r-lg: 22px; --r-xl: 30px; --r-2xl: 40px;
  --r-pill: 999px;

  /* Shadow — diffuse and low-contrast (frosted), plus luminous glow shadows */
  --shadow-1: 0 1px 2px rgba(35,40,51,0.05), 0 4px 14px rgba(35,40,51,0.06);
  --shadow-2: 0 2px 6px rgba(35,40,51,0.06), 0 18px 40px rgba(35,40,51,0.10);
  --shadow-3: 0 8px 24px rgba(35,40,51,0.10), 0 30px 70px rgba(35,40,51,0.14);
  --shadow-inset: inset 0 1px 0 rgba(255,255,255,0.65);
  --shadow-glow: 0 0 60px var(--glow-soft);

  /* Frosted glass */
  --glass-bg: rgba(249, 246, 240, 0.55);
  --glass-blur: blur(20px) saturate(1.15);
  --card-blur: blur(14px) saturate(1.08);

  /* Motion */
  --ease-soft: cubic-bezier(0.33, 1, 0.68, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --dur-1: 0.18s; --dur-2: 0.35s; --dur-3: 0.6s;

  /* Layout */
  --shell-max: 720px;

  /* Fine film grain (inline SVG turbulence) so surfaces feel like material. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.35'/%3E%3C/svg%3E");
}

/* ---------- 1b. DARK THEME (opt-in via Settings) ----------
   A warm dark base; the mood engine still rides on top through the aura/glow.
   Surfaces stay translucent so the scene shows through. */
html[data-theme="dark"] {
  --porcelain: #2A2621; --porcelain-2: #332E28; --mist: #3C362E;
  --surface: rgba(255, 250, 242, 0.055); --surface-2: rgba(255, 250, 242, 0.085);
  --ink: #ECE6DB; --ink-soft: #B4AB9C; --ink-faint: #857C6D;
  --line: rgba(255, 250, 242, 0.10); --line-strong: rgba(255, 250, 242, 0.17);
  --scene-bg-1: #252C2C; --scene-bg-2: #171D1D;   /* soft blue-green charcoal — calmer at night than warm brown */
  --glass-bg: rgba(28, 25, 21, 0.5);
  --shadow-inset: inset 0 1px 0 rgba(255,255,255,0.05);
  --shadow-1: 0 1px 2px rgba(0,0,0,0.30), 0 4px 14px rgba(0,0,0,0.28);
  --shadow-2: 0 2px 6px rgba(0,0,0,0.32), 0 18px 40px rgba(0,0,0,0.40);
  --shadow-3: 0 8px 24px rgba(0,0,0,0.40), 0 30px 70px rgba(0,0,0,0.5);
}

/* ---------- 2. RESET / BASE ---------- */
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font-ui);
  font-size: 17px;
  line-height: 1.5;
  color: var(--scene-ink);
  background: var(--scene-bg-2);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  transition: color var(--dur-3) var(--ease-soft);
}
h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 500;
  font-optical-sizing: auto;
  letter-spacing: -0.01em;
  line-height: 1.12;
  margin: 0;
}
h1 { font-size: clamp(2rem, 6vw, 2.9rem); }
h2 { font-size: clamp(1.5rem, 4.5vw, 2rem); }
h3 { font-size: 1.2rem; letter-spacing: 0; }
p  { margin: 0; }
button { font-family: inherit; font-size: inherit; color: inherit; cursor: pointer; }
input, textarea { font-family: inherit; font-size: inherit; color: inherit; }
:focus-visible { outline: 2.5px solid var(--glow-deep); outline-offset: 3px; border-radius: 6px; }
::selection { background: var(--glow-soft); }

/* ---------- 3. THE SCENE / MOOD ENGINE ----------
   One element (#scene) holds the atmosphere. The whole app switches feeling by
   setting data-mood on <html>. Excited and quiet are clearly different, but the
   crossfade is slow (0.6s) so it never jars. */

#scene {
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(120vmax 90vmax at 50% 118%, var(--scene-bg-1), transparent 70%),
    linear-gradient(180deg, var(--scene-bg-1), var(--scene-bg-2));
  transition: background var(--dur-3) var(--ease-soft);
  overflow: hidden;
}
/* The aura: the soft pool of light Mochi casts. Its size + warmth = the mood. */
#scene::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 46%;
  width: var(--aura-size);
  height: var(--aura-size);
  transform: translate(-50%, -50%);
  background: radial-gradient(circle,
    rgba(var(--glow-rgb), var(--aura-alpha)) 0%,
    rgba(var(--glow-rgb), calc(var(--aura-alpha) * 0.35)) 34%,
    transparent 68%);
  filter: blur(8px);
  transition: all var(--dur-3) var(--ease-soft);
  animation: aura-breathe 7s var(--ease-soft) infinite;
}
/* Fine grain so surfaces read as material, not flat digital fills. */
#scene::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0.5;
  mix-blend-mode: soft-light;
  background-image: var(--grain);
  background-size: 180px 180px;
}
@keyframes aura-breathe {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50%      { transform: translate(-50%, -50%) scale(1.05); }
}

/* MOOD: EXCITED — gameplay & wins. Warmer, bigger aura, background lifts a touch. */
html[data-mood="excited"] {
  --glow: var(--glow-warm); --glow-deep: var(--glow-warm-deep);
  --glow-soft: rgba(240,168,96,0.36); --glow-rgb: 240,168,96;
  --aura-size: 82vmin; --aura-alpha: 0.44;   /* energy lives in the aura, not the bg */
}
/* MOOD: NEUTRAL — home / browsing. Balanced, calm-warm. (default tokens) */
html[data-mood="neutral"] {
  --glow: var(--glow-warm); --glow-deep: #D98A54;
  --glow-soft: rgba(240,168,96,0.22); --glow-rgb: 240,168,96;
  --aura-size: 56vmin; --aura-alpha: 0.24;
  /* base background comes from the theme (light/dark) */
}
/* MOOD: QUIET — focus companionship. Cool, dim, restrained. The room darkens
   to protect attention. This is a deliberately low-stimulation space. */
/* [data-theme] is always set (inline script), so this selector's specificity
   (0,2,1) reliably beats html[data-theme="dark"] (0,1,1) regardless of order —
   the focus room forces its dim palette in BOTH themes. */
html[data-mood="quiet"][data-theme] {
  --glow: var(--glow-cool); --glow-deep: var(--glow-cool-deep);
  --glow-soft: rgba(111,201,176,0.18); --glow-rgb: 111,201,176;
  --aura-size: 46vmin; --aura-alpha: 0.16;
  --scene-bg-1: #262B36; --scene-bg-2: #1B1F27;
  --scene-ink: #C9CDD6; --scene-ink-soft: #8A909C;
  --surface: rgba(255,255,255,0.05); --surface-2: rgba(255,255,255,0.07);
  --glass-bg: rgba(38,43,54,0.6); --line: rgba(255,255,255,0.10);
  --ink: #C9CDD6; --ink-soft: #9AA0AC; --ink-faint: #6C7280;
}
html[data-mood="quiet"] #scene::before { animation-duration: 11s; } /* slower breath */

/* ---------- 4. APP SHELL / LAYOUT ---------- */
#app {
  position: relative;
  min-height: 100%;
  max-width: var(--shell-max);
  margin: 0 auto;
  padding: max(var(--s-6), env(safe-area-inset-top)) var(--s-5) var(--s-11);
}
.view { animation: view-in var(--dur-3) var(--ease-soft) both; }
@keyframes view-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
.stack   { display: flex; flex-direction: column; }
.gap-2 { gap: var(--s-2); } .gap-3 { gap: var(--s-3); } .gap-4 { gap: var(--s-4); }
.gap-5 { gap: var(--s-5); } .gap-6 { gap: var(--s-6); } .gap-8 { gap: var(--s-8); }
.center { align-items: center; text-align: center; }
.row { display: flex; align-items: center; }
.row.wrap { flex-wrap: wrap; }
.spread { justify-content: space-between; }
.grow { flex: 1; }

.eyebrow {
  font-family: var(--font-ui);
  font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-faint);
}
.lead { font-size: 1.06rem; color: var(--ink-soft); max-width: 40ch; }
.muted { color: var(--ink-soft); }
.faint { color: var(--ink-faint); }
.serif { font-family: var(--font-display); }

/* ---------- 5. BUTTONS ---------- */
.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  padding: var(--s-4) var(--s-6);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink);
  font-weight: 500;
  box-shadow: var(--shadow-1), var(--shadow-inset);
  transition: transform var(--dur-1) var(--ease-spring),
              box-shadow var(--dur-2) var(--ease-soft),
              background var(--dur-2) var(--ease-soft);
}
.btn:hover  { transform: translateY(-2px); box-shadow: var(--shadow-2), var(--shadow-inset); }
.btn:active { transform: translateY(0) scale(0.98); }
.btn-glow {
  border-color: transparent;
  background:
    linear-gradient(var(--surface), var(--surface)) padding-box,
    linear-gradient(140deg, var(--glow), var(--glow-deep)) border-box;
  color: var(--ink);
  box-shadow: var(--shadow-2), var(--shadow-glow), var(--shadow-inset);
}
.btn-glow::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: radial-gradient(80% 120% at 50% 0%, rgba(var(--glow-rgb),0.16), transparent 70%);
}
.btn-ghost { background: transparent; box-shadow: none; border-color: var(--line-strong); }
.btn-ghost:hover { background: rgba(var(--glow-rgb), 0.06); box-shadow: none; }
.btn-plain { background: transparent; border: none; box-shadow: none; padding: var(--s-2) var(--s-3); color: var(--ink-soft); }
.btn-plain:hover { color: var(--ink); transform: none; box-shadow: none; }
.btn-lg { padding: var(--s-5) var(--s-7); font-size: 1.08rem; }
.btn-block { width: 100%; }
.btn-icon { padding: var(--s-3); width: 44px; height: 44px; border-radius: var(--r-pill); }

/* ---------- 6. CARDS / SURFACES ---------- */
.card {
  position: relative;
  background: var(--surface);
  -webkit-backdrop-filter: var(--card-blur);
  backdrop-filter: var(--card-blur);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: var(--s-6);
  box-shadow: var(--shadow-1), var(--shadow-inset);
  transition: transform var(--dur-2) var(--ease-soft),
              box-shadow var(--dur-2) var(--ease-soft);
}
.card-hover { cursor: pointer; }
.card-hover:hover { transform: translateY(-3px); box-shadow: var(--shadow-2), var(--shadow-inset); }
.card-hover:hover .card-arrow { transform: translateX(4px); opacity: 1; }
.card-arrow { transition: transform var(--dur-2) var(--ease-spring); opacity: 0.5; color: var(--glow-deep); }
.glass {
  background: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
}
.divider { height: 1px; background: var(--line); border: none; margin: var(--s-5) 0; }

/* ---------- 7. THREE-OPTION DECISION BLOCK ----------
   Every keep-going / stop choice uses this. All options share identical
   visual weight — same size, same treatment, same warmth. None is styled as
   the "primary" or "correct" one. This is a hard design rule. */
.choices { display: grid; gap: var(--s-3); }
.choice {
  display: flex; align-items: flex-start; gap: var(--s-4);
  width: 100%; text-align: left;
  padding: var(--s-5);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-1), var(--shadow-inset);
  transition: transform var(--dur-1) var(--ease-spring),
              box-shadow var(--dur-2) var(--ease-soft),
              border-color var(--dur-2) var(--ease-soft);
}
.choice:hover { transform: translateY(-2px); border-color: var(--glow); box-shadow: var(--shadow-2), var(--shadow-inset); }
.choice:active { transform: scale(0.99); }
.choice-dot {
  flex: none; width: 12px; height: 12px; margin-top: 6px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff6, transparent 60%), var(--glow);
  box-shadow: 0 0 10px var(--glow-soft);
}
.choice-title { font-weight: 600; }
.choice-sub { color: var(--ink-soft); font-size: 0.94rem; margin-top: 2px; }

/* ---------- 8. FIELDS ---------- */
.field {
  width: 100%;
  padding: var(--s-4) var(--s-5);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  background: var(--surface-2);
  box-shadow: var(--shadow-inset);
  transition: border-color var(--dur-2) var(--ease-soft), box-shadow var(--dur-2) var(--ease-soft);
  resize: none;
}
.field::placeholder { color: var(--ink-faint); }
.field:focus { outline: none; border-color: var(--glow); box-shadow: 0 0 0 4px var(--glow-soft); }

/* ---------- 9. MOCHI CHARACTER (raster sprite, shapeshifting) ---------- */
.mochi { position: relative; display: inline-block; will-change: transform; touch-action: manipulation; }
.mochi-wrap { display: flex; justify-content: center; }
.mochi-sprite {
  display: block; width: 100%; height: 100%; object-fit: contain;
  transform-origin: 50% 92%;
  transition: opacity var(--dur-2) var(--ease-soft);
  filter: drop-shadow(0 6px 16px rgba(35,40,51,0.12));
  -webkit-user-drag: none; user-select: none; -webkit-user-select: none;
}
/* breathing scale loop lives on the sprite */
@keyframes mochi-breathe {
  0%, 100% { transform: scale(1, 1) translateY(0); }
  50%      { transform: scale(1.03, 0.975) translateY(1.5%); }
}
.mochi-sprite { animation: mochi-breathe 4.6s var(--ease-soft) infinite; }
html[data-mood="quiet"] .mochi-sprite { animation-duration: 7.6s; } /* calmer breath in focus */
html[data-reduce-motion="true"] .mochi-sprite { animation: none; }

/* morph: quick squash while the src swaps, then spring back (gooey feel) */
.mochi.is-morphing .mochi-sprite { animation: none; transform: scale(1.16, 0.82); transition: transform 0.16s var(--ease-soft); }
/* "blink": a fast eye-height-ish squash of the whole sprite */
.mochi.is-blinking .mochi-sprite { animation: none; transform: scale(1.01, 0.94); transition: transform 0.11s ease; }
/* poke squish */
.mochi.is-poked .mochi-sprite { animation: none; transform: scale(1.22, 0.72); transition: transform 0.12s var(--ease-soft); }
/* happy hop */
@keyframes mochi-hop {
  0% { transform: translateY(0) scale(1,1); }
  28% { transform: translateY(-16%) scale(0.94, 1.06); }
  55% { transform: translateY(0) scale(1.08, 0.90); }
  75% { transform: translateY(-5%) scale(0.98,1.02); }
  100% { transform: translateY(0) scale(1,1); }
}
.mochi.is-happy .mochi-sprite { animation: mochi-hop 0.72s var(--ease-spring); }
/* playful wobble */
@keyframes mochi-wobble {
  0%,100% { transform: rotate(0deg); } 25% { transform: rotate(-5deg) scale(1.02,0.98); }
  60% { transform: rotate(4deg); } 80% { transform: rotate(-2deg); }
}
.mochi.is-playful .mochi-sprite { animation: mochi-wobble 0.8s var(--ease-soft); }
/* soft coloured light Mochi casts, tinted by mood */
.mochi-halo {
  position: absolute; left: 50%; top: 52%; width: 116%; aspect-ratio: 1;
  transform: translate(-50%, -50%); z-index: -1; pointer-events: none;
  background: radial-gradient(circle, rgba(var(--glow-rgb), 0.30), transparent 66%);
  filter: blur(6px); transition: background var(--dur-3) var(--ease-soft);
  animation: aura-breathe 6s var(--ease-soft) infinite;
}

/* floating motes around Mochi when excited */
.motes { position: absolute; inset: -10% -10% 0 -10%; pointer-events: none; overflow: visible; }
.mote {
  position: absolute; width: 6px; height: 6px; border-radius: 50%;
  background: radial-gradient(circle, #fff, var(--glow));
  box-shadow: 0 0 8px var(--glow);
  opacity: 0; animation: mote-rise 3.2s var(--ease-soft) infinite;
}
@keyframes mote-rise {
  0% { opacity: 0; transform: translateY(10px) scale(0.6); }
  20% { opacity: 0.9; }
  100% { opacity: 0; transform: translateY(-60px) scale(1); }
}

/* ---------- 10. SCORES / TIMERS (mono, tabular) ---------- */
.stat { font-family: var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.stat-xl { font-size: clamp(2.6rem, 12vw, 4.4rem); font-weight: 500; line-height: 1; }
.stat-lg { font-size: 2rem; }
.pill {
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-4); border-radius: var(--r-pill);
  background: rgba(var(--glow-rgb), 0.12); color: var(--glow-deep);
  font-size: 0.85rem; font-weight: 600;
}
.badge-best {
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-4); border-radius: var(--r-pill);
  background: linear-gradient(135deg, var(--glow), var(--glow-deep));
  color: #fff; font-weight: 600; box-shadow: var(--shadow-glow);
}

/* ---------- 11. TOP BAR ---------- */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--s-6);
}
.brand { display: flex; align-items: center; gap: var(--s-3); font-family: var(--font-display); font-size: 1.15rem; }
/* Compact language switch on Home (EN / 中). Small, tappable, clearly a toggle. */
.lang-seg { display: inline-flex; padding: 3px; border-radius: var(--r-pill);
  background: var(--surface-2); border: 1px solid var(--line); gap: 2px;
  box-shadow: var(--shadow-1); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.lang-seg button { min-width: 34px; padding: 5px 11px; border: none; border-radius: var(--r-pill);
  background: transparent; color: var(--ink-faint); font-weight: 700; font-size: 0.86rem;
  cursor: pointer; transition: all var(--dur-1); line-height: 1.2; }
.lang-seg button[aria-pressed="true"] { background: var(--glow); color: #3a2410; box-shadow: var(--shadow-1); }
.lang-seg button:not([aria-pressed="true"]):hover { color: var(--ink); }
.lang-seg button:focus-visible { outline: 2px solid var(--glow-deep); outline-offset: 2px; }
.brand .dot { width: 26px; height: 26px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff8, transparent 55%), linear-gradient(140deg, var(--glow), var(--glow-deep));
  box-shadow: 0 0 14px var(--glow-soft); }

/* ---------- 12. GAME BOARD ---------- */
.board {
  position: relative;
  min-height: 46vh;
  display: flex; align-items: center; justify-content: center;
  padding: var(--s-6);
  border-radius: var(--r-2xl);
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-2), var(--shadow-inset);
  overflow: hidden;
}
.count-ring { display: grid; place-items: center; }
/* game library icon — bespoke rounded app-icon tile (distinct colour per game) */
.game-icon { width: 68px; height: 68px; flex: none; object-fit: cover;
  border-radius: 18px; box-shadow: 0 2px 6px rgba(35,40,51,0.12), 0 8px 20px rgba(35,40,51,0.12); }
/* in-game sushi token (image) sits on the plate */
.plate img.token { width: 62%; height: 62%; object-fit: contain;
  filter: drop-shadow(0 6px 10px rgba(35,40,51,0.14)); }
.fish img.token { width: 1em; height: 1em; object-fit: contain; vertical-align: middle; }

/* rule banner — always-visible how-to-play atop every game */
.rule-banner { align-self: center; text-align: center; font-size: 0.9rem; color: var(--ink-soft);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: var(--s-2) var(--s-5); max-width: 42ch; box-shadow: var(--shadow-1); }
.rule-banner:empty { display: none; }

.pill-quiet { background: var(--porcelain-2); color: var(--ink-soft); }
/* the level pill gives a quick bump when Sushi Memory changes level */
.pill.bump { animation: pill-bump 0.5s var(--ease-spring); }
@keyframes pill-bump { 0%,100% { transform: scale(1); } 40% { transform: scale(1.18); } }

/* button press feedback — taps clearly register */
.btn:active { transform: scale(0.96); }
.btn-glow:active, .btn-answer:active, .bin:active { box-shadow: var(--shadow-1), 0 0 0 5px var(--glow-soft); }
.btn.pressed { transform: scale(0.95); box-shadow: var(--shadow-1), 0 0 0 5px var(--glow-soft); }

/* right / wrong feedback lives ON the button: solid green / red fill (+ shake
   + haptic on wrong). background-image:none beats the .btn-glow gradient so the
   colour actually shows; the class is removed after ~480ms and transitions back. */
.btn.correct, .bin.correct, .gng-light.correct {
  background: #5FC4AA !important; background-image: none !important;
  border-color: #43A88C !important; color: #0E4034 !important;
  box-shadow: 0 0 0 4px rgba(95,196,170,0.42), var(--shadow-2) !important;
}
.btn.wrong, .bin.wrong, .gng-light.wrong {
  background: #E0413A !important; background-image: none !important;
  border-color: #BE2E28 !important; color: #fff !important;
  box-shadow: 0 0 0 4px rgba(224,65,58,0.42), var(--shadow-2) !important;
  animation: fb-shake 0.4s var(--ease-soft);
}
.btn.correct::after, .btn.wrong::after { display: none; }
@keyframes fb-shake {
  0%,100% { transform: translateX(0); }
  20% { transform: translateX(-7px); } 40% { transform: translateX(7px); }
  60% { transform: translateX(-5px); } 80% { transform: translateX(4px); }
}
.game-hud { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--s-4); }

/* Sushi plate */
.plate { width: min(58vw, 260px); aspect-ratio: 1; border-radius: 50%;
  display: grid; place-items: center; font-size: 4rem;
  background: radial-gradient(circle at 40% 32%, #fff, var(--porcelain-2));
  border: 1px solid var(--line); box-shadow: var(--shadow-2), inset 0 -8px 20px rgba(35,40,51,0.06);
  transition: transform var(--dur-2) var(--ease-spring), opacity var(--dur-2);
}
.plate.enter { animation: plate-in 0.32s var(--ease-spring); }
@keyframes plate-in { from { transform: translateX(40px) scale(0.9); opacity: 0; } to { transform: none; opacity: 1; } }

/* Flanker fish row */
.fish-row { display: flex; gap: var(--s-4); align-items: center; font-size: clamp(2.4rem, 12vw, 4rem); }
.fish { transition: transform 0.12s; }
.fish.mid { filter: drop-shadow(0 0 18px var(--glow-soft)); }
.flip { transform: scaleX(-1); }

/* Firefly */
.firefly {
  width: min(64vw, 300px); aspect-ratio: 1; border-radius: 50%;
  display: grid; place-items: center; transition: all 0.15s;
  background: radial-gradient(circle, #2a2f3a, #1c202a);
  color: #6c7280;
}
.firefly.lit {
  background: radial-gradient(circle, #fff, var(--glow) 45%, var(--glow-deep));
  box-shadow: 0 0 80px var(--glow), inset 0 0 40px #fff8; color: #4a2d12;
}

/* Space Customs traveler */
.traveler { width: min(40vw, 138px); aspect-ratio: 1; display: grid; place-items: center;
  border-radius: var(--r-lg); background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--shadow-2), var(--shadow-inset); }
.rule-sign { display: inline-flex; align-items: center; gap: var(--s-2);
  padding: var(--s-3) var(--s-5); border-radius: var(--r-pill);
  background: var(--ink); color: var(--surface-2); font-weight: 700; letter-spacing: 0.06em; }
html[data-mood] .rule-sign { background: var(--glow-deep); color: #fff; }
.bins { display: flex; gap: var(--s-4); width: 100%; }
.bin { flex: 1; padding: var(--s-4) var(--s-3) var(--s-5); border-radius: var(--r-lg);
  border: 2px dashed var(--line-strong); background: var(--surface-2);
  display: flex; flex-direction: column; align-items: center; gap: var(--s-2);
  transition: all var(--dur-1); cursor: pointer; }
.bin:hover { border-color: var(--glow); background: rgba(var(--glow-rgb),0.08); transform: translateY(-2px); }
.bin-accepts { font-size: 0.6rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-faint); }
.bin-label { font-weight: 700; }
.bin-badge { height: 46px; display: grid; place-items: center; }
.cdot { width: 34px; height: 34px; border-radius: 50%;
  box-shadow: inset 0 -4px 8px rgba(0,0,0,0.16), 0 2px 6px rgba(0,0,0,0.12); }
.smark { font-size: 2.1rem; line-height: 1; color: var(--ink-soft); }

/* feedback flashes */
.flash { position: absolute; inset: 0; pointer-events: none; opacity: 0; border-radius: inherit; }
.flash.good { background: radial-gradient(circle at 50% 50%, rgba(var(--glow-rgb),0.25), transparent 70%); animation: flash 0.4s; }
.flash.bad  { background: radial-gradient(circle at 50% 50%, rgba(228,99,58,0.16), transparent 70%); animation: flash 0.4s; }
@keyframes flash { 0% { opacity: 1; } 100% { opacity: 0; } }

/* ---------- 13. FOCUS TIMER (QUIET ZONE) ----------
   Deliberately spartan. No progress celebration, no color rewards, no numbers
   that climb. Just a soft ring winding down and Mochi keeping still. */
.focus-stage { min-height: 70vh; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-7); }
.focus-ring { --p: 0; width: min(70vw, 300px); aspect-ratio: 1; border-radius: 50%;
  display: grid; place-items: center; position: relative; }
.focus-ring svg { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.focus-ring .track { fill: none; stroke: var(--line); stroke-width: 3; }
.focus-ring .prog  { fill: none; stroke: var(--glow); stroke-width: 3; stroke-linecap: round;
  transition: stroke-dashoffset 1s linear; filter: drop-shadow(0 0 6px var(--glow-soft)); }
.focus-time { font-family: var(--font-mono); font-size: 2.4rem; font-variant-numeric: tabular-nums; color: var(--scene-ink); opacity: 0.9; }
.focus-move { color: var(--scene-ink-soft); font-size: 0.95rem; text-align: center; max-width: 34ch; }
.focus-say { color: var(--scene-ink-soft); font-family: var(--font-display); font-style: italic; }

/* ---------- 14. FIDGET ---------- */
.fidget-stage { min-height: 60vh; border-radius: var(--r-2xl); overflow: hidden; position: relative;
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-2), var(--shadow-inset); }
.fidget-tabs { display: flex; gap: var(--s-2); justify-content: center; margin: var(--s-4) 0; }
.tab { padding: var(--s-2) var(--s-5); border-radius: var(--r-pill); border: 1px solid var(--line);
  background: var(--surface); font-weight: 500; transition: all var(--dur-1); }
.tab.active { background: var(--glow); color: #3a2410; border-color: transparent; box-shadow: var(--shadow-glow); }
.bubble { position: absolute; border-radius: 50%; cursor: pointer;
  background: radial-gradient(circle at 35% 30%, #fff9, transparent 55%), var(--glow);
  box-shadow: var(--shadow-1); transition: transform 0.12s var(--ease-spring); }
.bubble.popped { animation: pop 0.28s var(--ease-spring) forwards; }
@keyframes pop { 60% { transform: scale(1.35); opacity: 0.5; } 100% { transform: scale(0.2); opacity: 0; } }

/* ---------- 15. MISC ---------- */
.list-link { display: flex; align-items: center; justify-content: space-between;
  padding: var(--s-4) var(--s-5); border-radius: var(--r-lg); background: var(--surface);
  border: 1px solid var(--line); box-shadow: var(--shadow-1); transition: all var(--dur-1); }
.list-link:hover { transform: translateX(2px); box-shadow: var(--shadow-2); }
.toggle { position: relative; width: 50px; height: 30px; border-radius: var(--r-pill);
  background: var(--mist); border: none; transition: background var(--dur-2); flex: none; box-shadow: var(--shadow-inset); }
.toggle::after { content: ""; position: absolute; top: 3px; left: 3px; width: 24px; height: 24px; border-radius: 50%;
  background: #fff; box-shadow: var(--shadow-1); transition: transform var(--dur-2) var(--ease-spring); }
.toggle[aria-checked="true"] { background: var(--glow); }
.toggle[aria-checked="true"]::after { transform: translateX(20px); }
.seg { display: inline-flex; padding: 3px; border-radius: var(--r-pill); background: var(--porcelain-2); gap: 2px; max-width: 100%; }
.seg button { padding: var(--s-2) var(--s-4); border-radius: var(--r-pill); border: none; background: transparent; font-weight: 500; color: var(--ink-soft); transition: all var(--dur-1); white-space: nowrap; }
.seg button[aria-pressed="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-1); }
/* full-width segmented control (used for wide options like intensity/language) */
.seg.full { display: flex; width: 100%; }
.seg.full button { flex: 1; text-align: center; padding: var(--s-3) var(--s-2); font-size: 0.92rem; }

.toast { position: fixed; left: 50%; bottom: calc(var(--s-8) + env(safe-area-inset-bottom));
  transform: translateX(-50%) translateY(20px); z-index: 50;
  padding: var(--s-3) var(--s-5); border-radius: var(--r-pill);
  background: var(--ink); color: var(--surface-2); box-shadow: var(--shadow-3);
  opacity: 0; transition: all var(--dur-2) var(--ease-spring); font-size: 0.92rem; pointer-events: none; }
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* Bottom nav */
.tabbar { position: fixed; left: 50%; transform: translateX(-50%); bottom: calc(var(--s-4) + env(safe-area-inset-bottom));
  z-index: 40; display: flex; gap: var(--s-1); padding: var(--s-2);
  border-radius: var(--r-pill); background: var(--glass-bg); border: 1px solid var(--line);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); box-shadow: var(--shadow-3); }
.tabbar.hidden { opacity: 0; pointer-events: none; transform: translateX(-50%) translateY(20px); }
.tabbar button { display: grid; place-items: center; width: 52px; height: 44px; gap: 2px; border: none; background: transparent;
  border-radius: var(--r-pill); color: var(--ink-faint); font-size: 0.62rem; font-weight: 600; transition: all var(--dur-1); }
.tabbar button.active { color: var(--glow-deep); background: rgba(var(--glow-rgb), 0.12); }
.tabbar button svg { width: 22px; height: 22px; }

.progress-dots { display: flex; gap: var(--s-2); justify-content: center; }
.progress-dots span { width: 7px; height: 7px; border-radius: 50%; background: var(--line-strong); transition: all var(--dur-2); }
.progress-dots span.on { background: var(--glow); width: 22px; border-radius: var(--r-pill); }

/* ---------- 15b. NEW GAMES (concepts 5–11) + difficulty + result ---------- */
/* difficulty rating dots + tag */
.diff-dots { display: inline-flex; gap: 3px; }
.diff-dots span { width: 7px; height: 7px; border-radius: 50%; background: var(--line-strong); }
.diff-dots span.on { background: var(--glow-deep); }
.diff-tag { display: inline-flex; align-items: center; gap: 8px; font-size: 0.8rem; font-weight: 600; color: var(--ink-soft); white-space: nowrap; flex: none; }
.diff-tag.calm { padding: 3px 11px; border-radius: var(--r-pill); color: var(--glow-cool-deep); background: rgba(111,201,176,0.16); }
.reflink { display: inline-block; align-self: flex-start; margin-top: 2px; padding: 8px 15px; border-radius: var(--r-pill);
  background: rgba(var(--glow-rgb), 0.15); color: var(--glow-deep); font-weight: 600; font-size: 0.9rem; text-decoration: none; }
.reflink:hover { background: rgba(var(--glow-rgb), 0.24); }

/* Go/No-Go light */
.gng-light { width: min(58vw, 220px); aspect-ratio: 1; border-radius: 50%; border: none; cursor: pointer;
  font-family: var(--font-display); font-weight: 600; font-size: 2rem; color: #fff; background: var(--mist);
  box-shadow: var(--shadow-2), inset 0 -10px 24px rgba(0,0,0,0.12); transition: transform .1s var(--ease-soft); }
.gng-light:active { transform: scale(0.96); }
.gng-light.go { background: radial-gradient(circle at 40% 34%, #82E3C4, #3FA189); }
.gng-light.stop { background: radial-gradient(circle at 40% 34%, #F0937A, #DE3E37); }

/* Stop-Signal arrow + flanker row */
.ss-arrow { width: min(56vw, 200px); aspect-ratio: 1; border-radius: var(--r-2xl); display: grid; place-items: center;
  font-size: 4.6rem; font-weight: 700; color: var(--ink); background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--shadow-2), var(--shadow-inset); font-family: var(--font-display); }
/* the flanker variant is a wide, short box that fits five arrows in a row */
.ss-arrow.flank { width: min(88vw, 340px); aspect-ratio: auto; min-height: 148px; padding: 0 14px; }
.ss-flankers { display: flex; gap: clamp(6px, 2.4vw, 14px); align-items: center; justify-content: center; }
.ss-glyph { font-size: clamp(1.9rem, 8.5vw, 3rem); font-weight: 700; line-height: 1; color: var(--ink); }
.ss-glyph.center { position: relative; }
.ss-glyph.center::after { content: ""; position: absolute; left: 12%; right: 12%; bottom: -11px;
  height: 3px; border-radius: 2px; background: var(--glow-deep); opacity: 0.7; }  /* marks WHICH is the middle, not its direction */
.ss-brake-label { display: none; font-size: 1.7rem; font-weight: 700; letter-spacing: 0.04em; font-family: var(--font-display); }
.ss-arrow.stop { background: #E0413A; color: #fff; border-color: #BE2E28; }
.ss-arrow.stop .ss-flankers { display: none; }
.ss-arrow.stop .ss-brake-label { display: block; }
/* a successful stop shows NO green confirmation — a withheld tap is its own reward */

/* CPT-AX radar */
.cpt-scope { width: min(64vw, 260px); aspect-ratio: 1; border-radius: 50%; display: grid; place-items: center;
  background: radial-gradient(circle, rgba(111,201,176,0.14), transparent 70%), #23282f;
  border: 2px solid rgba(111,201,176,0.4); box-shadow: inset 0 0 40px rgba(111,201,176,0.15); }
/* Every shape is the SAME colour — the target ✦ must be found by its shape,
   not a colour tell, or the vigilance challenge collapses into pop-out search. */
.cpt-blip { font-size: 4.4rem; color: #9FE3CE; opacity: 0; transform: scale(0.7); }
.cpt-blip.show { animation: blip-in 0.18s var(--ease-spring) forwards; }
@keyframes blip-in { to { opacity: 1; transform: scale(1); } }

/* Stroop */
.stroop-word { font-family: var(--font-display); font-weight: 600; font-size: clamp(3rem, 14vw, 5rem); letter-spacing: 0.02em; }
.stroop-word.enter { animation: plate-in 0.2s var(--ease-spring); }
.stroop-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-3); }
.stroop-btn { font-weight: 700; }

/* Trail Making */
.trails-stage { position: relative; width: 100%; height: 56vh; min-height: 340px; }
.trails-lines { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.trails-lines line { stroke: var(--glow); stroke-width: 3; stroke-linecap: round; opacity: 0.85; }
.trail-node { position: absolute; transform: translate(-50%, -50%); width: 48px; height: 48px; border-radius: 50%;
  border: 2px solid var(--line-strong); background: var(--surface-2); color: var(--ink); font-weight: 700; font-family: var(--font-mono);
  box-shadow: var(--shadow-1); cursor: pointer; transition: border-color .1s, transform .1s; }
.trail-node:hover { border-color: var(--glow); }
.trail-node.done { background: var(--glow); color: #3a2410; border-color: transparent; box-shadow: var(--shadow-glow); }
.trail-node.slip { animation: fb-shake 0.35s; border-color: #E0413A; }

/* Breathe with Mochi (calm interlude) */
.breath-stage { display: grid; place-items: center; height: 38vh; min-height: 230px; }
.breath-stage.calm { position: relative; }
.breath-stage.calm::before { content: ""; position: absolute; width: 62%; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle, rgba(111,201,176,0.42), transparent 68%); filter: blur(6px); }
.breath-mochi { position: relative; width: min(52vw, 210px); height: auto; user-select: none;
  filter: drop-shadow(0 8px 30px rgba(111,201,176,0.5)); will-change: transform; transform-origin: center 62%; }
.breath-cue { font-family: var(--font-display); font-style: italic; font-size: 1.3rem; color: var(--ink-soft); }

/* PASAT */
.pasat-num { font-family: var(--font-mono); font-weight: 600; font-size: clamp(4rem, 20vw, 7rem); line-height: 1; color: var(--ink); }
.pasat-num.enter { animation: plate-in 0.2s var(--ease-spring); }
.pasat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s-3); }

/* ---------- 16. ACCESSIBILITY ---------- */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; }
/* Reduce motion: the manual toggle and the OS preference each need their OWN
   valid rule — a selector list can't contain an @media, which silently voided
   the whole thing before (so the toggle appeared to do nothing). */
html[data-reduce-motion="true"] * {
  animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.08s !important;
}
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.08s !important; }
}
