/* ─────────────────────────────────────────────────────────────
   Mirror maze — styles
   Fonts + design tokens (baked in from ../design-system/tokens/*)
   + all UI chrome. The p5 canvas itself is unstyled beyond sizing;
   everything drawn on it is handled in game.js.
   ───────────────────────────────────────────────────────────── */

/* ── Fonts (shipped inside the folder — no network) ── */
@font-face {
  font-family: 'GT Walsheim';
  src: url('assets/fonts/GT-Walsheim-Regular.otf') format('opentype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'GT Walsheim';
  src: url('assets/fonts/GT-Walsheim-Medium.otf') format('opentype');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'GT Walsheim';
  src: url('assets/fonts/GT-Walsheim-Bold.otf') format('opentype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'GT Walsheim';
  src: url('assets/fonts/GT-Walsheim-Ultra-Bold.otf') format('opentype');
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('assets/fonts/inter-var-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ── Brand / logo colours ── */
  --brand-blue:   #38C3E4;
  --brand-orange: #FF8A20;
  --brand-pink:   #FC74B4;
  --brand-yellow: #FFD401;
  --brand-red:    #E83459;
  --brand-green:  #45BA90;

  /* ── Purple ramp ── */
  --purple-900: #300028;
  --purple-800: #401E50;
  --purple-700: #4B235D;
  --purple-600: #5D2E73;
  --purple-500: #7A4A92;
  --purple-300: #B79CC8;
  --purple-100: #EDE4F2;
  --purple-50:  #F6F1F9;

  /* ── Ink ramp ── */
  --ink-900: #1C1726;
  --ink-700: #3A3447;
  --ink-600: #5D5670;
  --ink-400: #938DA3;
  --ink-200: #E8E4EE;
  --ink-100: #F2EFF6;
  --white:   #FFFFFF;

  /* ── Dark plum theme (matches examples.fruit3d.com/exploding-dots) ── */
  --plum:       #2B0326;  /* page background + header/footer bars */
  --card:       #3a0a33;  /* pop-up cards / dark panels */
  --card-inset: #4a133f;  /* nested surfaces (tray cards, speech, quiz tiles) */
  --line-dark:  #5a1a4f;  /* plum hairline borders */
  --nav:        #A1FCD2;  /* navigation / primary buttons (mint / "lime") */
  --nav-dark:   #6fcea3;  /* mint button shadow / hover */

  /* ── Surfaces / text (light copy on the dark plum ground) ── */
  --surface-cream:  var(--card);
  --border-cream:   var(--line-dark);
  --text-strong:    #FFFFFF;
  --text-body:      #FFFFFF;
  --text-soft:      rgba(248, 244, 241, .68);
  --text-faint:     rgba(248, 244, 241, .5);

  /* ── Game-world palette (deep aubergine, never pure black) ── */
  --sb-room-1:      #3B1546;   /* room fill, lighter mid */
  --sb-room-2:      #260921;   /* room fill, dark edge (vignette) */
  --sb-wall-fill:   #55296A;
  --sb-wall-edge:   #7E52A0;
  --sb-mirror-cold: #1E5C77;   /* matte, not currently hit */
  --sb-mirror-hot:  #38C3E4;   /* gleaming, currently hit */
  --sb-handle:      #FF8A20;
  --sb-beam:        #FFD401;
  --sb-star:        #FFD401;
  --sb-spark-a:     #FFD401;
  --sb-spark-b:     #FC74B4;

  /* ── Type ──
     Raleway powers the Fruit3D chrome (loaded via Google Fonts, matching the
     exploding-dots reference); the shipped GT Walsheim / Inter faces stay as
     offline fallbacks. */
  --font-brand: 'Raleway', 'GT Walsheim', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-sans:  'Raleway', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  --font-chrome:'Raleway', 'GT Walsheim', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --fw-regular: 400;
  --fw-medium:  500;
  --fw-semibold:600;
  --fw-bold:    700;
  --fw-ultrabold:800;
  --tracking-tight: -0.02em;
  --text-xs:  12px;
  --text-sm:  14px;
  --text-base:16px;
  --text-md:  18px;
  --text-lg:  20px;
  --text-xl:  24px;
  --text-2xl: 30px;
  --text-3xl: 36px;

  /* ── Spacing / radius / shadow / motion ── */
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-5: 20px; --space-6: 24px; --space-8: 32px;
  --radius-md: 8px; --radius-lg: 12px; --radius-xl: 16px; --radius-full: 9999px;
  --shadow-card: 0 12px 28px rgba(28,10,36,0.35), 0 2px 6px rgba(28,10,36,0.20);
  --shadow-soft: 0 4px 12px rgba(28,10,36,0.22);
  --ease-pop: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast: 120ms;
  --dur-base: 220ms;
  --dur-slow: 360ms;
  --ring: color-mix(in srgb, var(--purple-700) 55%, transparent);

  --sb-header-h: 56px;
}

/* ── Reset & base ── */
* { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--plum);
  font-family: var(--font-sans);
  color: var(--text-body);
  -webkit-tap-highlight-color: transparent;
}
button {
  font-family: inherit;
  cursor: pointer;
  border: none;
  background: none;
  color: inherit;
}
p { margin: 0; }
h1, h2, h3 { margin: 0; }

:focus { outline: none; }
:focus-visible {
  outline: 3px solid var(--ring);
  outline-offset: 2px;
  border-radius: var(--radius-md);
}

/* Author `display:flex/grid` rules below have the same specificity as
   the UA [hidden]{display:none} rule and (being author-origin) would
   otherwise win the cascade. Force hidden elements to actually hide. */
[hidden] { display: none !important; }

/* ── App shell ── */
.sb-app {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
}

/* ═══════════════════════════════════════════════════════════════════
   Fruit3D site chrome — header & footer that bound the stage.
   Cloned from the reference example (examples.fruit3d.com/exploding-dots):
   the Fruit3D wordmark + an activity pill in the header; copyright, a
   "Created by" credit and a "Made with" wordmark in the footer. Raleway
   throughout, on the Fruit3D plum (#2b0326) bar.
   ═══════════════════════════════════════════════════════════════════ */
.site-header,
.site-footer {
  flex: none;
  background: var(--plum);
  z-index: 10;
  font-family: var(--font-chrome);
}
.site-header { border-bottom: 1px solid var(--line-dark); }
.site-footer { border-top: 1px solid var(--line-dark); }
.site-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 22px;
}
/* Header bar: fixed 60px, centred. */
.site-header .site-bar {
  height: 60px;
  padding: 0 20px;
  gap: 16px;
}
.site-logo-link {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  transition: opacity .15s ease;
}
.site-logo-link:hover { opacity: .85; }
.site-logo { height: 30px; width: auto; display: block; }
.site-title {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}
.site-title h1 {
  margin: 0;
  font-family: var(--font-chrome);
  font-size: clamp(14px, 2vw, 20px);
  font-weight: 700;
  letter-spacing: -.01em;
  line-height: 1.1;
  color: #fff;
}
.fruit3d-pill {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  border-radius: 11px;
  background: var(--card-inset);
  border: 1px solid var(--line-dark);
  padding: 6px 13px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .02em;
  color: #f8f4f1;
  text-decoration: none;
  transition: opacity .16s;
}
.fruit3d-pill:hover { opacity: .9; }
.fruit3d-pill .pill-logo { display: block; height: 16px; width: auto; }
/* Sign Up CTA — solid pink, same height as the Interactive Activity pill. */
.signup-btn {
  display: inline-flex; align-items: center;
  border: 1px solid transparent; border-radius: 11px;
  background: #EB7CB2; color: #fff;
  padding: 6px 16px;
  font-family: var(--font-chrome);
  font-size: 13px; font-weight: 700; letter-spacing: .02em; line-height: 16px;
  white-space: nowrap; cursor: pointer; text-decoration: none;
  transition: filter .16s;
}
.signup-btn:hover { filter: brightness(1.06); }

.site-footer .copyright,
.site-footer .made-with {
  white-space: nowrap;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: .01em;
  color: #f8f4f1;
}
.site-footer .copyright { margin-right: auto; }
.site-footer .site-bar { position: relative; }
.site-footer .created-by {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: .01em;
  color: #f8f4f1;
}
.site-footer .created-by svg { display: block; flex: none; }
.site-footer .wordmark-link { display: inline-flex; align-items: center; transition: opacity .16s; }
.site-footer .wordmark-link:hover { opacity: .8; }
.site-footer .wordmark { height: 22px; width: auto; }

@media (max-width: 560px) {
  .fruit3d-pill { font-size: 0; gap: 0; padding: 7px; }
  .fruit3d-pill .pill-logo { height: 17px; }
  .site-footer .made-with,
  .site-footer .created-by { display: none; }
}
@media (max-width: 640px) {
  .site-header .site-bar { height: auto; flex-wrap: wrap; padding: 10px 12px; gap: 10px 12px; }
  .site-logo-link { order: 1; }
  .fruit3d-pill { order: 2; }
  .signup-btn { order: 3; }
  .site-title { order: 4; flex-basis: 100%; }
  .site-title h1 { font-size: 17px; }
}

/* ── Stage wrap (fills remaining viewport, centres the canvas) ── */
.sb-stage-wrap {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  padding: 0;
  overflow: hidden;
}

.sb-canvas-wrap {
  position: relative;
  overflow: hidden;
  touch-action: none;
}
.sb-canvas-wrap canvas {
  display: block;
  width: 100% !important;
  height: 100% !important;
  touch-action: none;
}
#p5host {
  position: absolute;
  inset: 0;
}
/* Level 3 renders three.js into its own canvas layered over the p5 host. */
.sb-three-host {
  position: absolute;
  inset: 0;
  z-index: 2;
}
.sb-three-host[hidden] { display: none; }

/* Level 3 click-cursor hint — sits on the light source (its tip at 0,0 = the
   element's left/top) and is nudged around by JS until the child drags. */
.sb-l3-cursor {
  position: absolute;
  left: 0; top: 0;
  width: 44px; height: 44px;
  z-index: 12;
  pointer-events: none;
  will-change: left, top;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.3));
}
.sb-l3-cursor[hidden] { display: none; }
.sb-three-host canvas {
  display: block;
  width: 100% !important;
  height: 100% !important;
  touch-action: none;
}

