/* 波波乐园 · student app styles
   Layout: full-screen themed scene; floating HUD; landscape = Bobo on the left ground + play board + explanation sheet on the right;
   portrait (iPad upright / phone) = board on top, Bobo docked bottom-left, explanation as a bottom sheet. */
:root{
  --sky:#7fe3f2; --sun:#fff08a; --ink:#2b1d14; --paper:#fffaf0; --paper2:#fff3d6;
  --coral:#ff7b54; --good:#2fbf71; --bad:#ff5a5f; --grape:#9b74f0; --blue:#4d9dff; --hair:#ffd34a;
  --f-display:"ZCOOL KuaiLe","Baloo 2","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  --f-body:"Noto Sans SC","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  --f-num:"Baloo 2","Noto Sans SC","PingFang SC",sans-serif;
  /* Match the measured HUD (padding 12+8 + 52px controls + 6px gap). A lower
     default used to jump the whole page down once JS measured the real height. */
  --hudH:calc(78px + env(safe-area-inset-top,0px));
  --coachW:clamp(190px,23vw,330px);
  --sheetW:min(470px,40vw);
  --gutL:max(16px,env(safe-area-inset-left,0px)); --gutR:max(16px,env(safe-area-inset-right,0px)); --gutB:max(12px,env(safe-area-inset-bottom,0px));
  color-scheme:light;
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{height:100%;margin:0;overflow:hidden;overscroll-behavior:none}
body{position:fixed;inset:0;background:var(--sky);color:var(--ink);font:500 16px/1.55 var(--f-body);-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
button{font:inherit;color:inherit}
input{font:inherit;-webkit-user-select:text;user-select:text}
:focus-visible{outline:4px solid var(--grape);outline-offset:3px}
[hidden]{display:none!important}

/* ---------- scene ---------- */
.bg{position:fixed;inset:-40px;z-index:0;overflow:hidden;transition:background .6s}
/* JS updates transform every frame; a CSS ease would lag the pointer and look like shaking on PC. */
.bg-layer{position:absolute;inset:0;will-change:transform;transition:none}
.bg-layer svg{width:100%;height:100%;display:block}
.bg .drift{animation:drift var(--dur) linear infinite;animation-delay:var(--delay)}
@keyframes drift{from{transform:translateX(-300px)}to{transform:translateX(1900px)}}
.bg .float{animation:float var(--dur,3s) ease-in-out infinite alternate}
@keyframes float{from{transform:translateY(0)}to{transform:translateY(-4px)}}
.bg .flicker{transform-box:fill-box;transform-origin:50% 100%;animation:flicker var(--dur,.6s) ease-in-out infinite alternate}
@keyframes flicker{from{transform:scale(1,1) skewX(-4deg)}to{transform:scale(.88,1.14) skewX(4deg)}}
.bg .fly{animation:fly var(--dur) linear infinite;animation-delay:var(--delay)}
@keyframes fly{from{transform:translate(-200px,0)}25%{transform:translate(300px,-24px)}50%{transform:translate(800px,0)}75%{transform:translate(1300px,-24px)}to{transform:translate(1800px,0)}}
.bg .flap{transform-box:fill-box;transform-origin:50% 100%;animation:flap .45s ease-in-out infinite alternate}
@keyframes flap{from{transform:scaleY(1)}to{transform:scaleY(.35)}}
.bg .spin{transform-box:fill-box;transform-origin:center;animation:spin var(--dur,30s) linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.bg .sway{transform-box:fill-box;transform-origin:50% 100%;animation:sway var(--dur,4s) ease-in-out infinite alternate}
@keyframes sway{from{transform:rotate(-3deg)}to{transform:rotate(3deg)}}
.bg .swing{transform-box:fill-box;transform-origin:50% 0;animation:sway var(--dur,3s) ease-in-out infinite alternate}
.bg .wave{transform-box:fill-box;transform-origin:0 50%;animation:flagw 1.2s ease-in-out infinite alternate}
@keyframes flagw{to{transform:skewY(-6deg) scaleX(.9)}}
.bg .waves{animation:waves var(--dur) linear infinite}
@keyframes waves{to{transform:translateX(-400px)}}
.bg .bob{animation:bgBob var(--dur,3s) ease-in-out infinite alternate}
@keyframes bgBob{to{transform:translateY(-12px)}}
.bg .rise{animation:rise var(--dur) linear infinite;animation-delay:var(--delay);opacity:.85}
@keyframes rise{from{transform:translateY(120px) rotate(-8deg);opacity:0}15%{opacity:.85}to{transform:translateY(-900px) rotate(8deg);opacity:0}}
.bg .wander{animation:wander var(--dur) ease-in-out infinite;animation-delay:var(--delay)}
@keyframes wander{0%,100%{transform:translate(0,0)}25%{transform:translate(260px,-80px)}50%{transform:translate(480px,40px)}75%{transform:translate(200px,120px)}}
.bg .flutter{transform-box:fill-box;transform-origin:center;animation:flut .45s ease-in-out infinite alternate}
@keyframes flut{from{transform:rotate(-6deg) translateY(0)}to{transform:rotate(6deg) translateY(-4px)}}
.bg .twinkle{animation:twinkle 2.4s ease-in-out infinite;animation-delay:var(--delay)}
@keyframes twinkle{0%,100%{opacity:.15}50%{opacity:1}}
.bg .bubbleup{animation:bubbleUp 2.1s ease-in infinite;animation-delay:var(--delay)}
@keyframes bubbleUp{from{transform:translateY(0);opacity:1}to{transform:translateY(-150px);opacity:0}}

#wipe{position:fixed;inset:0;z-index:300;pointer-events:none;background:radial-gradient(circle,#ffb38f 3px,transparent 4px) 0 0/26px 26px,var(--coral);clip-path:circle(0 at var(--x,50%) var(--y,50%))}
#wipe.in{animation:wipeIn .42s cubic-bezier(.6,0,.9,.5) forwards}
#wipe.out{animation:wipeOut .5s cubic-bezier(.2,.6,.3,1) forwards}
@keyframes wipeIn{from{clip-path:circle(0 at var(--x) var(--y))}to{clip-path:circle(150% at var(--x) var(--y))}}
@keyframes wipeOut{from{clip-path:circle(150% at var(--x) var(--y))}to{clip-path:circle(0 at var(--x) var(--y))}}

/* ---------- HUD ---------- */
.hud{position:fixed;z-index:40;top:0;left:0;right:0;display:flex;align-items:center;gap:8px;padding:calc(env(safe-area-inset-top,0px) + 12px) var(--gutR) 8px var(--gutL);pointer-events:none}
.hud>*{pointer-events:auto}
.logo{display:flex;align-items:center;gap:8px;font:400 24px/1 var(--f-display);cursor:pointer;background:var(--paper);border:4px solid var(--ink);border-radius:999px;padding:4px 16px 4px 4px;box-shadow:0 4px 0 var(--ink);margin-right:auto}
.logo i{display:inline-grid;place-items:center;width:36px;height:36px;border-radius:50%;background:var(--coral);border:3px solid var(--ink);color:#fff;font-style:normal;font-size:20px;transform:rotate(-8deg)}
.pill{display:inline-flex;align-items:center;gap:6px;border:4px solid var(--ink);border-radius:999px;padding:4px 14px;background:#fff;font:800 16px/1.4 var(--f-num);cursor:pointer;box-shadow:0 4px 0 var(--ink);white-space:nowrap}
.pill:active,.logo:active{transform:translateY(3px);box-shadow:0 1px 0 var(--ink)}
.pill.star{background:var(--hair)}
.pill.bump{animation:bump .4s}
.pill svg{width:18px;height:18px}
@keyframes bump{40%{transform:scale(1.35) rotate(-6deg)}}
body.preview .logo,body.preview #gradePill,body.preview #parentBtn,body.preview #backMap{visibility:hidden}

/* ---------- views ---------- */
.view{position:absolute;inset:0;z-index:10;display:none;padding-top:var(--hudH)}
.view.on{display:block;animation:none}
@keyframes viewIn{from{opacity:0;transform:translateY(26px) scale(.98)}}
h1,h2,h3{font-family:var(--f-display);font-weight:400;text-wrap:balance;margin:0}
.btn{border:4px solid var(--ink);border-radius:16px;padding:6px 18px;font:700 16px var(--f-body);cursor:pointer;box-shadow:0 5px 0 var(--ink);background:#fff}
.btn.primary{background:var(--coral);color:#fff;font-size:18px}
.btn:active{transform:translateY(4px);box-shadow:0 1px 0 var(--ink)}
.bubble{position:relative;background:#fff;border:4px solid var(--ink);border-radius:22px;padding:10px 14px;font:700 19px/1.45 var(--f-body);box-shadow:4px 4px 0 var(--ink);min-height:52px}
.bubble::after{content:"";position:absolute;left:46%;bottom:-16px;width:22px;height:22px;background:#fff;border-right:4px solid var(--ink);border-bottom:4px solid var(--ink);transform:rotate(45deg) skew(10deg,10deg)}
.bubble.pop{animation:bpop .35s cubic-bezier(.3,1.7,.5,1)}
@keyframes bpop{from{transform:scale(.7) rotate(-4deg)}}
.bhost{cursor:pointer}

/* ---------- home ---------- */
.home{height:100%;display:grid;grid-template-columns:var(--coachW) minmax(0,640px);justify-content:center;align-items:end;gap:clamp(16px,4vw,60px);padding:0 var(--gutR) var(--gutB) var(--gutL)}
.coach{display:flex;flex-direction:column;justify-content:flex-end;align-items:stretch;gap:22px;height:100%;padding-bottom:1vh;min-width:0}
.coach.big{max-width:var(--coachW)}
.homecard{align-self:center;background:rgba(255,250,240,.94);border:5px solid var(--ink);border-radius:32px;box-shadow:9px 9px 0 var(--ink);padding:clamp(18px,3vw,32px);min-width:0}
.homecard h1{font-size:clamp(46px,7vw,84px);line-height:1;color:#fff;-webkit-text-stroke:3px var(--ink);paint-order:stroke fill;text-shadow:5px 5px 0 var(--ink);transform:rotate(-2deg);display:inline-block}
.homecard .sub{margin:14px 0 0;max-width:32em}
/* Reserve two rows so injecting the six grade buttons does not shove the card. */
.grades{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin:20px 0;min-height:207px}
.gbtn{border:4px solid var(--ink);border-radius:20px;background:var(--c);box-shadow:0 6px 0 var(--ink);padding:10px 6px;cursor:pointer;display:grid;justify-items:center;gap:0;transition:transform .2s cubic-bezier(.3,1.7,.5,1);animation:gIn .5s cubic-bezier(.3,1.6,.5,1) both;animation-delay:var(--d)}
@keyframes gIn{from{transform:scale(.4) rotate(-10deg);opacity:0}}
@media (hover:hover) and (pointer:fine){.gbtn{animation:none}}
.gbtn b{font:800 38px/1 var(--f-num)}
.gbtn span{font:400 18px var(--f-display)}
.gbtn small{font-size:12px;opacity:.75}
.gbtn:hover{transform:translateY(-6px) rotate(-3deg)}
.gbtn:active{transform:translateY(4px);box-shadow:0 2px 0 var(--ink)}
.gbtn.sel{outline:5px solid #fff;outline-offset:-11px}
.bigbtn{width:100%;font-size:22px;padding:10px}

/* ---------- map ---------- */
.maptitle{position:absolute;top:calc(var(--hudH) + 4px);left:0;right:0;text-align:center;font-size:clamp(26px,4vw,40px);color:#fff;-webkit-text-stroke:2.5px var(--ink);paint-order:stroke fill;text-shadow:3px 3px 0 var(--ink);pointer-events:none;z-index:2}
.worldwrap{position:absolute;left:0;right:0;bottom:0;top:calc(var(--hudH) + 40px);overflow-x:auto;overflow-y:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.worldwrap::-webkit-scrollbar{display:none}
.world{position:relative;height:100%;width:max(100%,1240px);min-height:440px;background:radial-gradient(circle at 50% 40%,rgba(255,255,255,.12),transparent 60%)}
.isle{position:absolute;left:var(--x);top:var(--y);transform:translate(-50%,-50%);border:0;background:none;cursor:pointer;padding:0;display:grid;justify-items:center;text-align:center;width:clamp(180px,min(21vw,46vh),310px);animation:floaty 3.4s ease-in-out infinite;animation-delay:var(--d)}
@keyframes floaty{50%{margin-top:-10px}}
.isle .land{position:relative;width:100%;display:grid;place-items:center;transition:transform .25s cubic-bezier(.3,1.7,.5,1)}
.isle .land svg{width:100%;height:auto;display:block;overflow:visible;filter:drop-shadow(0 12px 0 rgba(20,60,100,.25))}
.isle .foamring{transform-box:fill-box;transform-origin:center;animation:foam 2.6s ease-in-out infinite}
@keyframes foam{50%{transform:scale(1.06,1.15);opacity:.3}}
.isle .hopfrog{animation:hopf 2.2s ease-in-out infinite}
@keyframes hopf{0%,60%,100%{transform:none}75%{transform:translateY(-18px)}}
.isle .ico{position:absolute;top:8%;font-size:clamp(50px,5vw,70px);line-height:1;filter:drop-shadow(3px 3px 0 rgba(43,29,20,.35))}
.isle .land{perspective:700px}
.isle .land svg{transition:transform .12s ease-out}
.isle:hover .land svg,.isle:focus-visible .land svg{transform:rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) scale(1.07) translateY(-6px)}
.isle:hover .iname{animation:nameBounce .5s cubic-bezier(.3,1.7,.5,1)}
.isle.poke .land svg{animation:poke .55s cubic-bezier(.3,1.7,.5,1)}
@keyframes poke{30%{transform:scale(1.12,.92) translateY(6px)}60%{transform:scale(.96,1.06) translateY(-10px)}}
@keyframes nameBounce{40%{transform:translateY(-6px) scale(1.06)}}
/* island parts: idle motion, faster or bigger when hovered / tapped */
.isle [class^="i-"],.isle [class*=" i-"]{transform-box:fill-box}
.isle .i-lantern{transform-origin:50% 0;animation:iSwing 2.6s ease-in-out infinite alternate;animation-delay:var(--d,0s)}
.isle:hover .i-lantern,.isle.poke .i-lantern{animation-duration:.6s}
@keyframes iSwing{from{transform:rotate(-6deg)}to{transform:rotate(6deg)}}
.isle .i-ink{stroke-dasharray:1;stroke-dashoffset:0;transition:stroke-dashoffset .1s}
.isle:hover .i-ink,.isle.poke .i-ink{animation:iInk 1.6s ease-out}
@keyframes iInk{from{stroke-dashoffset:1}}
.isle .i-brush{transform-origin:50% 100%;animation:iBrush 3.2s ease-in-out infinite}
.isle:hover .i-brush,.isle.poke .i-brush{animation-duration:.8s}
@keyframes iBrush{0%,100%{transform:rotate(0)}50%{transform:rotate(-14deg) translateY(-4px)}}
.isle .i-kite{transform-origin:85% 100%;animation:iKite 3.4s ease-in-out infinite}
.isle .i-tail{transform-box:fill-box;transform-origin:50% 0;animation:iSwing 1.2s ease-in-out infinite alternate}
.isle:hover .i-kite,.isle.poke .i-kite{animation:iKiteUp 1.4s ease-in-out infinite}
@keyframes iKite{0%,100%{transform:rotate(0) translateY(0)}50%{transform:rotate(3deg) translateY(-6px)}}
@keyframes iKiteUp{0%,100%{transform:rotate(-4deg) translateY(-14px)}50%{transform:rotate(5deg) translateY(-28px)}}
.isle .i-page{transform-origin:0% 50%;animation:iPage 5s ease-in-out infinite}
.isle:hover .i-page,.isle.poke .i-page{animation-duration:1.4s}
@keyframes iPage{0%,60%,100%{transform:scaleX(1)}30%{transform:scaleX(-1)}}
.isle .i-letter{animation:iHop 2.4s ease-in-out infinite;animation-delay:var(--d,0s)}
.isle:hover .i-letter,.isle.poke .i-letter{animation-duration:.7s}
@keyframes iHop{0%,100%{transform:translateY(0)}20%{transform:translateY(-14px) rotate(-8deg)}40%{transform:translateY(0)}}
.isle .i-bead{animation:iBead 4s ease-in-out infinite;animation-delay:var(--d,0s)}
.isle:hover .i-bead,.isle.poke .i-bead{animation-duration:1.1s}
@keyframes iBead{0%,100%{transform:translateX(0)}45%,55%{transform:translateX(var(--dx,30px))}}
.isle .i-ball{transform-origin:50% 100%;animation:iBall 2.2s cubic-bezier(.3,0,.6,1) infinite}
.isle:hover .i-ball,.isle.poke .i-ball{animation-duration:.7s}
@keyframes iBall{0%,100%{transform:translateY(0) scale(1)}45%{transform:translateY(-22px)}}
.isle .i-scope{transform-origin:50% 100%;animation:iScope 6s ease-in-out infinite}
.isle:hover .i-scope,.isle.poke .i-scope{animation-duration:1.6s}
@keyframes iScope{0%,100%{transform:rotate(-12deg)}50%{transform:rotate(18deg)}}
.isle .i-sprout{transform-origin:50% 100%;animation:iSprout 3s ease-in-out infinite alternate}
.isle:hover .i-sprout,.isle.poke .i-sprout{animation:iGrow .8s cubic-bezier(.3,1.7,.5,1)}
@keyframes iSprout{from{transform:rotate(-5deg)}to{transform:rotate(5deg)}}
@keyframes iGrow{0%{transform:scale(.4)}70%{transform:scale(1.2)}}
.isle:hover .i-flask .bubbleup,.isle.poke .i-flask .bubbleup{animation-duration:.9s}
.isle .i-sum{animation:iSum 3s steps(1) infinite}
@keyframes iSum{50%{fill:#ffd34a}}
.gbtn.locked{filter:grayscale(.7);opacity:.75;cursor:not-allowed}
.gbtn.locked:hover{transform:none}
.gbtn.locked b{font-size:28px}
.gbtn.shake{animation:nope .45s}
/* bookshelf of a subject: books, then chapters and sections */
.shelf{position:absolute;inset:0;z-index:20;display:grid;place-items:center;padding:calc(var(--hudH,70px) + 4px) clamp(10px,3vw,30px) clamp(10px,2vw,20px);background:rgba(20,50,80,.35);animation:fadeIn .25s}
.shelf[hidden]{display:none}
@keyframes fadeIn{from{opacity:0}}
.shelf-card{width:min(960px,100%);max-height:100%;display:flex;flex-direction:column;background:var(--paper);border:5px solid var(--ink);border-radius:28px;box-shadow:8px 8px 0 var(--ink);overflow:hidden;animation:bpop .4s cubic-bezier(.3,1.6,.5,1)}
.shelf-card header{display:flex;align-items:center;gap:12px;padding:10px 16px;border-bottom:4px solid var(--ink);background:var(--paper2)}
.shelf-card header h3{margin:0;font:400 28px/1 var(--f-display)}
.shelf-card header small{font-weight:700;color:#7a6a58}
.shelf-card header .sx{position:static;margin-left:auto;font-size:32px}
.shelf-ico{width:76px;flex:none}.shelf-ico svg{width:100%;height:auto;display:block}
.books{flex:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px;padding:12px 16px}
.book{display:flex;gap:12px;align-items:center;text-align:left;border:4px solid var(--ink);border-radius:18px;background:#fff;padding:8px 12px;cursor:pointer;box-shadow:0 5px 0 var(--ink);transition:transform .2s cubic-bezier(.3,1.7,.5,1)}
.book:hover{transform:translateY(-4px) rotate(-1deg)}
.book.on{background:#fff7dc;outline:4px solid var(--coral);outline-offset:2px}
.book.empty{opacity:.7}
.book .cover{flex:none;width:52px;height:68px;border:3px solid var(--ink);border-radius:6px 10px 10px 6px;background:var(--c);box-shadow:inset 8px 0 0 rgba(43,29,20,.18);display:grid;place-items:center;font-style:normal;transform:rotate(-4deg)}
.book .cover b{writing-mode:vertical-rl;font:400 15px var(--f-display);letter-spacing:2px}
.book span{display:grid;gap:2px}.book span b{font:400 22px var(--f-display)}.book small{font-weight:700;color:#7a6a58}.book em{font:800 14px var(--f-num);font-style:normal;color:#b07800}
.chapters{overflow:auto;padding:0 16px 16px;display:grid;gap:12px;align-content:start}
.shelf-empty{text-align:center;font-weight:700;padding:30px 10px}
.chap{background:#fff;border:3px solid var(--ink);border-radius:18px;padding:10px 12px;animation:gIn .4s cubic-bezier(.3,1.6,.5,1) both;animation-delay:var(--d)}
.chap h4{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin:0 0 8px;font:800 21px var(--f-body)}
.chap h4 small{font-weight:700;color:#7a6a58;font-size:16px}
.chap h4 em{margin-left:auto;font:800 14px var(--f-num);font-style:normal;color:#b07800}.chap h4 em.full{color:var(--good)}
.cno{font:800 15px var(--f-num);background:var(--coral);color:#fff;border:2px solid var(--ink);border-radius:999px;padding:0 10px}
.secs{display:flex;flex-wrap:wrap;gap:8px}
/* filter tabs: 全部 / 学习关 / 练习关 / 小测 / 综合测试 */
.ftabs{flex:none;display:flex;gap:8px;padding:2px 16px 12px;overflow-x:auto;scrollbar-width:none}
.ftabs::-webkit-scrollbar{display:none}
.ft{flex:none;display:flex;align-items:center;gap:6px;border:3px solid var(--ink);border-radius:999px;background:#fff;padding:6px 14px;font:800 16px var(--f-body);cursor:pointer;box-shadow:0 3px 0 var(--ink);transition:transform .18s cubic-bezier(.3,1.7,.5,1),background .2s}
.ft i{font-style:normal;font-size:18px}.ft small{font:800 13px var(--f-num);background:rgba(43,29,20,.1);border-radius:999px;padding:0 7px}
.ft:hover{transform:translateY(-2px)}
.ft.on{transform:translateY(2px);box-shadow:0 1px 0 var(--ink)}
.ft.all.on{background:#ffe08a}.ft.learn.on{background:#bfe3ff}.ft.practice.on{background:#ffe0b8}.ft.boss.on{background:#ffc9c9}.ft.exam.on{background:#e3d4ff}
/* each unit: a learn lane, then a practice path that ends in the checkpoint */
.lanes{display:grid;grid-template-columns:minmax(170px,230px) 1fr;gap:10px;align-items:stretch}
.chap.exam .lanes,.lanes.one{grid-template-columns:1fr}
.lane{border-radius:14px;padding:8px;display:grid;gap:8px;align-content:start}
.lane.learn{background:#e9f5ff;border:3px dashed #7fbfff}
.lane.play{background:#fff6e6;border:3px dashed #f2c27a}
.chap.exam .lane.play{background:#f4eeff;border-color:#b79cf0}
.lane-t{display:flex;align-items:baseline;gap:6px;font:400 19px var(--f-display);color:var(--ink)}
.lane-t small{font:700 12px var(--f-body);color:#7a6a58}
.path{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.step-arrow{width:18px;height:18px;flex:none;background:no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M3 10h11M10 4l6 6-6 6' fill='none' stroke='%23c9a46a' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}
.sec{position:relative;display:flex;align-items:center;gap:8px;border:3px solid var(--ink);border-radius:14px;background:#fff;padding:6px 12px;cursor:pointer;font-weight:700;text-align:left;box-shadow:0 4px 0 var(--ink);transition:transform .2s cubic-bezier(.3,1.7,.5,1),box-shadow .2s,opacity .25s}
.sec:hover{transform:translateY(-4px) scale(1.03);box-shadow:0 7px 0 var(--ink)}
.sec:active{transform:translateY(2px);box-shadow:0 1px 0 var(--ink)}
.sec i{font-style:normal;font-size:22px}.sec span{display:grid;line-height:1.15;font-size:17px}.sec small{font-weight:600;font-size:12px;color:#7a6a58}
.sec em{font-style:normal;color:#e0a400;font-size:15px;letter-spacing:-1px}
.sec.k-learn{background:#d8eeff;width:100%}
.sec.k-practice{background:#fff1d6}
.sec.k-boss{background:#ffd9d4;border-width:4px}
.sec.k-boss i{animation:flagWave 1.6s ease-in-out infinite;transform-origin:20% 90%}
.sec.k-exam{background:#ece3ff}
.sec.done{border-color:#1f8f55}.sec.done::after{content:'✓';position:absolute;top:-9px;right:-8px;width:22px;height:22px;border-radius:50%;background:var(--good,#2fbf71);color:#fff;border:2px solid var(--ink);font:900 13px/18px var(--f-num);text-align:center}
.sec.dim{opacity:.28;filter:grayscale(.6)}
.sec.next{outline:4px solid #ffb020;outline-offset:2px;animation:nextGlow 1.6s ease-in-out infinite}
.nextpin{position:absolute;top:-13px;right:10px;z-index:1;background:#ffb020;color:#2b1d14;border:2px solid var(--ink);border-radius:999px;font:800 11px/1 var(--f-body);padding:3px 7px;animation:pinBob 1.2s ease-in-out infinite}
@keyframes nextGlow{50%{outline-color:#ffe08a;outline-offset:5px}}
@keyframes pinBob{50%{transform:translateY(-3px)}}
@keyframes flagWave{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(10deg)}}
@media (max-width:640px){.lanes{grid-template-columns:1fr}.path{display:grid}.step-arrow{display:none}.sec span{font-size:15px}}
@media (max-width:600px){.shelf{padding:calc(var(--hudH,70px) + 2px) 6px 6px}.shelf-ico{width:54px}.shelf-card header h3{font-size:22px}.books{grid-template-columns:1fr 1fr;gap:8px;padding:10px}.book .cover{width:38px;height:50px}.book span b{font-size:18px}}
@media (prefers-reduced-motion:reduce){.isle [class^="i-"],.isle [class*=" i-"]{animation:none!important}}
.isle .iname{font:400 clamp(18px,2.1vw,25px)/1.1 var(--f-display);background:var(--c);border:3px solid var(--ink);border-radius:14px;padding:2px 14px;margin-top:-14px;box-shadow:0 4px 0 var(--ink);position:relative;z-index:2}
.isle .isub{font:700 13px var(--f-body);margin-top:6px;background:rgba(255,255,255,.85);border-radius:10px;padding:0 8px}
.isle .istars{font:800 15px var(--f-num);margin-top:4px;background:var(--hair);border:2px solid var(--ink);border-radius:10px;padding:0 8px}
.isle.locked{filter:saturate(.7)}
.isle.locked .iname{opacity:.85}
.mapbobo{position:absolute;left:calc(var(--x) + 3%);top:calc(var(--y) - 12%);width:clamp(80px,8vw,120px);z-index:3;transition:left .7s cubic-bezier(.4,0,.3,1),top .7s cubic-bezier(.4,0,.3,1);pointer-events:none}
.mapbobo.moving{animation:mhop .35s ease-in-out 2}
@keyframes mhop{50%{transform:translateY(-36px)}}
.levels{position:absolute;left:var(--x);top:var(--y);z-index:5;transform:translate(-50%,-110%);background:var(--paper);border:4px solid var(--ink);border-radius:20px;box-shadow:6px 6px 0 var(--ink);padding:12px;display:grid;gap:8px;min-width:240px;animation:bpop .35s cubic-bezier(.3,1.7,.5,1)}
.levels>b{font:400 22px var(--f-display)}
.lvl{display:flex;align-items:center;gap:10px;border:3px solid var(--ink);border-radius:14px;background:#fff;padding:6px 10px;cursor:pointer;text-align:left;font-weight:700}
.lvl span{display:grid;place-items:center;width:28px;height:28px;border-radius:50%;background:var(--coral);color:#fff;border:2px solid var(--ink);font:800 15px var(--f-num)}
.lvl em{margin-left:auto;font-style:normal;color:#e0a400}
.lvx,.sx{position:absolute;top:6px;right:8px;border:0;background:none;font-size:26px;cursor:pointer;line-height:1}
.toast{position:absolute;left:50%;bottom:calc(var(--gutB) + 10px);transform:translateX(-50%);background:var(--ink);color:#fff;border-radius:14px;padding:8px 16px;font-weight:700;opacity:0;pointer-events:none}
.toast.show{animation:toast 2.6s}
@keyframes toast{10%,80%{opacity:1}}

/* ---------- game stage ---------- */
.stage{position:absolute;inset:var(--hudH) 0 0 0;display:grid;grid-template-columns:var(--coachW) minmax(0,1fr);gap:clamp(8px,2vw,28px);padding:0 var(--gutR) var(--gutB) var(--gutL);transition:none}
.stage.with-sheet{padding-right:calc(var(--sheetW) + 24px);--coachW:clamp(150px,17vw,240px)}
.play{display:flex;flex-direction:column;min-height:0;min-width:0;gap:10px;padding-bottom:4px}
.gbar{display:flex;align-items:center;gap:12px}
.back{border:4px solid var(--ink);background:#fff;border-radius:14px;padding:3px 12px;font-weight:700;cursor:pointer;box-shadow:0 4px 0 var(--ink);white-space:nowrap}
.qprog{display:flex;gap:6px;flex:1;min-width:80px}
.qprog i{flex:1;height:16px;border:3px solid var(--ink);border-radius:10px;background:#fff;transition:background .4s}
.qprog i.done{background:var(--good)}.qprog i.miss{background:var(--hair)}.qprog i.now{animation:nowp 1s infinite alternate}
@keyframes nowp{to{background:#d8f6ff}}
.combo{font:800 20px var(--f-num);color:#fff;-webkit-text-stroke:2px var(--ink);paint-order:stroke fill;min-width:96px;text-align:right}
.combo.show{animation:comboPop .6s cubic-bezier(.3,1.7,.5,1)}
@keyframes comboPop{0%{transform:scale(.3) rotate(-20deg)}70%{transform:scale(1.4) rotate(6deg)}}
.board{flex:0 1 auto;min-height:0;overflow:auto;-webkit-overflow-scrolling:touch;background:rgba(255,250,240,.96);border:5px solid var(--ink);border-radius:30px;box-shadow:8px 8px 0 var(--ink);padding:clamp(14px,2.2vw,26px);position:relative;align-self:stretch}
.board.leave{animation:qleave .16s forwards}.board.enter{animation:qenter .22s ease-out}
@keyframes qleave{to{transform:translateX(-8px);opacity:0}}
@keyframes qenter{from{transform:translateX(8px);opacity:0}}
.qhead{display:flex;gap:12px;align-items:center;margin-bottom:12px}
.qno{flex:none;display:grid;place-items:center;width:46px;height:46px;border-radius:50%;background:var(--coral);color:#fff;border:3px solid var(--ink);font:800 22px var(--f-num)}
.qhead h2{font-size:clamp(24px,2.9vw,36px);line-height:1.2}
.qhead .src{display:block;font:600 15px var(--f-body);opacity:.7}
.qarea{display:grid;gap:4px;align-content:start}
.coach .bubble{font-size:16px}
.coach .bhost{width:100%}

/* ---------- explanation sheet ---------- */
.sheet{position:absolute;z-index:30;top:var(--hudH);right:var(--gutR);max-height:calc(100% - var(--hudH) - var(--gutB));width:var(--sheetW);display:flex;flex-direction:column;gap:10px;overflow:auto;background:var(--paper);border:5px solid var(--ink);border-radius:30px;box-shadow:8px 8px 0 var(--ink);padding:16px;transform:translateX(calc(100% + 40px));transition:transform .5s cubic-bezier(.3,1.3,.5,1);pointer-events:none}
.sheet.in{transform:none;pointer-events:auto}
.ph{display:flex;align-items:center;gap:10px;flex-wrap:wrap;position:relative;padding-right:30px}
.badge{font:400 26px var(--f-display);color:#fff;border:3px solid var(--ink);border-radius:14px;padding:2px 14px;transform:rotate(-2deg)}
.sheet.ok .badge{background:var(--good)}.sheet.retry .badge{background:var(--coral)}.sheet.reveal .badge{background:var(--grape)}
.ptag{font:700 13px var(--f-body);letter-spacing:.08em;opacity:.7}
.ph .sx{top:-2px;right:0}
.demo{min-height:170px;display:grid;place-items:center;padding:16px 12px;border:3px dashed #d9caa6;border-radius:18px;background:repeating-linear-gradient(#fffdf6 0 30px,#f6efdc 30px 31px);overflow:hidden}
.ptext{font:700 20px/1.7 var(--f-body);margin:0}
.pbtns{display:flex;flex-wrap:wrap;gap:10px;justify-content:flex-end;margin-top:auto}

/* ---------- modals ---------- */
.modal{position:fixed;inset:0;z-index:60;display:grid;place-items:center;padding:calc(var(--hudH) + 8px) var(--gutR) var(--gutB) var(--gutL);background:rgba(43,29,20,.35);animation:fadeIn .3s}
@keyframes fadeIn{from{opacity:0}}
.mcard{position:relative;width:min(760px,100%);max-height:100%;overflow:auto;background:var(--paper);border:5px solid var(--ink);border-radius:30px;box-shadow:9px 9px 0 var(--ink);padding:clamp(16px,3vw,28px);animation:bpop .45s cubic-bezier(.3,1.6,.5,1)}
.reward{text-align:center}
.reward h2{font-size:clamp(38px,6vw,60px);color:#fff;-webkit-text-stroke:3px var(--ink);paint-order:stroke fill;text-shadow:4px 4px 0 var(--ink)}
.bigstars{display:flex;justify-content:center;gap:10px;margin:8px 0}
.bigstars svg{width:clamp(56px,9vw,84px);height:auto;animation:starIn .6s cubic-bezier(.3,1.7,.5,1) both;animation-delay:var(--t)}
.bigstars svg.off{opacity:.2}
@keyframes starIn{from{opacity:0;transform:scale(3) rotate(-90deg)}}
.rgrid{display:grid;grid-template-columns:200px minmax(0,1fr);gap:20px;align-items:center;text-align:left}
.rstats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-top:18px}
.rstats div{background:#fff;border:3px solid var(--ink);border-radius:16px;padding:8px;text-align:center;font:700 13px var(--f-body)}
.rstats b{display:block;font:800 28px var(--f-num)}
.rbtns{display:flex;flex-wrap:wrap;gap:10px;margin-top:16px;align-items:center}
.prep h2{font-size:34px}.prep h3{font-size:24px;margin-top:18px}
.prow{display:grid;grid-template-columns:70px minmax(0,1fr) 90px;gap:12px;align-items:center;margin:10px 0}
.pbar{height:18px;border:3px solid var(--ink);border-radius:10px;background:#fff;overflow:hidden}
.pbar u{display:block;height:100%;background:var(--good);transition:width 1s}
.wlist{margin:8px 0 0;padding-left:22px;-webkit-user-select:text;user-select:text}

/* ---------- question components ---------- */
.tray{display:flex;flex-wrap:wrap;justify-content:center;gap:clamp(8px,1.4vw,14px);margin-top:16px;padding:12px;border:3px dashed #d4c39c;border-radius:20px;background:var(--paper2)}
.tip{font-size:15px;margin:8px 0 0;text-align:center}
.tip.big{font-size:17px}
.tag{display:inline-block;font:700 15px var(--f-body);background:#fff;border:3px solid var(--ink);border-radius:12px;padding:2px 10px}
.chip{touch-action:none;cursor:grab;background:#fff;border:4px solid var(--ink);border-radius:18px;box-shadow:0 6px 0 var(--ink);padding:8px 16px;font:400 clamp(22px,2.4vw,28px)/1.1 var(--f-display);display:flex;flex-direction:column;align-items:center;gap:2px;position:relative;transition:transform .2s cubic-bezier(.3,1.7,.5,1),opacity .2s}
.chip small{font:500 12px var(--f-body)}
.chip.word{font:800 clamp(22px,2.5vw,30px)/1.1 var(--f-num)}
.chip.num{font:800 clamp(26px,3vw,34px)/1 var(--f-num);min-width:64px}
.chip:hover{transform:translateY(-5px) rotate(-3deg)}
.chip.lifted{opacity:.25;transform:none}
.chip.ghost{transition:none;box-shadow:0 18px 12px rgba(43,29,20,.3);cursor:grabbing;opacity:1}
.chip.used{opacity:.22;pointer-events:none;transform:none!important;box-shadow:none}
[data-drop]{transition:transform .2s cubic-bezier(.3,1.7,.5,1),background .2s}
[data-drop].hover{transform:scale(1.08) rotate(-2deg);background:#fff3c4!important;border-color:var(--coral)!important;border-style:solid!important}
[data-drop].nope{animation:nope .45s;background:#ffe1e1!important;border-color:var(--bad)!important}
[data-drop].yes{animation:yes .6s cubic-bezier(.3,1.7,.5,1);background:#dcf8e8!important;border-color:var(--good)!important;border-style:solid!important}
@keyframes nope{20%{transform:translateX(-12px) rotate(-4deg)}40%{transform:translateX(10px) rotate(3deg)}60%{transform:translateX(-7px)}80%{transform:translateX(4px)}}
@keyframes yes{0%{transform:scale(.6)}60%{transform:scale(1.25) rotate(4deg)}}
.slot{display:inline-flex;align-items:center;justify-content:center;min-width:130px;min-height:48px;padding:2px 12px;margin:0 4px;border:4px dashed var(--coral);border-radius:14px;background:#fff;font:800 24px var(--f-num);vertical-align:middle}
.slot.wide{min-width:180px}
.slot .ph{opacity:.4;font-size:18px}
.slot .pv{opacity:.55;font-style:italic}
.sent{font:700 clamp(18px,2.1vw,24px)/2.2 var(--f-num);text-align:center;margin:10px 0 0}
.picbox{display:grid;place-items:center}
.bigpic{font-size:clamp(90px,11vw,140px);line-height:1;display:inline-block;animation:bob 2.4s ease-in-out infinite alternate}
.bigpic.happy{animation:yes .6s}
@keyframes bob{to{transform:translateY(-8px)}}
.radstage{display:flex;gap:22px;justify-content:center;align-items:center;flex-wrap:wrap}
.bigch{display:grid;justify-items:center;gap:6px;padding:12px 26px;background:#fff;border:4px solid var(--ink);border-radius:22px;box-shadow:0 6px 0 var(--ink)}
.split{position:relative;display:inline-block;font:900 clamp(90px,10vw,124px)/1 var(--f-body)}
.split.big{font-size:clamp(70px,8vw,100px)}
.split .ghostch{visibility:hidden}
.split .p{position:absolute;left:0;top:0;transition:transform .8s cubic-bezier(.3,1.6,.5,1),color .4s,opacity .4s}
.split.h .a{clip-path:inset(0 calc(100% - var(--k)) 0 0)}.split.h .b{clip-path:inset(0 0 0 var(--k))}
.split.v .a{clip-path:inset(0 0 calc(100% - var(--k)) 0)}.split.v .b{clip-path:inset(var(--k) 0 0 0)}
.split.open.h .a{transform:translateX(-26px) rotate(-6deg);color:var(--coral)}.split.open.h .b{transform:translateX(22px)}
.split.open.v .a{transform:translateY(-22px) rotate(-4deg);color:var(--coral)}.split.open.v .b{transform:translateY(16px)}
.split.hint .a{animation:hintGlow .7s 4 alternate}
@keyframes hintGlow{to{color:var(--grape);text-shadow:0 0 14px rgba(155,116,240,.8)}}
/* stroke-level split (hanzi-split.js): the radical and the rest are separate sets of real strokes */
.split.hz-wait{visibility:hidden}
.split.hz-on{width:1em;height:1em}
.split .hz,.swapres .hz{display:block;width:1em;height:1em;overflow:visible}
.hz path{fill:currentColor}
.hz .hz-a,.hz .hz-b,.hz .hz-n{transform-box:fill-box;transform-origin:center;transition:transform .8s cubic-bezier(.3,1.6,.5,1),color .4s,opacity .35s}
.split.open .hz .hz-a{transform:translate(var(--mx),var(--my)) rotate(-5deg);color:var(--coral)}
.split.open .hz .hz-b{transform:translate(var(--bx),var(--by))}
.split.hint .hz .hz-a{animation:hzGlow .7s 4 alternate}
@keyframes hzGlow{to{color:var(--grape);filter:drop-shadow(0 0 10px rgba(155,116,240,.8))}}
.swapbox .hz .hz-n{color:var(--grape);opacity:0}
.swapbox.try .hz .hz-a{opacity:0;transform:translate(-300px,-260px) rotate(-40deg)}
.swapbox.try.hz-has .hz .hz-n{opacity:1}
.swapbox.hz-has .newrad{display:none}
.swapres.hz-on{width:1em;height:1em}
.swapres .hz .hz-b{color:var(--ink)}.swapres .hz .hz-a{color:var(--good)}
.radslot{display:grid;place-items:center;width:clamp(120px,13vw,150px);aspect-ratio:1;border:5px dashed var(--coral);border-radius:26px;background:#fff;font:400 18px var(--f-display);text-align:center}
.radslot b{font:900 clamp(70px,8vw,90px)/1 var(--f-body);color:var(--good)}
.swapbox{position:relative}
.swapbox .newrad{position:absolute;left:0;top:0;height:100%;width:var(--k);display:flex;justify-content:center;align-items:center;opacity:0;transition:opacity .3s}
.swapbox .newrad span{display:inline-block;transform:scaleX(.5);font:900 clamp(90px,10vw,124px)/1 var(--f-body);color:var(--grape)}
.swapbox.try .a{opacity:0;transform:translate(-40px,-30px) rotate(-40deg)}
.swapbox.try .newrad{opacity:1}
.swapbox .rz{position:absolute;left:-14px;top:-14px;bottom:-14px;width:calc(var(--k) + 28px);border:4px dashed var(--coral);border-radius:20px;z-index:2}
.swapbox .rz.hover{background:rgba(255,243,196,.3)!important;transform:none}
.swapres{font:900 clamp(90px,10vw,124px)/1 var(--f-body);color:var(--good);display:inline-block;animation:yes .7s cubic-bezier(.3,1.7,.5,1)}
.vg{position:relative;height:clamp(120px,19vh,170px);border:4px solid var(--ink);border-radius:22px;background:radial-gradient(ellipse 40px 14px at 20% 22%,#fff 60%,transparent 62%),radial-gradient(ellipse 56px 18px at 72% 16%,#fff 60%,transparent 62%),linear-gradient(#aef0ff 0,#dff9ff 58%,#9ee59a 58%,#9ee59a 66%,#7fd474 66%);overflow:hidden;display:flex;align-items:flex-end;justify-content:center;padding-bottom:12px}
.vg .sc-main{font-size:clamp(72px,9vw,104px);line-height:1;position:relative;z-index:2}
.vg .fx{position:absolute;font-size:46px;opacity:0}
.vg.go[data-act=walk] .sc-main{animation:walk 2.2s ease-in-out}
.vg[data-act=walk] .fx{right:24px;bottom:16px;left:auto!important;font-size:80px;opacity:1}
@keyframes walk{0%{transform:translateX(-160px)}25%,75%{transform:translateX(-40px) translateY(-10px)}100%{transform:translateX(90px)}}
.vg.go[data-act=wash] .fx{animation:bubbleUp2 1.6s ease-out var(--i) 2}
@keyframes bubbleUp2{0%{opacity:0;transform:translateY(20px) scale(.4)}30%{opacity:1}100%{opacity:0;transform:translateY(-90px) scale(1.2)}}
.vg.go[data-act=wrap] .fx,.vg.go[data-act=fruit] .fx,.vg.go[data-act=none] .fx{animation:wrapIn 1s cubic-bezier(.3,1.6,.5,1) var(--i) forwards}
@keyframes wrapIn{from{opacity:0;transform:rotate(-200deg) scale(.2)}to{opacity:1;transform:none}}
.vg.go[data-act=bin] .fx{animation:toss 1.2s cubic-bezier(.4,0,.6,1) var(--i) forwards}
@keyframes toss{0%{opacity:1;transform:translate(-120px,0) rotate(0)}50%{opacity:1;transform:translate(-50px,-80px) rotate(200deg)}100%{opacity:0;transform:translate(10px,-10px) rotate(400deg) scale(.4)}}
.lab{display:grid;grid-template-columns:1fr 1.3fr;gap:14px}
.lab>div{position:relative;display:grid;place-items:end center;min-height:clamp(170px,24vh,230px);border:4px solid var(--ink);border-radius:22px;padding:34px 10px 16px;overflow:hidden}
.lab .ref{background:#fffdf3}
.lab .exp{background:repeating-linear-gradient(45deg,#eef9ff 0 14px,#e2f4ff 14px 28px);border-style:dashed}
.lab .lbl{position:absolute;top:8px;left:12px;font:700 13px var(--f-body);background:#fff;border:2px solid var(--ink);border-radius:10px;padding:0 8px}
.obj{display:inline-block;font-size:clamp(80px,9vw,110px);line-height:1;transition:filter .4s}
.obj .ic{overflow:visible}
.obj .mg{transform-box:fill-box;transform-origin:50% 100%;transition:transform .65s cubic-bezier(.3,1.4,.5,1)}
/* objects may stretch, outlines stay the same thickness */
.obj[data-k=thing] .mg *{vector-effect:non-scaling-stroke}
.obj[data-k=thing][data-m=tall] .mg{transform:scale(1,1.7)}.obj[data-k=thing][data-m=short] .mg{transform:scale(1,.6)}
.obj[data-k=thing][data-m=fat] .mg{transform:scale(1.6,1)}.obj[data-k=thing][data-m=thin] .mg{transform:scale(.55,1)}
.obj[data-k=thing][data-m=long] .mg{transform:scale(1.9,1)}
.obj[data-k=thing][data-m=soft] .mg{animation:squish .5s 3}
/* animals and people: only grow or shrink as a whole; long/fat/thin/short use redrawn shapes */
.obj[data-m=big] .mg,.obj[data-k=live][data-m=tall] .mg,.obj[data-k=live][data-m=long] .mg,.obj[data-k=live][data-m=fat] .mg{transform:scale(1.5)}
.obj[data-m=small] .mg,.obj[data-k=live][data-m=short] .mg,.obj[data-k=live][data-m=thin] .mg{transform:scale(.6)}
.obj[data-k=live][data-m=soft] .mg{animation:hopsoft .5s 3}
.obj[data-k=variant] .mg{animation:morphIn .55s cubic-bezier(.3,1.5,.5,1)}
@keyframes morphIn{from{opacity:0;transform:translateY(10px) scale(.85)}}
@keyframes hopsoft{50%{transform:translateY(-14px)}}
.obj[data-m=hard]{filter:grayscale(.4) contrast(1.3)}
.obj[data-m=new]{filter:drop-shadow(0 0 12px #ffe36a) saturate(1.5) brightness(1.08)}
.obj[data-m=new] .mg{animation:objShine 1s 2}
.obj[data-m=old]{filter:sepia(.9) brightness(.8)}
@keyframes squish{50%{transform:scale(1.4,.6)}}
@keyframes objShine{50%{transform:rotate(-8deg) scale(1.15)}}
.stamp{position:absolute;right:10px;top:8px;font:400 22px var(--f-display);color:var(--good);border:3px solid currentColor;border-radius:10px;padding:0 8px;transform:rotate(10deg);animation:yes .5s}
.stamp.no{color:var(--bad)}
.nest{display:grid;gap:16px}
.babyzone{display:grid;justify-items:center}
.chip.baby{padding:10px;font-size:76px;border-radius:50%;width:clamp(110px,12vw,132px);height:clamp(110px,12vw,132px);justify-content:center}
.chip.baby small{font-size:15px;font-weight:700}
.moms{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-top:20px}
.mom{position:relative;display:grid;justify-items:center;gap:2px;padding:16px 6px 10px;border:4px solid var(--ink);border-radius:22px;background:#fff;box-shadow:0 6px 0 var(--ink)}
.mom .mface{font-size:clamp(56px,6.5vw,80px);line-height:1;transition:transform .3s}
.mom .mname{font:700 15px var(--f-body)}
.mom .mbub{position:absolute;top:-34px;left:50%;transform:translateX(-50%) scale(0);white-space:nowrap;background:#fff;border:3px solid var(--ink);border-radius:12px;padding:0 8px;font:700 13px var(--f-body);transition:transform .25s cubic-bezier(.3,1.7,.5,1);z-index:4}
.mom.hover .mbub,.mom.no .mbub,.mom.found .mbub{transform:translateX(-50%) scale(1)}
.mom.hover .mface{transform:scale(1.2) rotate(-8deg)}
.mom.no .mface{animation:headShake .5s 2}
.mom.found .mface{animation:hug .8s cubic-bezier(.3,1.7,.5,1)}
.mom .kid{position:absolute;right:6px;bottom:30px;font-size:34px;animation:yes .6s}
@keyframes headShake{25%{transform:rotate(-18deg)}75%{transform:rotate(18deg)}}
@keyframes hug{40%{transform:scale(1.4)}}
.ic{width:1em;height:1em;vertical-align:-.14em;overflow:visible;display:inline-block}
.story{font:800 clamp(22px,2.6vw,30px)/1.4 var(--f-num);text-align:center;background:#fff;border:4px solid var(--ink);border-radius:20px;padding:12px;box-shadow:0 5px 0 var(--ink)}
.story b{color:var(--coral);text-decoration:underline wavy;text-underline-offset:6px}
.eqrow{display:flex;justify-content:center;align-items:center;gap:10px;margin:18px 0 26px;flex-wrap:wrap}
.eslot{position:relative;display:grid;place-items:center;width:clamp(64px,7vw,84px);aspect-ratio:1;border:4px dashed var(--coral);border-radius:18px;background:#fff;font:800 clamp(30px,3.4vw,40px) var(--f-num)}
.eslot.ok{border-style:solid;border-color:var(--good);background:#dcf8e8}
.eslot em{position:absolute;top:100%;margin-top:8px;left:50%;transform:translateX(-50%);width:150px;font:700 12px/1.3 var(--f-body);font-style:normal;color:#fff;background:var(--ink);border-radius:10px;padding:4px 8px;text-align:center;z-index:5}
.eslot em:empty{display:none}
.eqs{font:800 clamp(34px,4vw,44px) var(--f-num)}
.nl{position:relative;height:150px;margin:18px 4px 0;touch-action:none}
.nl .axis{position:absolute;left:2%;right:2%;top:104px;height:5px;background:var(--ink);border-radius:3px}
.nl .tk{position:absolute;top:96px;width:4px;height:20px;background:var(--ink);transform:translateX(-50%)}
.nl .tn{position:absolute;top:120px;transform:translateX(-50%);font:800 22px var(--f-num)}
.nl .tn.cur{color:var(--coral);transform:translateX(-50%) scale(1.35)}
.nl svg.arcs{position:absolute;left:0;top:0;width:100%;height:110px;overflow:visible}
.arcl{position:absolute;top:34px;transform:translateX(-50%);font:800 15px var(--f-num);color:var(--coral);background:#fff;border:2px solid var(--ink);border-radius:50%;width:24px;height:24px;display:grid;place-items:center;z-index:4;animation:popIn .3s both}
.frog{position:absolute;top:44px;font-size:50px;line-height:1;transform:translateX(-50%);cursor:grab;touch-action:none;transition:left .18s cubic-bezier(.3,1.6,.5,1);z-index:3;filter:drop-shadow(0 4px 0 rgba(43,29,20,.3))}
.frog.drag{transition:none;cursor:grabbing}
.frog.hop{animation:hop .25s}
@keyframes hop{50%{margin-top:-24px}}
.live-eq{margin-top:10px;text-align:center;font:800 clamp(30px,3.6vw,40px) var(--f-num)}
.live-eq .q{color:var(--coral)}
.balls{display:grid;grid-template-columns:repeat(5,minmax(0,60px));justify-content:center;gap:12px;margin-top:16px;touch-action:none}
.ball{position:relative;aspect-ratio:1;max-width:100%;border-radius:50%;border:4px solid var(--ink);background:radial-gradient(circle at 32% 28%,rgba(255,255,255,.9) 0 10%,transparent 12%),conic-gradient(from 30deg,var(--coral) 0 25%,#fff 0 50%,var(--blue) 0 75%,var(--hair) 0);cursor:crosshair;transition:transform .3s,filter .3s;display:grid;place-items:center}
.ball:hover{transform:scale(1.08)}
.ball.x{filter:grayscale(1) brightness(.85);transform:scale(.8) rotate(-15deg)}
.ball.x::after{content:"";position:absolute;left:-14%;right:-14%;top:44%;height:7px;background:var(--bad);border-radius:4px;transform:rotate(-40deg);animation:slash .25s}
@keyframes slash{from{transform:rotate(-40deg) scaleX(0)}}
.ballnum{font:800 18px var(--f-num);-webkit-text-stroke:3px #fff;paint-order:stroke}
.matchbox{position:relative;display:grid;grid-template-columns:1fr 1fr;gap:clamp(40px,8vw,120px);padding:6px}
.mlines{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}
.mline{fill:none;stroke:var(--coral);stroke-width:5;stroke-linecap:round;stroke-dasharray:600;animation:drawl .5s ease-out forwards}
@keyframes drawl{from{stroke-dashoffset:600}to{stroke-dashoffset:0}}
.mcol{display:grid;gap:10px;align-content:start}
.mleft.used{opacity:1;background:#dcf8e8}
.mright{display:grid;place-items:center;min-height:56px;border:4px dashed var(--coral);border-radius:18px;background:#fff;font:400 clamp(20px,2.2vw,26px) var(--f-display);padding:6px}
.orow{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;margin-top:10px}
.oslot{display:grid;place-items:center;min-width:90px;min-height:52px;border:4px dashed var(--coral);border-radius:14px;background:#fff;font:800 22px var(--f-num);padding:2px 10px}
.tfrow{display:grid;grid-template-columns:1fr 1.4fr 1fr;gap:14px;align-items:center}
.tfbin{display:grid;place-items:center;gap:4px;min-height:150px;border:5px dashed var(--ink);border-radius:24px;font:400 26px var(--f-display);background:#fff}
.tfbin b{font:800 54px/1 var(--f-num)}
.tfbin.ok b{color:var(--good)}.tfbin.no b{color:var(--bad)}
.chip.tfcard{font:700 clamp(17px,1.8vw,20px)/1.5 var(--f-body);padding:16px;text-align:center}
.inrow{display:flex;gap:10px;justify-content:center;margin-top:16px;flex-wrap:wrap}
.inbox{font:800 28px var(--f-num);border:4px solid var(--ink);border-radius:16px;padding:6px 14px;width:min(100%,320px);background:#fff;transition:border-color .2s,background .2s}
.inbox.match{border-color:var(--good);background:#dcf8e8}
.inbox.nope{animation:nope .45s;border-color:var(--bad)}
.inmeter{display:flex;gap:6px;justify-content:center;margin-top:10px}
.inmeter i{width:14px;height:14px;border-radius:50%;border:3px solid var(--ink);background:#fff;transition:background .2s,transform .2s}
.inmeter i.on{background:var(--coral);transform:scale(1.2)}
.bins{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px}
.bin{min-height:140px;border:4px dashed var(--ink);border-radius:22px;background:#fff;padding:10px;display:grid;align-content:start;gap:8px;text-align:center}
.bin b{font:400 22px var(--f-display)}
.binin{display:flex;flex-wrap:wrap;gap:6px;justify-content:center}

/* demo pieces */
.pop{animation:popIn .5s cubic-bezier(.3,1.7,.5,1) both;animation-delay:var(--t,0s)}
@keyframes popIn{from{opacity:0;transform:scale(.2) rotate(-20deg)}}
.dm{display:grid;justify-items:center;gap:12px;text-align:center;width:100%}
.dm .row{display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap}
.famch{font:900 clamp(34px,4vw,46px)/1 var(--f-body);background:#fff;border:3px solid var(--ink);border-radius:14px;padding:6px 10px}
.blk{display:inline-block;font:800 clamp(24px,3vw,34px) var(--f-num);padding:4px 14px;border:4px solid var(--ink);border-radius:14px}
.blk.im{background:var(--hair);animation:blkL 1s cubic-bezier(.3,1.5,.5,1) both}
.blk.root{background:#9ee8ff;animation:blkR 1s cubic-bezier(.3,1.5,.5,1) both}
@keyframes blkL{from{transform:translateX(-90px) rotate(-20deg);opacity:0}}
@keyframes blkR{from{transform:translateX(90px) rotate(20deg);opacity:0}}
.res{font:800 clamp(32px,4vw,46px) var(--f-num);color:var(--good);-webkit-text-stroke:1px var(--ink)}
.res.wrong{color:var(--bad)}
.stg{display:grid;justify-items:center;gap:4px;font:700 13px var(--f-body)}
.stg .si{font-size:52px;line-height:1;background:#fff;border:3px solid var(--ink);border-radius:50%;width:74px;height:74px;display:grid;place-items:center}
.arr{font:800 24px var(--f-num)}
.bigstamp{font:400 26px var(--f-display);padding:4px 16px;border:4px solid currentColor;border-radius:14px;transform:rotate(-6deg);animation:stampIn .5s cubic-bezier(.3,1.7,.5,1) both;animation-delay:var(--t)}
.bigstamp.sim{color:var(--good)}.bigstamp.dis{color:var(--grape)}
@keyframes stampIn{from{opacity:0;transform:scale(3) rotate(-20deg)}}
.dots{display:grid;grid-template-columns:repeat(7,26px);gap:8px}
.dot{width:26px;height:26px;border-radius:50%;background:var(--blue);border:3px solid var(--ink);display:grid;place-items:center;font:800 12px var(--f-num);color:#fff}
.dot.gone{animation:gone .7s ease-in both;animation-delay:var(--t)}
@keyframes gone{to{transform:translate(60px,-60px) rotate(180deg) scale(.2);opacity:0}}
.blocks{display:flex;gap:4px;flex-wrap:wrap}
.blocks i{width:24px;height:24px;border:3px solid var(--ink);border-radius:6px;background:var(--blue)}
.blocks i.d{background:var(--coral);animation:popIn .4s both;animation-delay:var(--t)}
.mini-nl{position:relative;width:min(100%,520px);height:110px}
.word-big{font:800 clamp(38px,5vw,52px)/1 var(--f-num);letter-spacing:2px}
.word-big span{display:inline-block;animation:popIn .4s cubic-bezier(.3,1.7,.5,1) both;animation-delay:var(--t)}

/* fx */
.conf{position:fixed;width:11px;height:15px;pointer-events:none;z-index:400;border:2px solid var(--ink)}
.flystar{position:fixed;width:34px;height:34px;pointer-events:none;z-index:401}
.floattxt{position:fixed;z-index:401;pointer-events:none;font:800 26px var(--f-num);color:#fff;-webkit-text-stroke:2px var(--ink);paint-order:stroke fill}

/* ---------- bobo rig ----------
   Shoulder → elbow → hand joints. Poses only rotate joints or move the whole body; no squash or stretch. */
svg.bobo{width:100%;height:auto;display:block;overflow:visible}
svg.bobo *{transform-box:view-box}
.bobo .rig{transform-origin:100px 262px;transition:transform .35s cubic-bezier(.3,1.3,.5,1)}
.bobo .shadow{transform-origin:100px 262px}
.bobo .head{transform-origin:100px 150px;animation:headBob 2.6s ease-in-out infinite;transition:transform .35s}
.bobo .torso{animation:breathe 2.6s ease-in-out infinite}
.bobo .armL{transform-origin:68px 158px;transform:rotate(14deg);transition:transform .45s cubic-bezier(.3,1.3,.5,1)}
.bobo .armR{transform-origin:132px 158px;transform:rotate(-14deg);transition:transform .45s cubic-bezier(.3,1.3,.5,1)}
.bobo .armL .sw{transform-origin:68px 158px;animation:swingL 2.6s ease-in-out infinite}
.bobo .armR .sw{transform-origin:132px 158px;animation:swingR 2.6s ease-in-out infinite}
.bobo .armL .fa{transform-origin:68px 176px;transform:rotate(-12deg);transition:transform .45s cubic-bezier(.3,1.3,.5,1)}
.bobo .armR .fa{transform-origin:132px 176px;transform:rotate(12deg);transition:transform .45s cubic-bezier(.3,1.3,.5,1)}
.bobo .legL{transform-origin:86px 206px;transition:transform .3s}.bobo .legR{transform-origin:114px 206px;transition:transform .3s}
.bobo .lidL{transform-origin:78px 80px;transform:scaleY(0);transition:transform .08s}
.bobo .lidR{transform-origin:122px 80px;transform:scaleY(0);transition:transform .08s}
.bobo.blink .lidL,.bobo.blink .lidR{transform:scaleY(1)}
.bobo .browL{transform-origin:78px 74px;transition:transform .3s}.bobo .browR{transform-origin:122px 74px;transition:transform .3s}
.bobo .eyes{transform-origin:100px 98px;transition:transform .3s}
.bobo .mouth>*{display:none}
.bobo .sprout{transform-origin:104px 22px;animation:sprout 2.6s ease-in-out infinite}
@keyframes sprout{0%,100%{transform:rotate(-6deg)}50%{transform:rotate(8deg)}}
.bobo[data-state=cheer] .sprout,.bobo[data-state=wow] .sprout{animation-duration:.5s}
.bobo[data-mouth=smile] .m-smile,.bobo[data-mouth=open] .m-open,.bobo[data-mouth=o] .m-o,.bobo[data-mouth=frown] .m-frown,.bobo[data-mouth=smile2] .m-smile2{display:inline}
.bobo .sweat,.bobo .tear,.bobo .qm,.bobo .spark{display:none}
.bobo .spark path{transform-box:fill-box;transform-origin:center;animation:twinkleStar 1.1s ease-in-out infinite}
.bobo .spark .sp2{animation-delay:-.55s}
@keyframes twinkleStar{0%,100%{transform:rotate(0) scale(.7);opacity:.6}50%{transform:rotate(45deg) scale(1.1);opacity:1}}
@keyframes headBob{50%{transform:rotate(2.5deg) translateY(1.5px)}}
@keyframes breathe{50%{transform:translateY(-1.5px)}}
@keyframes swingL{50%{transform:rotate(-4deg)}}
@keyframes swingR{50%{transform:rotate(4deg)}}
/* states */
.bobo[data-state=wave] .armR{transform:rotate(-104deg)}
.bobo[data-state=wave] .armR .sw{animation:none}
.bobo[data-state=wave] .armR .fa{animation:waveF .34s ease-in-out infinite alternate}
@keyframes waveF{from{transform:rotate(-30deg)}to{transform:rotate(-62deg)}}
.bobo[data-state=point] .armR{transform:rotate(-82deg)}
.bobo[data-state=point] .armR .fa{transform:rotate(-6deg)}
.bobo[data-state=point] .armR .sw{animation:none}
.bobo[data-state=point] .rig{transform:rotate(2deg)}
.bobo[data-state=lean] .rig{transform:rotate(6deg) translateX(6px)}
.bobo[data-state=lean] .armL{transform:rotate(18deg)}.bobo[data-state=lean] .armR{transform:rotate(-18deg)}
.bobo[data-state=lean] .eyes{transform:scale(1.12)}
.bobo[data-state=lean] .browL,.bobo[data-state=lean] .browR{transform:translateY(-6px)}
.bobo[data-state=cheer] .rig{animation:jump .7s cubic-bezier(.3,.7,.4,1) 2}
.bobo[data-state=cheer] .shadow{animation:shadowJ .7s cubic-bezier(.3,.7,.4,1) 2}
.bobo[data-state=cheer] .armL{transform:rotate(108deg)}.bobo[data-state=cheer] .armR{transform:rotate(-108deg)}
.bobo[data-state=cheer] .armL .fa{transform:rotate(46deg)}.bobo[data-state=cheer] .armR .fa{transform:rotate(-46deg)}
.bobo[data-state=cheer] .sw,.bobo[data-state=dance] .sw{animation:none}
.bobo[data-state=cheer] .legL{transform:rotate(8deg)}.bobo[data-state=cheer] .legR{transform:rotate(-8deg)}
.bobo[data-state=cheer] .browL,.bobo[data-state=cheer] .browR,.bobo[data-state=dance] .browL,.bobo[data-state=dance] .browR{transform:translateY(-7px)}
.bobo[data-state=cheer] .spark,.bobo[data-state=dance] .spark{display:inline}
@keyframes jump{0%,100%{transform:translateY(0)}45%{transform:translateY(-44px)}}
@keyframes shadowJ{45%{transform:scale(.6);opacity:.5}}
.bobo[data-state=dance] .rig{animation:dance .6s ease-in-out infinite}
.bobo[data-state=dance] .armL{transform:rotate(106deg)}.bobo[data-state=dance] .armR{transform:rotate(-70deg)}
.bobo[data-state=dance] .armL .fa{animation:danceL .3s ease-in-out infinite alternate}
.bobo[data-state=dance] .armR .fa{animation:danceR .3s ease-in-out infinite alternate}
@keyframes danceL{from{transform:rotate(36deg)}to{transform:rotate(62deg)}}
@keyframes danceR{from{transform:rotate(-20deg)}to{transform:rotate(-50deg)}}
@keyframes dance{0%,100%{transform:rotate(-5deg)}50%{transform:rotate(5deg) translateY(-12px)}}
.bobo[data-state=sad] .head{animation:none;transform:rotate(8deg) translateY(6px)}
.bobo[data-state=sad] .rig{animation:shk .45s}
.bobo[data-state=sad] .armL{transform:rotate(6deg)}.bobo[data-state=sad] .armR{transform:rotate(-6deg)}
.bobo[data-state=sad] .armL .fa{transform:rotate(-4deg)}.bobo[data-state=sad] .armR .fa{transform:rotate(4deg)}
.bobo[data-state=sad] .browL{transform:rotate(-18deg) translateY(2px)}.bobo[data-state=sad] .browR{transform:rotate(18deg) translateY(2px)}
.bobo[data-state=sad] .sweat,.bobo[data-state=sad] .tear{display:inline}
.bobo[data-state=sad] .tear{animation:drip 1s ease-in infinite}
.bobo[data-state=sad] .tear2{animation-delay:.5s}
@keyframes drip{from{transform:translateY(0);opacity:1}to{transform:translateY(34px);opacity:0}}
@keyframes shk{25%{transform:translateX(-7px) rotate(-2deg)}75%{transform:translateX(7px) rotate(2deg)}}
.bobo[data-state=think] .armR{transform:rotate(-100deg)}
.bobo[data-state=think] .armR .fa{transform:rotate(-74deg)}
.bobo[data-state=think] .armR .sw{animation:none}
.bobo[data-state=think] .head{animation:none;transform:rotate(-6deg)}
.bobo[data-state=think] .browL{transform:translateY(-6px) rotate(-8deg)}
.bobo[data-state=think] .qm,.bobo[data-state=think] .sweat{display:inline}
.bobo[data-state=think] .qm{animation:qbob 1s ease-in-out infinite}
@keyframes qbob{50%{transform:translateY(-8px) rotate(10deg)}}
.bobo[data-state=wow] .eyes{transform:scale(1.2)}
.bobo[data-state=wow] .armL{transform:rotate(30deg)}.bobo[data-state=wow] .armR{transform:rotate(-30deg)}
.bobo[data-state=wow] .armL .fa{transform:rotate(30deg)}.bobo[data-state=wow] .armR .fa{transform:rotate(-30deg)}
.bobo[data-state=wow] .rig{animation:shk .3s}


/* ============ responsive ============ */
/* portrait: iPad upright and phones */
@media (orientation:portrait){
  :root{--coachW:clamp(96px,22vw,180px)}
  .home{grid-template-columns:1fr;grid-template-rows:minmax(0,1fr) auto;align-items:stretch;gap:0;padding-top:6px}
  .homecard{align-self:center;justify-self:center;width:min(640px,100%);overflow:auto;max-height:100%}
  .home .coach{flex-direction:row;align-items:flex-end;height:auto;gap:10px;max-width:none}
  .home .coach .bhost{width:var(--coachW);flex:none}
  .home .coach .bubble{flex:1;margin-bottom:30px}
  .coach .bubble::after{left:auto;right:-16px;bottom:18px;transform:rotate(-45deg) skew(10deg,10deg)}
  .stage{grid-template-columns:1fr;grid-template-rows:minmax(0,1fr) auto;gap:6px}
  .stage.with-sheet{padding-right:var(--gutR)}
  .stage .coach{flex-direction:row;align-items:flex-end;height:auto;gap:10px;padding:0;order:2}
  .stage .coach .bhost{width:var(--coachW);flex:none}
  .stage .coach .bubble{flex:1;margin-bottom:24px;font-size:15px;min-height:0}
  .play{order:1}
  .sheet{top:auto;bottom:var(--gutB);left:var(--gutL);right:var(--gutR);width:auto;max-height:66%;transform:translateY(calc(100% + 40px))}
  .rgrid{grid-template-columns:1fr;justify-items:center;text-align:center}
  .rgrid .bhost{width:150px}
  .world{width:100%;height:auto;min-height:max(100%,1380px)}
  .isle{left:var(--px);top:var(--py);width:clamp(170px,46vw,300px)}
  .mapbobo{left:calc(var(--px) + 14%);top:calc(var(--py) - 6%);width:clamp(70px,16vw,110px)}
  .levels{left:var(--px);top:var(--py)}
}
@media (orientation:portrait) and (max-width:600px){
  .world{min-height:1150px}
}
/* phones (narrow) */
@media (max-width:600px){
  :root{--hudH:calc(58px + env(safe-area-inset-top,0px))}
  .logo{font-size:0;padding:4px}.logo span{display:none}
  .pill{padding:3px 10px;font-size:14px}.pill span:not(#starNum):not(.ai):not(.kav){display:none}
  .grades{gap:8px}.gbtn b{font-size:30px}.gbtn span{font-size:15px}.gbtn small{display:none}
  .homecard{padding:16px;border-radius:24px}
  .homecard .sub{font-size:14px}
  .board{border-radius:22px;border-width:4px;box-shadow:5px 5px 0 var(--ink)}
  .qno{width:38px;height:38px;font-size:18px}
  .qhead h2{font-size:20px}
  .lab>div{min-height:140px;padding-top:30px}.lab .lbl{font-size:11px}.obj{font-size:54px}
  .moms{grid-template-columns:repeat(2,minmax(0,1fr))}
  .tfrow{grid-template-columns:1fr 1fr}
  .tfrow .tfcard{grid-column:1/-1;order:-1}
  .nl .tn{font-size:16px}.frog{font-size:38px}
  .combo{min-width:0;font-size:16px}
  .back{padding:2px 8px;font-size:14px}
  .matchbox{gap:28px}
  .sheet{max-height:72%;border-radius:24px;padding:12px}
  .ptext{font-size:16px}
  .rstats b{font-size:22px}
}
/* phones held sideways (short landscape) */
@media (orientation:landscape) and (max-height:520px){
  :root{--hudH:calc(52px + env(safe-area-inset-top,0px));--coachW:clamp(110px,16vw,150px);--sheetW:min(380px,46vw)}
  .hud{padding-top:calc(env(safe-area-inset-top,0px) + 6px)}
  .logo{font-size:18px}.logo i{width:28px;height:28px;font-size:15px}
  .pill{padding:2px 10px;font-size:14px}
  .coach .bubble{font-size:13px;padding:6px 10px;min-height:0}
  .coach{gap:14px}
  .board{padding:10px 14px;border-radius:20px}
  .qhead{margin-bottom:6px}.qno{width:34px;height:34px;font-size:16px}.qhead h2{font-size:19px}
  .tray{margin-top:8px;padding:8px}
  .split{font-size:76px}.radslot{width:100px}
  .homecard h1{font-size:44px}.grades{grid-template-columns:repeat(6,minmax(0,1fr));margin:10px 0}.gbtn small{display:none}
  .demo{min-height:120px}
  .nl{height:140px}
  .lab>div{min-height:120px}.obj{font-size:50px}.moms{margin-top:8px}.mom{padding:8px 4px 6px}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
}

/* ---------- parent account pill & panel ---------- */
.acctpill{display:inline-flex;align-items:center;gap:4px}
.acctpill small{font:800 12px var(--f-num);background:#efe3ff;border-radius:999px;padding:1px 6px}
.acctpill.vip{background:#ffe08a}
@media (max-width:640px){.acctpill .at{display:none}}
.acct .acard{width:min(560px,100%)}
.acard h2{margin:0;font:400 28px var(--f-display)}
.acard h3{margin:16px 0 8px;font:800 18px var(--f-body)}
.acard .why{background:#fff1d6;border:3px dashed #f2c27a;border-radius:14px;padding:10px 12px;font-weight:700;margin:10px 0}
.acard .ok{background:#dcf8e8;border-radius:12px;padding:8px 12px;font-weight:800;color:#1d7a4a}
.atabs{display:flex;gap:6px;margin:12px 0}
.atabs button{flex:1;border:3px solid var(--ink);border-radius:12px;background:#fff;padding:8px;font:800 17px var(--f-body);cursor:pointer}
.atabs button.on{background:var(--ink);color:#fff}
.aform{display:grid;gap:10px}
.aform label{display:grid;gap:4px;font-weight:800;font-size:15px}
.aform input,.redeem input{border:3px solid var(--ink);border-radius:12px;padding:10px 12px;font:700 18px var(--f-body);background:#fff;min-width:0}
.aerr{color:var(--bad,#e8474c);font-weight:800;margin:0;min-height:1.2em}
.perks{margin:14px 0 0;padding:0;list-style:none;display:grid;gap:6px;font-size:15px}
.perks li{background:#fff;border-radius:12px;padding:8px 12px;border:2px solid #eadfc8}
.perks b{color:#b05a00;margin-right:6px}
.ahead{display:flex;align-items:center;gap:12px;padding-right:40px}
.ahead small{color:#7a6a58;font-weight:700}
.ahead .btn{margin-left:auto}
.aav{font-size:40px}
.astats{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:14px}
.ast{display:grid;gap:2px;background:#fff;border:3px solid var(--ink);border-radius:16px;padding:10px 14px;box-shadow:0 4px 0 var(--ink)}
.ast span{font-weight:800;color:#7a6a58;font-size:14px}.ast b{font:800 24px var(--f-num)}.ast small{color:#7a6a58;font-weight:700}
.ast.vip{background:#fff3c4}.ast.pts{background:#f1e8ff}
.plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:10px}
.plan{position:relative;display:grid;gap:2px;background:#fff;border:3px solid var(--ink);border-radius:16px;padding:12px 14px}
.plan b{font:400 21px var(--f-display)}.plan em{font:800 22px var(--f-num);font-style:normal;color:#d24f1e}.plan small{color:#7a6a58;font-weight:700}
.plan.best{background:#fff7dc;border-width:4px}
.plan .ribbon{position:absolute;top:-12px;right:10px;background:#ff7b54;color:#fff;border:2px solid var(--ink);border-radius:999px;padding:2px 8px;font:800 12px var(--f-body)}
.paynote{color:#7a6a58;font-weight:700;font-size:14px}
.redeem{display:flex;gap:8px}.redeem input{flex:1;text-transform:uppercase;letter-spacing:1px}
.ledger summary{cursor:pointer;font-weight:800;margin-top:10px}
.ledger ul{list-style:none;padding:0;margin:6px 0;display:grid;gap:4px;max-height:200px;overflow:auto}
.ledger li{display:grid;grid-template-columns:90px 1fr auto;gap:8px;font-size:14px;background:#fff;border-radius:8px;padding:4px 8px}
.ledger b{color:#1d7a4a}.ledger b.neg{color:#d24f1e}
.hintline{color:#7a6a58;font-size:14px;font-weight:700}
.btn.small{padding:6px 12px;font-size:14px}
/* grade buttons: member grades */
.gbtn.vip small{background:#ffe08a;border-radius:999px;padding:0 8px;color:#7a4a00}
/* grade tabs inside a subject's shelf */
.gtabs{flex:none;display:flex;gap:6px;padding:10px 16px 0;overflow-x:auto;scrollbar-width:none}
.gtabs::-webkit-scrollbar{display:none}
.gt{flex:none;display:grid;justify-items:center;gap:0;border:3px solid var(--ink);border-radius:14px;background:#fff;padding:4px 12px;cursor:pointer;box-shadow:0 3px 0 var(--ink);transition:transform .15s}
.gt b{font:800 15px var(--f-body)}.gt small{font:700 11px var(--f-body);color:#7a6a58}
.gt.on{background:var(--coral);color:#fff;transform:translateY(2px);box-shadow:0 1px 0 var(--ink)}.gt.on small{color:#fff}
.gt.vip{background:#fff7dc}.gt.soon{opacity:.55}
.gt.shake{animation:nope .45s}

/* ===== livelier home: candy title, glossy 3D buttons ===== */
.homecard h1.ctitle{color:inherit;-webkit-text-stroke:0;text-shadow:none;transform:rotate(-2deg);display:inline-flex;gap:.02em}
.ctitle span{display:inline-block;color:var(--c);-webkit-text-stroke:3px var(--ink);paint-order:stroke fill;text-shadow:0 3px 0 var(--ink),0 6px 0 var(--ink),4px 8px 0 rgba(43,29,20,.25);animation:titleHop 2.4s ease-in-out infinite;animation-delay:calc(var(--i) * .15s)}
.ctitle span:nth-child(odd){rotate:-4deg}.ctitle span:nth-child(even){rotate:3deg}
@keyframes titleHop{0%,60%,100%{transform:translateY(0)}30%{transform:translateY(-10px) scale(1.06)}}
.gbtn{position:relative;overflow:hidden;background:linear-gradient(180deg,color-mix(in srgb,var(--c) 55%,#fff) 0%,var(--c) 55%,color-mix(in srgb,var(--c) 82%,#000) 100%)}
.gbtn::before{content:'';position:absolute;left:10%;right:10%;top:6px;height:34%;border-radius:999px;background:linear-gradient(rgba(255,255,255,.75),rgba(255,255,255,0));pointer-events:none}
.gbtn b{text-shadow:0 2px 0 rgba(255,255,255,.7)}
.gbtn:not(.locked):hover{transform:translateY(-8px) rotate(-3deg) scale(1.04)}
.gbtn.sel{box-shadow:0 6px 0 var(--ink),0 0 0 6px rgba(255,255,255,.9),0 0 22px 8px color-mix(in srgb,var(--c) 70%,#fff)}
.gbtn.locked{filter:saturate(.55);opacity:.9}
.bigbtn{background:linear-gradient(180deg,#ffa47f 0%,#ff7b54 55%,#e85d3a 100%);position:relative;overflow:hidden;animation:ctaPulse 2.2s ease-in-out infinite}
.bigbtn::before{content:'';position:absolute;left:4%;right:4%;top:4px;height:40%;border-radius:999px;background:linear-gradient(rgba(255,255,255,.6),rgba(255,255,255,0))}
.bigbtn::after{content:'';position:absolute;top:0;bottom:0;width:30%;left:-40%;background:linear-gradient(100deg,transparent,rgba(255,255,255,.55),transparent);animation:shine 3.2s ease-in-out infinite}
@keyframes ctaPulse{50%{transform:scale(1.025)}}
@keyframes shine{0%,55%{left:-40%}85%,100%{left:120%}}
.homecard{background:linear-gradient(180deg,rgba(255,255,255,.97),rgba(255,247,224,.95));position:relative}
.homecard::after{content:'';position:absolute;inset:8px;border:3px dashed rgba(255,180,90,.45);border-radius:24px;pointer-events:none}
.pill,.logo{background:linear-gradient(180deg,#fff 0%,#fff 50%,#f3ead8 100%)}
.isle .iname{background:linear-gradient(180deg,color-mix(in srgb,var(--c) 50%,#fff),var(--c))}
@media (prefers-reduced-motion:reduce){.ctitle span,.bigbtn,.bigbtn::after{animation:none}}
/* phone: everything in the top bar fits on one row */
@media (max-width:420px){.hud{gap:5px!important;padding-left:8px!important;padding-right:8px!important}.hud .pill{padding:3px 7px;font-size:13px}#gradePill{padding:3px 8px}}
/* close buttons: a big round button that is easy to see and tap */
.lvx,.sx{display:grid;place-items:center;width:44px;height:44px;padding:0;border:4px solid var(--ink)!important;border-radius:50%;background:linear-gradient(180deg,#ff8f6b,#ff5a4a)!important;color:#fff;font:900 26px/1 var(--f-num,sans-serif)!important;box-shadow:0 4px 0 var(--ink);z-index:5;transition:transform .15s}
.lvx:hover,.sx:hover{transform:scale(1.1) rotate(90deg)}
.lvx:active,.sx:active{transform:translateY(3px);box-shadow:0 1px 0 var(--ink)}
.aipanel .sx{top:10px;right:10px}
/* shelf: chapters fold open one at a time, practice grouped by sub-topic */
.chh{cursor:pointer;user-select:none;margin:0!important;align-items:center!important}
.chap.open .chh{margin-bottom:10px!important}
.chmeta{margin-left:auto;display:flex;align-items:center;gap:8px}
.chmeta small{font:800 13px var(--f-num)!important;color:#7a6a58}
.chmeta em{font:800 14px var(--f-num);font-style:normal;color:#b07800}.chmeta em.full{color:var(--good)}
.cbar{width:clamp(50px,9vw,110px);height:12px;border:2px solid var(--ink);border-radius:999px;background:#f3ead8;overflow:hidden}
.cbar i{display:block;height:100%;background:linear-gradient(90deg,#7ee0a0,#2fbf71)}
.chev{width:30px;height:30px;border:3px solid var(--ink);border-radius:50%;background:#ffe08a;position:relative;transition:transform .25s}
.chev::after{content:'';position:absolute;left:7px;top:5px;width:9px;height:9px;border-right:3px solid var(--ink);border-bottom:3px solid var(--ink);transform:rotate(45deg)}
.chap.open .chev{transform:rotate(180deg)}
.chap.shut{padding:10px 12px;transition:transform .2s}
.chap.shut:hover{transform:translateY(-2px);box-shadow:0 5px 0 var(--ink)}
.tpeek{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.tchip{display:inline-flex;gap:4px;align-items:center;border:2px solid #e5d6b8;border-radius:999px;background:#fffaf0;padding:2px 10px;font:700 13px var(--f-body);color:#6a5a48}
.tchip b{font:800 12px var(--f-num);color:#c2410c}.tchip.l{background:#e9f5ff;border-color:#9cc8f0}
.tlearn{background:#e9f5ff;border:3px dashed #7fbfff;border-radius:14px;padding:8px;margin-bottom:10px;display:grid;gap:8px}
.tl-row{display:flex;flex-wrap:wrap;gap:8px}.tl-row .sec.k-learn{width:auto}
.topics{display:grid;gap:10px}
.topic{display:grid;grid-template-columns:minmax(120px,170px) 1fr;gap:10px;align-items:start;background:#fff6e6;border:3px dashed #f2c27a;border-radius:14px;padding:8px}
.topic.boss{background:#fff0ee;border-color:#f5a9a0}
.topic.clear{background:#effaf3;border-color:#8fd8a8}
.tp-h{display:grid;gap:2px;align-content:start;padding-top:4px}
.tp-h b{font:400 18px/1.2 var(--f-display)}
.tp-h small{font:800 12px var(--f-num);color:#7a6a58}
.tcode{justify-self:start;font:800 13px var(--f-num);background:#fff;border:2px solid var(--ink);border-radius:8px;padding:0 6px}
.tp-tiles{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.tp-tiles .sec{padding:4px 10px}.tp-tiles .sec span{font-size:15px}.tp-tiles .sec i{font-size:18px}
.chap.exam .topic{background:#f4eeff;border-color:#b79cf0}
@media (max-width:640px){.topic{grid-template-columns:1fr}.tp-h{grid-auto-flow:column;justify-content:start;align-items:baseline;gap:8px}.tp-tiles{display:grid}.chmeta .cbar{display:none}.chh small:not(.chmeta small){display:none}}
.tp-tiles{display:grid!important;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px}
.tp-tiles .sec{gap:6px;padding:5px 8px}
.tp-tiles .sec small{display:none}
.tp-tiles .sec .tico{display:none}
.tp-tiles .sec .tnum{flex:none;display:grid;place-items:center;width:24px;height:24px;border-radius:50%;background:#ffb020;border:2px solid var(--ink);font:800 13px var(--f-num)!important;color:var(--ink)}
.tp-tiles .sec.k-boss .tnum{background:#ff7b6b;color:#fff}
.tp-tiles .sec.done .tnum{background:#2fbf71;color:#fff}
.tp-tiles .sec em{margin-left:auto;font-size:12px}
@media (max-width:640px){.tp-tiles{grid-template-columns:1fr 1fr}.tp-tiles .sec span{font-size:14px}.tp-tiles .sec em{display:none}
  .shelf-card .books .book small{display:none}.shelf-card .gtabs small{display:none}}
/* compact book picker so the chapter list gets the space */
.books{padding:8px 16px;gap:10px}
.book{padding:4px 10px;gap:10px}
.book .cover{width:36px;height:46px}
.book .cover b{font-size:12px}
.book span b{font-size:19px}
@media (max-height:900px){.shelf-card header{padding-top:6px;padding-bottom:6px}.shelf-ico{width:58px}}
.chapters{position:relative}.chapters.still .chap{animation:none}
.chap.shut{position:relative}.chap.hasnext{outline:4px solid #ffb020;outline-offset:2px}
/* continue chip + next level button */
.pill.cont{background:linear-gradient(180deg,#9ff0bd,#2fbf71);color:#123;max-width:min(42vw,340px);gap:6px;animation:contPulse 2s ease-in-out infinite}
.pill.cont i{font-style:normal;display:grid;place-items:center;width:22px;height:22px;border-radius:50%;background:#fff;border:2px solid var(--ink);font-size:11px}
.pill.cont span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:800}
.pill.cont small{font-weight:700;opacity:.8}
@keyframes contPulse{50%{box-shadow:0 3px 0 var(--ink),0 0 0 6px rgba(47,191,113,.25)}}
.btn.rnext{display:inline-grid;line-height:1.1;font-size:22px;background:linear-gradient(180deg,#9ff0bd,#2fbf71)}
.btn.rnext small{font-size:13px;font-weight:700;opacity:.85}
@media (max-width:600px){.pill.cont span small{display:none}.pill.cont{max-width:46vw}}
@media (max-width:600px){.pill.cont::after{content:'继续';font-weight:800}}
/* chapters fold smoothly (no re-drawing, no bounce) */
.chap{animation:chapFade .35s ease-out both!important;animation-delay:0s!important}
@keyframes chapFade{from{opacity:0;transform:translateY(6px)}}
.chap.shut:hover{transform:none;box-shadow:none;background:#fffdf6}
.chap .cbody{display:grid;grid-template-rows:0fr;opacity:0;transition:grid-template-rows .32s ease,opacity .28s ease}
.chap.open .cbody{grid-template-rows:1fr;opacity:1}
.chap .cin{overflow:hidden;min-height:0}
.chap.open .cin{padding-top:2px}
.chap.open .tpeek{display:none}
.chap .tpeek{animation:chapFade .3s ease-out}
.chap.open .chh{margin-bottom:10px!important}
.chap.shut .chh{margin-bottom:0!important}
.chev{transition:transform .3s ease}
@media (prefers-reduced-motion:reduce){.chap .cbody{transition:none}}

/* Off-screen explanations must not pull the whole exercise sideways on focus. */
#v-game{overflow:clip}
/* wrong book in the 家长 panel: each question can be redone or re-learnt */
.wlist .pw{display:flex;align-items:center;gap:10px;justify-content:space-between;padding:8px 0;border-bottom:2px dashed #eadfc8}
.wlist .pw small{display:block;font-size:12px;color:#8a7760;font-weight:600}
.wlist .pwb{display:flex;gap:6px;flex:none}
.btn.small.ghost{background:#fff}
@media(max-width:600px){.wlist .pw{flex-direction:column;align-items:flex-start}}
.board{overflow-x:hidden;overflow-y:auto}

/* Keep the receiving box still while the fitted drag preview follows the pointer. */
[data-drop].drag-destination{transform:none!important;scale:1!important}
/* T07-D05: a response is being checked by the server; the board waits (a note appears only if it takes a moment) */
#qarea.judging{cursor:progress}
#qarea.judging *{pointer-events:none}
#qarea.judging::after{content:'正在检查…';position:fixed;left:50%;bottom:22px;transform:translateX(-50%);z-index:60;padding:6px 14px;border:3px solid var(--ink,#2b1d14);border-radius:999px;background:#fffdf5;font:700 15px/1.2 'Noto Sans SC',sans-serif;color:var(--ink,#2b1d14);box-shadow:0 4px 0 var(--ink,#2b1d14);opacity:0;animation:judgeNote .01s linear .35s forwards;pointer-events:none}
html[lang^=en] #qarea.judging::after{content:'Checking…'}
@keyframes judgeNote{to{opacity:1}}
@media (prefers-reduced-motion:reduce){#qarea.judging::after{animation:none;opacity:1}}
