:root{
  --bg:#fff8ef; --card:#ffffff; --ink:#2b2a33; --muted:#6b6878; --line:#efe3d3;
  /* colours that carry white text all reach 4.5:1 (WCAG AA); --t-* = the same hue used as text/marks on cards */
  --pri:#c94d0a; --pri-ink:#fff; --ok:#1d8148; --bad:#c62b30; --focus:#2559d4;
  --c-thai:#c2185b; --c-math:#2559d4; --c-science:#0e7a52; --c-social:#9c5f00; --c-health:#c2410c;
  --c-arts:#8034c4; --c-career:#7a5a26; --c-english:#08729a;
  --t-pri:var(--pri); --t-thai:var(--c-thai); --t-math:var(--c-math); --t-science:var(--c-science); --t-social:var(--c-social);
  --t-health:var(--c-health); --t-arts:var(--c-arts); --t-career:var(--c-career); --t-english:var(--c-english);
  --ok-bg:#e6f8ee; --ok-ink:#126b3f; --no-bg:#fde9ea; --no-ink:#a3191e; --r:18px; --shadow:0 3px 0 rgba(0,0,0,.08),0 6px 18px rgba(80,50,0,.07);
}
@media (prefers-color-scheme:dark){:root:not([data-theme=light]){ --bg:#1c1b22; --card:#2a2932; --ink:#f3f1f7; --muted:#b4b0c2; --line:#3a3845; --shadow:0 3px 0 rgba(0,0,0,.3); --ok-bg:#173d2a; --ok-ink:#b9f1d0; --no-bg:#46191c; --no-ink:#ffc9cb; --t-pri:#ffa266; --t-thai:#ff8fb6; --t-math:#8fb2ff; --t-science:#4fd6a2; --t-social:#f5b84a; --t-health:#ff9a72; --t-arts:#c99bff; --t-career:#d6b47c; --t-english:#5cc8ec; --ok:#2a9a5c; --focus:#8fb2ff; color-scheme:dark; }}
:root[data-theme=dark]{ --bg:#1c1b22; --card:#2a2932; --ink:#f3f1f7; --muted:#b4b0c2; --line:#3a3845; --shadow:0 3px 0 rgba(0,0,0,.3); --ok-bg:#173d2a; --ok-ink:#b9f1d0; --no-bg:#46191c; --no-ink:#ffc9cb; --t-pri:#ffa266; --t-thai:#ff8fb6; --t-math:#8fb2ff; --t-science:#4fd6a2; --t-social:#f5b84a; --t-health:#ff9a72; --t-arts:#c99bff; --t-career:#d6b47c; --t-english:#5cc8ec; --ok:#2a9a5c; --focus:#8fb2ff; color-scheme:dark; }
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;touch-action:manipulation} /* no double-tap zoom: two quick taps on answers must both count (iOS) */
body{margin:0;background:var(--bg);color:var(--ink);font:18px/1.55 "Noto Sans Thai","Sarabun","Leelawadee UI","Thonburi",system-ui,sans-serif;min-height:100vh;overflow-x:hidden}
button{font:inherit;color:inherit;cursor:pointer;touch-action:manipulation}
a{color:inherit}
:focus-visible{outline:3px solid var(--focus);outline-offset:2px}

/* header */
#top{position:sticky;top:0;padding-left:max(12px,env(safe-area-inset-left));padding-right:max(12px,env(safe-area-inset-right));z-index:5;display:flex;align-items:center;gap:8px;padding-bottom:8px;padding-top:max(8px,env(safe-area-inset-top));background:var(--top,var(--pri));color:#fff;box-shadow:0 2px 8px rgba(0,0,0,.12)}
#top h1{flex:1;margin:0;font-size:20px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#top h1 a{text-decoration:none}
.icon-btn[hidden]{display:none}
.icon-btn{flex:none;border:0;background:rgba(255,255,255,.22);color:#fff;width:48px;height:48px;border-radius:14px;font-size:30px;line-height:1;display:grid;place-items:center;text-decoration:none}
#home{font-size:24px}
#top h1 a{display:block;line-height:48px;min-height:48px;overflow:hidden;text-overflow:ellipsis}
#top .brand{display:inline-flex;align-items:center;gap:6px}
#top .logo{width:42px;height:40px;flex:none;filter:drop-shadow(0 1px 0 rgba(0,0,0,.15))}
#top .wm{font-size:23px;font-weight:800;letter-spacing:.3px}
#top .wm b{color:#ffe08a;font-weight:800}
#top :focus-visible{outline-color:#fff;box-shadow:0 0 0 6px #2b2a33}
#stars{flex:none;display:inline-flex;align-items:center;min-height:48px;background:rgba(255,255,255,.22);padding:4px 12px;border-radius:999px;text-decoration:none;font-weight:700;white-space:nowrap}
main{max-width:760px;margin:0 auto;padding:16px max(16px,env(safe-area-inset-right)) 96px max(16px,env(safe-area-inset-left));outline:none}
.loading{text-align:center;color:var(--muted);padding:40px 0}

/* home */
.hello{display:flex;align-items:center;gap:12px;margin:4px 0 16px}
.hello .mascot{font-size:52px;animation:bob 2.4s ease-in-out infinite}
.hello h2{margin:0;font-size:22px}
.hello p{margin:0;color:var(--muted);font-size:16px}
.band{margin:18px 0 8px;font-size:17px;color:var(--muted);font-weight:700}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:12px}
.grid.wide{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
.tile{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;min-height:96px;padding:12px 8px;border-radius:var(--r);background:var(--card);box-shadow:var(--shadow);text-decoration:none;text-align:center;border:2px solid transparent;transition:transform .15s}
.tile:active{transform:scale(.96)}
.tile .ic{font-size:36px;line-height:1.1}
.tile b{font-size:19px}
.tile small{color:var(--muted);font-size:14px;line-height:1.3}
.tile.grade b{font-size:24px}
.tile .meter{position:absolute;left:10px;right:10px;bottom:7px;height:5px;border-radius:9px;background:var(--line);overflow:hidden}
.tile .meter i{display:block;height:100%;background:var(--ok)}
.tile.soon{opacity:.55}
.continue{display:flex;align-items:center;gap:12px;padding:14px;border-radius:var(--r);background:var(--card);box-shadow:var(--shadow);text-decoration:none;border-left:6px solid var(--pri)}
.continue .ic{font-size:34px}

/* units */
.unit{margin:16px 0;background:var(--card);border-radius:var(--r);box-shadow:var(--shadow);overflow:hidden}
.unit h3{margin:0;padding:12px 14px;font-size:18px;color:#fff;background:var(--sc,var(--pri))}
.lesson-row{display:flex;align-items:center;gap:10px;padding:10px 12px;border-top:1px solid var(--line)}
.lesson-row:first-of-type{border-top:0}
.lesson-row .ic{font-size:28px;width:40px;text-align:center;flex:none}
.lesson-row .nm{flex:1;min-width:0}
.lesson-row .nm div{font-weight:600;line-height:1.35}
.lesson-row .nm small{color:var(--muted);font-size:14px}
.lesson-row .acts{display:flex;gap:6px;flex:none}
.pill{display:inline-flex;align-items:center;justify-content:center;gap:4px;min-width:48px;height:44px;padding:0 12px;border-radius:14px;border:0;background:var(--line);text-decoration:none;font-weight:700;font-size:16px}
.pill.play{background:var(--sc,var(--pri));color:#fff}
.starline{letter-spacing:-2px;font-size:14px}
.subj-head{display:flex;align-items:center;gap:12px;padding:14px;border-radius:var(--r);color:#fff;background:var(--sc,var(--pri))}
.subj-head .ic{font-size:44px}
.subj-head h2{margin:0;font-size:22px}
.subj-head p{margin:0;font-size:16px}
.note{color:var(--muted);font-size:15px;text-align:center;padding:12px}

/* lesson player */
.stage{background:var(--card);border-radius:var(--r);box-shadow:var(--shadow);padding:16px;min-height:62vh;display:flex;flex-direction:column}
.bar{height:10px;border-radius:9px;background:var(--line);overflow:hidden;margin-bottom:12px}
.bar i{display:block;height:100%;background:var(--sc,var(--pri));transition:width .4s}
.slide{flex:1;display:flex;flex-direction:column;gap:12px;animation:slidein .45s ease}
.slide h2{margin:0;font-size:22px;overflow-wrap:anywhere;color:var(--sct,var(--t-pri))}
.slide .txt{font-size:19px;white-space:pre-line;overflow-wrap:anywhere}
.slide .vis{flex:1;display:flex;align-items:center;justify-content:center;min-height:160px}
.slide .vis>*{max-width:100%;min-width:0} /* wide tables/combos scroll inside the card, never the page */
.nav{display:flex;gap:10px;margin-top:14px}
.nav .grow{flex:1}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:54px;padding:0 18px;border-radius:16px;border:0;background:var(--line);font-weight:700;font-size:18px;text-decoration:none;box-shadow:0 3px 0 rgba(0,0,0,.12)}
.btn.main{background:var(--sc,var(--pri));color:#fff}
.btn:active{transform:translateY(2px);box-shadow:none}
.say{border:0;background:transparent;font-size:24px;min-width:44px;min-height:44px;padding:0 4px;border-radius:12px;vertical-align:middle}

/* visuals */
.v-objects{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:10px}
.v-objects .grp{display:flex;flex-wrap:wrap;justify-content:center;gap:4px;max-width:200px;padding:8px;border-radius:14px;background:rgba(0,0,0,.035)}
.v-objects .o{font-size:40px;line-height:1.1;display:inline-block}
.v-objects .op{font-size:40px;font-weight:800;color:var(--sct,var(--t-pri))}
.v-objects .lbl{width:100%;text-align:center;font-weight:800;font-size:22px}
.v-big{text-align:center}
.v-big .t{font-size:110px;line-height:1.1;font-weight:800;color:var(--sct,var(--t-pri));overflow-wrap:anywhere}
.v-big .e{font-size:72px;line-height:1.1}
.pic{display:inline-block;line-height:0}
.pic svg{max-width:100%;height:auto}
.v-big .s{font-size:26px;font-weight:700}
.v-list{min-width:0;box-sizing:border-box;list-style:none;margin:0;padding:0;width:100%;display:grid;gap:8px}
.v-list li{min-width:0;overflow-wrap:anywhere;display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:14px;background:rgba(0,0,0,.04);font-size:18px}
.v-list li .e{font-size:30px;flex:none}
.v-steps{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:6px}
.v-steps .st{display:flex;flex-direction:column;align-items:center;width:86px;text-align:center;font-size:14px;font-weight:600}
.v-steps .st .e{font-size:44px}
.v-steps .ar{font-size:26px;color:var(--muted)}
.v-table{border-collapse:collapse;font-size:17px;margin:0 auto;display:block;width:max-content;max-width:100%;overflow-x:auto}
.v-table td,.v-table th{border:2px solid var(--line);padding:6px 8px;text-align:center;overflow-wrap:anywhere}
/* nothing on a slide may be wider than the phone: a too-wide picture makes the whole page slide sideways and taps miss */
.slide{min-width:0}.slide .vis{min-width:0;max-width:100%}
.v-table th{background:rgba(0,0,0,.04)}
.v-svg svg{max-width:100%;height:auto;max-height:280px}
.v-bars{display:flex;align-items:flex-end;justify-content:center;gap:min(12px,2vw);height:200px;width:100%}
.v-bars .b{display:flex;flex-direction:column;align-items:center;justify-content:flex-end;height:100%;font-size:14px;font-weight:600;flex:0 1 auto;min-width:0;text-align:center;overflow-wrap:anywhere}
.v-bars .b i{display:block;width:38px;max-width:100%;border-radius:8px 8px 0 0;background:var(--sc,var(--pri));transform-origin:bottom;animation:growy .8s ease both}
.v-word{display:flex;gap:6px;justify-content:center;flex-wrap:wrap}
.v-word span{min-width:52px;padding:6px 10px;border-radius:12px;background:rgba(0,0,0,.05);font-size:40px;font-weight:800;text-align:center}
.v-word span.hl{background:var(--sc,var(--pri));color:#fff}
.v-eq{font-size:34px;font-weight:800;text-align:center;letter-spacing:.5px}
.v-eq .hl{color:var(--sct,var(--t-pri))}

/* games */
.q{font-size:21px;font-weight:700;overflow-wrap:anywhere;text-align:center;margin:4px 0 10px}
.q .say{font-size:22px}
.show{display:flex;justify-content:center;align-items:center;min-height:120px;margin:6px 0 12px}
.opts{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px}
.opts.one{grid-template-columns:1fr}
.opts.three{grid-template-columns:repeat(3,minmax(0,1fr))}
.opt{min-height:64px;padding:8px 10px;border-radius:16px;border:3px solid var(--line);background:var(--card);font-size:20px;font-weight:700;box-shadow:0 3px 0 var(--line);transition:transform .1s;min-width:0;overflow-wrap:break-word}
.opt.big{font-size:36px;min-height:84px}
.opt:active{transform:translateY(2px)}
.opt.ok{border-color:var(--ok);background:var(--ok-bg);color:var(--ok-ink);animation:pop .4s}
.opt.no{border-color:var(--bad);background:var(--no-bg);color:var(--no-ink);animation:shake .4s}
.opt[disabled]{opacity:.45}
.feedback{min-height:34px;text-align:center;font-weight:700;font-size:19px;margin-top:10px}
.feedback.ok{color:var(--ok-ink)} .feedback.no{color:var(--no-ink)}
.hint{font-weight:500;color:var(--muted);font-size:16px}
.pile-area{position:relative;display:flex;justify-content:center;align-items:center;gap:22px;min-height:150px;width:100%}
.pile{transition:width .4s;display:flex;flex-wrap:wrap;justify-content:center;align-content:center;gap:2px;width:132px;min-height:110px;padding:6px;border-radius:50% 50% 18px 18px / 30% 30% 18px 18px;background:rgba(0,0,0,.05);transition:transform .7s cubic-bezier(.5,-0.3,.4,1.3)}
.pile .o{font-size:32px;line-height:1.15;transition:transform .7s,opacity .7s}
.pile .o.away{transform:translate(60px,-90px) rotate(40deg) scale(.4);opacity:0}
.pile .o.cross{opacity:.35;filter:grayscale(1)}
.plus{font-size:34px;font-weight:800;color:var(--sct,var(--t-pri));transition:opacity .4s}
.count-field{display:flex;flex-wrap:wrap;justify-content:center;gap:6px;max-width:330px}
.count-field .o{border:0;background:transparent;min-width:48px;min-height:48px;font-size:42px;line-height:1.1;border-radius:12px;padding:0 2px;cursor:pointer;user-select:none;transition:transform .15s}
/* pop in where they sit: a drop from above let a not-yet-visible object lie over the row above and swallow taps */
.count-field .o.a-drop{animation-name:cdrop}
@keyframes cdrop{0%{transform:scale(.3);opacity:0}70%{transform:scale(1.1);opacity:1}100%{transform:none}}
.count-field .o.tapped{background:rgba(47,179,109,.18);transform:scale(.9)}
.count-field .o .n{position:absolute;font-size:14px;font-weight:800;color:var(--ok)}
.tally{text-align:center;color:var(--muted);font-size:15px;margin-top:-6px}
.match{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.match .col{display:grid;gap:10px;align-content:start}
.match .opt{min-height:58px}
.match .opt.sel{border-color:var(--focus);box-shadow:0 0 0 3px rgba(61,123,255,.25)}
.match .opt.done{border-color:var(--ok);opacity:.5}
.sort-item{display:flex;justify-content:center;align-items:center;min-height:120px;font-size:24px;font-weight:700;text-align:center;animation:pop .35s}
.sort-item .e{font-size:64px;display:block}
.bins{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.bin{min-height:96px;border-radius:18px;border:3px dashed var(--line);background:var(--card);font-weight:800;font-size:18px;padding:8px}
.order-ans{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;min-height:64px;padding:8px;border-radius:16px;border:3px dashed var(--line);margin-bottom:12px}
.order-ans .chip,.order-pool .chip{min-width:56px;min-height:52px;padding:4px 12px;border-radius:14px;border:3px solid var(--line);background:var(--card);font-weight:800;font-size:20px;animation:pop .3s}
.order-ans .chip{border-color:var(--ok)}
.order-pool{display:flex;flex-wrap:wrap;justify-content:center;gap:8px}
.keypad{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;max-width:340px;margin:0 auto}
.keypad button{min-height:56px;border-radius:14px;border:0;background:var(--line);font-size:24px;font-weight:800;box-shadow:0 3px 0 rgba(0,0,0,.1)}
.keypad .go{background:var(--ok);color:#fff}
.answer-box{min-height:62px;max-width:340px;margin:0 auto 10px;border-radius:14px;border:3px solid var(--line);background:var(--card);font-size:32px;font-weight:800;text-align:center;line-height:56px}
.answer-box.no{border-color:var(--bad);animation:shake .4s}

/* result */
.result{text-align:center;padding:20px 0}
.result .big-stars{font-size:58px;letter-spacing:4px}
.result .big-stars span{display:inline-block;animation:starin .6s both}
.result .big-stars span.off{filter:grayscale(1);opacity:.3}
.result h2{margin:8px 0}
.result .acts{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;margin-top:18px}
.confetti{position:fixed;inset:0;pointer-events:none;z-index:20;overflow:hidden}
.confetti i{position:absolute;top:-40px;font-style:normal;font-size:26px;animation:fall 2.4s linear forwards}

/* me / settings */
.panel{background:var(--card);border-radius:var(--r);box-shadow:var(--shadow);padding:14px;margin:12px 0}
.panel h3,.panel h2{margin:0 0 8px}
.panel h2{font-size:19px}
.row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:8px 0;border-top:1px solid var(--line)}
.row:first-of-type{border-top:0}
.switch{width:64px;height:44px;border-radius:99px;border:0;background:var(--line);position:relative;flex:none}
.switch::after{content:"";position:absolute;top:5px;left:5px;width:34px;height:34px;border-radius:50%;background:#fff;transition:left .2s;box-shadow:0 1px 3px rgba(0,0,0,.3)}
.switch[aria-checked=true]{background:var(--ok)}
.switch[aria-checked=true]::after{left:25px}
#toast{pointer-events:none;position:fixed;left:50%;bottom:24px;width:max-content;transform:translateX(-50%) translateY(120px);background:#2b2a33;color:#fff;padding:10px 18px;border-radius:999px;font-size:16px;transition:transform .3s;z-index:30;max-width:90vw;text-align:center}
#toast.on{transform:translateX(-50%) translateY(0)}

/* animation library */
.a-pop{animation:pop .5s both}
.a-drop{animation:drop .6s both}
.a-bounce{animation:bounce 1.2s both}
.a-grow{animation:grow 1.4s both}
.a-spin{animation:spin 1.2s both}
.a-float{animation:bob 2.4s ease-in-out infinite}
.a-fade{animation:fade .6s backwards}
.a-slide{animation:slidein .5s both}
.a-wiggle{animation:wiggle 1s ease-in-out 2}
@keyframes pop{0%{transform:scale(0)}70%{transform:scale(1.15)}100%{transform:scale(1)}}
@keyframes drop{0%{transform:translateY(-60px);opacity:0}60%{transform:translateY(6px);opacity:1}100%{transform:none}}
@keyframes bounce{0%{transform:scale(.3);opacity:0}40%{transform:scale(1.1);opacity:1}60%{transform:translateY(-14px)}80%{transform:translateY(0)}90%{transform:translateY(-5px)}100%{transform:none}}
@keyframes grow{0%{transform:scale(.1) translateY(40px);opacity:0}100%{transform:none;opacity:1}}
@keyframes growy{0%{transform:scaleY(0)}100%{transform:scaleY(1)}}
@keyframes spin{0%{transform:rotate(-180deg) scale(0)}100%{transform:none}}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}
@keyframes fade{from{opacity:0}to{opacity:1}}
@keyframes slidein{from{opacity:0;transform:translateX(24px)}to{opacity:1;transform:none}}
@keyframes wiggle{0%,100%{transform:rotate(0)}25%{transform:rotate(-12deg)}75%{transform:rotate(12deg)}}
@keyframes shake{0%,100%{transform:translateX(0)}20%,60%{transform:translateX(-8px)}40%,80%{transform:translateX(8px)}}
@keyframes starin{0%{transform:scale(0) rotate(-90deg)}100%{transform:none}}
@keyframes fall{to{transform:translateY(110vh) rotate(540deg)}}
@keyframes hand{0%{transform:rotate(0)}100%{transform:rotate(var(--to))}}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* offline downloads (#/me) */
.pack{display:flex;width:100%;justify-content:space-between;text-align:left;margin:6px 0;background:var(--card);border:2px solid var(--line);box-shadow:none;min-height:56px;font-size:17px}
.pack small{flex:none;max-width:45%;font-weight:600;color:var(--muted);font-size:14px;text-align:right}
.grid.packs{grid-template-columns:repeat(auto-fill,minmax(68px,1fr));gap:8px}
.grid.packs .tile{min-height:68px;padding:6px}
.grid.packs .tile .ic{font-size:26px}
.pack[data-saved="1"]{border-color:var(--ok)}
.pack:disabled{opacity:.7}
.pack-list .band{margin-top:14px}
.tile.on{outline:3px solid var(--pri)}
/* lite mode (slow phones / data saver): looping decorations play once, then rest */
.lite .mascot,.lite .mascot *,.lite .a-float{animation-iteration-count:1!important}
.lite #top{box-shadow:none}
/* scene: animated stage for emoji/letter slides (Visuals.render(spec,{scene})) */
.v-scene{position:relative;width:100%;max-width:360px;min-height:210px;margin:0 auto;display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:24px;overflow:hidden;isolation:isolate}
.v-scene.kid{min-height:240px}
.v-scene .sc-bg{position:absolute;inset:0;width:100%;height:100%;z-index:-1}
.v-scene .sc-m{transform-box:fill-box;transform-origin:center;animation:drift 6s ease-in-out infinite}
.v-scene .sc-pulse{transform-box:fill-box;transform-origin:center;animation:breathe 3.2s ease-in-out infinite}
.v-scene .sc-hero{display:flex;flex-direction:column;align-items:center;line-height:1.1}
.v-scene .t{font-size:104px;font-weight:800;line-height:1.05;color:var(--sct,var(--t-pri));text-shadow:0 4px 0 rgba(0,0,0,.08)}
.v-scene.kid .t{font-size:120px}
.v-scene .e{line-height:1.1;filter:drop-shadow(0 6px 4px rgba(0,0,0,.12))}
.v-scene .s{font-size:24px;font-weight:700;margin-top:4px;background:var(--card);padding:2px 14px;border-radius:999px;box-shadow:var(--shadow)}
.v-scene .sc-idle{display:inline-block;animation:bob 2.6s ease-in-out 1.3s infinite}
.v-scene .idle-drive{animation:drive 3.4s ease-in-out 1.3s infinite}
.v-scene .idle-fly{animation:fly 3.6s ease-in-out 1.3s infinite}
.v-scene .idle-flutter{animation:flutter 3s ease-in-out 1.3s infinite}
.v-scene .idle-beat{animation:beat 1.2s ease-in-out 1.3s infinite}
.v-scene .idle-swing{transform-origin:50% 0;animation:swing 1.6s ease-in-out 1.3s infinite}
.v-scene .idle-spin{animation:spinslow 9s linear 1.3s infinite}
.v-scene .idle-flicker{animation:flicker 1.1s ease-in-out 1.3s infinite}
.v-scene .idle-swim{animation:swim 3.2s ease-in-out 1.3s infinite}
.v-scene .idle-sway{transform-origin:50% 100%;animation:sway 2.8s ease-in-out 1.3s infinite}
.v-scene .idle-hop{animation:hop 1.4s ease-in-out 1.3s infinite}
.sc-fx{position:absolute;inset:0;pointer-events:none;z-index:-1;overflow:hidden}
.sc-fx i{position:absolute;bottom:10%;font-style:normal;font-weight:800;font-size:22px;color:var(--sct,var(--t-pri));opacity:0;animation:rise 3.4s ease-out infinite}
.fx-hearts i{color:#ef5d8f}
.fx-sparkle i{color:#f5b301;animation-name:twinkle;bottom:auto;top:18%;font-size:24px}
.fx-sparkle i:nth-child(2n){top:62%}
.fx-zzz i{color:#7a6bd6;font-size:20px}
.fx-think i{color:#ff8a3d;font-size:26px;animation-name:twinkle;bottom:auto;top:14%}
.fx-think i:nth-child(2n){top:60%}
.fx-leaves i{animation-name:leaf;bottom:auto;top:-8%;font-size:18px}
.fx-wind i{animation-name:windx;bottom:auto;top:30%;left:-10%!important;color:#7fb6e0;font-size:28px}
.fx-wind i:nth-child(2n){top:62%}
.fx-rain i,.fx-bubbles i,.fx-steam i{width:8px;height:8px;border-radius:50%}
.fx-rain i{width:3px;height:16px;border-radius:3px;background:#5aa9e6;bottom:auto;top:-10%;animation:rain 1.1s linear infinite}
.fx-bubbles i{border:2px solid #5aa9e6;background:rgba(255,255,255,.5);width:12px;height:12px}
.fx-bubbles i:nth-child(2n){width:8px;height:8px}
.fx-steam i{background:rgba(150,150,160,.35);width:16px;height:16px;bottom:44%;filter:blur(2px);animation-name:steam}
.fx-rays i,.fx-orbit i{left:50%;top:46%;width:240px;height:240px;margin:-120px 0 0 -120px;border-radius:50%;opacity:.35;animation:spinslow 14s linear infinite}
.fx-rays i{background:repeating-conic-gradient(from 0deg,#ffd23d 0 8deg,transparent 8deg 24deg);-webkit-mask:radial-gradient(circle,transparent 30%,#000 32%,transparent 70%);mask:radial-gradient(circle,transparent 30%,#000 32%,transparent 70%)}
.fx-orbit i{width:200px;height:200px;margin:-100px 0 0 -100px;border:2px dashed var(--sc,var(--pri));opacity:.45;animation:orbit 5s linear infinite}
.fx-orbit i::after{content:"";position:absolute;left:50%;top:-8px;width:14px;height:14px;margin-left:-7px;border-radius:50%;background:var(--sc,var(--pri))}
@keyframes drift{0%,100%{transform:translate(0,0) rotate(0)}50%{transform:translate(4px,-8px) rotate(8deg)}}
@keyframes breathe{0%,100%{transform:scale(1)}50%{transform:scale(1.12)}}
@keyframes drive{0%,100%{transform:translateX(-22px)}50%{transform:translateX(22px) translateY(-3px)}}
@keyframes fly{0%,100%{transform:translate(-10px,6px) rotate(-6deg)}50%{transform:translate(10px,-12px) rotate(6deg)}}
@keyframes flutter{0%{transform:translate(0,0)}25%{transform:translate(16px,-10px) rotate(8deg)}50%{transform:translate(0,-18px)}75%{transform:translate(-16px,-8px) rotate(-8deg)}100%{transform:translate(0,0)}}
@keyframes beat{0%,100%{transform:scale(1)}15%{transform:scale(1.14)}30%{transform:scale(1)}45%{transform:scale(1.1)}}
@keyframes swing{0%,100%{transform:rotate(-12deg)}50%{transform:rotate(12deg)}}
@keyframes spinslow{to{transform:rotate(360deg)}}
@keyframes flicker{0%,100%{transform:scale(1) skewX(0)}30%{transform:scale(1.06,.96) skewX(3deg)}60%{transform:scale(.96,1.06) skewX(-3deg)}}
@keyframes swim{0%,100%{transform:translateX(-18px) rotate(-4deg)}50%{transform:translateX(18px) rotate(4deg)}}
@keyframes sway{0%,100%{transform:rotate(-5deg)}50%{transform:rotate(5deg)}}
@keyframes hop{0%,100%{transform:translateY(0) scaleY(1)}10%{transform:scaleY(.9)}45%{transform:translateY(-22px) scaleY(1.04)}}
@keyframes rise{0%{transform:translateY(0) scale(.6);opacity:0}20%{opacity:.85}100%{transform:translateY(-130px) translateX(10px) scale(1.1);opacity:0}}
@keyframes twinkle{0%,100%{transform:scale(0) rotate(0);opacity:0}50%{transform:scale(1.2) rotate(90deg);opacity:1}}
@keyframes leaf{0%{transform:translate(0,0) rotate(0);opacity:0}15%{opacity:.9}100%{transform:translate(30px,230px) rotate(320deg);opacity:0}}
@keyframes windx{0%{transform:translateX(0);opacity:0}20%{opacity:.8}100%{transform:translateX(420px);opacity:0}}
@keyframes rain{0%{transform:translateY(0);opacity:0}10%{opacity:.8}100%{transform:translateY(240px);opacity:.2}}
@keyframes steam{0%{transform:translateY(0) scale(.6);opacity:0}30%{opacity:.8}100%{transform:translateY(-90px) scale(1.8);opacity:0}}
@keyframes orbit{from{transform:scaleY(.5) rotate(0)}to{transform:scaleY(.5) rotate(360deg)}}
/* mascot reacting to answers (Mascot.live) */
.mk-live{position:relative}
.mk-live .mk-pep{position:absolute;right:70%;bottom:86%;white-space:nowrap;background:var(--card);border:2px solid var(--line);border-radius:14px;padding:4px 10px;font-weight:800;font-size:15px;box-shadow:var(--shadow);animation:pop .35s both}
.mk-live .mk-burst{position:absolute;inset:-10%;pointer-events:none}
.mk-live .mk-burst i{position:absolute;left:50%;top:40%;font-style:normal;font-size:16px;animation:burst .8s ease-out both}
@keyframes burst{0%{transform:translate(0,0) scale(.3);opacity:1}100%{transform:translate(var(--dx),var(--dy)) scale(1);opacity:0}}
.slide-next{animation:nudge 1.4s ease-in-out 3s 3}
.lite .v-scene *,.lite .mk-live *{animation-iteration-count:1!important}
.lite .sc-fx{display:none}
@keyframes nudge{0%,100%{transform:none}50%{transform:translateX(5px)}}
@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}
/* "หยุดภาพเคลื่อนไหว" switch on #/me: the same, for phones where the system setting is hard to find */
.calm *,.calm *::before,.calm *::after{animation-duration:.01ms!important;animation-delay:0s!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
.calm .confetti{display:none}
/* "ตัวหนังสือใหญ่" switch on #/me */
.big #app{zoom:1.18}

/* mascot */
.mascot{flex:none;display:inline-block}
.mascot svg{width:100%;height:100%;overflow:visible}
.mascot .mk-l{fill:none;stroke:#2b2a33;stroke-width:3.5;stroke-linecap:round}
.mascot .mk-arm{fill:none;stroke:#2b2a33;stroke-width:14;stroke-linecap:round}
.mascot .mk-blink{transform-origin:94px 78px;animation:blink 4s infinite}
.mascot .mk-ears{transform-origin:94px 80px;animation:ears 3s ease-in-out infinite}
.mascot .mk-trunk{transform-origin:94px 92px;animation:trunk 2.6s ease-in-out infinite}
.mascot .mk-wave{transform-origin:140px 132px;animation:wave .9s ease-in-out infinite alternate}
.mascot .mk-pop{animation:pop .6s both}
.mascot.mk-cheer svg{animation:jump .7s ease-in-out infinite}
.mascot.mk-oops svg{animation:shake .5s 1}
.mascot.mk-think svg{animation:tilt 2s ease-in-out infinite}
.mascot.mk-hi svg,.mascot.mk-happy svg,.mascot.mk-read svg{animation:bob 2.6s ease-in-out infinite}
.mk-say{display:flex;align-items:flex-end;gap:6px}
.mk-say .bubble{position:relative;background:var(--card);border:2px solid var(--line);border-radius:18px;padding:10px 14px;font-weight:600;font-size:17px;box-shadow:var(--shadow);margin-bottom:28px;animation:pop .4s .2s both}
.mk-say .bubble::before{content:"";position:absolute;left:-10px;bottom:14px;border:8px solid transparent;border-right-color:var(--card)}
.game-mascot{position:fixed;right:10px;bottom:10px;z-index:4;pointer-events:none}
@keyframes blink{0%,92%,100%{transform:scaleY(1)}95%{transform:scaleY(.1)}}
@keyframes ears{0%,100%{transform:scaleX(1)}50%{transform:scaleX(1.05)}}
@keyframes trunk{0%,100%{transform:rotate(0)}50%{transform:rotate(-8deg)}}
@keyframes wave{from{transform:rotate(-10deg)}to{transform:rotate(25deg)}}
@keyframes jump{0%,100%{transform:translateY(0)}50%{transform:translateY(-14px)}}
@keyframes tilt{0%,100%{transform:rotate(-4deg)}50%{transform:rotate(4deg)}}
.v-svg svg [class*="a-"]{transform-box:fill-box;transform-origin:center}
.opt-wrap{position:relative;display:grid;min-width:0}
.opt-wrap .opt{padding:30px 8px 8px}
/* the speak button sits in the top-right corner, so long words keep the full width of the answer */
.opt-say{position:absolute;right:0;top:0;width:44px;height:44px;border-radius:50%;border:0;background:transparent;font-size:17px;line-height:1}
.opts.three .opt-wrap .opt{padding:40px 6px 8px}
.opts.three .opt-say{font-size:15px}

/* rewards: today's mission, ocean, stickers (js/reward.js) */
.rw-today{background:var(--card);border-radius:var(--r);box-shadow:var(--shadow);padding:14px;margin:0 0 14px;border-top:6px solid var(--pri)}
.rw-head{display:flex;gap:12px;align-items:center}
.rw-head h3{margin:0;font-size:19px}
.rw-head p{margin:2px 0 0;font-size:15px;color:var(--muted);line-height:1.4}
.rw-ring{position:relative;flex:0 0 64px;width:64px;height:64px}
.rw-ring svg{width:100%;height:100%}
.rw-ring circle{transition:stroke-dasharray .8s ease}
.rw-ring b{position:absolute;inset:0;display:grid;place-items:center;font-size:17px}
.rw-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
.rw-chips span{font-size:14px;font-weight:700;background:var(--bg);border-radius:999px;padding:2px 10px}
.rw-mlist{display:flex;flex-direction:column;gap:8px;margin:12px 0 10px}
.rw-m{display:flex;align-items:center;gap:10px;min-height:56px;padding:8px 12px;border-radius:14px;border:2px solid var(--line);background:none;text-decoration:none;text-align:left;width:100%}
.rw-m .ic{font-size:26px;flex:0 0 auto}
.rw-m b{display:block;font-size:16px;line-height:1.3}
.rw-m small{display:block;color:var(--muted);font-size:14px}
.rw-m.done{background:var(--ok-bg);border-color:transparent}
.rw-m.done b{color:var(--ok-ink)}
.rw-done{margin:0;font-size:15px;font-weight:700;color:var(--ok-ink);text-align:center}
.rw-ocean{display:flex;align-items:center;gap:8px;padding:10px 12px;border-radius:14px;background:linear-gradient(90deg,#d8f0ff,#c3e6ff);color:#14476b;text-decoration:none;margin:12px 0}
.rw-today .rw-ocean{margin:0}
.rw-ocean>span:first-child{font-size:26px}
.rw-ocean b{flex:1;font-size:16px}
.rw-ocean small{font-size:14px;font-weight:700}
.rw-ocean>span:last-child{font-size:22px}
.rw-pop{position:fixed;inset:0;z-index:30;background:rgba(20,30,50,.55);display:grid;place-items:center;padding:16px;animation:fade .25s}
.rw-card{background:var(--card);border-radius:24px;padding:18px;max-width:360px;width:100%;text-align:center;box-shadow:0 10px 40px rgba(0,0,0,.3);animation:bounce .7s}
.rw-card .mascot{margin:0 auto}
.rw-card h2{margin:4px 0;font-size:22px}
.rw-card p{margin:6px 0 12px;font-size:16px}
.rw-card .acts{display:flex;flex-wrap:wrap;gap:8px;justify-content:center}
.rw-gifts{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin:6px 0}
.rw-gift{font-size:56px;line-height:1.1;animation:spin .8s both}
.rw-sea{position:relative;height:300px;margin:12px 0 4px;border-radius:var(--r);overflow:hidden;background:linear-gradient(#5fc0f0 0,#2f8fd6 45%,#1f6fb5 100%);box-shadow:var(--shadow)}
.rw-sky{position:absolute;left:0;right:0;top:0;height:22%;background:linear-gradient(#bfe9ff,#9ed9fb);border-bottom:4px solid rgba(255,255,255,.55)}
.rw-sand{position:absolute;left:-5%;right:-5%;bottom:-30px;height:70px;border-radius:50% 50% 0 0;background:#f1d9a3}
.rw-it{position:absolute;margin:-22px 0 0 -22px;border:0;background:none;padding:0;font-size:30px;line-height:1;width:44px;height:44px;display:grid;place-items:center}
.rw-it.w{animation:swim 6s ease-in-out infinite}
.rw-it.f{animation:tilt 4s ease-in-out infinite}
.rw-it.s{font-size:26px}
.rw-it.hi{animation:wiggle .5s 2}
.rw-narwhal{position:absolute;left:50%;top:52%;margin:-46px 0 0 -46px;border:0;background:none;padding:0;animation:bob 3s ease-in-out infinite}
.rw-count{text-align:center;color:var(--muted);font-size:15px;margin:4px 0 0}
@keyframes swim{0%,100%{transform:none}50%{transform:translate(10px,-6px)}}
.rw-hint{margin:6px 0 0;font-size:14px;color:var(--muted)}
.rw-goals{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.rw-goals button{display:flex;flex-direction:column;align-items:center;gap:0;min-height:76px;border:2px solid var(--line);border-radius:14px;background:none;padding:6px}
.rw-goals button span{font-size:24px}
.rw-goals button small{color:var(--muted);font-size:14px}
.rw-goals button.on{border-color:var(--pri);background:var(--bg)}
.rw-cal{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;text-align:center}
.rw-cal div{border-radius:10px;padding:2px 0;background:var(--bg)}
.rw-cal div.now{outline:2px solid var(--pri)}
.rw-cal small{display:block;font-size:14px;color:var(--muted)}
.rw-cal span{font-size:18px;color:var(--muted)}
.rw-book{display:flex;flex-direction:column;gap:10px}
.rw-grp>b{font-size:15px}
.rw-row{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin-top:4px}
.rw-st{display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:50%;aspect-ratio:1;max-width:72px;width:100%;margin:0 auto;border:4px solid #c98a4b;background:radial-gradient(#fff,#ffe9cf)}
.rw-st span{font-size:24px;line-height:1}
.rw-st small{font-size:14px;font-weight:700;color:#5a4630;line-height:1.2}
.rw-st.t1{border-color:#9fb0c2;background:radial-gradient(#fff,#e4ecf5)}
.rw-st.t2{border-color:#e8b515;background:radial-gradient(#fff,#fff1b8)}
.rw-st.t3{border-color:transparent;background:radial-gradient(#fff 55%,transparent 56%),conic-gradient(#ff6b6b,#ffd93d,#6bcB77,#4d96ff,#c77dff,#ff6b6b)}
.rw-st.lock{filter:grayscale(1)}
.rw-st.lock span{opacity:.4}
.rw-st.big{width:64px;animation:spin .8s both}
.lite .rw-it,.lite .rw-narwhal{animation:none}

/* ---------- accessibility ---------- */
/* right / wrong are never shown by colour alone: a ✓ or ✗ badge too (colour-blind safe) */
.opt.ok,.opt.no,.answer-box.no{position:relative}
.opt.ok::after,.opt.no::after,.answer-box.no::after{position:absolute;top:-10px;right:-8px;width:28px;height:28px;border-radius:50%;color:#fff;font-size:17px;line-height:28px;font-weight:900;text-align:center;box-shadow:0 1px 3px rgba(0,0,0,.3)}
.opt.ok::after{content:"✓";background:var(--ok)}
.opt.no::after,.answer-box.no::after{content:"✗";background:var(--bad)}
.match .opt.done::after{content:"✓";position:absolute;top:-8px;right:-6px;width:24px;height:24px;border-radius:50%;background:var(--ok);color:#fff;font-size:15px;line-height:24px;font-weight:900;text-align:center}
.match .opt.done{position:relative;opacity:.75}
.match .opt.sel{border-style:dashed}
.opt[disabled]:not(.ok){opacity:.5}
/* tile with a "listen" button for children who can't read yet (อนุบาล) */
.tile-wrap{position:relative;display:grid}
.tile-wrap .tile{padding-bottom:16px}
.tile-say{position:absolute;top:2px;right:2px;width:44px;height:44px;border:0;border-radius:50%;background:transparent;font-size:20px}
.lesson-row .say{flex:none}
.panel .row > a{display:block;min-height:44px;padding:10px 0}
.nav .btn{min-width:64px;font-size:20px}
/* end-of-unit test / term review links (pages themselves: css/exam.css) */
.unit-test{display:flex;align-items:center;gap:10px;margin-top:8px;padding:10px 12px;border-radius:14px;border:2px dashed var(--sc,var(--line));text-decoration:none}
.unit-test .nm{flex:1;min-width:0}
.unit-test .nm b{display:block;font-size:17px}
.unit-test .nm small{color:var(--muted);font-size:14px}
.unit-test .best{font-weight:700;color:var(--ok-ink);white-space:nowrap}
.panel .unit-test:first-of-type{margin-top:0}
/* child's name, narwhal colour, players on this phone, storage meter */
.kid-chip{display:inline-flex;align-items:center;min-height:44px;margin-top:4px;padding:0 12px;border-radius:22px;background:var(--line);color:var(--ink);font-size:15px;font-weight:700;text-decoration:none}
.name-card{border:3px dashed var(--pri)}
.name-card p{margin:0 0 10px;font-size:16px}
.name-form label,.name-form .lbl{display:block;font-weight:700;font-size:16px;margin:6px 0}
.name-in{width:100%;box-sizing:border-box;min-height:54px;padding:0 14px;font:inherit;font-size:22px;border-radius:14px;border:2px solid var(--line);background:var(--card);color:var(--ink)}
.name-in:focus{border-color:var(--focus)}
.av-pick{display:flex;flex-wrap:wrap;gap:8px}
.av{width:60px;height:60px;padding:4px;border-radius:16px;border:3px solid transparent;background:var(--line);display:flex;align-items:center;justify-content:center}
.av.on{border-color:var(--pri);background:var(--card)}
.name-form .acts{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
.kid-row.on{background:var(--line);border-radius:14px;padding-left:6px;padding-right:6px}
.kid-pick{flex:1;display:flex;align-items:center;gap:10px;min-height:60px;border:0;background:none;color:inherit;font:inherit;text-align:left;padding:4px 0}
.kid-pick span{display:flex;flex-direction:column}
.kid-pick b{font-size:18px}
.kid-pick small{color:var(--muted);font-size:14px}
.kid-link>.mascot{flex:none}
.meter.space{height:12px;border-radius:9px;background:var(--line);overflow:hidden;margin:4px 0}
.meter.space i{display:block;height:100%;background:var(--ok)}
.meter.space.warn i{background:var(--bad)}
.kid-row.on .kid-pick small{color:var(--ink)}
