/* 题型的样式在 styles/exercises.css（index.html 里单独 <link>）。家长页的在 styles/parent.css（parent.js 自己挂）。 */
/* Pals 原型样式。动效只用 transform / opacity，150–250ms；不做模糊、不做阴影动画。 */
@font-face { font-family: "Fredoka"; src: url("../assets/fonts/fredoka-400-700.woff2") format("woff2"); font-weight: 400 700; font-display: swap; }
@font-face { font-family: "Pals Word"; src: url("../assets/fonts/bunnyword-700.woff2") format("woff2"); font-weight: 700; font-display: swap; }
@font-face { font-family: "Resource Han Rounded"; src: url("../assets/fonts/resource-han-rounded-500.woff2") format("woff2"); font-weight: 300 600; font-display: swap; }
@font-face { font-family: "Resource Han Rounded"; src: url("../assets/fonts/resource-han-rounded-700.woff2") format("woff2"); font-weight: 650 900; font-display: swap; }

:root {
  /* 自己的色板：奶油底 + 橘子橙 / 湖水青 / 葡萄紫 / 蜜桃粉；没有红色状态 */
  --bg: #FFF6E8;
  --bg-deep: #FFE9C9;
  --ink: #43324F;
  --ink-soft: #8C7B96;   /* 只用于大字（≥ 24px 或粗体 ≥ 19px）；小字用 --ink-mid（对比度 ≥ 4.5） */
  --ink-mid: #5E4F6A;
  --card: #FFFFFF;
  --card-edge: #EBDCC6;
  /* 上面要写白字的颜色（大按钮、单元横幅）都保证白字对比度 ≥ 3:1（大号粗体字的标准）：橙色比原来深一档（白字 3.3:1） */
  --orange: #E8671B;  --orange-edge: #B4500F;
  --teal: #1FB7A6;    --teal-edge: #12917F;   --teal-deep: #0B7C6E; /* deep：写小白字用（4.9:1） */
  --violet: #8272F2;  --violet-edge: #5F4FD0;
  --pink: #F2719F;    --pink-edge: #CE4E7E;
  --gold: #FFB224;    --gold-edge: #DB8E0B;
  --yes: #2FBF8F;     --yes-deep: #1A9A70; /* 答对；deep 上写白字（3.6:1） */
  --soft-yellow: #FFE39A; /* 再试试 */
  --lock: #E7E2EC;    --lock-edge: #CFC8D8;  --lock-ink: #A99FB5;  /* lock-ink 只画图标；锁着的字用 --lock-text（5.2:1） */
  --lock-text: #6F6479;
  --confetti-0: var(--orange); --confetti-1: var(--teal); --confetti-2: var(--violet); --confetti-3: var(--gold); --confetti-4: var(--pink);
  --tap: 88px;
  --pad: 16px;
  --font: "Fredoka", "Resource Han Rounded", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
}
@media (min-width: 700px) and (min-height: 700px) { :root { --tap: 104px; --pad: 28px; } }

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; margin: 0; overflow: hidden; background: var(--bg); overscroll-behavior: none; }
body { font-family: var(--font); color: var(--ink); -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; touch-action: manipulation; }
button { font: inherit; color: inherit; border: 0; padding: 0; background: none; cursor: pointer; touch-action: manipulation; }
img { pointer-events: none; -webkit-user-drag: none; }
h1 { margin: 0; }
.icon { display: inline-flex; pointer-events: none; }
.icon svg { width: 100%; height: 100%; display: block; }

#app { position: fixed; inset: 0; padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); }
.screen { height: 100%; display: flex; flex-direction: column; } /* 换画面不加动画：立刻出现 */

/* ── 按钮：实心底边，按下去会「陷」下去 ── */
.btn, .btn-round { --c: var(--orange); --e: var(--orange-edge); position: relative; display: inline-flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; background: var(--c); box-shadow: 0 7px 0 var(--e); transition: transform 90ms ease-out; }
.btn { min-height: var(--tap); min-width: min(320px, 78vw); padding: 0 40px; border-radius: 28px; font-size: 32px; letter-spacing: 2px; }
.btn-round { width: var(--tap); height: var(--tap); border-radius: 50%; flex: none; }
.btn-round .icon { width: 48%; height: 48%; }
.btn:active, .btn-round:active { transform: translateY(6px); box-shadow: 0 1px 0 var(--e); }
.btn:disabled { --c: var(--lock); --e: var(--lock-edge); color: var(--lock-text); }
.btn-go { --c: var(--orange); --e: var(--orange-edge); }
.btn-sound { --c: var(--violet); --e: var(--violet-edge); }
.btn-mic { --c: var(--teal); --e: var(--teal-edge); width: calc(var(--tap) * 1.2); height: calc(var(--tap) * 1.2); }

