:root {
  --ink: #2b2350;
  --ink2: #5a5385;
  --paper: #ffffff;
  --yellow: #ffd23f;
  --green: #3ec46d;
  --red: #ff5d6c;
  --blue: #4d8dff;
  --purple: #9b6bff;
  --panel-h: clamp(150px, 27dvh, 250px);
  --font-head: 'Fredoka', 'Baloo 2', 'Arial Rounded MT Bold', system-ui, sans-serif;
  --font-read: 'Andika', 'Fredoka', system-ui, sans-serif;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body {
  margin: 0; height: 100%; overflow: hidden; background: #7fd0ff; color: var(--ink);
  font-family: var(--font-head); -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
  touch-action: manipulation; overscroll-behavior: none;
}
button { font-family: var(--font-head); color: var(--ink); cursor: pointer; touch-action: manipulation; }
.lbl { font-family: var(--font-head); font-weight: 600; }

/* ---------- app shell */
#app { position: fixed; inset: 0; display: flex; flex-direction: column; overflow: hidden; transition: background 1s; }
#decor { position: absolute; inset: 0; pointer-events: none; }
#decor svg { width: 100%; height: 100%; }
.theme-sky { background: linear-gradient(#7fd0ff, #d4f1ff 70%); }
.theme-jungle { background: linear-gradient(#9fe8b8, #effed8 75%); }
.theme-craft { background: radial-gradient(circle at 20% 30%, #fff1a8 0 8%, transparent 9%), radial-gradient(circle at 80% 70%, #fff1a8 0 6%, transparent 7%), linear-gradient(#ffe066, #fff3b8); }
.theme-lab { background: linear-gradient(#bfe3ff, #eff8ff 75%); }
.theme-forest { background: linear-gradient(#bfe9ff, #e2f8d2 70%); }
.theme-splash { background: linear-gradient(#8fe2ff, #e4faff 75%); }
.theme-skyisland { background: linear-gradient(#5cb8ff, #d3eeff 75%); }
.theme-waterpark { background: linear-gradient(#7ad8ff, #fff2c9 80%); }
.theme-map { background: linear-gradient(#7fd0ff, #c3f3cf 80%); }
.theme-test { background: linear-gradient(#ffb86b, #ffe9a8 80%); }

#topbar { position: relative; z-index: 5; display: flex; align-items: center; gap: 12px; padding: max(10px, env(safe-area-inset-top)) 16px 6px; }
.chip { display: flex; align-items: center; gap: 8px; background: rgba(255,255,255,.88); border: 3px solid var(--ink); border-radius: 999px; padding: 6px 16px; font-weight: 700; font-size: clamp(16px, 2.3vmin, 24px); box-shadow: 0 4px 0 rgba(43,35,80,.25); }
.iconbtn { width: 54px; height: 54px; border-radius: 50%; border: 3px solid var(--ink); background: #fff; display: grid; place-items: center; box-shadow: 0 4px 0 rgba(43,35,80,.3); font-size: 26px; flex: none; transition: transform .1s; }
.iconbtn:active { transform: translateY(3px); box-shadow: 0 1px 0 rgba(43,35,80,.3); }
.iconbtn svg { width: 30px; height: 30px; }
#secTitle { flex: 1; justify-content: center; text-align: center; }
#dots { display: flex; gap: 6px; margin-left: 6px; }
#dots i { width: 12px; height: 12px; border-radius: 50%; background: #d8d4ec; border: 2px solid var(--ink); }
#dots i.on { background: var(--yellow); }
#dots i.cur { background: var(--green); transform: scale(1.25); }

#stage { position: relative; z-index: 2; flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; padding: 0 16px; }
#stage > svg, #scene svg { width: 100%; height: 100%; max-height: 100%; overflow: visible; }
#scene { position: absolute; inset: 0 16px; }
.scene-enter { animation: sceneIn .6s cubic-bezier(.2,1.4,.4,1) both; }
@keyframes sceneIn { from { opacity: 0; transform: translateX(60px) scale(.96); } to { opacity: 1; transform: none; } }

/* ---------- narration panel */
#panel { position: relative; z-index: 4; height: var(--panel-h); margin: 0 16px max(14px, env(safe-area-inset-bottom)); display: flex; align-items: stretch; gap: 14px;
  background: #fff; border: 4px solid var(--ink); border-radius: 30px; padding: 14px 16px; box-shadow: 0 8px 0 rgba(43,35,80,.28); }
#who { width: clamp(70px, 11vmin, 110px); flex: none; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; }
#who .av { width: 100%; aspect-ratio: 1; border-radius: 50%; border: 3px solid var(--ink); display: grid; place-items: center; overflow: hidden; background: #e9f4ff; }
#who .av svg { width: 86%; height: 86%; }
#who .nm { font-size: clamp(13px, 1.8vmin, 18px); font-weight: 700; }
#who.z .av { background: #d9fff9; }
#who.talking .av { animation: talk .5s ease-in-out infinite alternate; }
@keyframes talk { to { transform: scale(1.07) rotate(-3deg); } }
#text { flex: 1; overflow-y: auto; display: flex; align-items: center; font-family: var(--font-read); font-size: clamp(22px, 3.7vmin, 40px); line-height: 1.38; font-weight: 700; color: #4c4672; }
#text .inner { width: 100%; }
#text .w { display: inline; padding: 0 .06em; border-radius: .25em; transition: color .15s, background .15s; }
#text .w.done { color: var(--ink); }
#text .w.now { background: #ffe066; color: var(--ink); box-shadow: 0 0 0 3px #ffe066; }
#text .w.key { color: #7b3fe4; text-decoration: underline; text-decoration-thickness: 3px; text-underline-offset: 4px; }
#text .w.key.now { color: #7b3fe4; }
#ctrls { display: flex; flex-direction: column; justify-content: center; gap: 10px; flex: none; }
#ctrls .row { display: flex; gap: 10px; }
#nextBtn { width: clamp(84px, 13vmin, 120px); height: clamp(84px, 13vmin, 120px); border-radius: 50%; border: 4px solid var(--ink); background: #d6d3e6; font-size: 44px; display: grid; place-items: center; box-shadow: 0 6px 0 rgba(43,35,80,.35); transition: background .3s, transform .1s; }
#nextBtn svg { width: 55%; height: 55%; }
#nextBtn.ready { background: var(--green); animation: nudge 1.3s ease-in-out infinite; }
#nextBtn:disabled { opacity: .55; }
#nextBtn:active { transform: translateY(4px); box-shadow: 0 2px 0 rgba(43,35,80,.35); }
@keyframes nudge { 0%,100% { transform: scale(1); } 50% { transform: scale(1.09); } }

/* ---------- overlays */
.overlay { position: fixed; inset: 0; z-index: 20; display: none; align-items: center; justify-content: center; padding: 16px; }
.overlay.show { display: flex; }
.dim { background: rgba(32,24,70,.55); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }
.card { background: #fff; border: 5px solid var(--ink); border-radius: 36px; box-shadow: 0 12px 0 rgba(43,35,80,.35); }
.popin { animation: popin .55s cubic-bezier(.2,1.6,.4,1) both; }
@keyframes popin { from { transform: scale(.4) rotate(-4deg); opacity: 0; } to { transform: none; opacity: 1; } }

/* quiz */
#quiz .card { width: min(1100px, 100%); max-height: 100%; display: flex; flex-direction: column; padding: clamp(14px, 2.4vmin, 26px); gap: clamp(8px, 1.6vmin, 16px); overflow: hidden; }
#qhead { display: flex; align-items: center; gap: 12px; }
#qbadge { background: var(--purple); color: #fff; border-radius: 999px; padding: 6px 16px; font-weight: 700; font-size: clamp(15px, 2.2vmin, 22px); border: 3px solid var(--ink); white-space: nowrap; }
#qbadge.retry { background: #ff9a3c; }
#qprog { flex: 1; height: 16px; border-radius: 99px; background: #eee9ff; border: 3px solid var(--ink); overflow: hidden; }
#qprog i { display: block; height: 100%; background: linear-gradient(90deg, #3ec46d, #9be36a); transition: width .5s; }
#qtext { font-family: var(--font-read); font-weight: 700; font-size: clamp(24px, 4vmin, 44px); line-height: 1.25; text-align: center; }
#qtext .w.now { background: #ffe066; border-radius: .2em; box-shadow: 0 0 0 3px #ffe066; }
#qart { height: clamp(120px, 26dvh, 280px); display: none; }
#qart.show { display: block; }
#qart svg { width: 100%; height: 100%; }
#opts { display: grid; gap: clamp(10px, 1.6vmin, 18px); grid-template-columns: repeat(var(--n, 3), 1fr); }
#opts.textopts { grid-template-columns: 1fr; }
.opt { position: relative; border: 4px solid var(--ink); border-radius: 26px; background: #f4f1ff; padding: clamp(10px, 1.6vmin, 18px); font-size: clamp(20px, 3.1vmin, 34px); font-weight: 600; line-height: 1.15;
  box-shadow: 0 7px 0 rgba(43,35,80,.3); display: flex; align-items: center; justify-content: center; gap: 14px; min-height: clamp(64px, 9vmin, 92px); transition: transform .1s, background .2s; text-align: center; }
.opt .ic { width: clamp(70px, 14vmin, 150px); height: clamp(70px, 14vmin, 150px); flex: none; }
.opt.hasicon { flex-direction: column; gap: 6px; }
.opt:active { transform: translateY(5px); box-shadow: 0 2px 0 rgba(43,35,80,.3); }
.opt.reading { background: #fff6c2; }
.opt.right { background: #b9f5c8; border-color: #1d8a45; animation: bounceRight .6s; }
.opt.wrong { background: #ffd0d6; border-color: #c4283c; animation: shake .5s; }
.opt.dimmed { opacity: .45; }
.opt .mark { position: absolute; top: -18px; right: -14px; width: 48px; height: 48px; border-radius: 50%; display: grid; place-items: center; font-size: 28px; border: 3px solid var(--ink); color: #fff; font-weight: 700; }
.opt.right .mark { background: #1d8a45; }
.opt.wrong .mark { background: #c4283c; }
.opt.tf { font-size: clamp(28px, 4.5vmin, 46px); }
@keyframes shake { 20%,60% { transform: translateX(-12px); } 40%,80% { transform: translateX(12px); } }
@keyframes bounceRight { 30% { transform: scale(1.08); } 60% { transform: scale(.97); } }
#qfoot { display: flex; justify-content: center; gap: 14px; min-height: 0; }
.bigbtn { border: 4px solid var(--ink); border-radius: 999px; padding: 12px 34px; font-size: clamp(22px, 3.2vmin, 34px); font-weight: 700; background: var(--green); color: #fff; box-shadow: 0 7px 0 rgba(43,35,80,.35); text-shadow: 0 2px 0 rgba(0,0,0,.2); }
.bigbtn.alt { background: #fff; color: var(--ink); text-shadow: none; }
.bigbtn:active { transform: translateY(5px); box-shadow: 0 2px 0 rgba(43,35,80,.35); }
.hearbtn { width: 58px; height: 58px; }

/* explain */
#explain { display: none; border-radius: 26px; background: #fff8e1; border: 4px dashed #ffb02e; padding: clamp(10px, 1.8vmin, 18px); gap: 14px; align-items: center; }
#explain.show { display: flex; animation: popin .5s both; }
#explain .exart { width: clamp(110px, 20vmin, 220px); height: clamp(110px, 20vmin, 220px); flex: none; }
#explain .exart svg { width: 100%; height: 100%; }
#explain .ext { font-family: var(--font-read); font-size: clamp(20px, 3.1vmin, 32px); line-height: 1.3; font-weight: 700; color: #4c4672; }
#explain .ext .w.now { background: #ffe066; color: var(--ink); border-radius: .2em; }
#explain .ext .w.done { color: var(--ink); }
#explain .ans { display: inline-block; background: #b9f5c8; border: 3px solid #1d8a45; border-radius: 14px; padding: 2px 12px; margin-bottom: 6px; font-family: var(--font-head); color: #145c2f; }

/* sort */
#sortItem { display: none; justify-content: center; }
#sortItem.show { display: flex; }
#sortItem .ic { width: clamp(130px, 24vmin, 240px); height: clamp(130px, 24vmin, 240px); animation: popOut .7s cubic-bezier(.2,1.6,.4,1) both; }
@keyframes popOut { from { transform: translateY(80px) scale(.3); opacity: 0; } to { transform: none; opacity: 1; } }

/* title / map / summary */
#title { flex-direction: column; gap: 18px; text-align: center; }
#title h1 { margin: 0; font-size: clamp(52px, 11vmin, 120px); color: #fff; -webkit-text-stroke: 4px var(--ink); paint-order: stroke fill; text-shadow: 0 8px 0 rgba(43,35,80,.35); letter-spacing: 2px; line-height: 1; }
#title h1 span { color: var(--yellow); }
#title .sub { font-size: clamp(20px, 3.4vmin, 34px); font-weight: 700; color: var(--ink); background: rgba(255,255,255,.85); padding: 8px 22px; border-radius: 999px; border: 3px solid var(--ink); }
#title .zipbig { width: clamp(110px, 20vmin, 200px); height: clamp(160px, 31vmin, 300px); margin-bottom: 3vmin; }
#startBtn { font-size: clamp(30px, 5vmin, 52px); padding: 18px 60px; animation: nudge 1.4s ease-in-out infinite; }
#title .row { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; }
#grown { position: absolute; right: 18px; bottom: 18px; font-size: 18px; padding: 10px 18px; border-radius: 999px; border: 3px solid var(--ink); background: rgba(255,255,255,.9); font-weight: 700; }
#grown .fill { position: absolute; left: 0; bottom: 0; height: 6px; background: var(--purple); width: 0; border-radius: 99px; }

#map { flex-direction: column; padding: 0; }
#mapWrap { position: relative; width: 100%; height: 100%; }
#mapWrap > svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.stop { position: absolute; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; gap: 4px; background: none; border: 0; padding: 0; }
.stop .disc { width: clamp(84px, 13vmin, 130px); height: clamp(84px, 13vmin, 130px); border-radius: 50%; background: #fff; border: 5px solid var(--ink); display: grid; place-items: center; box-shadow: 0 7px 0 rgba(43,35,80,.35); }
.stop .disc svg { width: 72%; height: 72%; }
.stop .nm { background: #fff; border: 3px solid var(--ink); border-radius: 999px; padding: 3px 12px; font-weight: 700; font-size: clamp(13px, 2vmin, 19px); white-space: nowrap; }
.stop .stars { display: flex; gap: 2px; height: 26px; }
.stop .stars svg { width: 26px; height: 26px; }
.stop.locked .disc { filter: grayscale(1); opacity: .55; }
.stop.locked .nm { opacity: .7; }
.stop.next .disc { animation: glowp 1.2s ease-in-out infinite; background: #fff6c2; }
@keyframes glowp { 0%,100% { box-shadow: 0 7px 0 rgba(43,35,80,.35), 0 0 0 0 rgba(255,210,63,.9); } 50% { box-shadow: 0 7px 0 rgba(43,35,80,.35), 0 0 0 22px rgba(255,210,63,0); } }
#mapZip { position: absolute; width: clamp(70px, 11vmin, 110px); height: clamp(90px, 15vmin, 150px); transform: translate(-50%, -105%); transition: left 1.2s ease-in-out, top 1.2s ease-in-out; pointer-events: none; }
#mapTop { position: absolute; top: max(12px, env(safe-area-inset-top)); left: 16px; right: 16px; display: flex; justify-content: space-between; align-items: center; z-index: 3; }

#done .card, #summary .card { width: min(1000px, 100%); max-height: 100%; overflow-y: auto; padding: clamp(18px, 3vmin, 34px); text-align: center; }
#done h2, #summary h2 { margin: 0 0 8px; font-size: clamp(32px, 6vmin, 60px); }
#done .bigstars { display: flex; justify-content: center; gap: 10px; margin: 12px 0; }
#done .bigstars svg { width: clamp(60px, 12vmin, 110px); height: clamp(60px, 12vmin, 110px); animation: popin .6s both; }
#done .bigstars svg.off { filter: grayscale(1); opacity: .3; }
#summary .card { text-align: left; font-family: system-ui, -apple-system, sans-serif; color: #222; -webkit-user-select: text; user-select: text; }
#summary h2 { font-family: var(--font-head); }
#summary .meta { color: #666; margin-bottom: 14px; }
#summary table { width: 100%; border-collapse: collapse; margin: 8px 0 18px; font-size: 16px; }
#summary th, #summary td { border-bottom: 1px solid #e3e0ef; padding: 8px 6px; text-align: left; vertical-align: top; }
#summary th { background: #f4f1ff; }
#summary .ok { color: #1d8a45; font-weight: 700; }
#summary .bad { color: #c4283c; font-weight: 700; }
#summary .warn { color: #c46a00; font-weight: 700; }
#summary .pill { display: inline-block; padding: 2px 10px; border-radius: 99px; font-size: 13px; font-weight: 700; }
#summary .pill.ok { background: #d8f7e0; } #summary .pill.bad { background: #ffe0e4; } #summary .pill.warn { background: #fff0d6; }
#summary h3 { margin: 18px 0 6px; font-family: var(--font-head); }
#summary .miss { border: 1px solid #eee; border-radius: 12px; padding: 10px 12px; margin: 8px 0; background: #fffdfa; }
#summary .miss b { display: block; margin-bottom: 4px; }
#summary .btns { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; position: sticky; bottom: -34px; background: #fff; padding: 10px 0; }
#summary .btns button { border: 2px solid #2b2350; border-radius: 12px; padding: 10px 16px; font-size: 16px; background: #fff; font-family: system-ui, sans-serif; }
#summary .btns .danger { color: #c4283c; border-color: #c4283c; }

#toast { position: fixed; left: 50%; top: 14%; transform: translateX(-50%); z-index: 40; pointer-events: none; }
#toast .t { font-size: clamp(36px, 7vmin, 72px); font-weight: 700; color: #fff; -webkit-text-stroke: 3px var(--ink); paint-order: stroke fill; text-shadow: 0 6px 0 rgba(43,35,80,.35); animation: toast 1.6s ease-out both; white-space: nowrap; }
@keyframes toast { 0% { transform: scale(.3); opacity: 0; } 20% { transform: scale(1.15); opacity: 1; } 35% { transform: scale(1); } 80% { opacity: 1; } 100% { transform: translateY(-40px); opacity: 0; } }
#confetti { position: fixed; inset: 0; pointer-events: none; z-index: 45; overflow: hidden; }
#confetti i { position: absolute; top: -20px; width: 12px; height: 18px; border-radius: 3px; animation: fall linear forwards; }
@keyframes fall { to { transform: translate3d(var(--dx), 110vh, 0) rotate(var(--r)); } }
#rotate { display: none; }

/* ---------- SVG art animations */
svg .bob, svg .bob2, svg .floaty, svg .sway, svg .blink, svg .flame, svg .wave, svg .pulse, svg .twinkle, svg .wig, svg .squish, svg .bobwater,
svg .glow, svg .jelly, svg .wag, svg .drip, svg .rise, svg .stink, svg .windy, svg .soundw, svg .slide, svg .smoke, svg .choo, svg .bend, svg .leaf, svg .kite, svg .breathe, svg .pop, svg .jit, svg .saw, svg .brushmove, svg .pourdown, svg .ripple {
  transform-box: fill-box; transform-origin: center;
}
.bob { animation: bob 2.6s ease-in-out infinite; }
.bob2 { animation: bob 3.4s ease-in-out infinite; animation-delay: -1.1s; }
@keyframes bob { 50% { transform: translateY(-10px); } }
.floaty { animation: floaty 6s ease-in-out infinite; }
@keyframes floaty { 0%,100% { transform: translateY(0) rotate(-1.5deg); } 50% { transform: translateY(-22px) rotate(1.5deg); } }
.bobwater { animation: bobwater 3s ease-in-out infinite; }
@keyframes bobwater { 0%,100% { transform: translateY(0) rotate(-2deg); } 50% { transform: translateY(8px) rotate(2deg); } }
.sway { transform-origin: 50% 100% !important; animation: sway 4s ease-in-out infinite; }
@keyframes sway { 0%,100% { transform: rotate(-2.5deg); } 50% { transform: rotate(2.5deg); } }
.bend { animation: bend 1.4s ease-in-out infinite; transform-box: view-box !important; }
@keyframes bend { 0%,100% { transform: rotate(4deg) skewX(-3deg); } 50% { transform: rotate(10deg) skewX(-8deg); } }
.blink { animation: blink 4.5s infinite; }
@keyframes blink { 0%,92%,100% { transform: scaleY(1); } 95% { transform: scaleY(.1); } }
.flame { transform-origin: 50% 0 !important; animation: flame .18s ease-in-out infinite alternate; }
@keyframes flame { to { transform: scaleY(1.35) scaleX(.85); } }
.wave { transform-origin: 100% 100% !important; animation: wave 1s ease-in-out infinite alternate; }
@keyframes wave { from { transform: rotate(-8deg); } to { transform: rotate(18deg); } }
.glow { animation: glowc 1.2s ease-in-out infinite alternate; }
@keyframes glowc { to { fill: #ffe066; } }
.pulse { animation: pulse 1.4s ease-in-out infinite; }
@keyframes pulse { 50% { transform: scale(1.12); } }
.twinkle { animation: twinkle 2s ease-in-out infinite; }
@keyframes twinkle { 0%,100% { transform: scale(.6) rotate(0); opacity: .5; } 50% { transform: scale(1.1) rotate(25deg); opacity: 1; } }
.squish { transform-origin: 50% 100% !important; animation: squish 1.6s ease-in-out infinite; }
@keyframes squish { 0%,100% { transform: scale(1, 1); } 40% { transform: scale(1.14, .82); } 60% { transform: scale(.94, 1.06); } }
.wig { }
.tgt.done .wig, .wig.wig-on { animation: wig .5s ease-in-out 3; }
@keyframes wig { 25% { transform: rotate(-9deg) scale(1.05); } 75% { transform: rotate(9deg) scale(1.05); } }
.wag { transform-origin: 0 100% !important; animation: wig .6s ease-in-out infinite; }
.drip { animation: drip 1.8s ease-in infinite; }
.drip.slow { animation-duration: 4.5s; }
@keyframes drip { 0% { transform: translateY(-6px) scale(.4); opacity: 0; } 20% { opacity: 1; transform: translateY(0) scale(1); } 100% { transform: translateY(150px) scale(1); opacity: 0; } }
.drip-on .drip { animation-duration: 1.2s; }
.rise { animation: rise 2.4s ease-in infinite; }
@keyframes rise { 0% { transform: translateY(0); opacity: 0; } 20% { opacity: 1; } 100% { transform: translateY(-60px); opacity: 0; } }
.stink { animation: stink 1.4s ease-in-out infinite; }
@keyframes stink { 0%,100% { transform: translateY(0); opacity: .4; } 50% { transform: translateY(-8px); opacity: 1; } }
.windy { animation: windy 1.8s ease-in-out infinite; }
@keyframes windy { 0% { transform: translateX(-20px); opacity: 0; } 30% { opacity: 1; } 100% { transform: translateX(40px); opacity: 0; } }
.soundw { animation: stink 1s ease-in-out infinite; }
.leaf { animation: leaf 3.2s linear infinite; transform-box: view-box !important; }
@keyframes leaf { 0% { transform: translate(0,0) rotate(0); opacity: 0; } 10% { opacity: 1; } 100% { transform: translate(900px, -120px) rotate(720deg); opacity: 0; } }
.kite { animation: floaty 2.4s ease-in-out infinite; }
.smoke { animation: rise 3s ease-out infinite; }
.choo { animation: choo 5s ease-in-out infinite alternate; }
@keyframes choo { from { transform: translateX(-30px); } to { transform: translateX(30px); } }
.saw { animation: saw .5s ease-in-out infinite alternate; }
@keyframes saw { from { transform: translateX(-20px); } to { transform: translateX(30px); } }
.jit { animation: jit 1.6s ease-in-out infinite alternate; }
@keyframes jit { 0% { transform: translate(0,0); } 50% { transform: translate(6px,-5px); } 100% { transform: translate(-5px,6px); } }
.slide { animation: slidedown 3s ease-in infinite; transform-box: view-box !important; }
@keyframes slidedown { 0% { transform: translate(-380px,-200px); } 70% { transform: translate(260px,90px); opacity: 1; } 100% { transform: translate(380px,160px); opacity: 0; } }
.breathe { animation: floaty 5s ease-in-out infinite; }
.pourdown { animation: pulse .6s ease-in-out infinite; }
.ripple { animation: ripple 2s ease-out infinite; }
@keyframes ripple { from { transform: scale(.4); opacity: 1; } to { transform: scale(2.2); opacity: 0; } }
.waves { animation: waves 3s ease-in-out infinite alternate; }
@keyframes waves { to { transform: translateX(-40px); } }
.shimmer { animation: stink 2.4s ease-in-out infinite; }
.flow { animation: flow 1s linear infinite; }
.flow.fast { animation-duration: .5s; }
@keyframes flow { to { stroke-dashoffset: -110; } }
.spin { animation: spin 30s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.drift { animation: drift 60s linear infinite; }
@keyframes drift { from { transform: translateX(-500px); } to { transform: translateX(1900px); } }
.bubble { animation: bubble 9s linear infinite; }
@keyframes bubble { to { transform: translateY(-1150px); } }
.pop { animation: popin .6s cubic-bezier(.2,1.6,.4,1) both; }
.draw path { stroke-dasharray: 400; stroke-dashoffset: 400; animation: draw 1s ease-out forwards; animation-delay: inherit; }
.draw { animation: fadein .4s both; }
@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes fadein { from { opacity: 0; } }
.slidein { animation: slidein 1.2s cubic-bezier(.2,1.2,.4,1) both; }
@keyframes slidein { from { transform: translateX(-300px); opacity: 0; } }
.wrap { stroke-dasharray: 200; animation: draw 1.4s ease-out both; }
.unroll { stroke-dasharray: 300; stroke-dashoffset: 300; animation: draw 1.4s ease-out .3s forwards; }
.jelly { animation: jelly .6s ease-in-out; transform-box: fill-box; transform-origin: center; }
@keyframes jelly { 30% { transform: scale(1.08, .92); } 60% { transform: scale(.95, 1.05); } }
.sinker { animation: sink 2.4s ease-in .4s forwards; }
@keyframes sink { 30% { transform: translateY(10px) rotate(10deg); } 100% { transform: translateY(210px) rotate(70deg); } }
.tipper { transform-box: view-box; }
.lstep.on ~ .tipper { animation: tip 1s ease-in forwards; }
@keyframes tip { to { transform: rotate(88deg); } }
.puddle { transform-box: view-box; animation: puddle 1.6s ease-out .7s both; }
@keyframes puddle { from { transform: scaleX(.1) scaleY(.3); opacity: 0; } to { transform: none; opacity: 1; } }
.lstep:not(.on) .puddle { animation: none; opacity: 0; }

/* step reveals + targets */
.lstep { opacity: 0; transition: opacity .5s; }
.lstep.on { opacity: 1; }
.lstep.on > .lpop { animation: popin .55s cubic-bezier(.2,1.6,.4,1) both; transform-box: fill-box; transform-origin: center; }
.static .lstep { opacity: 1; }
.halo { fill: #fff6a8; opacity: 0; stroke: #ffd23f; stroke-width: 6; transform-box: fill-box; transform-origin: center; }
.waiting .tgt:not(.done) .halo { animation: halo 1.3s ease-in-out infinite; }
@keyframes halo { 0%,100% { opacity: .2; transform: scale(.92); } 50% { opacity: .65; transform: scale(1.02); } }
.tgt { cursor: pointer; }
.reveal { opacity: 0; transform: scale(.4); transition: opacity .4s, transform .5s cubic-bezier(.2,1.6,.4,1); transform-box: fill-box; transform-origin: center; }
.tgt.done .reveal, .done-all .reveal { opacity: 1; transform: none; }
.tgt.done .hideondone { display: none; }
.beam.reveal { transform: none; }
.tgt.done .beam.reveal { animation: beam 1.1s ease-out forwards; }
@keyframes beam { 0% { opacity: 0; } 20% { opacity: .8; } 100% { opacity: 0; } }
.bal .beam, .bal .panL, .bal .panR { transition: transform 1.3s cubic-bezier(.3,1.5,.5,1); }
.bal .beam { transform-box: view-box; }
.dropin { opacity: 0; transform: translateY(-160px); transition: transform .6s cubic-bezier(.3,1.5,.5,1), opacity .3s; }
.bal.loaded .dropin { opacity: 1; transform: none; }
.mover { transition: transform 1s cubic-bezier(.3,1.3,.5,1); transform-box: view-box; }
.fillup { transform: scaleY(0); transition: transform 1.6s ease-out .5s; transform-box: view-box; }
.tgt.done .fillup, .static .fillup, svg:not(.interactive) .fillup { transform: scaleY(1); }
.stream { opacity: 0; stroke-dasharray: 260; stroke-dashoffset: 260; }
.tgt.done .stream { animation: pour 1.8s ease-in-out forwards; }
@keyframes pour { 0% { opacity: 1; stroke-dashoffset: 260; } 40% { opacity: 1; stroke-dashoffset: 0; } 85% { opacity: 1; } 100% { opacity: 0; stroke-dashoffset: -260; } }
.infl { transform: scale(.35); transition: transform 1.6s cubic-bezier(.3,1.4,.5,1); transform-box: view-box; }
.tgt.done .infl { transform: scale(1); }
.flypencil { transition: transform .7s ease-in, opacity .7s ease-in; transform-box: view-box; }
.paintlayer { transform: scaleY(0); transform-origin: 50% 0; transition: transform 1.2s ease-in-out; transform-box: fill-box; }
.tgt.done .paintlayer { transform: scaleY(1); }
.brushmove { opacity: 0; }
.tgt.done ~ .brush .brushmove { animation: brush 1.2s ease-in-out; }
@keyframes brush { 0% { opacity: 1; transform: translate(-300px, 0); } 50% { transform: translate(-230px, 160px); } 100% { opacity: 0; transform: translate(-300px, 300px); } }
.stk .fullB, .bal .fullB { opacity: 0; transform: scale(.2); transform-origin: 0 40px; transition: opacity .3s, transform 1s cubic-bezier(.3,1.4,.5,1); transform-box: view-box; }
.bal.filled .fullB, .filled .bal .fullB { opacity: 1; transform: none; }
.bal.filled .emptyB, .filled .bal .emptyB { opacity: 0; transition: opacity .3s; }
.gd { transition: transform 2.2s cubic-bezier(.3,1,.4,1); }
.reveal2 { animation: fadein .6s 2.6s both; }

@media (orientation: portrait) {
  :root { --panel-h: clamp(170px, 24dvh, 260px); }
}
@media (prefers-reduced-motion: reduce) {
  .drift, .bubble, .leaf { animation: none; }
}

/* ---------- space layer */
#space { position: fixed; inset: 0; z-index: 15; display: none; width: 100%; height: 100%;
  background: radial-gradient(ellipse at 28% 18%, #4a2f99 0%, #22155e 38%, #0b0730 70%, #04021a 100%); transition: opacity .6s; }
#space.show { display: block; }
#space.warp { z-index: 60; }
#space.fade { opacity: 0; }
#title h1 { text-shadow: 0 0 30px rgba(255,210,63,.6), 0 8px 0 rgba(43,35,80,.35); }
#title .sub { background: rgba(255,255,255,.92); }
#title .zipbig { animation: bob 3s ease-in-out infinite; filter: drop-shadow(0 0 24px rgba(127,249,255,.45)); }
.tplanet { position: absolute; pointer-events: none; animation: floaty 9s ease-in-out infinite; }
.tplanet svg { width: 100%; height: 100%; }
#mapTop .chip { background: rgba(255,255,255,.92); }
.stop .disc { width: clamp(96px, 15vmin, 150px); height: clamp(96px, 15vmin, 150px); border: 0; background: none; box-shadow: none; border-radius: 50%; }
.stop .disc svg { width: 100%; height: 100%; }
.stop.next .disc { animation: glowp2 1.4s ease-in-out infinite; background: none; }
@keyframes glowp2 { 0%,100% { filter: drop-shadow(0 0 4px #fff6a8); transform: scale(1); } 50% { filter: drop-shadow(0 0 22px #ffd23f); transform: scale(1.07); } }
.stop.locked .disc { filter: grayscale(.55) brightness(.8); opacity: .8; }
.stop .stars svg { filter: drop-shadow(0 0 4px rgba(255,210,63,.8)); }
.stop.shake { animation: shake .45s; }
#rocket { position: absolute; width: clamp(56px, 8vmin, 84px); height: clamp(94px, 13.4vmin, 140px); z-index: 4; pointer-events: none;
  transition: left 1.8s cubic-bezier(.45,0,.3,1), top 1.8s cubic-bezier(.45,0,.3,1), transform .5s; transform: translate(-50%, -50%) rotate(var(--rot, 0deg)); }
#rocket .rin { width: 100%; height: 100%; animation: bob 1.6s ease-in-out infinite; }
#rocket svg { width: 100%; height: 100%; overflow: visible; }
#rocket.fly .rflame { transform: scaleY(1.8); }
#rocket.dive { transition: transform .8s ease-in, opacity .8s; transform: translate(-50%, -50%) rotate(var(--rot,0deg)) scale(.15); opacity: 0; }
.rflame { transform-box: fill-box; transform-origin: 50% 0; animation: flame .15s ease-in-out infinite alternate; transition: transform .4s; }
#pathSvg path { fill: none; stroke: rgba(255,255,255,.55); stroke-width: 4; stroke-dasharray: 2 14; stroke-linecap: round; }
#pathSvg path.lit { stroke: #ffd23f; stroke-width: 5; }
.stop .nm { background: rgba(255,255,255,.95); }
#quiz .card, #done .card { box-shadow: 0 12px 0 rgba(0,0,0,.35), 0 0 60px rgba(155,107,255,.55); }
#done h2 { color: #2b2350; }
/* cinematic slow camera drift on story scenes */
#scene > svg { animation: camera 16s ease-in-out infinite alternate; transform-origin: 50% 55%; }
@keyframes camera { from { transform: scale(1) translate(0, 0); } to { transform: scale(1.045) translate(-6px, -4px); } }
.fadein { animation: fadein .8s both; }
#banner .card { box-shadow: 0 12px 0 rgba(0,0,0,.3), 0 0 80px rgba(255,210,63,.6); }