/* Level 3 recolours the play area (not the header/footer) to a single
   flat backdrop so the dark 80%-black shadows read, with no nested card. */
body.sb-level3 .sb-stage-wrap { background: #B14884; }
body.sb-level3 .sb-canvas-wrap { box-shadow: none; border-radius: 0; background: #B14884; }

/* ── Per-level % complete HUD (level label + number + bar) ── */
.sb-hud-group {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 12;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: stretch;
}
.sb-hud-group[hidden] { display: none; }
.sb-hud {
  background: var(--card);
  border: 2px solid var(--nav);
  border-radius: 16px;
  padding: 10px 16px 12px;
  min-width: 168px;
  box-shadow: var(--shadow-soft);
  font-family: var(--font-brand);
  text-align: center;
}
.sb-hud-controls { display: flex; gap: 8px; }
.sb-hud-btn {
  flex: 1 1 0;
  font-family: var(--font-brand);
  font-weight: var(--fw-ultrabold);
  font-size: 14px;
  color: var(--nav);
  background: transparent;
  border: 2px solid var(--nav);
  border-radius: 13px;
  padding: 8px 10px;
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s, color .15s, transform .1s;
  touch-action: manipulation;
}
.sb-hud-btn:hover { background: var(--nav); color: var(--plum); }
.sb-hud-btn:active { transform: translateY(1px) scale(.98); }
.sb-hud[hidden] { display: none; }
.sb-hud-level {
  font-size: 20px;
  font-weight: var(--fw-ultrabold);
  color: var(--nav);
  line-height: 1.04;
  letter-spacing: .01em;
  margin-bottom: 4px;
}
.sb-hud-pct {
  font-size: 13px;
  font-weight: var(--fw-bold);
  color: var(--nav);
  opacity: .9;
  margin-bottom: 8px;
}
.sb-hud-track {
  height: 12px;
  border-radius: var(--radius-full);
  overflow: hidden;
  background: rgba(161, 252, 210, .22);
}
.sb-hud-fill {
  height: 100%;
  width: 0%;
  border-radius: var(--radius-full);
  background: var(--nav);
  transition: width .45s var(--ease-pop);
}

/* ── Opening-card level picker ── */
/* Level picker — copied from the exploding-dots template: all three levels
   sit in one centred, wrapping row. Level 1 is the filled mint button; Levels
   2 & 3 are mint-outline buttons, sized to match, so the eye goes to Level 1. */
.sb-level-picker {
  margin-top: 0;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 12px;
}
.sb-title-card .sb-level-picker .sb-btn { margin-top: 0; width: auto; }
/* .sb-btn (defined later) would otherwise win the min-height/padding/font at
   equal specificity, so qualify with .sb-btn to match the exploding-dots size. */
.sb-btn.sb-level-btn {
  flex: 0 0 auto;
  display: block;               /* match the exploding-dots button's block box */
  text-align: center;
  min-width: 0;
  min-height: 0;
  padding: 11px 30px;
  font-size: clamp(15px, 2.4vh, 18px);
  font-weight: var(--fw-ultrabold);
  line-height: 1.17;   /* match the exploding-dots button box height exactly */
  white-space: nowrap;
}
/* Level 1 — filled mint, flat (no 3D lift) so all three sit flush in the row. */
.sb-level-btn.sb-btn--primary {
  border: 2px solid var(--nav);
  box-shadow: 0 6px 14px rgba(0, 0, 0, .3);
}
.sb-level-btn.sb-btn--primary:active { transform: translateY(2px) scale(.98); box-shadow: 0 3px 8px rgba(0, 0, 0, .3); }
/* Levels 2 & 3 — mint outline only. */
.sb-level-btn.sb-btn--outline {
  background: transparent;
  color: #A1FCD2;
  border: 2px solid #A1FCD2;
  box-shadow: none;
}
.sb-btn--outline:hover { background: #A1FCD2; color: var(--plum); }
.sb-btn--outline:active { transform: translateY(2px) scale(.98); }

/* ── Mascot dock ── */
.sb-mascot-dock {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;      /* lemon + speech centred, like the kiwi's mascot-row */
  justify-content: center;
  gap: 12px;
  z-index: 10;
  pointer-events: none;
}
/* The lemon (3D model-viewer). The wrapper sways side to side (kiwi-style
   idle); the inner model does the one-shot bounce/tilt so they combine. */
.sb-mascot {
  width: clamp(64px, 10vh, 94px);
  height: clamp(64px, 10vh, 94px);
  flex: 0 0 auto;
  animation: sb-lemon-sway 3s ease-in-out infinite;
}
.sb-mascot-model {
  width: 100%;
  height: 100%;
  display: block;
  background: transparent;
  --poster-color: transparent;
  --progress-bar-color: transparent;
  /* Boost saturation so the lemon reads as vivid yellow, not washed out. */
  filter: saturate(1.5) contrast(1.04);
}
@keyframes sb-lemon-sway {
  0%, 100% { transform: translateX(-5px) rotate(-4deg); }
  50%      { transform: translateX(5px) rotate(4deg); }
}
.sb-mascot-model.sb-bounce { animation: sb-bounce 620ms var(--ease-pop); }
.sb-mascot-model.sb-tilt { animation: sb-tilt 560ms var(--ease-pop); }
@keyframes sb-bounce {
  0% { transform: translateY(0) scale(1); }
  35% { transform: translateY(-16px) scale(1.06); }
  60% { transform: translateY(2px) scale(0.98); }
  100% { transform: translateY(0) scale(1); }
}
@keyframes sb-tilt {
  0% { transform: rotate(0deg); }
  30% { transform: rotate(-12deg); }
  60% { transform: rotate(8deg); }
  100% { transform: rotate(0deg); }
}

/* Mascot speech — yellow bubble, tail pointing left toward the lemon
   (same size as the exploding-dots kiwi's speech). */
.sb-speech-bubble {
  position: relative;
  /* Fixed width (like the kiwi's) so the bubble never resizes per message and
     the lemon stays put — longer lines wrap instead of widening the bubble. */
  width: min(72vw, 420px);
  background: #F9DC4D;
  border: 2px solid #F9DC4D;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  padding: 8px 16px;
  opacity: 0;
  transform: scale(0.96);
  transition: opacity var(--dur-base) var(--ease-pop), transform var(--dur-base) var(--ease-pop);
}
.sb-speech-bubble.is-visible { opacity: 1; transform: scale(1); }
.sb-speech-bubble p {
  margin: 0;
  font-size: clamp(15px, 2.1vh, 18px);
  line-height: 1.4;
  color: #2B0326;
  font-weight: var(--fw-semibold);
  text-align: center;   /* centred, like the kiwi's play-screen bubble */
}
.sb-speech-bubble::before {
  content: '';
  position: absolute;
  left: -9px;
  top: 50%;
  transform: translateY(-50%) rotate(45deg);
  width: 14px;
  height: 14px;
  background: #F9DC4D;
  border-left: 2px solid #F9DC4D;
  border-bottom: 2px solid #F9DC4D;
}

/* ── Level 1 light controls: lamp power bar + torch beam buttons ── */
.sb-power,
.sb-beams {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 3%;
  z-index: 10;
  background: var(--surface-cream);
  border: 2px solid var(--border-cream);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  padding: 10px 14px;
  text-align: center;
}
.sb-power[hidden],
.sb-beams[hidden] { display: none; }
.sb-power-label {
  display: block;
  font-family: var(--font-brand);
  font-weight: var(--fw-bold);
  font-size: var(--text-xs);
  color: var(--text-strong);
  margin-bottom: 8px;
}
.sb-power-row { display: flex; align-items: center; gap: 10px; }
.sb-power-btn {
  width: 48px; height: 48px; flex: 0 0 auto;
  border-radius: 50%;
  border: 2px solid #F9DC4D;
  background: transparent;
  color: #F9DC4D;   /* yellow "−/+" and ring, no fill */
  font-family: var(--font-brand); font-weight: 800;
  font-size: 24px; line-height: 1;
  cursor: pointer;
  transition: transform .12s var(--ease-pop), background .15s, color .15s;
}
.sb-power-btn:hover { background: #F9DC4D; color: var(--plum); }
.sb-power-btn:active { transform: scale(0.92); }
.sb-power-track {
  width: 96px; height: 14px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--brand-blue) 16%, #fff);
  overflow: hidden;
}
.sb-power-fill {
  height: 100%; width: 50%;
  background: linear-gradient(90deg, #FFD24A, #FFA91E);
  border-radius: inherit;
  transition: width .22s var(--ease-pop);
}

.sb-beams-row { display: flex; gap: 8px; }
.sb-beam-btn {
  width: 66px; min-height: 64px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  background: #fff;
  border: 2px solid var(--border-cream);
  border-radius: var(--radius-lg);
  cursor: pointer;
  font-family: var(--font-sans); font-weight: var(--fw-semibold);
  font-size: var(--text-xs); color: var(--text-strong);
  transition: transform .12s var(--ease-pop), border-color .15s, box-shadow .15s;
}
.sb-beam-btn:hover { transform: translateY(-2px); }
.sb-beam-btn:active { transform: scale(0.95); }
.sb-beam-btn.is-active {
  border-color: var(--brand-blue);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-blue) 32%, transparent), var(--shadow-soft);
}
.sb-beam-ico { width: 30px; height: 26px; display: flex; align-items: flex-end; justify-content: center; }
/* A little beam of light — a taller triangle means the beam reaches further. */
.sb-beam-cone {
  display: block; width: 0; height: 0;
  border-left: 9px solid transparent;
  border-right: 9px solid transparent;
  border-bottom: 26px solid #FFB021;
}
.sb-beam-cone--small  { border-bottom-width: 12px; border-bottom-color: #FFE3A0; }
.sb-beam-cone--medium { border-bottom-width: 19px; border-bottom-color: #FFCB4D; }
.sb-beam-cone--full   { border-bottom-width: 26px; border-bottom-color: #FFB021; }

/* ── "How light works" intro card ── */
.sb-light-card { text-align: center; max-width: 480px; }
.sb-light-card h2 {
  font-family: var(--font-brand); font-weight: var(--fw-bold);
  font-size: clamp(22px, 3.6vh, 30px);
  color: #fff; margin: 6px 0 14px;
}
.sb-light-card p {
  font-size: clamp(15px, 2.2vh, 18px);
  line-height: 1.5; color: #fff; margin: 0 0 14px;
}
.sb-light-card p b { color: #F9DC4D; font-weight: 800; }
.sb-light-card .sb-btn { margin-top: 6px; }

/* ── Tray (stages 3 & 5) ── */
.sb-tray {
  position: absolute;
  right: 2%;
  bottom: 3%;
  z-index: 10;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.sb-tray-card {
  width: 96px;
  min-height: 72px;
  background: var(--surface-cream);
  border: 2px solid var(--border-cream);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 6px;
  font-family: var(--font-sans);
  font-weight: var(--fw-semibold);
  font-size: var(--text-xs);
  color: var(--text-strong);
  transition: transform var(--dur-base) var(--ease-pop), box-shadow var(--dur-base) var(--ease-pop), border-color var(--dur-base) var(--ease-pop);
}
.sb-tray-card:hover { transform: translateY(-2px); }
.sb-tray-card:active { transform: scale(0.96); }
.sb-tray-card.is-selected {
  border-color: var(--brand-blue);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-blue) 35%, transparent), var(--shadow-soft);
}
/* Guided reflector task: only the current material is pickable; the rest grey. */
.sb-tray-card.is-locked {
  opacity: 0.38;
  filter: grayscale(0.7);
  cursor: default;
  pointer-events: none;
}
.sb-tray-card.is-locked:hover { transform: none; box-shadow: var(--shadow-soft); }
.sb-tray-card.is-done { opacity: 0.5; }
.sb-tray-icon {
  width: 34px;
  height: 24px;
  border-radius: 4px;
  flex-shrink: 0;
}
.sb-tray-icon--mirror { background: linear-gradient(135deg, #38C3E4, #1E90AC); border: 1px solid #14495B; }
.sb-tray-icon--flat-foil { background: linear-gradient(135deg, #E9EEF2, #B7C2CC); border: 1px solid #8C97A1; }
.sb-tray-icon--crumpled-foil {
  background: repeating-linear-gradient(115deg, #D7DEE4 0 3px, #A7B2BC 3px 6px);
  border: 1px solid #8C97A1;
}
.sb-tray-icon--cardboard { background: linear-gradient(135deg, #C79A63, #9A6F42); border: 1px solid #6E4D2B; }
.sb-tray-card .sb-tray-tag {
  display: none;
  font-size: 10px;
  font-weight: var(--fw-bold);
  color: color-mix(in srgb, var(--brand-blue) 60%, var(--ink-900));
}
.sb-tray-card.is-selected .sb-tray-tag { display: block; }

/* ── Foil lab controls — bottom-centre, Crumple on the left ── */
.sb-lab-controls {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 3%;
  z-index: 10;
  display: flex;
  flex-direction: row;
  gap: 10px;
}
#btnCrumple { order: 1; }
#btnSmooth { order: 2; }
#btnLabNext { order: 3; }
.sb-lab-btn, .sb-lab-next {
  min-width: 128px;
  min-height: 64px;
  padding: 10px 20px;
  border-radius: var(--radius-lg);
  background: var(--surface-cream);
  border: 2px solid var(--border-cream);
  box-shadow: var(--shadow-soft);
  font-family: var(--font-brand);
  font-weight: var(--fw-bold);
  font-size: var(--text-md);
  color: var(--text-strong);
  transition: transform var(--dur-base) var(--ease-pop), box-shadow var(--dur-base) var(--ease-pop), border-color var(--dur-base) var(--ease-pop), background var(--dur-base) var(--ease-pop);
}
.sb-lab-btn:active, .sb-lab-next:active { transform: scale(0.96); }
.sb-lab-btn.is-active {
  background: var(--brand-yellow);
  border-color: #C79E00;
  color: var(--ink-900);
}
.sb-lab-next {
  background: var(--nav);
  border-color: var(--nav-dark);
  color: var(--plum);
}
.sb-lab-next[hidden] { display: none; }

/* ── Banner ── */
.sb-banner {
  position: absolute;
  top: 3%;
  left: 50%;
  transform: translate(-50%, -8px);
  z-index: 11;
  background: var(--surface-cream);
  border: 1px solid var(--border-cream);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-soft);
  padding: 10px 22px;
  max-width: 80%;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-slow) var(--ease-pop), transform var(--dur-slow) var(--ease-pop);
}
.sb-banner.is-visible { opacity: 1; transform: translate(-50%, 0); }
.sb-banner p {
  font-family: var(--font-sans);
  font-weight: var(--fw-semibold);
  font-size: var(--text-md);
  color: var(--text-strong);
  text-align: center;
  white-space: nowrap;
}

/* ── Drag hint (stage 1 only, first drag) ── */
.sb-drag-hint {
  position: absolute;
  z-index: 9;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.sb-drag-hint[hidden] { display: none; }
.sb-drag-hint-hand {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 3px solid rgba(255,255,255,0.85);
  animation: sb-pulse 1.4s ease-in-out infinite;
}
.sb-drag-hint p {
  font-family: var(--font-sans);
  font-weight: var(--fw-semibold);
  font-size: var(--text-sm);
  color: var(--white);
  background: rgba(38, 9, 33, 0.75);
  padding: 3px 10px;
  border-radius: var(--radius-full);
  white-space: nowrap;
}
@keyframes sb-pulse {
  0%   { transform: scale(0.85); opacity: 0.9; }
  50%  { transform: scale(1.25); opacity: 0.35; }
  100% { transform: scale(0.85); opacity: 0.9; }
}

/* ── Overlays (title / quiz) ── */
.sb-overlay {
  position: absolute;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(38, 9, 33, 0.6);
  padding: 16px;
  opacity: 1;
  transition: opacity var(--dur-slow) var(--ease-pop);
}
.sb-overlay[hidden] { display: none; }

.sb-card {
  background: var(--card);
  border: 1px solid var(--line-dark);
  border-radius: 24px;
  box-shadow: var(--shadow-card);
  padding: var(--space-8);
  max-width: 560px;
  width: 100%;
  max-height: 100%;
  overflow: auto;
  animation: f3d-pop var(--dur-base) var(--ease-pop);
}
@keyframes f3d-pop {
  from { opacity: 0; transform: scale(0.96); }
  to   { opacity: 1; transform: scale(1); }
}

/* ── Opening window — matches the exploding-dots intro card ── */
.sb-title-card { text-align: center; }
/* Opening card sized to the shared Fruit3D template (exploding-dots .intro-card)
   so every experience's title card is identical: width and padding matched. */
.sb-card.sb-title-card {
  width: min(520px, calc(100vw - 32px));
  max-width: none;
  padding: clamp(28px, 4vh, 42px) clamp(24px, 4vw, 40px) clamp(26px, 3.4vh, 36px);
}
.intro-logo { display: block; height: 34px; width: auto; margin: 0 auto 16px; }
.intro-emoji { font-size: clamp(38px, 6vh, 48px); line-height: 1; }
.sb-title-card h1 {
  margin: 12px 0 8px;
  font-family: var(--font-brand);
  font-weight: var(--fw-bold);
  font-size: clamp(26px, 4.6vh, 38px);
  line-height: 1.1;
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
  color: #fff;
}
.intro-sub {
  font-size: clamp(13px, 1.8vh, 15px);
  font-weight: 700;
  letter-spacing: .02em;
  color: #EB7CB2;
  margin: 0 0 6px;
}
.intro-subtitle {
  font-size: clamp(15px, 2.2vh, 19px);
  font-weight: 800;
  letter-spacing: .01em;
  color: #EB7CB2;
  margin: 0 0 12px;
}
.intro-subhead {
  margin: clamp(24px, 5vh, 46px) auto;
  max-width: 420px;
  font-size: clamp(16px, 2.6vh, 21px);
  font-weight: 700;
  line-height: 1.2;
  text-wrap: balance;
  color: #fff;
}
.intro-hook {
  margin: 0 auto;
  max-width: 400px;
  font-size: clamp(15px, 2vh, 17px);
  line-height: 1.55;
  color: #fff;
  font-weight: 700;
}

.sb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 64px;
  padding: 14px 32px;
  border-radius: var(--radius-full);
  font-family: var(--font-brand);
  font-weight: var(--fw-bold);
  font-size: var(--text-md);
  letter-spacing: var(--tracking-tight);
  transition: transform var(--dur-fast) var(--ease-pop), box-shadow var(--dur-base) var(--ease-pop), background var(--dur-base) var(--ease-pop);
}
.sb-btn:active { transform: scale(0.96); }
/* Primary CTA — mint ("lime"), plum ink, with the lifted 3D shadow from
   the exploding-dots Start button. */
.sb-btn--primary {
  background: var(--nav);
  color: var(--plum);
  border: none;
  box-shadow: 0 8px 0 var(--nav-dark), 0 14px 22px rgba(0,0,0,.4);
}
.sb-btn--primary:hover { background: #b6ffdd; }
.sb-btn--primary:active { transform: translateY(3px) scale(.98); box-shadow: 0 4px 0 var(--nav-dark), 0 8px 14px rgba(0,0,0,.4); }
.sb-btn--secondary {
  background: transparent;
  color: #fff;
  border: 2px solid var(--line-dark);
  box-shadow: var(--shadow-soft);
}
.sb-btn--secondary:hover { border-color: var(--nav); background: var(--card-inset); }
.sb-title-card .sb-btn {
  margin-top: var(--space-6);
  width: 100%;
}

/* ── Quiz ── */
/* Quiz cards copy the exploding-dots quiz: dark plum card, pink question,
   bold outlined option tiles, mint correct answer, mint continue pill. */
.sb-quiz-card { text-align: center; }
.sb-card.sb-quiz-card {
  position: relative;
  max-width: 520px;
  padding: clamp(24px, 5vh, 44px) clamp(24px, 5vw, 52px);
}
/* Round nav buttons on a question card: Back (top-left) and Next (bottom-right,
   shown once an answer is right so the child advances in their own time). */
.sb-quiz-back,
.sb-quiz-next {
  position: absolute;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border-radius: 50%;
  border: 2px solid var(--nav);
  background: transparent;
  color: var(--nav);
  font-family: var(--font-brand);
  font-weight: var(--fw-bold);
  font-size: 21px;
  line-height: 1;
  cursor: pointer;
  transition: background .15s, color .15s, transform .1s;
}
.sb-quiz-back { top: 12px; left: 12px; }
.sb-quiz-next { bottom: 12px; right: 12px; }
.sb-quiz-next[hidden] { display: none; }
.sb-quiz-back:hover,
.sb-quiz-next:hover { background: var(--nav); color: var(--plum); }
.sb-quiz-back:active,
.sb-quiz-next:active { transform: scale(0.95); }
/* Keep the lemon's speech clear of the Next button in the bottom-right. */
.sb-quiz-mascot-row { padding-right: 46px; }
.sb-quiz-stars {
  display: flex;
  gap: 8px;
  justify-content: center;
  margin-bottom: var(--space-5);
}
.sb-quiz-star {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  opacity: 0.35;
  transition: opacity var(--dur-base) var(--ease-pop), transform var(--dur-base) var(--ease-pop);
}
.sb-quiz-star.is-earned { opacity: 1; transform: scale(1.12); }

.sb-quiz-prompt {
  font-family: var(--font-brand);
  font-weight: var(--fw-ultrabold);
  font-size: clamp(16px, 2.6vh, 21px);
  color: #EB7CB2;
  text-align: center;
  text-wrap: balance;
  margin-bottom: var(--space-2);
}
.sb-quiz-scene {
  display: flex;
  justify-content: center;
  margin: var(--space-3) 0 var(--space-4);
}
.sb-quiz-scene svg { width: min(220px, 70%); height: auto; }
.sb-quiz-optrow { display: inline-flex; align-items: center; gap: 8px; }
.sb-quiz-optrow .sb-dir-arrow { flex: 0 0 auto; }
.sb-quiz-title {
  font-family: var(--font-brand);
  font-weight: var(--fw-bold);
  font-size: clamp(20px, 3.2vh, 28px);
  color: #fff;
  text-align: center;
  margin-bottom: var(--space-3);
}
.sb-quiz-options {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  width: 100%;
  margin-top: var(--space-4);
}
.sb-quiz-option {
  flex: 0 1 auto;
  min-width: 88px;
  min-height: 64px;
  background: var(--card-inset);
  border: 3px solid var(--line-dark);
  border-radius: var(--radius-lg);
  padding: 12px 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-brand);
  font-weight: var(--fw-ultrabold);
  font-size: clamp(16px, 2.6vh, 22px);
  color: #fff;
  text-align: center;
  box-shadow: var(--shadow-soft);
  transition: transform .16s var(--ease-pop), border-color .16s, background .16s, color .16s;
}
.sb-quiz-option:hover { transform: translateY(-2px); }
.sb-quiz-option:active { transform: scale(0.95); }
.sb-quiz-option.is-correct {
  background: #A1FCD2;
  color: var(--plum);
  border-color: #A1FCD2;
  transform: scale(1.06);
}
.sb-quiz-option.is-wrong {
  border-color: var(--brand-orange);
  opacity: 0.55;
  animation: sb-shake .4s;
}
.sb-quiz-option svg { width: 22px; height: 22px; }
@keyframes sb-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-7px); }
  40% { transform: translateX(7px); }
  60% { transform: translateX(-5px); }
  80% { transform: translateX(5px); }
}

.sb-quiz-feedback {
  margin-top: var(--space-5);
  min-height: 2.4em;
  font-size: clamp(14px, 2vh, 17px);
  font-weight: var(--fw-semibold);
  color: var(--text-soft);
  text-align: center;
}
.sb-quiz-feedback[hidden] { display: none; }
.sb-quiz-feedback.is-good { color: var(--brand-green); }
.sb-quiz-feedback.is-good strong,
.sb-quiz-feedback.is-kind strong { color: inherit; }

.sb-quiz-continue {
  margin-top: var(--space-5);
  font-size: clamp(20px, 3.2vh, 28px);
  min-height: 68px;
  padding: 18px 40px;
}
.sb-quiz-continue[hidden] { display: none; }

/* The lemon relays each answer in a speech bubble (exploding-dots kiwi style):
   lemon on the left, bubble to its right with the tail pointing back at it. */
.sb-quiz-mascot-row {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 12px;
  width: 100%;
  margin-top: var(--space-5);
}
.sb-quiz-mascot-row[hidden] { display: none; }
.sb-quiz-mascot {
  width: clamp(54px, 8vh, 72px);
  height: clamp(54px, 8vh, 72px);
  flex: 0 0 auto;
}
.sb-quiz-speech {
  width: auto;
  flex: 1 1 auto;
  opacity: 1;
  transform: none;
}
.sb-quiz-speech p { text-align: left; }

/* The end-quiz / interim-question card sits on a plain background — the level's
   interactive scene behind it is a distraction, so the overlay is opaque. */
#quizOverlay { background: var(--plum); }

.sb-finale-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin-top: var(--space-4);
}
.sb-finale h2 {
  font-family: var(--font-brand);
  font-weight: var(--fw-bold);
  font-size: var(--text-2xl);
  color: var(--text-strong);
  text-align: center;
}
.sb-finale-take {
  margin-top: var(--space-4);
  padding: var(--space-5);
  background: var(--card-inset);
  border: 1px solid var(--line-dark);
  border-radius: var(--radius-lg);
  font-size: var(--text-md);
  color: #fff;
  text-align: center;
}
.sb-finale-note {
  margin-top: var(--space-3);
  font-size: var(--text-sm);
  color: var(--text-faint);
  text-align: center;
}
.sb-finale .sb-btn { margin-top: var(--space-6); width: 100%; }
/* When a round Next button sits in the bottom-right, the menu button shrinks to
   its content and centres so the two never overlap. */
.sb-finale .sb-btn.sb-finale-menu { width: auto; min-width: 200px; align-self: center; }

/* ── End-of-experience feedback card ── */
.sb-card.sb-endcard { max-width: 540px; text-align: center; }
.sb-end-title {
  font-family: var(--font-brand);
  font-weight: var(--fw-ultrabold);
  font-size: clamp(26px, 4.4vh, 38px);
  line-height: 1.12;
  color: #fff;
  text-align: center;
  text-wrap: balance;
}
.sb-end-ask {
  margin-top: var(--space-4);
  font-family: var(--font-brand);
  font-weight: var(--fw-ultrabold);
  font-size: clamp(17px, 2.8vh, 22px);
  color: var(--brand-pink);
  text-align: center;
}
.sb-end-row {
  display: flex;
  gap: 12px;
  margin-top: var(--space-5);
  align-items: flex-end;
}
.sb-end-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  text-align: left;
  margin-top: var(--space-4);
}
.sb-end-row .sb-end-field { margin-top: 0; }
.sb-end-field--grow { flex: 1 1 auto; }
.sb-end-field--age { flex: 0 0 88px; }
.sb-end-label {
  font-family: var(--font-brand);
  font-weight: var(--fw-bold);
  font-size: clamp(13px, 1.8vh, 15px);
  color: var(--text-soft);
}
.sb-end-input {
  width: 100%;
  min-height: 52px;
  background: var(--card-inset);
  border: 3px solid var(--line-dark);
  border-radius: var(--radius-lg);
  padding: 12px 16px;
  font-family: var(--font-brand);
  font-weight: var(--fw-semibold);
  font-size: clamp(15px, 2.2vh, 18px);
  color: #fff;
  transition: border-color .16s;
}
.sb-end-input::placeholder { color: var(--text-faint); }
.sb-end-input:focus { outline: none; border-color: var(--brand-pink); }
.sb-end-select { min-height: 52px; cursor: pointer; text-align: center; }
.sb-end-select option { color: #fff; background: var(--plum); }
.sb-end-textarea { resize: vertical; min-height: 76px; line-height: 1.4; }
.sb-end-rate { margin-top: var(--space-5); }
.sb-end-actions {
  display: flex;
  gap: 12px;
  margin-top: var(--space-6);
}
.sb-end-actions .sb-btn { flex: 1 1 0; width: auto; margin-top: 0; text-decoration: none; }
@media (max-width: 480px) {
  .sb-end-actions { flex-direction: column; }
}

/* ── Responsive tweaks ── */
@media (max-width: 1100px) {
  .sb-tray-card { width: 84px; }
  .sb-quiz-options.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
}
@media (max-width: 860px) {
  .sb-card { padding: var(--space-6); }
}

/* ═══════════════════════════════════════════════════════════════════
   Mobile / narrow phones — same formula as the exploding-dots reference:
   the interactive (the maze) hugs the top of the stage, and the guidance
   (mascot, speech) and the controls (material tray / foil lab) dock along
   the bottom instead of floating over the small letterboxed canvas. The
   title & quiz overlays break out to cover the whole screen so their cards
   never clip inside the canvas box.
   ═══════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  /* Reserve room at the bottom of the stage for the docked controls; the
     landscape maze then centres in the space that remains, sitting in the
     upper part of the screen with the guidance docked below it. */
  .sb-stage-wrap {
    padding: 6px 6px calc(150px + env(safe-area-inset-bottom, 0px));
  }

  /* The banner mirrors the docked speech on every stage entry, so it is
     redundant (and would overlap the maze) on a phone — hide it. */
  .sb-banner { display: none !important; }

  /* Shrink the % HUD so it doesn't cover the small maze. */
  .sb-hud { top: 6px; right: 6px; min-width: 112px; padding: 6px 10px 8px; border-width: 1.5px; }
  .sb-hud-level { font-size: 15px; margin-bottom: 2px; }
  .sb-hud-pct { font-size: 11px; margin-bottom: 5px; }
  .sb-hud-track { height: 9px; }

  /* ── Title & quiz overlays cover the whole viewport ── */
  .sb-overlay {
    position: fixed;
    inset: 0;
    z-index: 50;
    padding: 14px;
  }
  .sb-card {
    padding: var(--space-6);
    max-height: calc(100dvh - 28px);
    max-width: 460px;
  }
  /* Clear the top-left Back button so it doesn't overlap the centred title. */
  .sb-card.sb-quiz-card { padding-top: 56px; }
  .sb-title-card h1 { font-size: clamp(24px, 8vw, 34px); }
  .intro-logo { height: 28px; margin-bottom: 12px; }

  /* ── Guidance dock: lemon + speech as a bottom bar (kiwi mobile layout:
        lemon 54px on the left, speech to its right) ── */
  .sb-mascot-dock {
    position: fixed;
    left: 8px;
    right: 8px;
    top: auto;         /* undo the desktop top:10 so it docks at the bottom */
    bottom: calc(47px + env(safe-area-inset-bottom, 0px));
    transform: none;   /* undo the desktop top-centre translateX(-50%) */
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    z-index: 15;
  }
  .sb-mascot { width: 54px; height: 54px; }
  .sb-speech-bubble {
    flex: 1 1 auto;
    max-width: calc(100vw - 92px);
  }
  .sb-speech-bubble p { font-size: clamp(14px, 3.7vw, 16px); }

  /* ── Material tray: a horizontal row of compact cards above the dock ── */
  .sb-tray {
    position: fixed;
    left: 8px;
    right: 8px;
    bottom: calc(115px + env(safe-area-inset-bottom, 0px));
    grid-template-columns: repeat(4, 1fr);
    gap: 6px;
    z-index: 15;
  }
  .sb-tray-card {
    width: auto;
    min-height: 62px;
    padding: 6px 4px;
    gap: 4px;
    font-size: 11px;
  }
  .sb-tray-icon { width: 30px; height: 20px; }

  /* ── Foil lab controls: a horizontal row ── */
  .sb-lab-controls {
    position: fixed;
    left: 8px;
    right: 8px;
    bottom: calc(115px + env(safe-area-inset-bottom, 0px));
    transform: none;
    flex-direction: row;
    justify-content: center;
    gap: 8px;
    z-index: 15;
  }
  .sb-lab-btn, .sb-lab-next {
    min-width: 0;
    flex: 1 1 auto;
    min-height: 62px;
    padding: 8px 10px;
    font-size: var(--text-base);
  }

  /* ── Level 1 light controls dock above the guidance bar ── */
  .sb-power, .sb-beams {
    position: fixed;
    left: 8px;
    right: 8px;
    bottom: calc(115px + env(safe-area-inset-bottom, 0px));
    transform: none;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 8px 10px;
    z-index: 15;
  }
  .sb-power-label { margin-bottom: 0; white-space: nowrap; }
  .sb-power-row { flex: 1 1 auto; justify-content: center; }
  .sb-power-track { flex: 1 1 auto; max-width: 180px; }
  .sb-beams-row { flex: 1 1 auto; justify-content: center; }
  .sb-beam-btn { flex: 1 1 auto; max-width: 96px; min-height: 60px; }

  /* Banner sits just under the nav, at the top of the maze. */
  .sb-banner { top: 8px; max-width: calc(100% - 16px); }
  .sb-banner p { white-space: normal; }
}

/* ── Fruit sprinkle ──
   A variety of fruit rains from under the header when a level is finished
   (see sprinkle.js). The sprinkle sits behind the header/footer so it pours
   out from under the header; the burst rides its own top layer. */
.fruit-sprinkle {
  position: fixed;
  inset: 0 0 auto 0;
  height: 0;
  pointer-events: none;
  z-index: 900;             /* above the header/footer (10); pours from under the header edge */
}
.fruit-sprinkle-item {
  position: fixed;
  display: block;
  height: auto;
  opacity: 0;               /* hidden until its animation fades it in (no start flash) */
  will-change: transform, opacity;
  filter: drop-shadow(0 3px 4px rgba(0, 0, 0, .16));
}
.fruit-burst {
  position: fixed;
  inset: 0;
  height: 0;
  pointer-events: none;
  z-index: 950;
}
.fruit-burst-item {
  position: fixed;
  display: block;
  height: auto;
  opacity: 0;
  will-change: transform, opacity;
  filter: drop-shadow(0 3px 4px rgba(0, 0, 0, .18));
}

/* ── Reduced motion ──
   Keep the live beam (it is the lesson). Replace position/scale
   animation with a brief opacity pulse so events still "answer back"
   within 100ms, per output-guidance. Banner keeps only its opacity
   fade, dropping the slide-up transform. */
@media (prefers-reduced-motion: reduce) {
  .sb-mascot { animation: none; }
  .sb-mascot-model.sb-bounce, .sb-mascot-model.sb-tilt { animation: sb-fade-pulse 380ms ease-in-out; }
  .sb-drag-hint-hand { animation: none; opacity: 0.75; }
  .sb-banner, .sb-banner.is-visible { transform: translate(-50%, 0) !important; }
  .sb-overlay, .sb-card, .sb-banner, .sb-speech-bubble {
    animation: none !important;
    transition-duration: 180ms !important;
  }
  .sb-tray-card, .sb-lab-btn, .sb-btn, .sb-quiz-option {
    transition-duration: 80ms !important;
  }
}
@keyframes sb-fade-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}

/* ═══════════════════════════════════════════════════════════════════
   SOUND BLENDER — smoothie-bar theme overrides + blender components.
   Re-themes the reused Fruit3D chrome to a strawberry-smoothie identity
   (berry primary, mango/lime rewards) and adds the blender play furniture.
   ═══════════════════════════════════════════════════════════════════ */
:root {
  /* Primary now = strawberry berry (was mint). Everything that referenced
     --nav (HUD, level buttons, CTAs) picks this up. */
  --nav:        #FF4D8D;
  --nav-dark:   #D62E6E;

  /* Smoothie accents */
  --accent-berry:     #FF4D8D;
  --accent-mango:     #FFB020;
  --accent-lime:      #39D98A;
  --accent-blueberry: #5B7CFA;
  --accent-grape:     #9B5DE5;
  --smoothie-warn:    #FF6B4A;

  /* A rounded, dyslexia-friendly display face for the phonics words/cubes.
     Fredoka + Baloo 2 loaded in <head>; falls back to the shipped faces. */
  --font-round: 'Fredoka', 'Baloo 2', var(--font-brand);
}

/* Primary CTA: berry fill needs white ink (not plum). */
.sb-btn--primary { color: #fff; }
.sb-btn--primary:hover { background: #ff669d; }
/* Level-1 filled button + level outline buttons already use --nav via the base
   rules; the outline variant text was mint — recolour to berry. */
.sb-level-btn.sb-btn--outline { color: var(--accent-berry); border-color: var(--accent-berry); }
.sb-btn--outline:hover { background: var(--accent-berry); color:#fff; }

/* Teaching-card bold keywords: mango, not the old torch-yellow. */
.sb-light-card p b { color: var(--accent-mango); }

/* The canvas host fills the whole stage (no letterbox frame). */
.sb-canvas-wrap { width: 100%; height: 100%; }
.sb-three-host { z-index: 1; }
.sb-stage-wrap { background: radial-gradient(120% 100% at 50% 0%, var(--purple-700) 0%, var(--plum) 62%); }

/* Instruction chip (reuses .sb-banner) — brighter, translucent white pill. */
.sb-banner {
  background: rgba(255,255,255,0.94);
  border: 2px solid rgba(255,255,255,0.6);
}
.sb-banner p { color: var(--plum); }

/* ── Speaker replay button (persistent audio control) ── */
.sb-replay {
  position: absolute;
  bottom: calc(14px + env(safe-area-inset-bottom, 0px)); right: 14px;
  z-index: 13;
  width: 46px; height: 46px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--card);
  border: 2px solid var(--accent-mango);
  color: var(--accent-mango);
  box-shadow: var(--shadow-soft);
  transition: transform .12s var(--ease-pop), background .15s, color .15s;
}
.sb-replay[hidden] { display: none; }
.sb-replay:hover { background: var(--accent-mango); color: var(--plum); }
.sb-replay:active { transform: scale(.9); }
.sb-replay svg { width: 24px; height: 24px; display: block; }

/* ═══════════ Sound-cube tray ═══════════ */
.sb-cubes {
  position: absolute;
  left: 50%; transform: translateX(-50%);
  bottom: 3%;
  z-index: 10;
  display: flex; flex-wrap: wrap; gap: 10px; justify-content: center;
  max-width: 94%;
  padding: 12px 14px;
  background: var(--card);
  border: 2px solid var(--line-dark);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-soft);
}
.sb-cubes[hidden] { display: none; }
.sb-cubes-label {
  position: absolute; top: -11px; left: 50%; transform: translateX(-50%);
  font-family: var(--font-brand); font-weight: 800; font-size: 12px;
  color: #fff; background: var(--card); padding: 0 10px; white-space: nowrap;
}

.sb-cube {
  position: relative;
  min-width: 58px; height: 62px; padding: 0 12px;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-round); font-weight: 700; font-size: 26px;
  color: #fff; letter-spacing: .01em;
  background: var(--accent-blueberry);
  border: none;
  border-radius: 16px;
  box-shadow: 0 5px 0 rgba(0,0,0,.28), inset 0 2px 0 rgba(255,255,255,.28);
  cursor: grab;
  touch-action: none;
  user-select: none;
  transition: transform .12s var(--ease-pop), box-shadow .12s var(--ease-pop), opacity .2s;
  will-change: transform;
}
.sb-cube.is-vowel { background: var(--accent-grape); }
.sb-cube.is-digraph { background: var(--accent-mango); color: var(--plum); }
.sb-cube:active { transform: translateY(2px); box-shadow: 0 3px 0 rgba(0,0,0,.28), inset 0 2px 0 rgba(255,255,255,.28); }
.sb-cube.is-dragging { cursor: grabbing; z-index: 60; box-shadow: 0 12px 20px rgba(0,0,0,.4); }
.sb-cube.is-used { opacity: .32; pointer-events: none; }
.sb-cube.is-wobble { animation: sb-wobble .45s; }
@keyframes sb-wobble {
  0%,100% { transform: translateX(0) rotate(0); }
  25% { transform: translateX(-6px) rotate(-5deg); }
  75% { transform: translateX(6px) rotate(5deg); }
}

/* ── The jug "recipe" strip: cubes the child has dropped, in order ── */
.sb-recipe {
  position: absolute;
  left: 50%; transform: translateX(-50%);
  top: 40%;                 /* sits down in the liquid, not up by the jug mouth */
  z-index: 9;
  display: flex; gap: 6px; align-items: center;
  min-height: 56px; padding: 8px 12px;
  border-radius: var(--radius-lg);
  background: rgba(43,3,38,.42);
  border: 2px dashed rgba(255,255,255,.34);
  transition: border-color .18s, background .18s;
}
.sb-recipe[hidden] { display: none; }
.sb-recipe.is-drop { border-color: var(--accent-lime); background: rgba(57,217,138,.18); }
.sb-recipe.is-empty::after {
  content: 'Drop sounds here';
  font-family: var(--font-sans); font-weight: 600; font-size: 14px;
  color: rgba(255,255,255,.66);
  white-space: nowrap;
}
.sb-recipe-cube {
  min-width: 44px; height: 46px; padding: 0 9px;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-round); font-weight: 700; font-size: 21px; color: #fff;
  background: var(--accent-blueberry); border-radius: 12px;
  box-shadow: 0 3px 0 rgba(0,0,0,.26);
  animation: sb-pop-in .28s var(--ease-pop);
}
.sb-recipe-cube.is-vowel { background: var(--accent-grape); }
.sb-recipe-cube.is-digraph { background: var(--accent-mango); color: var(--plum); }
@keyframes sb-pop-in { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* ── BLEND lever / button ── */
.sb-blend {
  position: absolute;
  right: 4%; bottom: 20%;
  z-index: 11;
  display: flex; flex-direction: column; gap: 10px; align-items: stretch;
}
.sb-blend[hidden] { display: none; }
.sb-blend-btn {
  min-width: 132px; min-height: 66px;
  padding: 14px 26px;
  border-radius: var(--radius-full);
  background: var(--accent-berry); color: #fff;
  font-family: var(--font-brand); font-weight: 800; font-size: 21px; letter-spacing: .04em;
  box-shadow: 0 7px 0 var(--nav-dark), 0 12px 20px rgba(0,0,0,.38);
  transition: transform .1s var(--ease-pop), box-shadow .1s var(--ease-pop), opacity .2s, filter .15s;
}
.sb-blend-btn:hover { filter: brightness(1.05); }
.sb-blend-btn:active { transform: translateY(4px); box-shadow: 0 3px 0 var(--nav-dark), 0 6px 12px rgba(0,0,0,.38); }
.sb-blend-btn:disabled { opacity: .4; box-shadow: 0 7px 0 var(--nav-dark); cursor: default; filter: grayscale(.3); }
.sb-blend-btn.is-reverse { background: var(--accent-grape); box-shadow: 0 7px 0 #6d3aa8, 0 12px 20px rgba(0,0,0,.38); }
.sb-mini-btn {
  min-height: 48px; padding: 8px 16px; border-radius: var(--radius-full);
  background: transparent; color: #fff; border: 2px solid rgba(255,255,255,.5);
  font-family: var(--font-brand); font-weight: 700; font-size: 15px;
  transition: transform .1s, background .15s, border-color .15s;
}
.sb-mini-btn:hover { border-color: #fff; background: rgba(255,255,255,.12); }
.sb-mini-btn:active { transform: scale(.96); }
.sb-mini-btn[hidden] { display: none; }

/* ── The poured word, printed big on the glass (DOM label over the 3D glass) ── */
.sb-word {
  position: absolute;
  left: 50%; transform: translate(-50%, 0);
  top: 30%;
  z-index: 12;
  text-align: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity .3s var(--ease-pop), transform .3s var(--ease-pop);
}
.sb-word.is-visible { opacity: 1; }
.sb-word.is-draggable { pointer-events: auto; cursor: grab; }
.sb-word-chip {
  display: inline-block;
  font-family: var(--font-round); font-weight: 700;
  font-size: clamp(32px, 7vh, 52px);
  color: var(--plum);
  background: #fff;
  padding: 8px 26px;
  border-radius: var(--radius-full);
  box-shadow: 0 10px 24px rgba(0,0,0,.4);
  letter-spacing: .02em;
}
.sb-word-chip .sb-syl { color: var(--accent-berry); }
.sb-word-chip .sb-syl:nth-child(even) { color: var(--accent-blueberry); }
.sb-word-chip .sb-vowel { color: var(--accent-grape); text-decoration: underline; }

/* ═══════════ Level 1 — picture match targets ═══════════ */
.sb-pics {
  position: absolute;
  left: 50%; transform: translateX(-50%);
  top: 46%;
  z-index: 11;
  display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;
}
.sb-pics[hidden] { display: none; }
.sb-pic {
  width: 104px; min-height: 108px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  background: #F8F4F1;
  border: 3px solid #F8F4F1;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  transition: transform .15s var(--ease-pop), border-color .15s, box-shadow .15s;
}
.sb-pic-emoji { font-size: 54px; line-height: 1; }
.sb-pic-label { font-family: var(--font-round); font-weight: 600; font-size: 15px; color: var(--plum); }
.sb-pic.is-drop { border-color: var(--accent-lime); transform: scale(1.06); box-shadow: 0 0 0 4px rgba(57,217,138,.4), var(--shadow-card); }
.sb-pic.is-correct { border-color: var(--accent-lime); background: #eafff4; }
.sb-pic.is-wrong { animation: sb-shake .4s; }
@keyframes sb-shake { 0%,100%{transform:translateX(0)} 20%{transform:translateX(-8px)} 40%{transform:translateX(8px)} 60%{transform:translateX(-5px)} 80%{transform:translateX(5px)} }

/* ═══════════ Level 2 — target-sound screen + spelling outfits ═══════════ */
.sb-sound-screen {
  position: absolute;
  left: 50%; transform: translateX(-50%);
  top: 15%;
  z-index: 11;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 10px 26px;
  background: #10131f;
  border: 3px solid var(--accent-mango);
  border-radius: var(--radius-lg);
  box-shadow: 0 0 22px rgba(255,176,32,.35), var(--shadow-soft);
}
.sb-sound-screen[hidden] { display: none; }
.sb-sound-screen .sb-ss-cap { font-family: var(--font-sans); font-weight: 700; font-size: 12px; color: #8fe1ff; letter-spacing:.08em; }
.sb-sound-screen .sb-ss-sound { font-family: var(--font-round); font-weight: 700; font-size: 40px; color: #8fe1ff; line-height: 1; text-shadow: 0 0 14px rgba(143,225,255,.7); }

.sb-frame {
  position: absolute; left: 50%; transform: translateX(-50%);
  top: 34%; z-index: 11;
  font-family: var(--font-round); font-weight: 700; font-size: clamp(30px, 6.5vh, 46px);
  color: #fff; background: rgba(43,3,38,.5); padding: 6px 22px; border-radius: var(--radius-lg);
  border: 2px dashed rgba(255,255,255,.4);
  letter-spacing: .04em;
}
.sb-frame[hidden] { display: none; }
.sb-frame .sb-slot { color: var(--accent-mango); }

.sb-outfits {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: 3%; z-index: 10;
  display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;
  padding: 12px 16px 14px;
  background: var(--card); border: 2px solid var(--line-dark);
  border-radius: var(--radius-xl); box-shadow: var(--shadow-soft);
}
.sb-outfits[hidden] { display: none; }
.sb-outfit {
  min-width: 64px; height: 64px; padding: 0 14px;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-round); font-weight: 700; font-size: 28px; color:#fff;
  background: var(--accent-blueberry); border-radius: 16px;
  box-shadow: 0 5px 0 rgba(0,0,0,.28), inset 0 2px 0 rgba(255,255,255,.25);
  transition: transform .12s var(--ease-pop), box-shadow .12s, opacity .2s;
}
.sb-outfit:active { transform: translateY(2px); box-shadow: 0 3px 0 rgba(0,0,0,.28); }
.sb-outfit.is-wobble { animation: sb-wobble .45s; }
.sb-outfit.is-done { opacity: .3; pointer-events: none; }

/* Collected-outfit tokens for the target sound */
.sb-collected {
  position: absolute; right: 4%; top: 16%; z-index: 11;
  display: flex; flex-direction: column; gap: 6px; align-items: flex-end;
}
.sb-collected[hidden] { display: none; }
.sb-collected-cap { font-family: var(--font-sans); font-weight: 700; font-size: 12px; color: #fff; opacity: .8; }
.sb-collected-row { display: flex; gap: 6px; }
.sb-token {
  width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
  border-radius: 9px; font-family: var(--font-round); font-weight: 700; font-size: 15px;
  color:#fff; background: rgba(255,255,255,.14); border: 2px dashed rgba(255,255,255,.4);
}
.sb-token.is-filled { background: var(--accent-lime); color: var(--plum); border-style: solid; border-color: var(--accent-lime); }

/* ═══════════ Level 3 — syllable beat pad + chunk slots ═══════════ */
.sb-beatpad {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: 3%; z-index: 10;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 12px 18px 14px;
  background: var(--card); border: 2px solid var(--line-dark);
  border-radius: var(--radius-xl); box-shadow: var(--shadow-soft);
}
.sb-beatpad[hidden] { display: none; }
.sb-beatpad-label { font-family: var(--font-brand); font-weight: 800; font-size: 13px; color: #fff; }
.sb-beat-btn {
  min-width: 150px; min-height: 66px; padding: 12px 28px;
  border-radius: var(--radius-full);
  background: var(--accent-mango); color: var(--plum);
  font-family: var(--font-brand); font-weight: 800; font-size: 20px;
  box-shadow: 0 6px 0 #c98700, 0 10px 18px rgba(0,0,0,.34);
  transition: transform .08s var(--ease-pop), box-shadow .08s;
}
.sb-beat-btn:active { transform: translateY(3px); box-shadow: 0 3px 0 #c98700; }
.sb-beat-count { font-family: var(--font-round); font-weight: 700; font-size: 15px; color: #fff; }
.sb-beat-dots { display: flex; gap: 7px; }
.sb-beat-dot { width: 14px; height: 14px; border-radius: 50%; background: rgba(255,255,255,.22); transition: background .15s, transform .15s; }
.sb-beat-dot.is-on { background: var(--accent-mango); transform: scale(1.2); }

.sb-chunks {
  position: absolute; left: 50%; transform: translateX(-50%);
  top: 30%; z-index: 11;
  display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;
}
.sb-chunks[hidden] { display: none; }
.sb-chunk {
  position: relative;
  min-width: 76px; min-height: 74px; padding: 10px 16px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  background: #fff; border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  font-family: var(--font-round); font-weight: 700; font-size: 30px; color: var(--plum);
  animation: sb-pop-in .3s var(--ease-pop);
}
.sb-chunk .sb-chunk-vowel { color: var(--accent-grape); text-decoration: underline; }
.sb-chunk-tag {
  font-family: var(--font-sans); font-weight: 700; font-size: 11px;
  padding: 2px 8px; border-radius: 999px;
}
.sb-chunk.vowel-ok .sb-chunk-tag { background: #eef7ff; color: var(--accent-grape); }
.sb-chunk.vowel-ok .sb-chunk-tag::before { content: '✓ vowel'; }
.sb-chunk.vowel-bad { box-shadow: 0 0 0 3px var(--smoothie-warn), var(--shadow-card); }
.sb-chunk.vowel-bad .sb-chunk-tag { background: #ffe8e2; color: var(--smoothie-warn); }
.sb-chunk.vowel-bad .sb-chunk-tag::before { content: '! no vowel'; }
.sb-chunk.is-tap { cursor: pointer; }
.sb-chunk.is-tap:active { transform: scale(.96); }

/* Reduced-motion: cube/chunk pop + wobble collapse to opacity */
@media (prefers-reduced-motion: reduce) {
  .sb-cube, .sb-outfit, .sb-recipe-cube, .sb-chunk { transition-duration: 80ms !important; animation: none !important; }
  .sb-word { transition-duration: 120ms !important; }
}

/* ── Mobile: dock the play furniture, like the reference ── */
@media (max-width: 640px) {
  .sb-cubes, .sb-outfits, .sb-beatpad {
    left: 8px; right: 8px; transform: none;
    bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    max-width: none;
  }
  .sb-blend { right: 8px; bottom: calc(118px + env(safe-area-inset-bottom, 0px)); }
  .sb-recipe { top: 14%; }
  .sb-pics { top: 42%; gap: 8px; }
  .sb-pic { width: 84px; min-height: 92px; }
  .sb-pic-emoji { font-size: 42px; }
  .sb-collected { top: 64px; right: 8px; }
  .sb-cube { min-width: 52px; height: 56px; font-size: 23px; }
}

/* locked-level nudge */
.sb-shake { animation: sb-shake .45s; }

/* Level 2 collected-outfit tokens wrap so 9 fit without overflowing. */
.sb-collected-row { flex-wrap: wrap; max-width: 168px; justify-content: flex-end; }
@media (max-width: 640px) { .sb-collected-row { max-width: 120px; } }

/* Desktop: anchor the mascot to the top-left so it clears the centred
   instruction chip (mobile docks it to the bottom via the query below). */
@media (min-width: 641px) {
  .sb-mascot-dock { left: 16px; right: auto; transform: none; justify-content: flex-start; max-width: 62%; }
  .sb-speech-bubble { width: min(42vw, 300px); }
  .sb-banner { top: 2.4%; }
}

/* ═══════════════════════════════════════════════════════════════════
   SOUND BLENDER — mobile layout (primary target). Supersedes the
   inherited reference mobile rules: dock the interactive controls in a
   bottom cluster, keep the informational overlays in the mid scene, and
   clear the top chrome (HUD + replay). Wins the cascade by being last.
   ═══════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  /* Top chrome */
  /* On mobile the bottom-right holds the control cluster, so keep the
     speaker top-left (the mascot is hidden there). */
  .sb-replay { top: 8px; left: 8px; bottom: auto; right: auto; width: 40px; height: 40px; }
  .sb-hud-group { top: 6px; right: 6px; }

  /* Mascot is desktop-only flourish; the chip carries guidance on mobile. */
  .sb-mascot-dock { display: none !important; }

  /* Instruction chip: show it (reference hid its banner) and sit it below
     the HUD, centred over the scene. */
  .sb-banner {
    display: block !important;
    top: 150px; bottom: auto;
    max-width: calc(100% - 24px);
  }
  .sb-banner p { white-space: normal; }

  /* Primary control bar: the tray of cubes / outfits / the beat pad. */
  .sb-cubes, .sb-outfits, .sb-beatpad {
    left: 8px; right: 8px; transform: none; max-width: none;
    bottom: calc(10px + env(safe-area-inset-bottom, 0px));
    gap: 8px;
  }
  .sb-cube { min-width: 50px; height: 54px; font-size: 22px; }
  .sb-outfit { min-width: 56px; height: 56px; font-size: 24px; }

  /* Action bar just above the tray: the poured-word "recipe" (L1) on the
     left, BLEND on the right. */
  .sb-blend {
    left: auto; right: 8px; transform: none;
    bottom: calc(116px + env(safe-area-inset-bottom, 0px));
    flex-direction: row; gap: 8px;
  }
  .sb-blend-btn { min-width: 108px; min-height: 58px; font-size: 19px; padding: 12px 20px; }
  .sb-mini-btn { min-height: 44px; }
  .sb-recipe {
    left: 8px; right: 132px; transform: none;
    top: auto; bottom: calc(120px + env(safe-area-inset-bottom, 0px));
    min-height: 54px;
  }

  /* Mid-scene informational overlays */
  .sb-word { top: 196px; }
  .sb-word-chip { font-size: clamp(28px, 9vw, 44px); padding: 6px 20px; }

  .sb-pics { top: 250px; gap: 8px; }
  .sb-pic { width: 92px; min-height: 96px; }
  .sb-pic-emoji { font-size: 44px; }

  .sb-sound-screen { top: 150px; }
  .sb-frame { top: 226px; }
  .sb-collected { display: none !important; }   /* declutter L2 on mobile */

  .sb-chunks { top: 196px; gap: 10px; }
  .sb-chunk { min-width: 70px; min-height: 66px; font-size: 26px; }

  /* When the beat pad is the bottom bar, blend is hidden anyway (L3 clap). */
}

/* Mobile layout — corrected: stacked bottom bars (no side-by-side overlap)
   and a consistent mid-scene vertical rhythm. Last block wins. */
@media (max-width: 640px) {
  .sb-banner { top: 138px; }

  /* Bottom cluster, stacked bottom→up: tray → BLEND → recipe */
  .sb-cubes, .sb-outfits, .sb-beatpad {
    bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  }
  .sb-blend {
    left: 8px; right: 8px; transform: none; flex-direction: row; justify-content: center;
    bottom: calc(108px + env(safe-area-inset-bottom, 0px));
  }
  .sb-blend-btn { flex: 1 1 auto; min-width: 0; }
  .sb-recipe {
    left: 8px; right: 8px; transform: none; top: auto;
    bottom: calc(174px + env(safe-area-inset-bottom, 0px));
    justify-content: center;
  }

  /* Mid-scene overlays */
  .sb-word { top: 208px; }
  .sb-pics { top: 284px; }
  .sb-sound-screen { top: 188px; }
  .sb-frame { top: 266px; }
  .sb-chunks { top: 208px; }
}

/* Mobile: give the pics / chunks rows full width so they stay a single row
   and don't shrink-wrap into a vertical stack. */
@media (max-width: 640px) {
  .sb-pics, .sb-chunks {
    left: 8px; right: 8px; transform: none; width: auto;
  }
  .sb-pic { width: 30%; min-width: 0; max-width: 108px; }
  .sb-word { top: 214px; }
}

/* Mobile: clear the (sometimes 2-line) instruction chip above the L2 screen. */
@media (max-width: 640px) {
  .sb-sound-screen { top: 214px; }
  .sb-frame { top: 298px; }
}

/* Mobile: drop the L3 chunks below the (up-to-2-line) instruction chip. */
@media (max-width: 640px) {
  .sb-chunks { top: 250px; }
}

/* Locked level buttons: dimmed, with the padlock in the label. */
.sb-level-btn.is-locked { opacity: .5; }

/* ═══════════════════════════════════════════════════════════════════
   Follow-up tweaks: red speech bubbles, mint HUD (matching Mirror maze),
   and the 3D strawberry mascot canvas.
   ═══════════════════════════════════════════════════════════════════ */

/* Speech bubbles → soft peach #F9D9D2 with dark plum text (tail included). */
.sb-speech-bubble { background: #F9D9D2; border-color: #F9D9D2; }
.sb-speech-bubble p { color: #2B0326; }
.sb-speech-bubble::before { background: #F9D9D2; border-left-color: #F9D9D2; border-bottom-color: #F9D9D2; }

/* HUD "% complete" box → mint colourway, like the reference. Scoping --nav
   locally recolours the whole HUD (box, text, bar, Back/Menu) to mint. */
.sb-hud-group { --nav: #A1FCD2; --nav-dark: #6fcea3; }

/* 3D strawberry mascot: the WebGL model bobs itself, so drop the wrapper
   sway and the old <img> saturation filter. */
.sb-mascot { animation: none; }
.sb-mascot-model { filter: none; background: transparent; }
canvas.sb-mascot-model { width: 100%; height: 100%; display: block; }

/* Level 2 spelling-outfit buttons → pale blue #D2F4FB with dark plum text. */
.sb-outfit { background: #D2F4FB; color: #2B0326; }

/* BLEND button → same yellow as the lever handle (#F8D648), dark ink. */
.sb-blend-btn { background: #F8D648; color: #2B0326; box-shadow: 0 7px 0 #C9A400, 0 12px 20px rgba(0,0,0,.38); }
.sb-blend-btn:active { box-shadow: 0 3px 0 #C9A400, 0 6px 12px rgba(0,0,0,.38); }
.sb-blend-btn:disabled { box-shadow: 0 7px 0 #C9A400; }

/* Level 2 "Outfits found" tokens sit below the HUD so they never overlap
   the Back/Menu buttons in the top-right. */
.sb-collected { top: 31%; }

/* ── Peach mascot placement (the instruction chip was removed; the peach's
   bubble is now the single instruction surface) ── */
@media (min-width: 641px) {
  /* Centred at the top, like the Mirror maze lemon. */
  .sb-mascot-dock { left: 50%; right: auto; transform: translateX(-50%); justify-content: center; max-width: none; }
  .sb-speech-bubble { width: min(46vw, 380px); }
}
@media (max-width: 640px) {
  /* Show the peach + bubble on mobile too (it carries the instructions now),
     anchored top-left and capped so it clears the top-right HUD. */
  .sb-mascot-dock {
    display: flex !important;
    position: absolute; top: 8px; left: 8px; right: auto; bottom: auto;
    transform: none; justify-content: flex-start; z-index: 16; max-width: none;
  }
  .sb-mascot { width: 50px; height: 50px; }
  .sb-speech-bubble { width: auto; max-width: calc(100vw - 200px); }
}

/* Opening screen: a solid plum background behind the title card (like the
   exploding-dots intro), rather than the 3D scene showing through. */
#titleOverlay { background: var(--plum); }

/* Sound cubes use Raleway, bold (not the rounded display face). */
.sb-cube, .sb-recipe-cube { font-family: var(--font-brand); font-weight: 800; }

/* ── Level 1 sound-cube colours (tray + in-jug), per request ── */
.sb-cube, .sb-recipe-cube { background: #65C0E0; color: #fff; }            /* consonant → blue */
.sb-cube.is-vowel, .sb-recipe-cube.is-vowel { background: #D2F4FB; color: #2B0326; }  /* vowel → pale blue */
.sb-cube.is-digraph, .sb-recipe-cube.is-digraph { background: #67B893; color: #fff; } /* digraph → green */

/* Speaker/replay button symbol + outline → mint #A1FCD2. */
.sb-replay { border-color: #A1FCD2; color: #A1FCD2; }
.sb-replay:hover { background: #A1FCD2; color: var(--plum); }

/* Keep the recipe docked at the bottom on mobile (override the desktop 40%). */
@media (max-width: 640px) {
  .sb-recipe { top: auto; }
}

/* BLEND + Empty docked up level with the jug top on desktop (right of it). */
@media (min-width: 641px) {
  .sb-blend { left: 62%; right: auto; top: 17%; bottom: auto; transform: none; }
}

/* "BLEND" text — the Fruit3D pink→red→orange gradient (like the exploding-dots
   "BANG"). Applied to an inner span so the button keeps its yellow fill. */
.sb-blend-label {
  background-image: linear-gradient(110deg, #FF7AA2, #FF4D6D 55%, #FF9D57);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* Opening-card level buttons → mint #A1FCD2 (matching the exploding-dots intro). */
.sb-level-btn.sb-btn--primary {
  background: #A1FCD2; color: var(--plum); border-color: #A1FCD2;
  box-shadow: 0 6px 0 #6fcea3, 0 12px 20px rgba(0,0,0,.3);
}
.sb-level-btn.sb-btn--primary:hover { background: #b6ffdd; }
.sb-level-btn.sb-btn--primary:active { box-shadow: 0 3px 0 #6fcea3, 0 8px 14px rgba(0,0,0,.3); }
.sb-level-btn.sb-btn--outline { color: #A1FCD2; border-color: #A1FCD2; }
.sb-level-btn.sb-btn--outline:hover { background: #A1FCD2; color: var(--plum); }

/* ── Level 1 picture-match question card (faded scene, peach on top) ── */
#questionOverlay { background: rgba(43, 3, 38, 0.82); }
.sb-mascot-dock.on-card {
  position: static; top: auto; left: auto; right: auto; bottom: auto;
  transform: none; justify-content: center; margin: 0 auto 6px; max-width: none; display: flex;
}
.sb-mascot-dock.on-card .sb-speech-bubble { display: none; }
.sb-mascot-dock.on-card .sb-mascot { width: 88px; height: 88px; animation: none; }
.sb-quiz-word { display: flex; justify-content: center; margin: 4px 0 14px; }
.sb-quiz-word .sb-word-chip { cursor: pointer; font-size: clamp(30px, 5vh, 44px); }
.sb-quiz-card .sb-quiz-options { margin-top: 8px; }
.sb-quiz-card .sb-pic { cursor: pointer; }
.sb-quiz-prompt { color: var(--brand-pink); }

/* Intro/teaching card CTAs → mint #A1FCD2; bold keywords → yellow #F8D648. */
.sb-light-card .sb-btn--primary {
  background: #A1FCD2; color: var(--plum); border: none;
  box-shadow: 0 8px 0 #6fcea3, 0 14px 22px rgba(0,0,0,.4);
}
.sb-light-card .sb-btn--primary:hover { background: #b6ffdd; }
.sb-light-card .sb-btn--primary:active { transform: translateY(3px) scale(.98); box-shadow: 0 4px 0 #6fcea3, 0 8px 14px rgba(0,0,0,.4); }
.sb-light-card p b { color: #F8D648; }

/* "Turn Sound On" button on the title card (below the levels), mint #A1FCD2.
   Doubles as an explicit audio-unlock tap for mobile. */
.sb-sound-toggle {
  display: inline-flex; align-items: center; gap: 10px;
  margin: 20px auto 0; padding: 10px 22px;
  border-radius: 999px; background: transparent;
  border: 2px solid #A1FCD2; color: #A1FCD2;
  font-family: var(--font-brand); font-weight: 800; font-size: 16px;
  cursor: pointer; transition: background .15s, color .15s, transform .1s;
}
.sb-sound-toggle svg { width: 22px; height: 22px; display: block; }
.sb-sound-toggle:hover { background: #A1FCD2; color: var(--plum); }
.sb-sound-toggle:active { transform: scale(.97); }
.sb-sound-toggle.is-on { background: #A1FCD2; color: var(--plum); }

/* ═══════════════════════════════════════════════════════════════════
   MOBILE LAYOUT — authoritative (last block wins). Blender sits small in
   the upper area (camera pulled back); controls dock cleanly at the bottom:
   recipe/drop-zone → BLEND+Empty → sound-cube tray, no overlaps.
   ═══════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  /* Sound-cube tray / spelling shelf / beat pad — the very bottom bar. */
  .sb-cubes, .sb-outfits, .sb-beatpad {
    left: 6px; right: 6px; transform: none; max-width: none;
    top: auto; bottom: calc(6px + env(safe-area-inset-bottom, 0px));
    gap: 8px; padding: 10px 10px 12px;
  }
  .sb-cube { min-width: 48px; height: 52px; font-size: 21px; }
  .sb-outfit { min-width: 52px; height: 54px; font-size: 22px; }

  /* BLEND + Empty — a row just above the tray. */
  .sb-blend {
    left: 6px; right: 6px; transform: none; top: auto;
    bottom: calc(92px + env(safe-area-inset-bottom, 0px));
    flex-direction: row; justify-content: center; gap: 8px;
  }
  .sb-blend-btn { flex: 1 1 auto; min-width: 0; min-height: 54px; font-size: 19px; padding: 10px 16px; }
  .sb-mini-btn { flex: 0 0 auto; min-height: 48px; }

  /* Recipe drop-zone — a bar above BLEND (short drag from the tray). */
  .sb-recipe {
    left: 6px; right: 6px; transform: none; top: auto;
    bottom: calc(150px + env(safe-area-inset-bottom, 0px));
    justify-content: center; min-height: 50px;
  }

  /* Mid-scene overlays for L2 / L3 (L1 uses the question card). */
  .sb-word { top: 150px; }
  .sb-sound-screen { top: 132px; }
  .sb-frame { top: 214px; }
  .sb-collected { display: none !important; }
  .sb-chunks { top: 150px; left: 6px; right: 6px; transform: none; }

  /* HUD compact, peach top-left (kept), replay stays top-left too. */
  .sb-hud-group { top: 6px; right: 6px; }
  .sb-replay { top: 8px; left: 8px; bottom: auto; right: auto; width: 40px; height: 40px; }

  /* Question card: full-width-ish, pics stay a row. */
  .sb-quiz-card .sb-pic { width: 30%; min-width: 0; }
  .sb-mascot-dock.on-card .sb-mascot { width: 70px; height: 70px; }
}

/* Turn Sound On → filled pink background (white icon + text). */
.sb-sound-toggle { background: #EB7CB2; color: #fff; border-color: #EB7CB2; }
.sb-sound-toggle:hover { background: #f090bf; color: #fff; }
.sb-sound-toggle.is-on { background: #EB7CB2; color: #fff; }

/* Question-card Back (top-left) / Next (bottom-right) buttons → mint #A1FCD2
   (matching the Mirror maze quiz cards). */
.sb-quiz-back, .sb-quiz-next { border-color: #A1FCD2; color: #A1FCD2; }
.sb-quiz-back:hover, .sb-quiz-next:hover { background: #A1FCD2; color: var(--plum); }
.sb-quiz-card .sb-pic.is-done { opacity: .4; pointer-events: none; }

/* On the question card, the peach shows a speech bubble with the blended word
   (replacing the old white word chip). Peach + bubble sit as a row at the top. */
.sb-mascot-dock.on-card { align-items: center; gap: 12px; }
.sb-mascot-dock.on-card.show-bubble .sb-speech-bubble { display: block; width: auto; max-width: 62%; }
.sb-mascot-dock.on-card .sb-speech-bubble p {
  font-family: var(--font-round); font-weight: 700;
  font-size: clamp(30px, 5.4vh, 46px); letter-spacing: .02em;
}