/* ── 伙伴 ── */
.buddy { aspect-ratio: 4 / 5; flex: none; transform-origin: 50% 95%; }
.buddy img { width: 100%; height: 100%; display: block; object-fit: contain; }
.buddy.hop { animation: hop 240ms ease-out; }
.buddy.cheer { animation: cheer 520ms ease-out; }
.buddy.oops { animation: oops 420ms ease-in-out; }
@keyframes hop { 40% { transform: translateY(-9%) scale(1.03, .98); } }
@keyframes cheer { 25% { transform: translateY(-16%) scale(.97, 1.05); } 50% { transform: translateY(0) scale(1.05, .95); } 75% { transform: translateY(-8%); } }
@keyframes oops { 30% { transform: rotate(-7deg); } 65% { transform: rotate(5deg); } }

@keyframes pop-in { 0% { transform: scale(.9); } 60% { transform: scale(1.07); } }
.pop-in { animation: pop-in 200ms ease-out; }
@keyframes wiggle { 20% { transform: translateX(-7px) rotate(-2deg); } 50% { transform: translateX(6px) rotate(2deg); } 80% { transform: translateX(-3px); } }
.wiggle { animation: wiggle 240ms ease-in-out; }
@keyframes ring-pulse { 0% { transform: scale(.92); opacity: .9; } 100% { transform: scale(1.22); opacity: 0; } }

/* ═══════════ 选伙伴 ═══════════ */
.picker { padding: var(--pad); gap: 12px; align-items: center; background: radial-gradient(120% 60% at 50% 0%, var(--bg-deep), var(--bg) 70%); }
.picker-title { font-size: clamp(30px, 5vh, 44px); font-weight: 700; padding-top: 6px; }
.buddy-grid { flex: 1; min-height: 0; width: 100%; max-width: 980px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: minmax(0, 1fr); gap: 12px; align-content: center; justify-items: center; padding: 6px 0 14px; }
.buddy-card { width: 100%; max-width: 230px; height: 100%; max-height: 250px; min-height: var(--tap); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  padding: 10px 8px 8px; border-radius: 30px; background: var(--card); border: 4px solid var(--card-edge); box-shadow: 0 6px 0 var(--card-edge); transition: transform 90ms ease-out; }
.buddy-card:active { transform: translateY(4px); }
.buddy-card .buddy { flex: 1; min-height: 0; height: 0; max-width: 100%; }
.buddy-name { font-size: 20px; font-weight: 700; color: var(--ink-soft); line-height: 1.2; }
.buddy-card.selected { border-color: var(--orange); box-shadow: 0 6px 0 var(--orange-edge); background: #FFF1DD; }
.buddy-card.selected .buddy-name { color: var(--orange-edge); }
.picker-ok { flex: none; margin-bottom: 10px; }
.picker { position: relative; }
/* 从头像点进来时左上角的 ←（和闯关页的 × 一样：看上去 60px，可点的范围 --tap） */
.picker .picker-back { position: absolute; z-index: 2; top: 0; left: calc(var(--pad) - (var(--tap) - 60px) / 2); margin: 0; }
.picker.has-back .picker-title { padding-inline: 58px; font-size: clamp(28px, 4.4vh, 44px); }
@media (min-width: 700px), (orientation: landscape) { .buddy-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px; } }
.picker[data-count="1"] .buddy-grid, .picker[data-count="2"] .buddy-grid, .picker[data-count="3"] .buddy-grid { grid-auto-rows: minmax(0, 250px); }
@media (min-width: 700px), (orientation: landscape) { .picker[data-count="3"] .buddy-grid { grid-template-columns: repeat(3, minmax(0, 250px)); justify-content: center; } }

