/* ==========================================================================
   Qafiya Little Muslim — V2 styles
   Landscape-first, touch-first. Sizes scale with the viewport's short side.
   ========================================================================== */
/* ==========================================================================
   Fonts — all hosted locally (fonts/). No CDN for Malayalam or Arabic.
   • Manjari (SMC, SIL OFL 1.1) — Malayalam. fonts/manjari/OFL.txt
   • KFGQPC Uthman Taha Naskh (King Fahd Glorious Qur'an Printing Complex) — Arabic learning text.
     Bundled: fonts/kfgqpc/ Bold (primary, weight 700) and Regular (v0.10, both unmodified) + LICENSE.txt. If they are missing, the
     local system Naskh fonts below are used. NOT the separate "KFGQPC Uthmanic Hafs" Qur'an font.
   ========================================================================== */
@font-face { font-family: 'Manjari'; src: url('../fonts/manjari/Manjari-Regular.otf') format('opentype'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Manjari'; src: url('../fonts/manjari/Manjari-Bold.otf') format('opentype'); font-weight: 700; font-style: normal; font-display: swap; }
@font-face {
  font-family: 'KFGQPC Uthman Taha Naskh';
  /* Original, unmodified TTF (licence forbids altering it, so no WOFF2 conversion or subsetting) */
  src: local('KFGQPC Uthman Taha Naskh'), local('KFGQPCUthmanTahaNaskh'),
       url('../fonts/kfgqpc/KFGQPC%20Uthman%20Taha%20Naskh%20Regular.ttf') format('truetype');
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF, U+0020, U+00A0, U+200C-200F, U+25CC;
}
@font-face {
  font-family: 'KFGQPC Uthman Taha Naskh';
  /* Primary Arabic face: the real Bold cut (v0.10, unmodified; TrueType outlines despite the .otf name) */
  src: local('KFGQPC Uthman Taha Naskh Bold'), local('KFGQPCUthmanTahaNaskh-Bold'),
       url('../fonts/kfgqpc/KFGQPC%20Uthman%20Taha%20Naskh%20Bold.otf') format('opentype');
  font-weight: 700; font-style: normal; font-display: swap;
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF, U+0020, U+00A0, U+200C-200F, U+25CC;
}

:root {
  --ink: #1f3d40;
  --pink: #e2187f; --pink-d: #a40c5a;
  --teal: #16a08c; --teal-d: #0b6b5d;
  --gold: #f6bd36; --gold-d: #c98a0c;
  --white: #fffdf6;
  --sky: #7cd0f5;
  --bar: clamp(64px, 11.5vmin, 88px);           /* tall enough for a 2-line Malayalam instruction */
  --u: min(1vw, 1.7vh);              /* layout unit tuned for landscape */
  --vh: 100vh;
  --scene-h: calc(var(--vh) - var(--bar));                     /* available scene height (no top bar / system UI) */
  --helper-h: clamp(132px, calc(var(--scene-h) * .42), 450px); /* corner Hanan height: 42% of scene (was 37%) — keep in step with mascot.js SIZES.helper */
  --helper-gutter: calc(var(--helper-h) * .6 + 14px);          /* space kept free for him */
  --font-ui: 'Baloo 2', 'Manjari', 'Noto Sans Malayalam', 'Nirmala UI', system-ui, sans-serif;  /* Malayalam glyphs fall through to Manjari */
  --font-ml: 'Manjari', 'Noto Sans Malayalam', 'Nirmala UI', 'Kartika', sans-serif;
  --font-ar: 'KFGQPC Uthman Taha Naskh', 'Traditional Arabic', 'Noto Naskh Arabic', 'Geeza Pro', 'Segoe UI', 'Arabic Typesetting', serif;
  --ar-shadow: 0 2px 6px rgba(0, 0, 0, .22);                   /* the ONLY effect on Arabic glyphs: a soft shadow, no extrusion */
}
@supports (height: 100dvh) { :root { --vh: 100dvh; } }
.stage.screen-intro { --scene-h: var(--vh); }      /* Intro has no top bar */
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; overflow: hidden; }
body {
  font-family: var(--font-ui); color: var(--ink); background: var(--sky);
  -webkit-user-select: none; user-select: none; overscroll-behavior: none;
}
[lang="ml"], :lang(ml) { font-family: var(--font-ml); }
button { font: inherit; color: inherit; cursor: pointer; border: 0; background: none; padding: 0; }
button:focus-visible { outline: 4px solid var(--gold); outline-offset: 3px; }
[hidden] { display: none !important; }

/* Arabic: always RTL with a proper Naskh face so dots are correctly shaped */
/* Arabic: the real KFGQPC Uthman Taha Naskh Bold cut (weight 700 maps to the Bold file) — never synthetic bold/italic, no stretching */
.ar { font-family: var(--font-ar); direction: rtl; unicode-bidi: isolate; font-weight: 700; font-style: normal; font-synthesis: none; line-height: 1.25; display: inline-block; }

/* Teaching form (ui.js arabic()): the dotless body + separate dots. The zero-size anchor sits on the
   baseline at the left edge of the body (RTL flow puts it after the letter), so dots are placed in em. */
.ar-dots { display: inline-block; position: relative; width: 0; height: 0; vertical-align: baseline; }
.ar-dots b { position: absolute; width: .106em; height: .106em; background: currentColor; border-radius: .014em; transform: rotate(45deg); }

#app { position: fixed; inset: 0; display: flex; flex-direction: column; }

/* ---------- top bar ---------- */
.topbar {
  height: var(--bar); flex: 0 0 auto; display: flex; align-items: center; gap: 10px;
  padding: 0 max(14px, env(safe-area-inset-right)) 0 max(14px, env(safe-area-inset-left));
  background: rgba(255, 253, 246, .92); box-shadow: 0 4px 0 rgba(0, 0, 0, .08); z-index: 20;
}
.topbar.hidden { display: none; }
.tb-title { flex: 1; margin: 0; font-size: clamp(18px, 3.4vmin, 28px); font-weight: 800; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Hanan's instruction bubble (top bar). Text is fitted by QLM.ui.fitCaption(): comfortable size first,
   down to 16px, and if it still does not fit the bubble grows below the bar — never clipped. */
.tb-caption {
  --cap-max: clamp(18px, 3.3vmin, 25px);
  display: none; flex: 1; min-width: 0; align-items: center; gap: var(--cap-gap); align-self: center; position: relative;
  --cap-gap: clamp(10px, 1.4vw, 18px);                      /* breathing room between Hanan's face and the bubble */
  margin-left: clamp(4px, 1.2vw, 18px);                     /* the whole caption sits a little right of the nav buttons */
}
.cap-avatar {
  flex: 0 0 auto; width: calc(var(--bar) - 14px); aspect-ratio: 1; border-radius: 50%;
  background: #dff3ff url(../assets/hanan/point-right.png) no-repeat 32% 9% / 215% auto;   /* framed on his face */
  box-shadow: 0 3px 0 rgba(0, 0, 0, .1), inset 0 0 0 3px #fff;
}
.cap-bubble {
  position: relative; flex: 1; min-width: 0; display: flex; align-items: center;
  height: calc(var(--bar) - 8px); padding: 2px 18px; overflow: hidden;
  background: #fffef6; border-radius: 20px; border: 3px solid #ffd75e;
  box-shadow: 0 3px 0 rgba(201, 138, 12, .25);
}
.tb-caption::after { content: ''; position: absolute; left: calc(var(--bar) - 14px + var(--cap-gap) - 11px); top: 50%; margin-top: -8px; z-index: 1;
  border-right: 11px solid #ffd75e; border-top: 8px solid transparent; border-bottom: 8px solid transparent; }
.cap-text { display: block; width: 100%; font-size: var(--cap-max); font-weight: 700; line-height: 1.5; color: #24414a; letter-spacing: .01em; overflow-wrap: anywhere; }
.cap-text:lang(ml) { font-family: var(--font-ml); font-weight: 700; line-height: 1.5; letter-spacing: 0; word-spacing: .08em; }
/* Too long even at the minimum size: let the bubble drop below the bar so every line shows */
.tb-caption.expanded { align-self: flex-start; margin-top: 4px; z-index: 25; }
.tb-caption.expanded::after { top: calc((var(--bar) - 14px) / 2 + 4px); }
.tb-caption.expanded .cap-bubble { height: auto; overflow: visible; padding: 6px 18px; box-shadow: 0 8px 18px rgba(20, 50, 80, .18), 0 3px 0 rgba(201, 138, 12, .25); }
.topbar.captioning .tb-title { display: none; }
.topbar.captioning .tb-caption { display: flex; animation: popin .25s; }
.tb-actions { display: flex; gap: 10px; }
.btn-round {
  width: calc(var(--bar) - 14px); height: calc(var(--bar) - 14px); border-radius: 50%;
  background: #fff; box-shadow: 0 4px 0 #c9dcd6, inset 0 0 0 3px #d9ece6; font-size: clamp(18px, 3.6vmin, 26px);
  display: grid; place-items: center; transition: transform .1s;
}
.btn-round:active { transform: translateY(3px); box-shadow: 0 1px 0 #c9dcd6, inset 0 0 0 3px #d9ece6; }
.tb-stars { background: var(--gold); color: #5a3a00; border-radius: 999px; padding: 4px 14px; font-weight: 800; font-size: clamp(16px, 3vmin, 22px); box-shadow: 0 4px 0 var(--gold-d); }

/* ---------- stage ---------- */
.stage { position: relative; flex: 1; overflow: hidden; outline: none; }
.landscape { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; }
.stage > div:not(.landscape):not(.scene):not(.scene-fg) { position: relative; z-index: 1; }

/* ---------- V3 layered scenes (js/core/scene.js) ---------- */
.scene { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.scene-bg { position: absolute; inset: 0; background-position: center bottom; background-size: cover; background-repeat: no-repeat; }
/* Cloud strip: exactly one tile per viewport width, so the loop is seamless; transform-only animation */
.scene-clouds { position: absolute; left: 0; top: 0; width: 200vw; height: 21.9vw; max-height: 48%;
  background: url(../assets/scenes/clouds.svg) left top / 100vw 21.9vw repeat-x; animation: clouds 140s linear infinite; will-change: transform; }
@keyframes clouds { to { transform: translateX(-100vw); } }
.scene-fg { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; height: clamp(56px, calc(var(--scene-h) * .14), 150px);
  background: url(../assets/scenes/grass-fg.svg) center bottom / auto 100% repeat-x; pointer-events: none; }
.drift { animation: drift 30s linear infinite alternate; }
@keyframes drift { to { transform: translateX(80px); } }
/* Mid layer: props from js/content/scenes.js, each pinned to an edge so it stays outside the screen's safe zones */
.scene-mid { position: absolute; inset: 0; }
.prop { position: absolute; display: block; max-width: none; pointer-events: none; user-select: none; }

/* Welcome Meadow (Intro): a toy pinwheel at the bottom-left edge, a blossom tree at the right edge below the speech bubble */
.scene--welcome-meadow .prop-pinwheel { left: .8vw; bottom: calc(var(--scene-h) * .05); height: calc(var(--scene-h) * .28); width: auto;
  transform-origin: 50% 100%; animation: pinRock 4s ease-in-out infinite alternate; }
.scene--welcome-meadow .prop-blossom-tree { right: .6vw; bottom: calc(var(--scene-h) * .14); height: calc(var(--scene-h) * .36); width: auto;
  transform-origin: 60% 100%; animation: treeSway 7s ease-in-out infinite alternate; }
@keyframes pinRock { from { transform: rotate(-3deg); } to { transform: rotate(3deg); } }

/* Sunny Letter Hills (29-letter map): kite in the top of Hanan's gutter, pennant post at the right edge */
.scene--letter-hills .prop-kite { left: calc(var(--helper-gutter) * .14); top: calc(var(--scene-h) * .05); height: calc(var(--scene-h) * .17); width: auto;
  transform-origin: 50% 85%; animation: kiteBob 5s ease-in-out infinite alternate; }
.scene--letter-hills .prop-pennant { right: .6vw; bottom: calc(var(--scene-h) * .015); height: calc(var(--scene-h) * .2); width: auto; }
@keyframes kiteBob { from { transform: rotate(-5deg) translateY(0); } to { transform: rotate(5deg) translateY(calc(var(--scene-h) * .015)); } }

/* Letter Activity Hub (letter menu): bunting along the top edge, signpost behind Hanan with its blank arrows above his head */
.scene--activity-hub .prop-bunting { left: 0; top: 0; width: 100%; height: calc(var(--scene-h) * .1); transform-origin: 50% 0; animation: bunting 4s ease-in-out infinite alternate; }
.scene--activity-hub .prop-signpost { right: .5vw; bottom: 0; height: calc(var(--scene-h) * .97); width: auto; }
/* new foreground strips are drawn edge-to-edge, not tiled. The strip's height follows the viewport WIDTH
   (art is 1920×260; the top 60 units are empty sky) so the art is never cropped: grass tufts and flower
   heads stay whole at every aspect ratio instead of being sliced flat by a height-clamped box. */
.scene-fg--letter-hills, .scene-fg--activity-hub, .scene-fg--welcome-meadow { height: calc(100vw * 200 / 1920); background-size: 100% auto; }
@keyframes bunting { from { transform: scaleY(1); } to { transform: scaleY(1.08) rotate(.3deg); } }
@keyframes treeSway { from { transform: rotate(-.8deg); } to { transform: rotate(.8deg); } }
@media (max-aspect-ratio: 3/2) {
  /* 4:3: the Intro title column and speech bubble spread wider, so the pinwheel steps out and the tree shrinks */
  .scene--welcome-meadow .prop-pinwheel { display: none; }
  .scene--welcome-meadow .prop-blossom-tree { height: calc(var(--scene-h) * .3); bottom: calc(var(--scene-h) * .12); }
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 56px; padding: 8px 26px; border-radius: 22px; font-weight: 800; font-size: clamp(18px, 3.4vmin, 26px);
  transition: transform .1s, box-shadow .1s, opacity .2s;
}
.btn:active:not(:disabled) { transform: translateY(4px); }
.btn:disabled { opacity: .45; cursor: default; }
.btn-pink { background: var(--pink); color: #fff; box-shadow: 0 6px 0 var(--pink-d); }
.btn-pink:active:not(:disabled) { box-shadow: 0 2px 0 var(--pink-d); }
.btn-teal { background: var(--teal); color: #fff; box-shadow: 0 6px 0 var(--teal-d); }
.btn-white { background: #fff; color: var(--ink); box-shadow: 0 6px 0 #c4d8d1; }
.btn-small { min-height: 42px; padding: 4px 16px; font-size: 16px; border-radius: 14px; }
.btn.danger { background: #ffe1e1; color: #a1112b; }
.btn-next.ready, .btn-next:not(:disabled) { animation: nudge 1.6s ease-in-out infinite; }
@keyframes nudge { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.06); } }

/* ==========================================================================
   Hanan mascot component (js/core/mascot.js)
   Size is driven by --mh (image height); width follows each pose's aspect ratio.
   ========================================================================== */
.mascot { position: relative; display: inline-flex; flex-direction: column; align-items: center; justify-content: flex-end; flex: 0 0 auto; --mh: 200px; }
button.mascot { cursor: pointer; border-radius: 24px; }
.mascot-figure { position: relative; z-index: 1; display: block; transform-origin: 50% 100%; animation: breathe 3.4s ease-in-out infinite; }
.mascot-img { display: block; height: var(--mh); width: auto; max-width: none; pointer-events: none; -webkit-user-drag: none; filter: drop-shadow(0 6px 8px rgba(20, 60, 80, .2)); }
/* Soft contact shadow so Hanan stands on the ground instead of floating */
.mascot-ground {
  position: absolute; z-index: 0; left: 50%; bottom: calc(var(--mh) * -.018); transform: translateX(-50%);
  width: calc(var(--mh) * .42); height: calc(var(--mh) * .07); border-radius: 50%;
  background: radial-gradient(closest-side, rgba(20, 60, 35, .38), rgba(20, 60, 35, 0));
}
.mascot[data-pose="jump"] .mascot-ground { width: calc(var(--mh) * .28); opacity: .5; bottom: calc(var(--mh) * -.07); }

/* Height = scene height × --ms (set per size token by mascot.js), limited by an optional
   column width (--mw ÷ aspect ratio) and clamped to sane pixel bounds. */
.mascot {
  --mh: clamp(var(--mh-min, 96px),
              min(calc(var(--scene-h) * var(--ms, .5)), calc(var(--mw, 100vw) / var(--ar, .5))),
              var(--mh-max, 760px));
}
.mascot--size-home   { --mh-max: 920px; }
.mascot--size-reward { --mh-max: 700px; --mh-min: 140px; }
.mascot--size-helper { --mh: var(--helper-h); }    /* gutter math depends on this exact height */
.mascot--size-helper .mascot-img { filter: none; } /* helper: lighter rendering, ground shadow only */
/* Scene positioning: feet on the scene's ground line */
.mascot--at-bottom-right { position: absolute !important; right: var(--ax, 3vw); bottom: var(--ay, 3%); z-index: 3; }
.mascot--at-bottom-left  { position: absolute !important; left: var(--ax, 3vw);  bottom: var(--ay, 3%); z-index: 3; }

@keyframes breathe { 50% { transform: translateY(-1.2%) scale(1.01, .995); } }
.mascot--hop .mascot-figure { animation: hop .45s ease-out; }
@keyframes hop { 40% { transform: translateY(-7%) scale(.98, 1.03); } 70% { transform: translateY(0) scale(1.03, .97); } }
/* While narration plays, the speaking Hanan bobs gently */
body.talking [data-speaker] .mascot-figure { animation: talkbob .4s ease-in-out infinite alternate; }
@keyframes talkbob { to { transform: translateY(-2.5%) rotate(-1.2deg); } }
button.mascot:active .mascot-figure { transform: scale(.96); }
@keyframes wave { 0%, 100% { transform: rotate(0); } 50% { transform: rotate(-16deg); } }

/* Speech bubble (used where there is no top bar, i.e. Home): sits beside Hanan's head */
.mascot-say {
  position: absolute; z-index: 2; left: 86%; top: 6%; width: max-content; max-width: min(30vw, 340px);
  background: #fff; border-radius: 22px; padding: 10px 16px; text-align: left;
  font-size: clamp(15px, 3vmin, 22px); font-weight: 700; line-height: 1.3; color: var(--ink);
  box-shadow: 0 5px 0 rgba(0, 0, 0, .1); pointer-events: none;
  opacity: 0; transform: scale(.85); transform-origin: left bottom; transition: opacity .25s, transform .25s;
}
.mascot-say::before { content: ''; position: absolute; left: -12px; bottom: 16px; border-right: 14px solid #fff; border-top: 9px solid transparent; border-bottom: 9px solid transparent; }
.mascot.saying .mascot-say { opacity: 1; transform: none; }
.mascot-say:lang(ml) { font-family: var(--font-ml); line-height: 1.55; font-size: clamp(16px, 3.1vmin, 23px); }

/* Corner helper on menu + game screens. Content on those screens keeps a left gutter (--helper-gutter). */
.helper { position: fixed; left: max(6px, env(safe-area-inset-left)); bottom: 6px; z-index: 30; }
body.celebrating .helper { visibility: hidden; }

/* ---------- overlay / celebration ---------- */
.overlay { position: fixed; inset: 0; z-index: 50; background: rgba(20, 40, 60, .45); display: grid; place-items: center; opacity: 0; transition: opacity .3s; }
.overlay.show { opacity: 1; }
.done-wrap { position: relative; display: flex; align-items: center; justify-content: center; gap: clamp(8px, 3vw, 40px); max-width: 96vw; }
.done-card {
  position: relative; background: var(--white); border-radius: 36px; padding: 24px 40px 30px; text-align: center;
  box-shadow: 0 12px 0 #d7c79a; width: min(500px, 58vw); animation: popin .45s cubic-bezier(.2, 1.6, .4, 1);
}
/* Celebrating Hanan: centre stage beside the card, with a warm glow behind him */
.done-mascot { position: relative; animation: popin .5s .1s cubic-bezier(.2, 1.6, .4, 1) both; }
.done-mascot::before { content: ''; position: absolute; inset: 0 -30% 4%; background: radial-gradient(circle, rgba(255, 233, 140, .95), rgba(255, 233, 140, 0) 62%); animation: glow 2s ease-in-out infinite; }
@keyframes glow { 50% { transform: scale(1.08); opacity: .75; } }
.done-mascot .mascot[data-pose="jump"] .mascot-figure { animation: jumpjoy 1s ease-in-out infinite; }
.done-mascot .mascot[data-pose="jump"] .mascot-ground { animation: shadowjoy 1s ease-in-out infinite; }
@keyframes jumpjoy { 50% { transform: translateY(-8%); } }
@keyframes shadowjoy { 50% { transform: translateX(-50%) scale(.7); opacity: .3; } }
.done-card h2 { margin: 4px 0; font-size: clamp(28px, 6vmin, 46px); color: var(--pink); }
.star-row { display: flex; justify-content: center; gap: 10px; margin: 6px 0 18px; }
.big-star { font-size: clamp(44px, 10vmin, 72px); color: #e3dccb; transform: scale(0); animation: starpop .5s forwards; }
.big-star.on { color: var(--gold); text-shadow: 0 4px 0 var(--gold-d); }
.done-actions { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
@keyframes popin { from { transform: scale(.5); opacity: 0; } }
@keyframes starpop { 60% { transform: scale(1.3); } to { transform: scale(1); } }
.confetti { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.confetti i { position: absolute; top: -20px; width: 12px; height: 18px; border-radius: 3px; animation: fall linear forwards; }
@keyframes fall { to { transform: translateY(110vh) rotate(720deg); } }
.burst { position: fixed; z-index: 60; pointer-events: none; font-size: 34px; color: var(--gold); transform: translate(-50%, -50%); animation: burst .9s ease-out forwards; }
@keyframes burst { to { transform: translate(-50%, -160%) scale(1.6); opacity: 0; } }
.shake { animation: shake .5s; }
@keyframes shake { 20%, 60% { translate: -8px 0; } 40%, 80% { translate: 8px 0; } }

/* ---------- settings ---------- */
.settings { position: fixed; inset: 0; z-index: 70; background: rgba(20, 40, 60, .55); display: grid; place-items: center; overflow: auto; padding: 16px; }
.settings-card { background: var(--white); border-radius: 28px; padding: 22px 26px; width: min(560px, 100%); box-shadow: 0 10px 0 #cfd9d3; }
.settings-card h2 { margin: 0 0 10px; }
.set-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 2px dashed #e2ece7; font-weight: 700; }
.seg { display: flex; background: #e8f2ee; border-radius: 14px; padding: 4px; }
.seg button { padding: 6px 14px; border-radius: 10px; font-weight: 700; }
.seg button.on { background: var(--teal); color: #fff; }
.toggle { min-width: 74px; padding: 6px 14px; border-radius: 999px; background: #e3e8e6; font-weight: 800; }
.toggle.on { background: var(--teal); color: #fff; }
.set-info { font-size: 14px; color: #557; margin: 12px 0 16px; line-height: 1.6; }

/* ---------- rotate hint ---------- */
/* Landscape-only: friendly rotate screen */
.rotate { position: fixed; inset: 0; z-index: 90; display: grid; place-items: center; text-align: center; padding: 24px;
  background: radial-gradient(circle at 50% 30%, #d9f4ff, #7cd0f5 70%); }
.rotate-card { display: flex; flex-direction: column; align-items: center; gap: 10px; max-width: 90vw; }
.rotate-card h2 { margin: 6px 0 0; font-size: clamp(22px, 6vw, 34px); color: var(--ink); }
.rotate-card p { margin: 0; font-size: clamp(16px, 4.2vw, 22px); color: #11506a; }
.rotate-ml { font-family: var(--font-ml); line-height: 1.6; }
.rotate-hanan .mascot { --mh: min(30vh, 260px); }
.rotate-phone { width: 64px; height: 104px; border-radius: 14px; border: 6px solid var(--ink); background: #fff; position: relative; animation: turn 2.4s ease-in-out infinite; }
.rotate-phone i { position: absolute; left: 50%; bottom: 6px; width: 10px; height: 10px; margin-left: -5px; border-radius: 50%; background: var(--ink); }
@keyframes turn { 0%, 20% { transform: rotate(0); } 50%, 80% { transform: rotate(-90deg); } 100% { transform: rotate(0); } }

/* ==========================================================================
   Screen 1 — Home
   ========================================================================== */
.home { position: absolute !important; inset: 0; z-index: 3 !important; display: flex; align-items: center; justify-content: center; gap: 4vw; padding: 3vh 4vw; }
.home-title { text-align: center; }
.home-badge { display: inline-block; background: #fff; border-radius: 26px; padding: 6px 22px; box-shadow: 0 6px 0 #c4d8d1; }
.home-letters { font-size: clamp(34px, 8vmin, 60px); color: var(--pink); letter-spacing: 12px; }
.home h1 { margin: 10px 0 0; font-size: clamp(40px, 11vmin, 92px); line-height: .95; color: #fff; font-weight: 800; text-shadow: 0 5px 0 var(--pink-d), 0 0 2px var(--pink-d); -webkit-text-stroke: 2px var(--pink); }
.home-sub { margin: 6px 0 18px; font-size: clamp(16px, 3.4vmin, 26px); font-weight: 700; color: #11506a; }
.btn-play { background: var(--gold); color: #5a3a00; box-shadow: 0 8px 0 var(--gold-d); font-size: clamp(28px, 7vmin, 50px); padding: 10px 46px; border-radius: 999px; animation: nudge 1.8s ease-in-out infinite; }
.btn-play:active { transform: translateY(5px); box-shadow: 0 3px 0 var(--gold-d); }
.play-tri { width: 0; height: 0; border-left: 26px solid #5a3a00; border-top: 16px solid transparent; border-bottom: 16px solid transparent; }
.home-stars { margin-top: 14px; display: inline-block; background: rgba(255,255,255,.85); border-radius: 999px; padding: 4px 16px; font-size: 20px; color: #8a5a00; }
/* Home Hanan: big and welcoming, standing on the hill with his speech bubble beside his head */
.home-mascot { align-self: flex-end; margin-bottom: 3vh; margin-right: min(26vw, 300px); }
@keyframes bob { 50% { transform: translateY(-10px); } }
.floaty { position: absolute; font-size: clamp(36px, 9vmin, 70px); color: #fff; text-shadow: 0 4px 0 rgba(0,0,0,.15); animation: bob 3s ease-in-out infinite; pointer-events: none; }
.floaty.f1 { left: 6%; top: 14%; color: #ff8ac4; } .floaty.f2 { right: 8%; top: 10%; color: #c79bff; animation-delay: .6s; } .floaty.f3 { left: 4%; bottom: 8%; color: #7ee0a6; animation-delay: 1.2s; }
.parents-btn { position: absolute; right: 14px; bottom: 12px; background: rgba(255,255,255,.85); border-radius: 999px; padding: 8px 16px; font-weight: 700; font-size: 15px; overflow: hidden; }
.parents-btn .ring { position: absolute; left: 0; bottom: 0; height: 4px; width: 0; background: var(--pink); }
.parents-btn.holding .ring { width: 100%; transition: width 1.2s linear; }

/* ==========================================================================
   Intro (logo)
   ========================================================================== */
.home-logo { display: block; width: min(40vw, calc(var(--scene-h) * .62), 620px); height: auto; margin: 0 auto -1vh;
  filter: drop-shadow(0 8px 12px rgba(20, 60, 80, .18)); animation: logoIn .6s cubic-bezier(.2, 1.5, .4, 1) both; }
@keyframes logoIn { from { transform: scale(.7) translateY(-20px); opacity: 0; } }
.home-stats { display: flex; gap: 10px; justify-content: center; margin-top: 14px; }
.home-pill { background: rgba(255, 255, 255, .9); border-radius: 999px; padding: 4px 16px; font-size: clamp(15px, 2.6vmin, 20px); color: #11506a; box-shadow: 0 4px 0 rgba(0, 0, 0, .08); }

/* ==========================================================================
   Letter map — 29 letters, Arabic reading order (right → left)
   ========================================================================== */
.screen-letters {
  --gap: clamp(6px, 1.3vmin, 14px);
  --map-head: clamp(34px, calc(var(--scene-h) * .085), 60px);
  --tile: min(calc((100vw - var(--helper-gutter) - 7vw - 9 * var(--gap)) / 10),
              calc((var(--scene-h) - var(--map-head) - 9vh - 2 * var(--gap)) / 3), 170px);
}
.map { position: absolute !important; inset: 0; z-index: 3 !important; display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 1.6vh 3vw calc(var(--scene-h) * .08) calc(var(--helper-gutter) + 1vw); gap: 1.4vh; pointer-events: none; }
.map-head { height: var(--map-head); display: flex; align-items: center; gap: 12px; pointer-events: auto; }
.map-legend { display: flex; gap: 12px; background: rgba(255, 255, 255, .85); border-radius: 999px; padding: 4px 14px; font-size: clamp(12px, calc(var(--map-head) * .3), 16px); font-weight: 700; color: #4a5a66; box-shadow: 0 4px 0 rgba(0, 0, 0, .06); }
.map-legend span { display: flex; align-items: center; gap: 5px; white-space: nowrap; }
.lg { width: 1.25em; height: 1.25em; border-radius: 30%; display: inline-grid; place-items: center; font-style: normal; font-size: 1em; }
.lg-done { background: #f6bd36; color: #fff; font-size: .8em; }
.lg-now { background: #fff; box-shadow: 0 0 0 3px #ffd23f; }
.lg-next { background: #fff; outline: 2px dashed #f2b51c; outline-offset: 1px; }
.lg-lock { background: #eef1f4; color: #7d8a99; } .lg-lock svg { width: 80%; height: 80%; }
.map-progress { display: flex; align-items: center; gap: 10px; background: rgba(255, 255, 255, .92); border-radius: 999px; padding: 4px 18px 4px 8px;
  font-size: clamp(14px, calc(var(--map-head) * .36), 20px); font-weight: 700; color: #11506a; box-shadow: 0 4px 0 rgba(0, 0, 0, .08); }
.map-bar { width: clamp(80px, 16vw, 220px); height: 12px; border-radius: 999px; background: #e3edf2; overflow: hidden; box-shadow: inset 0 2px 3px rgba(0, 0, 0, .12); }
.map-bar i { display: block; height: 100%; min-width: 12px; border-radius: inherit; background: linear-gradient(90deg, #ffd23f, #f6a821); }
/* The cream letter board stands in the meadow on two wooden legs: one plain, opaque backing for all 29 tiles */
.map-board { position: relative; pointer-events: auto; padding: var(--gap); border-radius: calc(var(--tile) * .32);
  background: linear-gradient(180deg, #fffdf6, #fff6e2);
  box-shadow: 0 0 0 calc(var(--gap) * .55) #ffd95e, 0 0 0 calc(var(--gap) * .55 + 3px) #f0a830, 0 calc(var(--tile) * .14) calc(var(--tile) * .3) rgba(70, 90, 40, .22); }
.map-board::before, .map-board::after { content: ''; position: absolute; top: 96%; z-index: -1; width: calc(var(--tile) * .16); height: calc(var(--scene-h) * .3);
  background: linear-gradient(90deg, #8a5a2b, #c48c55 45%, #7a4e24); border-radius: 0 0 8px 8px; box-shadow: 0 6px 10px rgba(60, 80, 30, .2); }
.map-board::before { left: 14%; } .map-board::after { right: 14%; }
.map-grid { display: grid; grid-template-columns: repeat(10, var(--tile)); gap: var(--gap); }

.map-tile {
  position: relative; width: var(--tile); aspect-ratio: 1; border-radius: 24%; color: #fff;
  background: linear-gradient(160deg, color-mix(in srgb, var(--c) 52%, #fff) 0%, var(--c) 48%, var(--cs) 100%);
  box-shadow: 0 calc(var(--tile) * .07) 0 var(--cs), 0 calc(var(--tile) * .1) calc(var(--tile) * .14) rgba(20, 40, 60, .25), inset 0 3px 0 rgba(255, 255, 255, .45);
  transition: transform .15s; display: grid; place-items: center;
}
.map-tile::before { content: ''; position: absolute; left: 12%; top: 8%; width: 42%; height: 20%; border-radius: 50%; background: rgba(255, 255, 255, .38); transform: rotate(-18deg); pointer-events: none; }
.map-tile:active { transform: translateY(3px) scale(.96); }
.tile-glyph { font-size: calc(var(--tile) * .44); line-height: 1; margin-top: -30%; pointer-events: none;   /* Naskh descenders (ج ح خ ع ي) clear the name label */
  text-shadow: var(--ar-shadow); }
.tile-name { position: absolute; bottom: 7%; left: 0; right: 0; text-align: center; font-weight: 800; font-size: clamp(10px, calc(var(--tile) * .15), 17px); pointer-events: none;
  text-shadow: 0 1px 0 var(--cs); }
.tile-badge { position: absolute; top: -10%; right: -10%; width: 38%; aspect-ratio: 1; border-radius: 50%; display: grid; place-items: center; pointer-events: none; }
.tile-badge.star { background: radial-gradient(circle at 35% 30%, #fff5b8, #f6bd36 60%, #d39410); color: #fff; font-size: calc(var(--tile) * .22);
  box-shadow: 0 3px 0 #b97f0c; text-shadow: 0 1px 0 #b97f0c; }
.tile-badge.lock { background: #fff; color: #7d8a99; box-shadow: 0 3px 0 rgba(0, 0, 0, .18); }
.tile-badge.lock svg { width: 62%; height: 62%; }
/* locked: every letter stays colourful — its own colour, just a little softer and lighter than an open
   tile, with the white glyph at full strength. The small lock badge is what marks it as not yet open. */
.map-tile.is-locked {
  background: linear-gradient(160deg, color-mix(in srgb, var(--c) 45%, #fff) 0%, color-mix(in srgb, var(--c) 78%, #fff) 50%, color-mix(in srgb, var(--cs) 80%, #fff) 100%);
  box-shadow: 0 calc(var(--tile) * .06) 0 color-mix(in srgb, var(--cs) 70%, #fff), 0 calc(var(--tile) * .09) calc(var(--tile) * .12) rgba(20, 40, 60, .16), inset 0 3px 0 rgba(255, 255, 255, .4);
  filter: saturate(.88);
}
.map-tile.is-locked .tile-glyph { text-shadow: 0 2px 3px color-mix(in srgb, var(--cs) 60%, transparent); }
.map-tile.is-locked .tile-name { text-shadow: 0 1px 0 color-mix(in srgb, var(--cs) 80%, #000); }
.map-tile.is-locked .tile-badge.lock { width: 28%; top: -6%; right: -6%; }
/* up next: the letter that opens after the current one — dashed gold outline, still locked */
.map-tile.is-upnext::after { content: ''; position: absolute; inset: -7%; border-radius: 28%; border: 3px dashed #f2b51c; pointer-events: none; }
.map-tile.is-upnext .tile-badge.lock { background: #fff6cf; color: #b8860b; }
/* current: golden ring + gentle bounce */
.map-tile.is-current { animation: nudge 1.6s ease-in-out infinite; z-index: 1; }
.map-tile.is-current::after { content: ''; position: absolute; inset: -9%; border-radius: 28%; border: calc(var(--tile) * .05) solid #ffd23f;
  box-shadow: 0 0 0 4px rgba(255, 210, 63, .35), 0 0 22px rgba(255, 200, 40, .8); animation: glow 1.8s ease-in-out infinite; pointer-events: none; }
/* just unlocked (arrived from a letter-complete celebration) */
.map-tile.just-unlocked { animation: unlockPop .9s .3s cubic-bezier(.2, 1.6, .4, 1) both, nudge 1.6s 1.3s ease-in-out infinite; }
@keyframes unlockPop { 0% { transform: scale(.6) rotate(-8deg); filter: grayscale(1); } 60% { transform: scale(1.18) rotate(4deg); } 100% { transform: none; filter: none; } }

/* ==========================================================================
   Letter menu — Meet · Hanan's Story · Game 1 · Game 2 · Game 3
   ========================================================================== */
.screen-letter {
  --lm-mascot-w: calc(var(--scene-h) * .61 * .553);   /* = SIZES.choose × point-left aspect */
  --toy-w: min(calc(var(--scene-h) * .42), 22vw, 300px);
}
.letter-menu { position: absolute !important; inset: 0; z-index: 3 !important; display: flex; align-items: center; justify-content: center;
  gap: 3vw; padding: 2vh calc(var(--lm-mascot-w) + 3vw) calc(var(--scene-h) * .06) 3vw; pointer-events: none; }
.letter-menu > * { pointer-events: auto; }
.lm-hero { display: flex; flex-direction: column; align-items: center; gap: 1vh; width: var(--toy-w); }
.lm-toy { width: 100%; position: relative; z-index: 1; }
/* Round stone pedestal the letter stands on (decorative, part of the hub scene) */
.lm-pedestal { display: block; width: 86%; height: calc(var(--toy-w) * .15); margin-top: calc(var(--toy-w) * -.13); border-radius: 50%; pointer-events: none;
  background: radial-gradient(ellipse at 45% 35%, #fffdf6 0%, #fff1d6 55%, #f6dca8 100%);
  box-shadow: 0 calc(var(--toy-w) * .035) 0 #3fc4bd, 0 calc(var(--toy-w) * .04) 0 #2aa9a4, 0 calc(var(--toy-w) * .07) calc(var(--toy-w) * .06) rgba(40, 90, 80, .25); }
.lm-name { margin: 0; display: flex; align-items: baseline; gap: 10px; background: #fff; border-radius: 999px; padding: 2px 18px;
  box-shadow: 0 4px 0 rgba(0, 0, 0, .1); font-size: clamp(18px, calc(var(--toy-w) * .1), 30px); color: var(--cs); }
.lm-name [lang="ml"] { font-size: .8em; color: #55606b; }
.lm-dots { margin: 0; display: flex; gap: 8px; }
.lm-dots i { width: 14px; height: 14px; border-radius: 50%; background: rgba(255, 255, 255, .7); box-shadow: inset 0 0 0 2px rgba(0, 0, 0, .1); }
.lm-dots i.on { background: #ffd23f; box-shadow: 0 2px 0 #c98a0c; }
/* Five step cards: a "learn" row (Meet · Story) above a "play" row (Game 1–3), same card design */
.lm-steps { --sg: clamp(8px, 1.8vmin, 16px); flex: 1 1 auto; min-width: 0; max-width: max(640px, 46vw); display: flex; flex-direction: column; gap: var(--sg); }
.lm-row { display: grid; gap: var(--sg); }
.lm-learn { grid-template-columns: repeat(2, 1fr); }
.lm-play { grid-template-columns: repeat(3, 1fr); }
.step-card {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: clamp(2px, .8vmin, 8px);
  height: clamp(104px, calc(var(--scene-h) * .34), 230px); padding: clamp(6px, 1.2vmin, 12px) 6px; text-align: center; min-width: 0;
  background: linear-gradient(180deg, #fff, #f4f8fb); border-radius: clamp(16px, 3vmin, 26px);
  box-shadow: 0 6px 0 rgba(20, 50, 80, .14), 0 10px 18px rgba(20, 50, 80, .1); transition: transform .15s;
  animation: toyIn .45s calc(var(--i) * .07s + .1s) cubic-bezier(.2, 1.5, .4, 1) both;
}
.step-card:active { transform: translateY(4px); }
.sc-num { position: absolute; top: clamp(5px, 1vmin, 10px); left: clamp(5px, 1vmin, 10px); width: clamp(22px, 4vmin, 34px); aspect-ratio: 1; border-radius: 50%;
  display: grid; place-items: center; font-weight: 800; background: var(--c); color: #fff; font-size: clamp(12px, 2.3vmin, 18px); box-shadow: 0 3px 0 var(--cs); }
.sc-num svg { width: 58%; height: 58%; }
.sc-icon { width: clamp(34px, calc(var(--scene-h) * .11), 76px); aspect-ratio: 1; display: grid; place-items: center; border-radius: 30%;
  background: color-mix(in srgb, var(--c) 10%, #fff); box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--c) 18%, #fff); }
.sc-icon .ico { width: 80%; height: 80%; filter: drop-shadow(0 3px 2px rgba(0, 0, 0, .15)); }
.sc-q { font-size: clamp(18px, calc(var(--scene-h) * .06), 40px); font-weight: 800; color: #9aa8b4; }
.sc-text { display: flex; flex-direction: column; line-height: 1.12; min-width: 0; }
.sc-label { font-weight: 800; font-size: clamp(14px, calc(var(--scene-h) * .045), 26px); color: var(--ink); }
.sc-sub { font-weight: 700; font-size: clamp(11px, calc(var(--scene-h) * .03), 16px); color: var(--cs); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sc-status { font-weight: 800; font-size: clamp(11px, calc(var(--scene-h) * .03), 16px); padding: 2px 10px; border-radius: 999px; background: #eef3f6; color: #4c5b66; white-space: nowrap; }
.step-card.is-done .sc-status { background: #d4f5dd; color: #136b33; }
.step-card.is-next { box-shadow: 0 6px 0 var(--gold-d), 0 0 0 4px var(--gold), 0 12px 24px rgba(246, 189, 54, .45);
  animation: toyIn .45s calc(var(--i) * .07s + .1s) cubic-bezier(.2, 1.5, .4, 1) both, nudge 1.8s .8s ease-in-out infinite; }
.step-card.is-next .sc-status { background: var(--gold); color: #5a3a00; }
/* locked: an earlier step is not done yet — still friendly, clearly waiting */
.step-card.is-locked { background: linear-gradient(180deg, #f6f8fa, #e9eef2); }
.step-card.is-locked .sc-num { background: #9aa8b4; box-shadow: 0 3px 0 #77858f; }
.step-card.is-locked .sc-icon { filter: saturate(.45); opacity: .75; }
.step-card.is-locked .sc-label, .step-card.is-locked .sc-sub { opacity: .7; }
/* soon: the game for this slot is not built yet */
.step-card.is-soon { background: #f7f9fb; box-shadow: inset 0 0 0 3px #dbe3ea, 0 4px 0 rgba(20, 50, 80, .08); }
.step-card.is-soon .sc-icon, .step-card.is-soon .sc-num { filter: grayscale(.8); opacity: .55; }
.step-card.is-soon .sc-label { opacity: .6; }
.lm-mascot { --ax: 2.5vw; --ay: calc(var(--scene-h) * .03); }   /* head stays below the signpost arrows */

/* Meet: letter name under the big letter */
.letter-title { margin: 0; font-size: clamp(18px, 3.6vmin, 28px); background: #fff; border-radius: 999px; padding: 0 16px; box-shadow: 0 4px 0 rgba(0, 0, 0, .1); }
.letter-title [lang="ml"] { color: #55606b; font-size: .85em; }

/* Celebration: unlocked line */
.done-sub { margin: -6px 0 16px; font-size: clamp(17px, 3.4vmin, 24px); font-weight: 800; color: #136b33; }

/* 3D letter toy (letter menu; sized by --toy-w) */
.letter-blob { position: absolute; inset: 0; width: 100%; height: 100%; filter: drop-shadow(0 8px 0 rgba(0,0,0,.12)); }

.toy { position: relative; width: 100%; aspect-ratio: 200 / 216; display: block; transition: transform .2s; animation: toyIn .5s calc(var(--i) * .08s) cubic-bezier(.2, 1.5, .4, 1) both; }
.toy:hover { transform: translateY(-6px) rotate(-2deg); }
.toy:active { transform: translateY(3px) scale(.96); }
@keyframes toyIn { from { transform: translateY(30px) scale(.8); opacity: 0; } }
.toy-body { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.toy-glyph {
  position: absolute; left: 47.5%; top: 50%; transform: translate(-50%, -50%); font-size: calc(var(--toy-w) * .56); color: #fff;
  text-shadow: var(--ar-shadow);
}
.toy-name {
  position: absolute; left: 47.5%; bottom: 13%; transform: translateX(-50%); white-space: nowrap;
  background: #fff; color: var(--cs); border-radius: 999px; padding: 0 .7em; font-weight: 800; font-size: clamp(14px, calc(var(--toy-w) * .1), 34px);
  box-shadow: 0 3px 0 rgba(0, 0, 0, .15);
}
.toy-badge { position: absolute; right: 2%; top: 0; width: 26%; aspect-ratio: 1; border-radius: 50%; display: grid; place-items: center;
  background: radial-gradient(circle at 35% 30%, #fff5b8, #f6bd36 60%, #d39410); color: #fff; font-size: calc(var(--toy-w) * .14);
  box-shadow: 0 4px 0 #b97f0c, 0 6px 10px rgba(0, 0, 0, .2); text-shadow: 0 2px 0 #b97f0c; }

/* ==========================================================================
   Screens 3 & 7 — Meet
   ========================================================================== */
.meet, .bus-intro { position: absolute !important; inset: 0; display: flex; align-items: center; justify-content: center; gap: 3vw; padding: 2vh 3vw 3vh; }
/* Lesson Hanan: part of the composition, grounded on the grass, sized so all three columns fit */
.lesson-mascot { align-self: flex-end; margin-bottom: 2vh; }
.lesson-mascot { --mw: 17vw; }                     /* width cap so all three columns fit */
.meet-left { display: flex; flex-direction: column; align-items: center; gap: 1vh; }
.meet-letter { position: relative; width: min(clamp(200px, 52vmin, 440px), 30vw); aspect-ratio: 200 / 220; transition: transform .2s; }
.meet-letter.bounce { animation: boing .5s; }
@keyframes boing { 30% { transform: scale(1.1, .9); } 60% { transform: scale(.95, 1.06); } }
.meet-glyph { position: absolute; left: 50%; top: 46%; transform: translate(-50%, -50%); font-size: clamp(110px, 30vmin, 260px); color: #fff; }
.tap-stars { display: flex; gap: 10px; }
.tap-star { font-size: clamp(30px, 7vmin, 52px); color: rgba(255,255,255,.7); text-shadow: 0 3px 0 rgba(0,0,0,.12); transition: .3s; }
.tap-star.on { color: var(--gold); transform: scale(1.2); }
.hint { margin: 0; background: rgba(255,255,255,.85); padding: 4px 16px; border-radius: 999px; font-weight: 700; }
.meet-right, .bus-intro-side { display: flex; flex-direction: column; gap: 2.4vh; align-items: stretch; width: min(36vw, 440px); }
.card { background: var(--white); border-radius: 26px; padding: 14px 18px; box-shadow: 0 7px 0 rgba(0,0,0,.12); display: flex; align-items: center; gap: 14px; text-align: left; font-size: clamp(16px, 3.2vmin, 22px); font-weight: 700; transition: transform .15s; }
.card:active { transform: translateY(4px); }
.card-ico { font-size: 1.5em; flex: 0 0 auto; }
.feature-text { flex: 1; }
.kw-art { position: relative; width: clamp(80px, 18vmin, 130px); flex: 0 0 auto; }
.kw-art svg { width: 100%; display: block; }
.kw-in-frame { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size: clamp(18px, 4.4vmin, 32px); color: #c21862; }
.kw-text { flex: 1; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.kw-ar { font-size: clamp(38px, 9vmin, 64px); color: var(--letter, var(--pink)); line-height: 1.3; }
.kw-tr { font-size: .85em; color: #557; }

/* ==========================================================================
   Screens 4 & 8 — Story
   ========================================================================== */
.story { position: absolute !important; inset: 0; display: flex; align-items: center; justify-content: center; padding: 2vh 3vw 3vh; gap: 2vw; }
.story-book { --book-h: min(calc(var(--scene-h) * .9), 640px); display: flex; background: var(--white); border-radius: 30px; box-shadow: 0 10px 0 rgba(0,0,0,.12); overflow: hidden; width: min(84vw, 1100px); height: var(--book-h); }
.story-pic { position: relative; flex: .9; overflow: hidden; }
.story-scene { position: absolute; inset: 0; width: 100%; height: 100%; }
/* Reading Hanan stands on the sand / in front of the window sill inside the picture */
.story-mascot { position: absolute !important; left: 5%; bottom: 4%; z-index: 2; }
.story-mascot { --mh-max: calc(var(--book-h) * .86); --mh-min: 120px; }  /* must stay inside the picture */
.story-glyph { position: absolute; top: 6%; right: 6%; background: #fff; border-radius: 22px; padding: 4px 18px; font-size: clamp(40px, 9vmin, 72px); color: var(--pink); box-shadow: 0 5px 0 rgba(0,0,0,.12); }
.wave.w1 { animation: waves 6s ease-in-out infinite alternate; } .wave.w2 { animation: waves 4.5s ease-in-out infinite alternate-reverse; }
@keyframes waves { to { transform: translateX(-100px); } }
.fish { animation: swim 7s linear infinite; } @keyframes swim { from { transform: translateX(-200px); } to { transform: translateX(600px); } }
.twinkle circle { animation: twinkle 2s infinite alternate; } .twinkle circle:nth-child(2n) { animation-delay: 1s; }
@keyframes twinkle { to { opacity: .2; } }
.story-page { flex: 1.2; padding: 2.4vh 2.2vw; display: flex; flex-direction: column; gap: 1.4vh; min-width: 0; }
.story-lang { align-self: center; }
.story-lang button { min-height: 40px; padding: 4px 18px; font-size: clamp(15px, 2.6vmin, 19px); }
.story-lang button[lang="ml"] { font-family: var(--font-ml); }
/* Reading card: one language at a time, generous line height, no cramped ribbons */
.story-card { flex: 1; overflow: auto; background: #fffdf6; border-radius: 22px; padding: clamp(12px, 2.2vh, 22px) clamp(14px, 2vw, 26px);
  box-shadow: inset 0 0 0 2px #f1e6c8, 0 3px 0 rgba(0, 0, 0, .04); display: flex; flex-direction: column; gap: 1vh; }
.story-title { margin: 0; color: var(--pink); font-size: clamp(20px, 3.7vmin, 30px); line-height: 1.4; }
.story-title:lang(ml) { font-family: var(--font-ml); font-weight: 700; line-height: 1.55; }
.badge-review { align-self: flex-start; background: #fff1c8; color: #7a5200; border-radius: 10px; padding: 2px 10px; font-size: 13px; font-weight: 700; }
.story-text { font-size: clamp(17px, 3.1vmin, 24px); line-height: 1.75; max-width: 38em; }
.story-text:lang(ml) { font-family: var(--font-ml); line-height: 1.85; word-spacing: .06em; }
.story-text.pending { border: 3px dashed #e3c25e; background: #fffaf0; border-radius: 18px; padding: 12px 16px; font-size: clamp(16px, 3vmin, 21px); }
.story-text.pending p { margin: 6px 0 0; font-weight: 500; }
.story-controls { display: flex; gap: 10px; justify-content: center; align-items: center; }
.btn-icon { min-width: 56px; padding: 6px 14px; }
.story-play { min-width: 56px; font-size: 22px; }
.story-play:disabled { opacity: .55; }
.story-fwd { min-width: clamp(110px, 14vw, 170px); }
.story-text { white-space: pre-line; }               /* a scene may hold two short paragraphs */
.story-meta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.audio-soon { background: #fff3cf; color: #6b5a2a; border-radius: 999px; padding: 1px 10px; font-size: 13px; font-weight: 700; }
.story-count { background: #e8f5f1; color: #11706a; border-radius: 999px; padding: 1px 12px; font-size: 14px; font-weight: 800; }
/* a language whose reviewed text is not ready yet: visible, greyed, not selectable */
.story-lang button.soon { opacity: .75; color: #7a8a90; cursor: not-allowed; display: inline-flex; align-items: center; gap: 6px; }
.soon-tag { background: #fff1c8; color: #7a5200; border-radius: 8px; padding: 0 7px; font-size: 12px; font-weight: 800; }
.story-voice-note { margin: 0; text-align: center; font-size: 14px; color: #6b5a2a; background: #fff3cf; border-radius: 12px; padding: 6px 10px; }
.story-next { margin-left: auto; white-space: nowrap; }                 /* Done sits at the end of the controls row */

/* ==========================================================================
   Shared game chrome
   ========================================================================== */
.goal-bar { position: absolute !important; top: 1.6vh; left: 50%; transform: translateX(-50%); display: flex; align-items: center; gap: 12px; background: rgba(255,255,255,.92); border-radius: 999px; padding: 4px 18px 4px 6px; box-shadow: 0 5px 0 rgba(0,0,0,.1); z-index: 5; }
.goal-target { background: var(--pink); color: #fff; border-radius: 50%; width: clamp(46px, 10vmin, 64px); aspect-ratio: 1; display: grid; place-items: center; font-size: clamp(28px, 6.4vmin, 42px); }
.goal-slots { display: flex; gap: 6px; font-size: clamp(22px, 5vmin, 34px); }

/* ---------- Screen 5: Balloon Pop ---------- */
.balloon-game { position: absolute !important; inset: 0; }
/* Balloons fly in the area right of Hanan's helper gutter; the grass foreground (z 2) sits in front,
   so balloons rise out of the meadow. pointer-events: none on the grass keeps them tappable. */
.balloon-field { position: absolute; inset: 0 0 0 var(--helper-gutter); overflow: hidden; }
.balloon { position: absolute; left: 0; top: 0; will-change: transform; touch-action: manipulation; }
.balloon svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 8px 6px rgba(20, 50, 80, .18)); }
.balloon-glyph {
  position: absolute; left: 50%; top: 36%; transform: translate(-50%, -50%); font-size: calc(var(--bs, 120px) * .62); line-height: 1; color: #fff; pointer-events: none;   /* sized for KFGQPC Naskh (smaller visual size than Noto) */
  text-shadow: 0 1px 4px var(--bc, rgba(0,0,0,.35)), 0 0 8px rgba(0, 0, 0, .2);   /* soft halo for contrast on the balloon, no offset copies */
}
.balloon.popped svg, .balloon.popped .balloon-glyph { animation: popout .3s forwards; }
@keyframes popout { to { transform: scale(1.6); opacity: 0; } }
.balloon.nope svg { animation: nope .5s; transform-origin: 50% 80%; }
@keyframes nope { 25% { transform: rotate(-12deg); } 75% { transform: rotate(12deg); } }
.pop-bit { position: absolute; width: 12px; height: 9px; border-radius: 40%; pointer-events: none; animation: popbit .6s ease-out forwards; }
@keyframes popbit { to { transform: translate(var(--dx), var(--dy)) rotate(260deg) scale(.4); opacity: 0; } }

/* Balloon counter board: target balloon + one mini balloon per goal, filled with the popped colour */
.balloon-game .goal-bar { padding: 6px 22px 6px 8px; gap: 14px; border-radius: 28px; background: rgba(255, 255, 255, .94);
  box-shadow: 0 6px 0 rgba(0, 0, 0, .1), inset 0 0 0 3px #ffe08a; }
.balloon-game .goal-target { --gw: clamp(46px, calc(var(--scene-h) * .1), 88px); position: relative; background: none; border-radius: 0; width: var(--gw); aspect-ratio: 2 / 3; display: block; margin: -4px 0; }
.balloon-game .goal-target svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.balloon-game .goal-target .ar { position: absolute; left: 50%; top: 37%; transform: translate(-50%, -50%); color: #fff; font-size: calc(var(--gw) * .8); line-height: 1; text-shadow: 0 1px 4px #8e0f50; }
.goal-slots { display: flex; gap: 6px; }
.slot { display: block; width: clamp(24px, calc(var(--scene-h) * .055), 50px); aspect-ratio: 2 / 3; opacity: .55; transition: transform .3s, opacity .3s; }
.slot svg { width: 100%; height: 100%; overflow: visible; display: block; }
.slot.on { opacity: 1; transform: scale(1.12) translateY(-2px); }


/* ---------- Screen 6: Letter Train ---------- */
.train-game { position: absolute !important; inset: 0; display: flex; flex-direction: column; justify-content: space-between; padding: 3vh 3vw 3vh var(--helper-gutter); }
.track-area { position: relative; flex: 1; display: flex; align-items: flex-end; }
.train { display: flex; align-items: flex-end; gap: 6px; padding-bottom: 8px; transition: transform 2.2s ease-in; }
.train.depart { transform: translateX(-140vw); }
.train.depart .wheel { animation: spin .5s linear infinite; }
.engine { position: relative; width: clamp(150px, 30vmin, 250px); }
.engine svg { width: 100%; display: block; }
.smoke { position: absolute; left: 18%; top: -10%; }
.smoke i { position: absolute; width: 24px; height: 24px; border-radius: 50%; background: #fff; opacity: .8; animation: smoke 2.4s infinite; }
.smoke i:nth-child(2) { animation-delay: .8s; } .smoke i:nth-child(3) { animation-delay: 1.6s; }
@keyframes smoke { from { transform: translate(0, 0) scale(.5); opacity: .9; } to { transform: translate(-30px, -70px) scale(1.8); opacity: 0; } }
.wagons { display: flex; gap: 6px; }
.wagon { width: clamp(100px, 20vmin, 160px); display: flex; flex-direction: column; align-items: stretch; transition: transform .15s; }
.wagon-box { background: var(--wagon); border-radius: 18px 18px 6px 6px; padding: 10px; box-shadow: inset 0 -8px 0 rgba(0,0,0,.15); }
.wagon-slot { background: #fff8e5; border-radius: 12px; aspect-ratio: 1; display: grid; place-items: center; border: 4px dashed rgba(0,0,0,.15); }
.wagon.full .wagon-slot { border-style: solid; border-color: transparent; }
.wagon.drop-hover { transform: translateY(-8px) scale(1.06); }
.wagon.drop-hover .wagon-slot { border-color: var(--gold); background: #fff3c4; }
.wagon-wheels { width: 100%; display: block; margin-top: -2px; }
.wheel { transform-box: fill-box; transform-origin: center; }
@keyframes spin { to { transform: rotate(-360deg); } }
.rails { position: absolute; left: -20vw; right: -5vw; bottom: 0; height: 12px; background: repeating-linear-gradient(90deg, #7a4a1f 0 18px, transparent 18px 40px), linear-gradient(#9b9b9b, #6f6f6f); background-size: auto, 100% 5px; background-repeat: repeat-x, no-repeat; background-position: 0 4px, 0 0; }
.tray { display: flex; justify-content: center; gap: clamp(8px, 1.6vw, 18px); flex-wrap: wrap; padding: 1.4vh 1vw; background: rgba(255,255,255,.55); border-radius: 26px; margin-top: 2vh; min-height: clamp(90px, 18vmin, 140px); }
.card-tile { width: clamp(78px, 15vmin, 120px); aspect-ratio: 1; background: #fff; border-radius: 20px; box-shadow: 0 6px 0 #c4d8d1; font-size: clamp(48px, 10vmin, 80px); color: var(--ink); display: grid; place-items: center; position: relative; z-index: 2; }
.card-tile .ar { pointer-events: none; }
.card-tile.dragging { z-index: 40; box-shadow: 0 16px 20px rgba(0,0,0,.25); cursor: grabbing; }
.card-tile.returning { transition: transform .3s; }
.card-tile.loaded { width: 100%; height: 100%; box-shadow: none; background: transparent; color: var(--pink); cursor: default; font-size: clamp(44px, 10vmin, 84px); }

/* ---------- Screen 9: Apple Sorting ---------- */
.apple-game { position: absolute !important; inset: 0; display: flex; align-items: flex-end; justify-content: center; gap: 2vw; padding: 2vh 3vw 3vh var(--helper-gutter); }
.tree-box { position: relative; height: 92%; aspect-ratio: 400 / 360; max-width: 52vw; }
.tree-box > svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.apple { position: absolute; width: 16%; aspect-ratio: 1; transform-origin: 50% 0; animation: sway 3s ease-in-out infinite alternate; z-index: 2; }
.apple svg { position: absolute; inset: 0; width: 100%; height: 100%; filter: drop-shadow(0 4px 2px rgba(0,0,0,.2)); }
.apple-glyph { position: absolute; left: 50%; top: 58%; transform: translate(-50%, -50%); color: #fff; font-size: clamp(26px, 6.4vmin, 50px); pointer-events: none; text-shadow: var(--ar-shadow); }
@keyframes sway { from { rotate: -4deg; } to { rotate: 4deg; } }
.apple.selected { animation: none; z-index: 5; filter: drop-shadow(0 0 0 #fff) drop-shadow(0 0 10px #fff6a8); scale: 1.18; }
.apple.dragging { animation: none; z-index: 40; }
.apple.returning { transition: transform .3s; }
.apple.sorted { position: relative; left: auto !important; top: auto !important; width: clamp(36px, 7vmin, 54px); animation: none; display: inline-block; margin: -6px; }
.basket { position: relative; width: clamp(150px, 26vmin, 240px); aspect-ratio: 200 / 150; margin-bottom: 2vh; transition: transform .2s; display: flex; flex-direction: column; justify-content: flex-end; }
.basket > svg { width: 100%; height: 80%; display: block; }
.basket-label { position: absolute; left: 50%; bottom: 14%; transform: translateX(-50%); background: #fff; border-radius: 16px; padding: 0 14px; font-size: clamp(34px, 7vmin, 54px); color: var(--ink); box-shadow: 0 4px 0 rgba(0,0,0,.15); }
.basket-pile { position: absolute; left: 6%; right: 6%; bottom: 66%; display: flex; flex-wrap: wrap-reverse; justify-content: center; }
.basket.drop-hover { transform: scale(1.1); }
.basket.drop-hover .basket-label { background: #fff3c4; }
.basket.happy { animation: boing .5s; }

/* ---------- Screen 10: School Bus ---------- */
/* Meet "Count the dots" aid (letters with a teaching form only): the letter body with its dots drawn
   separately, in its own dashed frame and labelled, so it is never mistaken for the real glyph. */
.dot-aid { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 4px 8px 3px; border-radius: 12px;
  border: 2px dashed color-mix(in srgb, var(--letter, #1f7a43) 55%, #fff); background: #fff; color: var(--letter, #1f7a43); }
.dot-aid-glyph { font-size: clamp(40px, 9.5vmin, 76px); line-height: 1.15; }
.dot-aid-tag { font: 800 clamp(9px, 1.6vmin, 12px)/1 var(--font-ui); color: #6b7a86; white-space: nowrap; }
.dot-aid .ar-dots b { animation: dotCount 2.4s ease-in-out infinite both; }
.dot-aid .ar-dots b:nth-child(2) { animation-delay: .35s; } .dot-aid .ar-dots b:nth-child(3) { animation-delay: .7s; }
@keyframes dotCount { 0%, 100% { box-shadow: 0 0 0 0 transparent; } 20% { box-shadow: 0 0 0 .05em var(--gold); } 40% { box-shadow: 0 0 0 0 transparent; } }
@keyframes ring { 50% { transform: scale(1.25); opacity: .5; } }
.say-bubble { background: #fff; border-radius: 22px; padding: 10px 18px; font-size: clamp(22px, 5vmin, 36px); font-weight: 800; color: var(--teal-d); text-align: center; box-shadow: 0 5px 0 rgba(0,0,0,.1); }
.say-bubble.pulse { animation: boing .6s 2; }
.say-bubble .mic { margin-right: 8px; }
.bus-game { position: absolute !important; inset: 0; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; padding: 0 2vw 0 var(--helper-gutter); }
.bus { position: relative; width: min(calc(98vw - var(--helper-gutter)), 140vh); aspect-ratio: 1000 / 440; margin-bottom: 3vh; transition: transform 2s ease-in; }
.bus.drive { transform: translateX(130vw); }
.bus.drive .wheel { animation: spin .5s linear infinite reverse; }
.bus-art { position: absolute; inset: 0; width: 100%; height: 100%; }
.bus-windows { position: absolute; left: 7%; right: 18%; top: 17%; bottom: 36%; display: grid; grid-template-columns: repeat(6, 1fr); grid-template-rows: repeat(2, 1fr); gap: 3%; }
/* Framed glass windows with a diagonal shine; the Arabic letter is the clear focus */
.bus-window { position: relative; display: grid; place-items: center; overflow: hidden; font-size: clamp(30px, 7.4vmin, 60px); color: #6a1b9a;
  background: linear-gradient(160deg, #f2fbff 0%, #d6f1ff 55%, #bfe6fb 100%); border: 4px solid #2f5f78; border-radius: 16px;
  box-shadow: inset 0 -5px 0 rgba(47, 95, 120, .18), 0 4px 0 rgba(120, 70, 0, .25); transition: background .25s, box-shadow .25s, transform .15s; }
.bus-window::before { content: ''; position: absolute; left: -30%; top: -40%; width: 45%; height: 180%; background: rgba(255, 255, 255, .45); transform: rotate(25deg); pointer-events: none; }
.bus-window:active { transform: scale(.96); }
/* Correct: the window glows warm gold, a star badge pops into the corner, and a shine sweeps across once */
.bus-window.boarded { color: #8a3a00; background: radial-gradient(circle at 50% 45%, #fffbe6 0%, #ffeaa0 60%, #ffd75e 100%); border-color: #e0a10e;
  box-shadow: 0 0 0 3px #ffd23f, 0 0 18px 6px rgba(255, 205, 50, .75), inset 0 -5px 0 rgba(201, 138, 12, .25); animation: winGlow 2.4s ease-in-out .6s infinite; }
.bus-window.boarded .ar { position: relative; z-index: 1; }
.win-star { position: absolute; top: 4%; right: 4%; width: 34%; aspect-ratio: 1; z-index: 2; pointer-events: none; animation: starPop .55s cubic-bezier(.2, 1.8, .4, 1) both; filter: drop-shadow(0 2px 2px rgba(150, 90, 0, .4)); }
.win-star svg { width: 100%; height: 100%; display: block; }
.win-shine { position: absolute; inset: 0; pointer-events: none; background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, .85) 50%, transparent 70%); transform: translateX(-120%); animation: winShine .8s ease-out .1s both; }
@keyframes starPop { 0% { transform: scale(0) rotate(-40deg); } 70% { transform: scale(1.25) rotate(8deg); } 100% { transform: scale(1) rotate(0); } }
@keyframes winShine { to { transform: translateX(120%); } }
@keyframes winGlow { 50% { box-shadow: 0 0 0 3px #ffd23f, 0 0 26px 10px rgba(255, 205, 50, .55), inset 0 -5px 0 rgba(201, 138, 12, .25); } }
.bus-wheel { position: absolute; width: 14%; aspect-ratio: 1; bottom: -6%; }
.bus-wheel.w1 { left: 14%; } .bus-wheel.w2 { left: 70%; }
.bus-wheel svg { width: 100%; display: block; }
/* Road: soft asphalt with a dashed lane line */
.road { position: absolute !important; left: 0; right: 0; bottom: 0; height: 4vh; z-index: 0 !important;
  background: repeating-linear-gradient(90deg, transparent 0 60px, #fff 60px 100px) center / 100% 4px no-repeat, linear-gradient(#6f7882, #5b636c); }
/* Counter: one gold star per Taa found */
.bus-game .seat { display: inline-block; width: clamp(24px, 5vmin, 34px); aspect-ratio: 1; border-radius: 50%; box-shadow: inset 0 0 0 3px #c9d6df; vertical-align: middle; }
.bus-game .seat.on { box-shadow: none; animation: starPop .5s cubic-bezier(.2, 1.8, .4, 1) both; }
.bus-game .seat svg { width: 100%; height: 100%; display: block; }
.bus-game .goal-target { background: #1f7a43; }

/* ---------- small / short screens ---------- */
@media (max-height: 460px) {
  /* Story on phone landscape: taller book, narrower picture, compact controls so the reading card has room */
  .story { padding: 1vh 2vw; }
  .story-book { --book-h: calc(var(--scene-h) * .94); width: 94vw; }
  .story-page { padding: 1.4vh 1.6vw; gap: 1vh; }
  .story-lang button { min-height: 34px; padding: 2px 14px; }
  .story-title { font-size: 19px; }
  .story-controls .btn { min-height: 44px; padding: 2px 14px; }
  .story-play { min-width: 0; }
  /* phone landscape: a narrower picture and tighter rhythm give the reading card room for the longer scenes;
     the scene counter/audio chip row steps out (the dots and the muted 🔇 button carry the same information) */
  .story-pic { flex: .62; }
  .story-page { flex: 1.38; }
  .story-card { padding: 8px 14px; gap: 4px; }
  .story-meta { display: none; }
  .story-text { font-size: 17px; line-height: 1.7; }
  .story-text:lang(ml) { line-height: 1.7; }
  .btn { min-height: 46px; padding: 4px 18px; }
  .pip { font-size: 13px; padding: 2px 10px; }      /* keeps 44px touch height, narrower so two fit per row */
  .step-pips { gap: 4px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01s !important; animation-iteration-count: 1 !important; transition-duration: .01s !important; }
}

/* ==========================================================================
   Meet — See → Listen → Touch (js/screens/meet.js)
   ========================================================================== */
.meet3 .meet-left { gap: 1.2vh; }
.meet3 .meet-letter { width: min(clamp(180px, 46vmin, 400px), 30vw); }
.msteps { list-style: none; margin: 0; padding: 4px 10px; display: flex; align-items: center; gap: 4px; background: rgba(255, 255, 255, .9);
  border-radius: 999px; box-shadow: 0 4px 0 rgba(0, 0, 0, .08); }
.mstep { display: flex; align-items: center; gap: 6px; padding: 3px 12px 3px 4px; border-radius: 999px; font-weight: 800;
  font-size: clamp(13px, 2.4vmin, 18px); color: #8494a1; transition: background .25s, color .25s; }
.mstep-ico { width: clamp(24px, 4.4vmin, 34px); aspect-ratio: 1; display: grid; place-items: center; opacity: .55; transition: opacity .25s, transform .25s; }
.mstep-ico .ico { width: 100%; height: 100%; }
.mstep.is-active { background: #fff3c4; color: #5a3a00; box-shadow: inset 0 0 0 2px #ffd23f; }
.mstep.is-active .mstep-ico { opacity: 1; transform: scale(1.12); }
.mstep.is-done { color: #136b33; }
.mstep.is-done .mstep-ico { opacity: 1; }
.mstep.is-done::after { content: '✓'; margin-left: 2px; }
.mstep-arrow { color: #b3c0c9; font-weight: 800; font-size: 20px; }

/* only the current step's panel is shown — one clear thing to do at a time */
.meet3 .mpanel { display: none; flex-direction: column; align-items: center; gap: 2vh; animation: popin .35s cubic-bezier(.2, 1.5, .4, 1); }
.meet3[data-stage="see"] .mpanel[data-panel="see"],
.meet3[data-stage="listen"] .mpanel[data-panel="listen"],
.meet3[data-stage="touch"] .mpanel[data-panel="touch"],
.meet3[data-stage="done"] .mpanel[data-panel="done"] { display: flex; }
.meet3 .mpanel[data-panel="see"] { align-items: stretch; }
.ico-wrap .ico { width: 1.6em; height: 1.6em; display: block; }
.mpanel-label { margin: 0; background: #fff; border-radius: 999px; padding: 4px 18px; font-weight: 800; font-size: clamp(16px, 3vmin, 24px); box-shadow: 0 4px 0 rgba(0, 0, 0, .1); }

.listen-btn { width: clamp(110px, 26vmin, 200px); aspect-ratio: 1; border-radius: 50%; display: grid; place-items: center; position: relative;
  background: radial-gradient(circle at 35% 30%, #ffffff, #e6fbf4 60%, #c8efe3); box-shadow: 0 8px 0 #8fd3c0, 0 14px 24px rgba(22, 160, 140, .3); }
.listen-btn .ico { width: 62%; height: 62%; }
.listen-btn::after { content: ''; position: absolute; inset: -10px; border-radius: 50%; border: 5px solid rgba(22, 160, 140, .45); animation: ring 1.6s ease-in-out infinite; }
.listen-btn:active { transform: translateY(5px); box-shadow: 0 3px 0 #8fd3c0; }
.rec-note { margin: 0; max-width: 34ch; text-align: center; font-size: 13px; line-height: 1.4; color: #6b5a2a; background: #fff3cf; border-radius: 12px; padding: 5px 12px; }

.touch-ico { width: clamp(64px, 14vmin, 110px); animation: tapHint 1.4s ease-in-out infinite; }
.touch-ico .ico { width: 100%; height: auto; }
@keyframes tapHint { 50% { transform: translate(-8px, -6px) rotate(-8deg); } }
.meet3 .tap-star { color: #d6dde3; font-size: clamp(38px, 8vmin, 64px); }
.meet3 .tap-star.on { color: var(--gold); text-shadow: 0 3px 0 var(--gold-d); }

/* letter feedback: soft ripple on each tap, warm glow while its sound plays */
.meet-letter .ripple { position: absolute; left: 50%; top: 46%; width: 30%; aspect-ratio: 1; border-radius: 50%; transform: translate(-50%, -50%) scale(0);
  border: 6px solid rgba(255, 255, 255, .85); pointer-events: none; }
.meet-letter.bounce .ripple { animation: ripple .6s ease-out; }
@keyframes ripple { from { transform: translate(-50%, -50%) scale(.4); opacity: 1; } to { transform: translate(-50%, -50%) scale(2.6); opacity: 0; } }
.meet-letter.glow .letter-blob { filter: drop-shadow(0 0 18px rgba(255, 214, 80, .95)) drop-shadow(0 8px 0 rgba(0, 0, 0, .12)); }
.meet3[data-stage="see"] .meet-letter { animation: seeIn .7s cubic-bezier(.2, 1.5, .4, 1) both; }
@keyframes seeIn { from { transform: scale(.6); opacity: 0; } }

.btn-done { font-size: clamp(24px, 5vmin, 40px); padding: 10px 34px 10px 18px; min-height: clamp(64px, 14vmin, 96px); border-radius: 999px; gap: 12px; animation: nudge 1.6s ease-in-out infinite; }
.btn-done .ico { width: 1.5em; height: 1.5em; }

/* Story scenes (js/screens/story.js) */
.story-art { position: absolute; inset: 0; }
.story-art > img, .story-art > svg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.story-dots { display: flex; justify-content: center; gap: 8px; min-height: 10px; }
.story-dots i { width: 12px; height: 12px; border-radius: 50%; background: #dfe7ee; box-shadow: inset 0 0 0 2px rgba(0, 0, 0, .06); }
.story-dots i.seen { background: #8fd3a0; }
.story-dots i.cur { box-shadow: 0 0 0 3px #ffd23f; }
.story-next:disabled { opacity: .45; filter: grayscale(.4); animation: none; }
.story-next.ready:not(:disabled) { animation: nudge 1.6s ease-in-out infinite; }
.story-text .other-lang { margin-top: 8px; font-weight: 700; color: #136b33; }
/* Listen / Touch panels sit on a soft card so stars and icons stay clear over any scenery */
.meet3 .mpanel[data-panel="listen"], .meet3 .mpanel[data-panel="touch"] {
  background: rgba(255, 255, 255, .96); border-radius: 30px; padding: clamp(12px, 2.6vh, 24px) clamp(16px, 2.4vw, 30px);
  box-shadow: 0 8px 0 rgba(20, 50, 80, .1), 0 12px 24px rgba(20, 50, 80, .1);
}
.meet3 .mpanel .mpanel-label { box-shadow: none; background: #f1f6f9; }
.meet3 .tap-star { color: #cfd8e0; text-shadow: 0 2px 0 #b8c3cd; }

/* ==========================================================================
   Engine — Letter Colouring (js/games/colouring.js)
   ========================================================================== */
.colour-game { position: absolute !important; inset: 0; z-index: 3 !important; display: flex; align-items: center; justify-content: center;
  padding: max(calc(var(--scene-h) * .14), 70px) 4vw calc(var(--scene-h) * .05) var(--helper-gutter); }
.colour-stage { display: flex; align-items: center; justify-content: center; gap: clamp(14px, 4vw, 56px); width: 100%; height: 100%; }
.colour-canvas-wrap { height: min(100%, calc(var(--scene-h) * .8)); aspect-ratio: 1; max-width: 62vw; border-radius: clamp(22px, 4vmin, 40px);
  background: radial-gradient(circle at 50% 42%, #fffef8 0%, #fff7e2 70%, #fbe9c4 100%); box-shadow: 0 8px 0 rgba(150, 110, 40, .25), 0 14px 30px rgba(40, 60, 30, .2); }
.colour-canvas { width: 100%; height: 100%; display: block; touch-action: manipulation; }
.colour-glyph { font-family: var(--font-ar); font-weight: 700; font-synthesis: none; direction: rtl; }
.glyph-base { fill: #f3efe6; }
.glyph-line { fill: none; stroke: #3d3a4a; stroke-width: 9; stroke-linejoin: round; pointer-events: none; }
.region { transition: fill .25s; pointer-events: none; }
.region.pending { fill: #fff3b0; animation: partHint 2.2s ease-in-out var(--d, 0s) infinite; }
.region.splash { animation: partSplash .45s ease-out; transform-box: fill-box; transform-origin: center; }
@keyframes partHint { 0%, 100% { opacity: .15; } 50% { opacity: .7; } }
@keyframes partSplash { 0% { opacity: .3; } 100% { opacity: 1; } }
.part-line { stroke: #fff; stroke-width: 7; stroke-dasharray: 18 14; opacity: .9; pointer-events: none; }
.part-hit { fill: transparent; pointer-events: all; cursor: pointer; outline: none; }
.part-hit:focus-visible { stroke: var(--gold); stroke-width: 8; }
.colour-canvas.done { animation: letterDone 1s cubic-bezier(.2, 1.6, .4, 1); filter: drop-shadow(0 0 18px rgba(255, 210, 63, .9)); }
@keyframes letterDone { 0% { transform: scale(1); } 40% { transform: scale(1.06) rotate(-2deg); } 100% { transform: scale(1); } }
/* Palette: two columns of big round paint pots; the chosen one gets a gold ring and lifts */
.colour-palette { display: grid; grid-template-columns: repeat(2, auto); gap: clamp(8px, 1.8vmin, 16px); flex: 0 0 auto; }
.swatch { width: clamp(46px, calc(var(--scene-h) * .13), 92px); aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, color-mix(in srgb, var(--sw) 55%, #fff) 0%, var(--sw) 55%, color-mix(in srgb, var(--sw) 75%, #000) 100%);
  box-shadow: 0 5px 0 color-mix(in srgb, var(--sw) 60%, #000), inset 0 -4px 0 rgba(0, 0, 0, .12); transition: transform .15s, box-shadow .15s; }
.swatch.on { transform: translateY(-4px) scale(1.08); box-shadow: 0 0 0 5px #fff, 0 0 0 9px var(--gold), 0 9px 0 color-mix(in srgb, var(--sw) 60%, #000); }
.swatch:active { transform: translateY(2px) scale(.96); }
.colour-game .goal-bar .goal-target { background: var(--pick, #e2187f); transition: background .25s; }
.cslot { display: inline-block; width: clamp(22px, 4.6vmin, 32px); aspect-ratio: 1; border-radius: 50%; box-shadow: inset 0 0 0 3px #c9d6df; vertical-align: middle; }
.cslot.on { background: var(--sw); box-shadow: 0 2px 0 rgba(0, 0, 0, .2); animation: starPop .45s cubic-bezier(.2, 1.8, .4, 1) both; }

/* Preview / testing mode (?preview=1): its progress is stored apart from the learner's */
body.preview-mode::after { content: 'PREVIEW · test progress'; position: fixed; left: 50%; bottom: 4px; transform: translateX(-50%); z-index: 60;
  padding: 2px 12px; border-radius: 999px; background: rgba(31, 61, 64, .85); color: #fff; font: 800 11px/1.6 var(--font-ui); letter-spacing: .06em; pointer-events: none; }

/* ==========================================================================
   Engine — Memory Match (js/games/memory.js)
   ========================================================================== */
.memory-game { position: absolute !important; inset: 0; z-index: 3 !important; display: flex; align-items: center; justify-content: center;
  padding: max(calc(var(--scene-h) * .15), 72px) 4vw calc(var(--scene-h) * .05) var(--helper-gutter); }
.memory-grid { --gap: clamp(8px, 1.8vmin, 18px); display: grid; grid-template-columns: repeat(var(--cols), 1fr); gap: var(--gap);
  height: min(100%, calc(var(--scene-h) * .78)); aspect-ratio: calc(var(--cols) * 3) / 4; max-width: 100%; }
.mem-card { position: relative; width: 100%; height: 100%; min-height: 0; perspective: 900px; border-radius: clamp(14px, 2.6vmin, 24px); }
.mem-inner { position: absolute; inset: 0; transform-style: preserve-3d; transition: transform .45s cubic-bezier(.3, 1.4, .5, 1); }
.mem-card.up .mem-inner, .mem-card.matched .mem-inner { transform: rotateY(180deg); }
.mem-back, .mem-front { position: absolute; inset: 0; display: grid; place-items: center; backface-visibility: hidden; border-radius: inherit; }
.mem-back { background: radial-gradient(circle at 30% 25%, #8fd8ff 0%, #3d9df5 60%, #2a78c9 100%);
  box-shadow: 0 6px 0 #1f5f9e, inset 0 0 0 5px rgba(255, 255, 255, .45); }
.mem-back svg { width: 42%; height: 42%; opacity: .95; }
.mem-front { transform: rotateY(180deg); background: linear-gradient(180deg, #fff, #f4f8fb); box-shadow: 0 6px 0 rgba(20, 50, 80, .18), inset 0 0 0 4px color-mix(in srgb, var(--c) 30%, #fff); }
.mem-glyph { font-size: clamp(34px, calc(var(--scene-h) * .15), 110px); line-height: 1; color: var(--c); margin-top: -12%; }
.mem-card.matched .mem-front { background: radial-gradient(circle at 50% 45%, #fffbe6, #ffeaa0); box-shadow: 0 0 0 4px #ffd23f, 0 0 16px 4px rgba(255, 205, 50, .6); }
.mem-card.matched { animation: starPop .5s cubic-bezier(.2, 1.8, .4, 1); }
.memory-game .seat { display: inline-block; width: clamp(24px, 5vmin, 34px); aspect-ratio: 1; border-radius: 50%; box-shadow: inset 0 0 0 3px #c9d6df; vertical-align: middle; }
.memory-game .seat.on { box-shadow: none; animation: starPop .5s cubic-bezier(.2, 1.8, .4, 1) both; }
.memory-game .seat svg { width: 100%; height: 100%; display: block; }

/* ==========================================================================
   Engine — Letter Tracing (js/games/tracing.js) — shares the colouring card layout
   ========================================================================== */
.trace-game { position: absolute !important; inset: 0; z-index: 3 !important; display: flex; align-items: center; justify-content: center;
  padding: max(calc(var(--scene-h) * .14), 70px) 4vw calc(var(--scene-h) * .05) var(--helper-gutter); }
.trace-canvas { touch-action: none; }
/* positioned from the left edge of its advance (guides are measured that way); one isolated letter, so shaping is unchanged */
.trace-canvas .tr-text { direction: ltr; text-anchor: start; }
.tr-ink { fill: none; stroke: #3d9df5; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
.tr-fill { fill: #3d9df5; opacity: 0; transition: opacity .6s; pointer-events: none; }
.trace-canvas.done .tr-fill { opacity: 1; }
.trace-canvas.done .tr-ink { stroke: #3d9df5; }
.tr-guide { fill: none; stroke: #f0a830; stroke-width: 7; stroke-dasharray: 3 22; stroke-linecap: round; pointer-events: none; opacity: .9; }
.tr-guide.hide { display: none; }
.tr-arrow { fill: none; stroke: #f0a830; stroke-width: 7; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
.tr-pt circle { fill: #fff; stroke: #c9a06a; stroke-width: 5; }
.tr-pt.start circle { fill: #2bb58c; stroke: #fff; stroke-width: 7; }
.tr-pt.next circle { fill: #ffd23f; stroke: #fff; stroke-width: 6; animation: trPulse 1.2s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
.tr-pt.start.next circle { fill: #2bb58c; }
.tr-pt.done circle { fill: #3d9df5; stroke: #fff; }
.tr-pt.big { cursor: pointer; outline: none; }
.tr-pt.big:focus-visible circle { stroke: var(--gold); stroke-width: 10; }
.tr-num { font: 800 34px var(--font-ui); fill: #1f3d40; text-anchor: middle; dominant-baseline: central; pointer-events: none; }
.tr-pt.done .tr-num, .tr-pt.start .tr-num { fill: #fff; }
.tr-dot { cursor: pointer; outline: none; }
.tr-dot circle { fill: rgba(255, 255, 255, .35); stroke: #f0a830; stroke-width: 7; stroke-dasharray: 10 8; }
.tr-dot.next circle { fill: rgba(255, 210, 63, .55); animation: trPulse 1.2s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
.tr-dot.done circle { fill: rgba(61, 157, 245, .35); stroke: #3d9df5; stroke-dasharray: none; }
.tr-dot:focus-visible circle { stroke: var(--gold); stroke-width: 10; }
@keyframes trPulse { 50% { transform: scale(1.18); } }
.trace-modes { display: flex; flex-direction: column; gap: clamp(8px, 1.8vmin, 16px); flex: 0 0 auto; }
.trace-mode { display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: clamp(84px, 13vmin, 130px); padding: clamp(6px, 1.2vmin, 12px);
  border-radius: clamp(14px, 2.6vmin, 22px); background: #fff; box-shadow: 0 5px 0 rgba(20, 50, 80, .14); font-weight: 800; font-size: clamp(12px, 2.2vmin, 17px); color: var(--ink); }
.trace-mode span { font-size: clamp(22px, 5vmin, 40px); line-height: 1.1; }
.trace-mode.on { box-shadow: 0 5px 0 var(--gold-d), 0 0 0 4px var(--gold); }
.trace-game .seat { display: inline-block; width: clamp(24px, 5vmin, 34px); aspect-ratio: 1; border-radius: 50%; box-shadow: inset 0 0 0 3px #c9d6df; vertical-align: middle; }
.trace-game .seat.on { box-shadow: none; animation: starPop .5s cubic-bezier(.2, 1.8, .4, 1) both; }
.trace-game .seat svg { width: 100%; height: 100%; display: block; }

/* ==========================================================================
   Engine — Listen & Find (js/games/listen.js) — prepared; playable only with reviewed recordings
   ========================================================================== */
.listen-game { position: absolute !important; inset: 0; z-index: 3 !important; display: flex; align-items: center; justify-content: center;
  padding: max(calc(var(--scene-h) * .15), 72px) 4vw calc(var(--scene-h) * .05) var(--helper-gutter); }
.listen-stage { display: flex; align-items: center; justify-content: center; gap: clamp(20px, 5vw, 70px); }
.listen-play { width: clamp(90px, calc(var(--scene-h) * .28), 190px); aspect-ratio: 1; }
.listen-cards { display: flex; gap: clamp(10px, 2.4vmin, 24px); }
.listen-card { width: clamp(84px, calc(var(--scene-h) * .26), 170px); font-size: clamp(44px, calc(var(--scene-h) * .15), 100px); }
.listen-card.right { box-shadow: 0 0 0 5px #ffd23f, 0 0 16px 4px rgba(255, 205, 50, .6); }