/* ═══════════ 地图 ═══════════ */
.map { position: relative; background: var(--bg); }
.topbar { flex: none; display: flex; align-items: center; justify-content: space-between; padding: calc((var(--tap) - 64px) / 2) var(--pad) 8px; background: var(--bg); border-bottom: 3px solid var(--bg-deep); z-index: 2; }
/* 头像：看上去是 64px 的圆，可点的范围是 --tap（88 / 104px）——负外边距让它在布局里仍只占 64px；顶栏上边的内边距正好让可点范围不出屏 */
.avatar { position: relative; width: var(--tap); height: var(--tap); margin: calc((64px - var(--tap)) / 2); flex: none; display: grid; place-items: center; transition: transform 90ms; }
.avatar:active { transform: scale(.93); }
.avatar-face { width: 64px; height: 64px; border-radius: 50%; background: #fff; border: 4px solid var(--orange); overflow: hidden; display: grid; place-items: center; pointer-events: none; }
.avatar-face img { width: 120%; height: 150%; object-fit: cover; object-position: 50% 8%; }
.stats { display: flex; gap: 10px; }
.stat { display: inline-flex; align-items: center; gap: 6px; height: 48px; padding: 0 16px 0 12px; border-radius: 24px; background: #fff; border: 3px solid var(--card-edge); font-size: 24px; font-weight: 700; }
.stat .icon { width: 28px; height: 28px; }
.stat small { font-size: 16px; color: var(--ink-soft); margin-left: -2px; }
.stat-stars .icon { color: var(--gold); }
.stat-streak .icon { color: var(--orange); }

.map-scroll { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
/* 背景上几团淡淡的圆：跟着内容一起滚（圆心在整条路的 12%/18% 这些位置）。用普通圆块，不用 radial-gradient（没有显卡加速时重画太慢） */
.map-field { position: relative; min-height: 100%; overflow: hidden; }
.map-blob { position: absolute; border-radius: 50%; pointer-events: none; }
.map-blob-0 { left: calc(12% - 70px); top: calc(18% - 70px); width: 140px; height: 140px; background: #FFE7C2; }
.map-blob-1 { left: calc(88% - 90px); top: calc(42% - 90px); width: 180px; height: 180px; background: #DFF5EF; }
.map-blob-2 { left: calc(10% - 80px); top: calc(72% - 80px); width: 160px; height: 160px; background: #E9E5FF; }
.map-blob-3 { left: calc(90% - 70px); top: calc(92% - 70px); width: 140px; height: 140px; background: #FFE1EC; }
.map-inner { position: relative; --amp: min(96px, 24vw); --node: var(--tap); width: min(100%, 560px); margin: 0 auto; padding: 8px var(--pad) calc(var(--tap) + 2 * var(--pad) + 24px + env(safe-area-inset-bottom)); } /* 底下留出齿轮和贴纸按钮那一条：最后一关也能滚到按钮上面 */
@media (min-width: 700px) { .map-inner { --amp: 150px; } }
/* --c / --e：关卡圆点的颜色；--b / --be：单元横幅（上面写白字，所以用深一档的颜色：白字都 ≥ 3.3:1，横幅上的字都是大号粗体） */
.unit { --c: var(--orange); --e: var(--orange-edge); --b: var(--orange); --be: var(--orange-edge); }
.unit-teal { --c: var(--teal); --e: var(--teal-edge); --b: var(--teal-edge); --be: #0B6B5E; }
.unit-violet { --c: var(--violet); --e: var(--violet-edge); --b: var(--violet); --be: var(--violet-edge); }
.unit-pink { --c: var(--pink); --e: var(--pink-edge); --b: #D84C80; --be: #A93462; }
.unit-banner { margin: 16px 0 26px; padding: 12px 22px 14px; border-radius: 24px; background: var(--b); box-shadow: 0 6px 0 var(--be); color: #fff; display: flex; align-items: baseline; gap: 12px; }
.unit-banner small { font-size: 19px; font-weight: 700; letter-spacing: .5px; }
.unit-banner strong { font-size: 28px; font-weight: 700; }
.path { position: relative; }
.path-dot { position: absolute; top: calc(var(--y) + var(--node) + 44px + var(--k) * 14px); left: calc(50% + var(--x) * var(--amp)); width: 12px; height: 12px; margin-left: -6px; border-radius: 50%; background: var(--card-edge); }
.node-slot { position: absolute; left: calc(50% + var(--x) * var(--amp)); width: var(--node); margin-left: calc(var(--node) / -2); display: flex; flex-direction: column; align-items: center; }
.node { position: relative; z-index: 1; width: var(--node); height: var(--node); border-radius: 50%; display: grid; place-items: center; background: var(--c); box-shadow: 0 8px 0 var(--e); color: #fff; transition: transform 90ms ease-out; }
.node:active { transform: translateY(6px); box-shadow: 0 2px 0 var(--e); }
.node-pic { width: 62%; height: 62%; object-fit: contain; }
.node-done { background: #fff; border: 5px solid var(--c); }
.node-current { background: #fff; border: 6px solid var(--c); }
.node-locked { background: var(--lock); box-shadow: 0 8px 0 var(--lock-edge); color: var(--lock-ink); }
.node-locked .icon { width: 36%; height: 36%; }
.node-stars { position: absolute; left: 50%; bottom: -16px; transform: translateX(-50%); display: flex; gap: 1px; padding: 3px 7px; border-radius: 14px; background: #fff; border: 3px solid var(--card-edge); }
.node-stars .icon { width: 19px; height: 19px; color: var(--lock-edge); }
.node-stars .icon.on { color: var(--gold); }
.node-title { margin-top: 18px; width: max-content; max-width: 12em; font-size: 14px; line-height: 1.25; font-weight: 600; color: var(--ink-mid); text-align: center; } /* 12em：宝箱关 12 个字的标题在 iPhone 上也不换行 */
.node-locked + .node-title { color: var(--lock-text); font-weight: 500; } /* 锁着的关：字淡一点、细一点，但对比度仍 ≥ 4.5 */
.node-ring { position: absolute; top: 0; left: 0; width: var(--node); height: var(--node); border-radius: 50%; border: 6px solid var(--c); animation: ring-pulse 1.4s ease-out infinite; pointer-events: none; }
.map-buddy { position: absolute; top: calc(var(--node) * -0.22); height: calc(var(--node) * 1.25); pointer-events: none; animation: bob 1.6s ease-in-out infinite; }
.map-buddy.right { left: calc(var(--node) + 6px); }
.map-buddy.left { right: calc(var(--node) + 6px); }
@keyframes bob { 50% { transform: translateY(-5px); } }
.node-pic.art-missing { border: 0; background: none; }
/* 宝箱关：金色的大方块 + 宝箱 + 闪闪的星星（锁着也看得出是宝箱） */
.node-treasure { --c: var(--gold); --e: var(--gold-edge); width: calc(var(--node) * 1.16); height: calc(var(--node) * 1.16); border-radius: 30%; background: #FFF3D1; border: 6px solid var(--gold); }
.node-treasure.node-done { background: #FFF3D1; border: 6px solid var(--gold); }
.node-treasure.node-locked { background: var(--lock); border-color: var(--lock-edge); box-shadow: 0 8px 0 var(--lock-edge); }
.node-chest { width: 70%; pointer-events: none; }
.node-chest svg { display: block; width: 100%; }
img.node-chest { display: block; }
.node-locked .node-chest { opacity: .5; filter: grayscale(1); }
.slot-treasure .node-ring { top: calc(var(--node) * -0.0); left: calc(var(--node) * -0.08); width: calc(var(--node) * 1.16); height: calc(var(--node) * 1.16); border-radius: 30%; }
.slot-treasure .node-title { color: #8A5A08; font-weight: 700; } /* 深一点的金，小字对比度够 */
.slot-treasure .node-locked + .node-title { color: var(--lock-text); font-weight: 600; }
.node-sparkle { position: absolute; inset: -14px; pointer-events: none; color: var(--gold); }
.node-sparkle .icon { position: absolute; width: 22px; height: 22px; animation: twinkle 1.8s ease-in-out infinite; }
.node-sparkle .icon:nth-child(1) { top: -2px; left: 2px; }
.node-sparkle .icon:nth-child(2) { top: 8px; right: -6px; width: 16px; height: 16px; animation-delay: -.6s; }
.node-sparkle .icon:nth-child(3) { bottom: 12px; left: -8px; width: 14px; height: 14px; animation-delay: -1.2s; }
@keyframes twinkle { 50% { transform: scale(.5) rotate(20deg); opacity: .35; } }
/* 故事关：右上角一本小书 */
.node-badge { position: absolute; top: -8px; right: -8px; width: 38px; height: 38px; padding: 7px; border-radius: 50%; background: var(--violet); color: #fff; border: 3px solid #fff; }
.node-badge .icon { width: 100%; height: 100%; }
.node-locked .node-badge { background: var(--lock-edge); }
/* 屏幕最下面那一条（齿轮、贴纸按钮所在）：地图内容滚到那里时渐渐淡进奶油底色，横幅、关卡不会和按钮叠在一起看不清。不动、不重画 */
.map::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; height: calc(var(--tap) + var(--pad) + 18px + env(safe-area-inset-bottom)); pointer-events: none;
  background: linear-gradient(to bottom, rgba(255, 246, 232, 0), var(--bg) 62%); }
/* 右下角：贴纸册；左下角：家长入口（小、淡，按住 1.5 秒才进） */
.map-fab { position: absolute; z-index: 3; right: var(--pad); bottom: calc(var(--pad) + env(safe-area-inset-bottom)); }
.map-stickers { --c: #fff; --e: var(--violet-edge); color: var(--violet); border: 4px solid var(--violet); }
.map-stickers .icon { width: 56%; height: 56%; }
.map-gear { position: absolute; z-index: 3; left: var(--pad); bottom: calc(var(--pad) + env(safe-area-inset-bottom)); width: 48px; height: 48px; border-radius: 50%; display: grid; place-items: center;
  color: var(--lock-ink); background: #fff; border: 2px solid var(--lock-edge); touch-action: none; } /* 不透明：底下滚过去的横幅不会透出来 */
.map-gear .icon { width: 26px; height: 26px; }
.gear-ring { position: absolute; inset: -6px; border-radius: 50%; border: 5px solid var(--violet); transform: scale(.55); opacity: 0; pointer-events: none; }
.map-gear.holding .gear-ring { opacity: 1; transform: scale(1.3); transition: transform var(--hold, 1500ms) linear, opacity 120ms; }
.gear-tip { position: absolute; left: 58px; top: 50%; margin-top: -15px; height: 30px; padding: 0 10px; display: flex; align-items: center; white-space: nowrap; font-size: 14px; color: var(--ink-mid); background: #fff; border: 2px solid var(--card-edge); border-radius: 12px; opacity: 0; pointer-events: none; }
.map-gear.show-tip .gear-tip { animation: tip 2s ease-out; }
@keyframes tip { 0% { opacity: 0; } 8%, 80% { opacity: 1; } 100% { opacity: 0; } }

/* ═══════════ 贴纸册 ═══════════ */
.stickers { background: radial-gradient(120% 60% at 50% 0%, var(--bg-deep), var(--bg) 70%); }
.stickers .topbar { justify-content: flex-start; gap: 16px; padding-top: calc((var(--tap) - 60px) / 2); background: none; border: 0; }
.stickers-title { font-size: clamp(26px, 4vh, 36px); font-weight: 700; }
.sticker-grid { flex: 1; min-height: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 190px)); justify-items: center; gap: clamp(16px, 3vh, 30px); justify-content: center; align-content: center; padding: var(--pad); }
.sticker-grid[data-count="1"] { grid-template-columns: minmax(0, 190px); }
@media (min-width: 700px) { .sticker-grid { grid-template-columns: repeat(4, minmax(0, 190px)); } .sticker-grid[data-count="1"] { grid-template-columns: minmax(0, 190px); } .sticker-grid[data-count="2"] { grid-template-columns: repeat(2, minmax(0, 190px)); } }
.sticker-slot { width: 100%; max-width: 190px; aspect-ratio: 1; min-height: var(--tap); border-radius: 50%; display: grid; place-items: center; border: 4px dashed var(--lock-edge); background: rgba(255, 255, 255, .5); transition: transform 90ms ease-out; }
.sticker-slot.got { border: 7px solid #fff; background: #fff; box-shadow: 0 0 0 4px var(--gold), 0 8px 0 3px var(--gold-edge); transform: rotate(var(--tilt, 0deg)); }
.sticker-empty { width: 46%; opacity: .35; filter: grayscale(1); }
.sticker-empty svg { display: block; width: 100%; }
.stickers-foot { flex: none; display: flex; justify-content: center; padding-bottom: var(--pad); }
.stickers-buddy { height: clamp(100px, 17vh, 190px); }

/* ═══════════ 闯关 ═══════════ */
.player { background: var(--bg); }
.player-top { position: relative; z-index: 1; flex: none; display: flex; align-items: center; gap: 14px; padding: calc((var(--tap) - 60px) / 2) var(--pad) 6px; }
/* ×：看上去是 60px 的小圆圈，可点的范围是 --tap（88 / 104px）——负外边距让它在布局里仍只占 60px */
.btn-close { position: relative; width: var(--tap); height: var(--tap); margin: calc((60px - var(--tap)) / 2); flex: none; display: grid; place-items: center; color: var(--ink-soft); transition: transform 90ms; }
.btn-close::before { content: ""; position: absolute; inset: calc((var(--tap) - 60px) / 2); border-radius: 50%; background: #fff; border: 3px solid var(--card-edge); }
.btn-close:active { transform: scale(.9); }
.btn-close .icon { position: relative; width: 26px; height: 26px; }
.progress { flex: 1; height: 22px; border-radius: 11px; background: #F1E3CD; overflow: hidden; }
.progress-fill { display: block; height: 100%; border-radius: 11px; background: var(--teal); transform-origin: 0 50%; transform: scaleX(.04); transition: transform 220ms ease-out; }
.player.is-finish .player-top { visibility: hidden; }
.stage { flex: 1; min-height: 0; display: flex; }

.ex { flex: 1; min-width: 0; display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: 8px; padding: 4px var(--pad) calc(var(--pad) + 4px); animation: ex-in 170ms ease-out both; }
@keyframes ex-in { from { opacity: 0; transform: translateX(18px); } }
.ex-main { min-height: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; }
.ex-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; min-height: calc(var(--tap) * 1.2 + 8px); }
.ex-foot .buddy { height: clamp(120px, 19vh, 210px); }
.ex-pick .ex-foot .buddy { height: clamp(110px, 16vh, 180px); } /* 选图题：底栏的伙伴（不能点）不比答案卡片还抢眼 */
.ex-foot > :last-child { margin-bottom: 8px; }
.foot-spacer { width: 1px; }

.pic-card { position: relative; width: var(--size); height: var(--size); flex: none; display: grid; place-items: center; border-radius: 16%; background: var(--card); border: 4px solid var(--card-edge); box-shadow: 0 7px 0 var(--card-edge); transition: transform 90ms ease-out, opacity 150ms; }
.pic-card:active { transform: translateY(5px); }
.pic-card .pic { width: 74%; height: 74%; object-fit: contain; }
.pic-card.big { --size: min(76vw, 42vh, 440px); }
.pic-card.mid { --size: min(60vw, 34vh, 360px); }
.word { font-family: "Pals Word", var(--font); font-weight: 700; font-size: clamp(34px, 5.6vh, 60px); line-height: 1.1; }

.pic-card.right { border-color: var(--yes); box-shadow: 0 7px 0 #1E9C72; animation: pop-in 220ms ease-out; }
.pic-card.faded { opacity: .45; }
.pic-card.wiggle { animation: wiggle 240ms ease-in-out; }
.badge { position: absolute; top: -12px; right: -12px; width: 46px; height: 46px; padding: 9px; border-radius: 50%; background: var(--yes); color: #fff; border: 4px solid #fff; animation: pop-in 200ms ease-out; }
/* 发光提示：一个外圈一呼一吸（只动 transform/opacity） */
.glow::after, .hint::after { content: ""; position: absolute; inset: -10px; border-radius: inherit; border: 7px solid var(--gold); animation: ring-pulse 1.1s ease-out infinite; pointer-events: none; }
.pic-card.glow { border-color: var(--gold); box-shadow: 0 7px 0 var(--gold-edge); }

.cards { --size: min(42vw, 25vh, 300px); display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 16px; max-width: calc(var(--size) * 2 + 20px); }
.cards-2 { --size: min(42vw, 30vh, 320px); }
.cards-1 { --size: min(60vw, 34vh, 360px); } /* 只有一张图的「稳赢题」：和前一题的大图差不多大 */
/* 手机竖屏的两选一：上下摆、卡片大一圈（左右摆只有 164px，屏幕空了快一半） */
@media (orientation: portrait) and (max-width: 560px) {
  .cards-2:not(.missing-options):not(.scenes):not(.floaty) { flex-direction: column; flex-wrap: nowrap; --size: min(62vw, 27vh, 320px); }
}

.pair-row { --size: min(27vw, 21vh, 190px); display: flex; justify-content: center; gap: min(4vw, 22px); }
.ex-pairs .ex-main { gap: clamp(22px, 5vh, 56px); }
.bubble { position: relative; width: var(--size); height: var(--size); flex: none; border-radius: 50%; display: grid; place-items: center; color: #fff; background: var(--violet); box-shadow: 0 7px 0 var(--violet-edge); transition: transform 180ms ease-out, opacity 180ms; }
.bubble-1 { background: var(--teal); box-shadow: 0 7px 0 var(--teal-edge); }
.bubble-2 { background: var(--pink); box-shadow: 0 7px 0 var(--pink-edge); }
.bubble .icon { width: 46%; height: 46%; }
.bubble:active { transform: translateY(5px); }
.bubble.selected { outline: 6px solid var(--gold); outline-offset: 5px; transform: translateY(-6px); }
.bubble.hint::after { border-radius: 50%; }
.pair-row .pic-card { transition: transform 180ms ease-out, opacity 180ms; }
.gone { transform: scale(.2) !important; opacity: 0 !important; pointer-events: none; }

.btn-mic .mic-ring { position: absolute; inset: -12px; border-radius: 50%; border: 8px solid var(--teal); opacity: 0; pointer-events: none; transition: transform 80ms linear; }
.btn-mic.listening { --c: var(--gold); --e: var(--gold-edge); }
.btn-mic.listening .mic-ring { opacity: .55; border-color: var(--gold); }
.btn-mic.said, .btn-said.said { --c: var(--yes-deep); --e: #127352; } /* 深一点的绿：上面的白字 3.6:1 */
.btn-said { min-width: 0; gap: 10px; padding: 0 30px 0 22px; font-size: 28px; white-space: nowrap; }
.btn-said .icon { width: 40px; height: 40px; flex: none; }
@media (max-width: 480px) { .btn-said { font-size: 24px; gap: 8px; padding: 0 22px 0 16px; } .btn-said .icon { width: 34px; height: 34px; } }
/* 末尾的全角「！」（圆体里这个字画在格子左边，右边空了大半格）：只给它 0.44 个字宽的格子，居中的字才真的在中间（ui.js label）。
   不用负的 margin-right：WebKit 算宽度时不认行内元素的负外边距 */
.bang { display: inline-block; width: .44em; text-align: left; }

/* 横屏：伙伴在左，题目在中间，按钮在右 */
@media (orientation: landscape) {
  .ex { grid-template-rows: none; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 12px; }
  .ex-foot { display: contents; }
  .ex { --foot-buddy: clamp(110px, 29vh, 230px); }
  .ex-pick { --foot-buddy: clamp(100px, 24vh, 190px); } /* 选图题：伙伴比答案卡片小（它不能点） */
  .ex-foot .buddy, .ex-pick .ex-foot .buddy { grid-column: 1; grid-row: 1; align-self: end; height: var(--foot-buddy); }
  .ex-main { grid-column: 2; grid-row: 1; height: 100%; }
  .ex-foot > :last-child { grid-column: 3; grid-row: 1; align-self: end; margin-bottom: 12px; }
  .ex-meet .ex-main, .ex-say .ex-main { gap: 8px; }
  .pic-card.big { --size: min(40vw, 58vh, 440px); }
  .pic-card.mid { --size: min(34vw, 50vh, 360px); }
  /* 一排 2–4 张卡：按主区域真正的宽度（--avail）平分，一张都不会超出去。
     --avail = 整屏宽 − 两边留白 − 左边的伙伴（高 --foot-buddy，宽是高的 4/5）− 右边的圆按钮 − 两个格子间隙；
     支持容器单位的浏览器直接量主区域（下面 @supports） */
  .ex-main { --avail: calc(100vw - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px) - 2 * var(--pad) - 0.8 * var(--foot-buddy) - var(--tap) - 24px); }
  .cards { --size: min((var(--avail) - 3 * 16px) / 4, 50vh, 270px); flex-wrap: nowrap; max-width: none; }
  .cards-2 { --size: min((var(--avail) - 16px) / 2, 54vh, 300px); }
  .cards-3 { --size: min((var(--avail) - 2 * 16px) / 3, 54vh, 300px); }
  .cards-1 { --size: min(34vw, 50vh, 360px); }
  .pair-row { --size: max(88px, min(15vw, 30vh, 190px)); }
  .ex-pairs .ex-main { gap: clamp(12px, 4vh, 44px); }
  .foot-spacer { width: calc(var(--tap) * 0.6); }
}
/* iPad 横屏的四选一：2×2（一排四张只有 ~185px，上下各空出一大块） */
@media (orientation: landscape) and (min-height: 600px) {
  .cards-4:not(.missing-options) { --size: min((var(--avail) - 16px) / 2, (100vh - 250px) / 2, 290px); flex-wrap: wrap; max-width: calc(var(--size) * 2 + 20px); }
}
@supports (width: 1cqi) {
  @media (orientation: landscape) { .ex-main { container-type: inline-size; --avail: 100cqi; } }
}

/* ── 过关 ── */
.finish { position: relative; flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: clamp(8px, 2.4vh, 26px); padding: 0 var(--pad) var(--pad); overflow: hidden; }
.finish-title { font-size: clamp(36px, 7vh, 64px); font-weight: 700; color: var(--orange-edge); animation: pop-in 220ms ease-out; }
.finish-stars { display: flex; align-items: flex-end; gap: 10px; }
.finish-stars .icon { width: clamp(64px, 11vh, 104px); height: clamp(64px, 11vh, 104px); color: var(--lock); }
.finish-stars .icon:nth-child(2) { transform: translateY(-14px); }
.finish-stars .icon.pop { color: var(--gold); animation: star-pop 240ms ease-out; }
@keyframes star-pop { 0% { scale: .4; } 70% { scale: 1.25; } }
.finish-buddy { height: clamp(140px, 30vh, 300px); }
.finish-hero { display: flex; align-items: flex-end; justify-content: center; gap: 10px; }
.finish-sticker { width: clamp(84px, 15vh, 140px); margin-bottom: 4%; transform: rotate(8deg); animation: pop-in 260ms ease-out; }
/* 过关页的贴纸用美术画的白边底托（assets/art/sticker-frame.svg），图片缩在中间 66%（exercises.css 里的金边圆圈留给开宝箱那一步） */
.finish .finish-sticker { background: url("../assets/art/sticker-frame.svg") center / contain no-repeat; border: 0; border-radius: 0; }
.finish .finish-sticker .sticker-pic { width: 66%; height: 66%; }
.finish-parent { margin: 0; max-width: 34em; padding: 0 8px; text-align: center; font-size: 14px; line-height: 1.5; color: var(--ink-mid); line-break: strict;
  position: relative; z-index: 1; } /* 叠在彩纸上面：彩纸从字后面落下去，不挡住给家长看的那行字 */
.finish-parent b { font-weight: 600; }
.finish-parent .finish-tip { display: block; }
.finish-parent .nb { white-space: nowrap; } /* 「…」里的话不在中间断行 */
.finish-ok { flex: none; }
.confetti { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.confetti i { position: absolute; top: -24px; left: 0; width: 12px; height: 18px; border-radius: 3px; background: var(--c); transform: translate3d(var(--x), 0, 0); animation: confetti 1.7s var(--d) cubic-bezier(.3, .4, .6, 1) both; will-change: transform; }
@keyframes confetti { from { transform: translate3d(var(--x), -30px, 0) rotate(0); opacity: 1; } 85% { opacity: 1; } to { transform: translate3d(var(--x), 105vh, 0) rotate(var(--r)); opacity: 0; } }
@media (orientation: landscape) and (max-height: 500px) {
  .finish { flex-direction: row; flex-wrap: wrap; align-content: center; gap: 6px 28px; }
  .finish-title { width: 100%; text-align: center; font-size: 34px; }
}

/* 慢设备上的地图（map.js calmIfSlow）和「减少动态效果」：地图上的装饰不动，当前关的光圈静止地亮着 */
.map.calm .node-ring { animation: none; transform: scale(1.1); opacity: .45; }
.map.calm .map-buddy, .map.calm .node-sparkle .icon { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .node-ring, .map-buddy, .glow::after, .hint::after, .node-sparkle .icon { animation: none; }
  .node-ring { transform: scale(1.1); opacity: .45; }
  .confetti { display: none; }
}

/* 跟读：话筒 + 备用的「我说了！」按钮并排 */
.say-actions { display: flex; align-items: center; gap: 16px; }
/* 手机竖屏：话筒和「我说了！」一行放不下（再加上伙伴），按钮叠在话筒上面 */
@media (max-width: 480px) { .say-actions { flex-direction: column-reverse; align-items: flex-end; gap: 12px; } }
