/* IPA font: Charis SIL (SIL Open Font License 1.1, see fonts/OFL.txt), self-hosted subset, IPA spans only */
@font-face{font-family:"EWN IPA";src:url("fonts/CharisSIL-IPA.woff2") format("woff2");font-display:swap;unicode-range:U+0020-007E,U+00A0-00FF,U+0250-02FF,U+0300-036F,U+1D00-1DBF,U+2010-2027}
:root{--c:#1f6feb;--bg:#f6f8fa;--fg:#1b1f24;--muted:#57606a;--err:#cf222e}
*{box-sizing:border-box}
html,body{margin:0;background:var(--bg);color:var(--fg);font:16px/1.5 -apple-system,BlinkMacSystemFont,"PingFang SC","Helvetica Neue",sans-serif;-webkit-text-size-adjust:100%}
main{max-width:480px;margin:0 auto;min-height:100dvh;padding:calc(env(safe-area-inset-top) + 24px) calc(env(safe-area-inset-right) + 20px) calc(env(safe-area-inset-bottom) + 24px) calc(env(safe-area-inset-left) + 20px)}
section{display:flex;flex-direction:column;gap:14px}
.hero{font-size:72px;text-align:center;margin-top:10vh}
h1{margin:0;font-size:26px;text-align:center}
.muted{color:var(--muted);text-align:center;margin:0}
form{display:flex;flex-direction:column;gap:14px}
label{display:flex;flex-direction:column;gap:6px;font-weight:600}
input{font-size:16px;padding:12px 14px;border:1px solid #d0d7de;border-radius:12px;background:#fff;min-height:48px}
input:focus{outline:2px solid var(--c);border-color:var(--c)}
.btn{display:flex;align-items:center;justify-content:center;min-height:52px;border-radius:14px;border:1px solid #d0d7de;background:#fff;color:var(--fg);font-size:17px;font-weight:600;text-decoration:none;cursor:pointer;touch-action:manipulation}
.btn.primary{background:var(--c);border-color:var(--c);color:#fff}
.btn:disabled{opacity:.6}
.link{text-align:center;color:var(--c)}
.error{color:var(--err);min-height:1.5em;margin:0}
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.stats div{background:#fff;border-radius:14px;padding:14px;text-align:center;display:flex;flex-direction:column}
.stats b{font-size:24px}
[hidden]{display:none!important}
.unit{background:#fff;border-radius:16px;padding:14px;margin-bottom:12px}
.unit h2{margin:0;font-size:19px}.unit .muted{text-align:left;font-size:14px}
.lessons{display:flex;flex-direction:column;gap:8px;margin-top:10px}
.lesson{display:flex;justify-content:space-between;align-items:center;min-height:52px;padding:0 14px;border-radius:12px;border:1px solid #d0d7de;color:var(--fg);text-decoration:none}
.lesson.unlocked{border-color:var(--c);background:#ddf4ff}.lesson.completed{background:#dafbe1;border-color:#2da44e}.lesson.locked{opacity:.55}
.lesson .st{font-size:14px;color:var(--muted)}
.progress{height:10px;background:#d0d7de;border-radius:6px;overflow:hidden}.progress div{height:100%;background:#2da44e}
.ex-head{display:flex;flex-direction:column;gap:8px}.ex-head h2{margin:0;font-size:20px}
.prompt{font-size:24px;font-weight:700;margin:0}.pic{align-self:center}
.opts{display:flex;flex-direction:column;gap:10px}.opts.pics{display:grid;grid-template-columns:repeat(3,1fr)}
.opt,.tile{font-size:17px;min-height:48px;padding:8px 14px;border-radius:12px;border:2px solid #d0d7de;background:#fff;color:var(--fg);cursor:pointer;touch-action:manipulation}
.opt img{width:100%;height:auto;max-width:96px}
.opt.sel,.tile.sel{border-color:var(--c);background:#ddf4ff}
.line{min-height:60px;border-bottom:2px solid #d0d7de;display:flex;flex-wrap:wrap;gap:8px;padding:6px 0}
.bank{display:flex;flex-wrap:wrap;gap:8px;padding-top:10px}
.match{display:grid;grid-template-columns:1fr 1fr;gap:12px}.col{display:flex;flex-direction:column;gap:8px}
.tile[data-pair]{border-color:#8250df;background:#fbefff}
.answer{font-size:16px;padding:12px 14px;border:1px solid #d0d7de;border-radius:12px;width:100%;font-family:inherit}
.feedback{border-radius:14px;padding:14px;display:flex;flex-direction:column;gap:8px}.feedback p{margin:0}
.feedback.good{background:#dafbe1}.feedback.bad{background:#ffebe9}
.result{text-align:center;display:flex;flex-direction:column;gap:12px;margin-top:8vh}.stars{font-size:48px;color:#d4a72c}
.close{align-self:flex-start}.btn.small{min-height:44px;min-width:44px;font-size:15px;align-self:flex-start;padding:0 12px}
#player{display:flex;flex-direction:column;gap:14px}
.ex-body{display:flex;flex-direction:column;gap:10px}
.tile[data-pair]::before{content:attr(data-pair);display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;margin-right:8px;border-radius:50%;background:#8250df;color:#fff;font-size:13px}
.muted-l{color:var(--muted);font-size:14px;margin:0}
:focus-visible{outline:3px solid #0969da;outline-offset:2px}
.play{display:flex;gap:8px;flex-wrap:wrap}
.note{background:#fff8c5;border-radius:10px;padding:8px 12px;margin:0;font-size:14px}
.dialogue{display:flex;flex-direction:column;gap:8px;background:#fff;border-radius:14px;padding:12px}
.dl{display:flex;gap:6px;align-items:center;flex-wrap:wrap}.dl.mia b{color:#bf3989}.dl.leo b{color:#0969da}
.intro{background:#fff;border-radius:16px;padding:16px;display:flex;flex-direction:column;gap:6px}.intro h1{text-align:left}.intro h3{margin:10px 0 0;font-size:16px}
.intro ul{margin:0;padding-left:20px}.words{list-style:none;padding:0!important;display:flex;flex-direction:column;gap:6px}
.word{display:flex;gap:10px;align-items:center;flex-wrap:wrap}.ipa{color:var(--muted);font-family:"EWN IPA","Charis SIL","Lucida Sans Unicode","Arial Unicode MS",serif}
.pattern{display:flex;flex-direction:column;gap:4px;background:#ddf4ff;border-radius:12px;padding:10px}
.tts{display:flex;flex-direction:column;gap:10px;margin-top:8px}.tts select{font-size:16px;min-height:44px;border-radius:10px}
.chk{flex-direction:row;align-items:center;gap:10px;font-weight:400}.chk input{width:24px;height:24px;min-height:0}
summary{min-height:44px;display:flex;align-items:center;cursor:pointer;font-weight:600}
.mist{padding-left:18px;display:flex;flex-direction:column;gap:10px}
/* ---------------- P4 characters: transforms/opacity only; reduced motion disables */
.char{width:120px;height:auto;display:block;overflow:visible}
.char.sz-s{width:72px}.char.sz-m{width:96px}.char.sz-l{width:150px}.char.sz-xl{width:190px}
.char .breathe{transform-box:fill-box;transform-origin:50% 100%;animation:ch-breathe 3.2s ease-in-out infinite}
.char .eyes{transform-box:fill-box;transform-origin:50% 50%;animation:ch-blink 4.6s infinite}
.char .m-open{opacity:0}
.char.talking .m-open{animation:ch-mouth-a .28s steps(1) infinite}
.char.talking .m-closed{animation:ch-mouth-b .28s steps(1) infinite}
.char .tail{transform-box:fill-box;transform-origin:0% 100%;animation:ch-tail 2.4s ease-in-out infinite}
.char .fx-twinkle{transform-box:fill-box;transform-origin:50% 50%;animation:ch-twinkle 1.4s ease-in-out infinite}
.char .fx-bob{transform-box:fill-box;animation:ch-bob 1.8s ease-in-out infinite}
.char .fx-spin{transform-box:fill-box;transform-origin:50% 50%;animation:ch-spin 2.2s linear infinite}
.char .fx-pop{transform-box:fill-box;transform-origin:50% 100%;animation:ch-pop .9s ease-out infinite alternate}
.char .fx-rise{transform-box:fill-box;animation:ch-rise 1.2s ease-in-out infinite alternate}
.char .fx-flicker{transform-box:fill-box;transform-origin:50% 100%;animation:ch-flicker .5s ease-in-out infinite alternate}
.char .fx-confetti{transform-box:fill-box;animation:ch-fall 2.4s linear infinite}.char .fx-confetti.c1{animation-delay:-.6s}.char .fx-confetti.c2{animation-delay:-1.2s}.char .fx-confetti.c3{animation-delay:-1.8s}
.char .fx-drip{transform-box:fill-box;animation:ch-drip 1.6s ease-in infinite}
.char .fx-swing{transform-box:fill-box;transform-origin:50% 0%;animation:ch-swing 1.6s ease-in-out infinite}
.char .fx-steam{transform-box:fill-box;animation:ch-bob 2s ease-in-out infinite}
.st-welcome .arm-r,.st-happy .arm-r{transform-box:fill-box;transform-origin:20% 100%;animation:ch-wave .8s ease-in-out infinite alternate}
.st-happy .fig,.st-complete .fig,.st-levelup .fig{transform-box:fill-box;animation:ch-bounce .7s ease-in-out infinite}
.st-correct .fig{transform-box:fill-box;animation:ch-jump .9s cubic-bezier(.3,1.6,.5,1) infinite}
.st-surprised .fig{transform-box:fill-box;animation:ch-jolt .6s ease-out 1}
.st-confused .head-in,.st-thinking .head-in{transform-box:fill-box;transform-origin:50% 100%;animation:ch-tilt 2.4s ease-in-out infinite}
.st-encourage .arm-r,.st-streak .arm-r{transform-box:fill-box;transform-origin:50% 100%;animation:ch-pump .6s ease-in-out infinite alternate}
.st-sad .fig{transform-box:fill-box;animation:ch-sag 2.4s ease-in-out infinite}
.st-comfort .fig{transform-box:fill-box;animation:ch-sway 3s ease-in-out infinite}
@keyframes ch-breathe{0%,100%{transform:scale(1,1)}50%{transform:scale(1.015,.985)}}
@keyframes ch-blink{0%,92%,100%{transform:scaleY(1)}95%{transform:scaleY(.1)}}
@keyframes ch-mouth-a{0%{opacity:1}50%{opacity:0}}
@keyframes ch-mouth-b{0%{opacity:0}50%{opacity:1}}
@keyframes ch-tail{0%,100%{transform:rotate(0)}50%{transform:rotate(-8deg)}}
@keyframes ch-twinkle{0%,100%{transform:scale(.6);opacity:.5}50%{transform:scale(1.15);opacity:1}}
@keyframes ch-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-5px)}}
@keyframes ch-spin{to{transform:rotate(360deg)}}
@keyframes ch-pop{from{transform:scale(.85)}to{transform:scale(1.1)}}
@keyframes ch-rise{from{transform:translateY(6px)}to{transform:translateY(-6px)}}
@keyframes ch-flicker{from{transform:scale(1,1) rotate(-3deg)}to{transform:scale(.92,1.1) rotate(3deg)}}
@keyframes ch-fall{0%{transform:translateY(-20px) rotate(0);opacity:0}15%{opacity:1}100%{transform:translateY(120px) rotate(200deg);opacity:0}}
@keyframes ch-drip{0%{transform:translateY(0);opacity:1}100%{transform:translateY(14px);opacity:0}}
@keyframes ch-swing{0%,100%{transform:rotate(-6deg)}50%{transform:rotate(6deg)}}
@keyframes ch-wave{from{transform:rotate(-10deg)}to{transform:rotate(12deg)}}
@keyframes ch-bounce{0%,100%{transform:translateY(0)}50%{transform:translateY(-8px)}}
@keyframes ch-jump{0%,100%{transform:translateY(0)}40%{transform:translateY(-22px)}}
@keyframes ch-jolt{0%{transform:translateY(0)}30%{transform:translateY(-10px)}100%{transform:translateY(0)}}
@keyframes ch-tilt{0%,100%{transform:rotate(0)}50%{transform:rotate(-4deg)}}
@keyframes ch-pump{from{transform:translateY(0)}to{transform:translateY(-6px)}}
@keyframes ch-sag{0%,100%{transform:translateY(0)}50%{transform:translateY(3px)}}
@keyframes ch-sway{0%,100%{transform:rotate(-1.5deg)}50%{transform:rotate(1.5deg)}}
@media (prefers-reduced-motion:reduce){.char,.char *{animation:none!important}.char.talking .m-open{opacity:1}.char.talking .m-closed{opacity:0}}
.reduce-motion .char,.reduce-motion .char *{animation:none!important}.reduce-motion .char.talking .m-open{opacity:1}.reduce-motion .char.talking .m-closed{opacity:0}
/* ---------------- P4 UI */
.hud{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.hud div{background:#fff;border-radius:12px;padding:8px 4px;text-align:center;display:flex;flex-direction:column;font-size:13px;color:var(--muted)}
.hud b{font-size:18px;color:var(--fg)}
.lvbar{height:8px;background:#d0d7de;border-radius:6px;overflow:hidden}.lvbar div{height:100%;background:#8250df;transform-origin:0 50%}
.cast{display:flex;gap:10px;align-items:flex-end}
.bubble{position:relative;background:#fff;border:2px solid #3b2a20;border-radius:16px;padding:10px 12px;flex:1;font-size:15px}
.bubble b{display:block;font-size:13px;color:var(--muted)}
.card{background:#fff;border-radius:16px;padding:14px;display:flex;flex-direction:column;gap:10px}
.card h3{margin:0;font-size:17px}
.quest{display:flex;justify-content:space-between;align-items:center;gap:8px}
.quest .q{flex:1;display:flex;flex-direction:column;gap:4px}
.qbar{height:6px;background:#d0d7de;border-radius:4px;overflow:hidden}.qbar div{height:100%;background:#2da44e}
.ach{display:grid;grid-template-columns:repeat(2,1fr);gap:8px}
.ach div{border:1px solid #d0d7de;border-radius:12px;padding:8px;font-size:13px}.ach .on{background:#fff8c5;border-color:#d4a72c}.ach .off{opacity:.5}
.rewards{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.rewards div{background:#fff;border-radius:12px;padding:10px;display:flex;flex-direction:column;align-items:center}
.rewards b{font-size:22px}
.events{display:flex;flex-direction:column;gap:8px}
.event{display:flex;align-items:center;gap:10px;background:#fff;border-radius:14px;padding:8px 12px;text-align:left}
.gallery{display:flex;flex-direction:column;gap:14px}
.gal-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
.gal-grid figure{margin:0;display:flex;flex-direction:column;align-items:center;font-size:12px;color:var(--muted)}
.gal-grid .char{width:100%}
.ex-host{display:flex;align-items:center;gap:8px}
.dl .char{flex:none}
.heartlost{color:var(--err);font-weight:700}
.nohearts{background:#ffebe9;border-radius:14px;padding:12px;display:flex;flex-direction:column;gap:8px}
/* ---- P4-fix: winding course path (original design) ---- */
.punit{margin:18px 0 8px}
.phead{border-radius:16px;padding:12px 16px;color:#fff;background:#2da44e;box-shadow:0 4px 0 rgba(0,0,0,.18)}
/* Unit word list: tap a unit banner to open the unit's new words */
.phead[role="button"]{cursor:pointer}
.phead[role="button"]:hover{filter:brightness(1.07)}
.uwords-hint{display:block;margin-top:6px;opacity:.85}
.uwords-ov{position:fixed;inset:0;background:rgba(30,20,10,.55);display:flex;align-items:flex-end;justify-content:center;z-index:60}
.uwords-box{background:#fff;border-radius:20px 20px 0 0;width:100%;max-width:560px;max-height:82vh;display:flex;flex-direction:column;padding:16px 16px calc(16px + env(safe-area-inset-bottom))}
.uwords-head{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}
.uwords-head h2{font-size:18px;margin:0}
.uwords-actions{margin-top:10px}
.uwords-list{overflow:auto;list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:8px}
.uwords-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;background:#f7f7f5;border-radius:12px;padding:10px 12px}
.uwords-row b{font-size:17px}
.uwords-row .tapword{cursor:pointer}
.phead small{opacity:.9;font-weight:700;letter-spacing:.02em}.phead h2{margin:2px 0 0;font-size:20px}.phead p{margin:4px 0 0;font-size:13px;opacity:.92}
.punit.u1 .phead{background:#8250df}.punit.u2 .phead{background:#cf4a3a}.punit.u3 .phead{background:#d4a017}.punit.u4 .phead{background:#1f6feb}.punit.u5 .phead{background:#bf3989}
.ptrack{position:relative;width:320px;max-width:100%;margin:14px auto 0;overflow-x:clip}
.ppath{position:absolute;left:0;top:0;width:320px;height:100%;pointer-events:none}
.ppath path{fill:none;stroke:#d0d7de;stroke-width:10;stroke-linecap:round;stroke-dasharray:2 16}
.prow{position:relative;width:128px;margin:0 auto;height:108px;display:flex;flex-direction:column;align-items:center;justify-content:flex-start}
.prow.off0{transform:translateX(-112px)}.prow.off1{transform:translateX(-56px)}.prow.off3{transform:translateX(56px)}.prow.off4{transform:translateX(112px)}
.pnode{width:64px;height:64px;margin-top:8px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:26px;font-weight:800;text-decoration:none;color:#fff;
  background:#58a6ff;box-shadow:0 6px 0 #1f6feb;position:relative;z-index:1}
.pnode.completed{background:#f2c037;box-shadow:0 6px 0 #c08b00;color:#7a4b00}
.pnode.locked{background:#e5e7eb;box-shadow:0 6px 0 #bfc5cc;color:#8c959f}
.pnode.current{background:#2da44e;box-shadow:0 6px 0 #1a7f37,0 0 0 6px #fff,0 0 0 11px #2da44e55;transform:scale(1.12)}
.pnode:active{transform:translateY(4px);box-shadow:0 2px 0 #1f6feb}
.plabel{display:flex;flex-direction:column;align-items:center;margin-top:8px;line-height:1.1;max-width:120px;text-align:center}
.plabel small{font-size:11px;color:var(--muted)}.pst{color:#d4a017;font-size:13px;letter-spacing:1px;min-height:14px}
.pstart{position:absolute;top:-30px;z-index:2;background:#fff;color:#1a7f37;border:2px solid #2da44e;border-radius:12px;padding:4px 14px;font-weight:800;text-decoration:none;box-shadow:0 3px 0 #2da44e;
  animation:pbob 1.6s ease-in-out infinite}
.pstart::after{content:"";position:absolute;left:50%;bottom:-8px;margin-left:-6px;border:6px solid transparent;border-top-color:#2da44e;border-bottom:0}
@keyframes pbob{50%{transform:translateY(-4px)}}
.pmascot{position:absolute;z-index:0;width:96px}.pmascot.left{left:0}.pmascot.right{right:0}.pmascot .char{width:96px}
@media (max-width:360px){.prow.off0{transform:translateX(-96px)}.prow.off4{transform:translateX(96px)}}
@media (prefers-reduced-motion:reduce){.pstart{animation:none}}
.sheet{padding:16px;background:#fff}.sheet h1{font-size:20px;margin:0 0 8px}
.sheet-grid,.sheet-names{display:grid;grid-template-columns:60px repeat(7,150px);gap:6px;align-items:center}
.sheet-names span{text-align:center;font-weight:700}.sheet-grid .char{width:150px}

/* ---------------- P4 3D cast: pre-rendered WebP inside .char3d; same state classes; transforms only */
.char.char3d{display:block;position:relative;aspect-ratio:4/5;line-height:0;user-select:none}
.char3d .fig,.char3d .breathe{display:block;position:absolute;inset:0;transform-origin:50% 100%}
.char3d img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;object-position:50% 100%;-webkit-user-drag:none;pointer-events:none}
.char3d .c3-talk{opacity:0}
.char3d.talking .c3-talk{opacity:1}.char3d.talking .c3-main{opacity:0}
.char3d.talking.st-talk .c3-main{opacity:1}
.char3d.talking.c-mochi .c3-main{opacity:1}  /* ZHBA baby has no .c3-talk layer: without this, .talking hides its only image and only the shadow stays */
.char3d .shadow3d{position:absolute;left:22%;right:22%;bottom:-2%;height:6%;border-radius:50%;background:radial-gradient(closest-side,rgba(0,0,0,.18),rgba(0,0,0,0))}
.char3d .breathe{animation:ch-breathe 3.2s ease-in-out infinite}
.char3d.talking .breathe{animation:ch-squash .32s ease-in-out infinite alternate}
.char3d.st-welcome .fig,.char3d.st-idle .fig,.char3d.st-encourage .fig,.char3d.st-thinking .fig{animation:ch-bob 2.6s ease-in-out infinite}
/* P7: ZHBA welcome = sitting, wide-eyed, gently looking around (transform-only; off under reduced motion via the rule below) */
.char3d.c-mochi.st-welcome .fig{transform-origin:50% 90%;animation:zhba-look 3.6s ease-in-out infinite}
@keyframes zhba-look{0%,100%{transform:rotate(0) translateX(0)}25%{transform:rotate(-4deg) translateX(-2%)}50%{transform:rotate(0) translateX(0)}75%{transform:rotate(4deg) translateX(2%)}}
.char3d.st-happy .fig,.char3d.st-complete .fig,.char3d.st-levelup .fig,.char3d.st-achievement .fig,.char3d.st-streak .fig{animation:ch-hop .8s cubic-bezier(.3,1.5,.5,1) infinite}
.char3d.st-sad .fig{animation:ch-shake 2.8s ease-in-out infinite}
.char3d.st-confused .fig{animation:ch-tilt3 2.4s ease-in-out infinite}
@keyframes ch-squash{from{transform:scale(1,1)}to{transform:scale(1.025,.975)}}
@keyframes ch-hop{0%,100%{transform:translateY(0) scale(1,1)}10%{transform:translateY(0) scale(1.06,.94)}45%{transform:translateY(-9%) scale(.97,1.03)}80%{transform:translateY(0) scale(1.04,.96)}}
@keyframes ch-shake{0%,60%,100%{transform:translateX(0) rotate(0)}66%{transform:translateX(-3%) rotate(-2deg)}74%{transform:translateX(3%) rotate(2deg)}82%{transform:translateX(-2%) rotate(-1deg)}90%{transform:translateX(1%)}}
@keyframes ch-tilt3{0%,100%{transform:rotate(0)}50%{transform:rotate(-4deg)}}
@media (prefers-reduced-motion:reduce){.char3d,.char3d *{animation:none!important}}
/* path labels: pill above the dotted course so long titles never sit on the dashes */
.plabel{position:relative;z-index:1}
.plabel small{background:#fff;border-radius:8px;padding:2px 7px;box-shadow:0 1px 3px rgba(0,0,0,.14);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;max-width:120px;word-break:break-word}
.msheet{display:grid;grid-template-columns:repeat(6,170px);gap:8px}.msheet figure{margin:0;display:flex;flex-direction:column;align-items:center;font-weight:700}
/* P5 */
.prow.off4 .plabel{transform:translateX(-22px)}.prow.off0 .plabel{transform:translateX(22px)}
.tabbar{position:fixed;left:0;right:0;bottom:0;z-index:20;display:flex;justify-content:space-around;background:#fff;border-top:2px solid #e5e5e5;padding:6px 4px calc(6px + env(safe-area-inset-bottom))}
.tabbar[hidden]{display:none}
.tabbar a{position:relative;flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;font-size:12px;color:var(--muted);text-decoration:none;padding:4px 0;border-radius:10px;min-height:44px}
.tabbar a span{font-size:22px;line-height:1}
.tabbar a.on{color:#1cb0f6;background:#ddf4ff;font-weight:700}
.tbadge{position:absolute;top:0;right:calc(50% - 22px);background:#ff4b4b;color:#fff;font-style:normal;font-size:11px;font-weight:700;border-radius:9px;padding:1px 5px;min-width:10px;text-align:center}
.tbadge[hidden]{display:none}
body.has-tabs main{padding-bottom:88px}
#p5box{display:flex;flex-direction:column;gap:12px}
#p5box h1{margin:4px 0;font-size:24px}
.due-card{text-align:center;display:flex;flex-direction:column;gap:8px}
.bigdue b{font-size:48px;color:#1cb0f6;display:block;line-height:1.1}.bigdue span{color:var(--muted)}
.btn.off{opacity:.5;pointer-events:none}
.links{display:flex;flex-direction:column;gap:8px}
a.due{text-decoration:none;color:inherit}
.chips{display:flex;flex-wrap:wrap;gap:6px}
.chip{border:2px solid #e5e5e5;background:#fff;border-radius:16px;padding:6px 12px;font-size:14px;min-height:36px;cursor:pointer}
.chip.on{border-color:#1cb0f6;background:#ddf4ff;color:#1899d6;font-weight:700}
.vlist,.mist,.skills{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}
.vrow{display:flex;gap:10px;align-items:flex-start;background:#fff;border:2px solid #e5e5e5;border-radius:14px;padding:10px}
.vrow img,.vpic{width:44px;height:44px;border-radius:10px;flex:none;object-fit:cover}
.vpic{display:flex;align-items:center;justify-content:center;background:#ddf4ff;color:#1899d6;font-weight:800;font-size:20px}
.vmain{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;overflow-wrap:anywhere}
.vex{font-size:14px}
.vact{display:flex;flex-direction:column;gap:4px;align-items:center}
.vact .play{margin:0}
.star{border:0;background:none;font-size:24px;color:#ccc;min-width:44px;min-height:44px;cursor:pointer}.star.on{color:#ffc800}
.badge{display:inline-block;border-radius:8px;padding:0 6px;font-size:12px;background:#eee;color:#555}
.s-new{background:#fff4d6;color:#a26b00}.s-learning{background:#ffe5e5;color:#c0392b}.s-review{background:#ddf4ff;color:#1899d6}.s-mastered{background:#d7ffb8;color:#3d8b00}
.mist li{background:#fff;border:2px solid #e5e5e5;border-radius:14px;padding:10px;display:flex;flex-direction:column;gap:4px}
.skills li{display:flex;gap:8px;align-items:baseline;border-bottom:1px solid #eee;padding:6px 0}.skills li span{min-width:3em}
.onboard{display:flex;flex-direction:column;gap:8px}
.empty{text-align:center;display:flex;flex-direction:column;align-items:center;gap:8px}
.stats.four{grid-template-columns:repeat(4,1fr);gap:6px}.stats.four div{padding:10px 2px}.stats a.due{background:#fff;border-radius:14px;padding:14px;text-align:center;display:flex;flex-direction:column}.stats span{font-size:13px;color:var(--muted)}
/* P6: new exercise types */
.passage{white-space:pre-line;background:#fff8ec;border-radius:12px;padding:12px 14px;line-height:1.6;margin:8px 0;font-size:1.05rem}
.scene{background:#eef6ff;border-radius:12px;padding:10px 12px;margin:8px 0}
.gapped{font-size:1.25rem;letter-spacing:.02em}
.pq{margin:14px 0 6px}
.dl.gap span{color:#999;font-weight:700}
.badge{display:inline-block;align-self:flex-start;background:#ffe9a8;color:#6b4b00;border-radius:999px;padding:3px 10px;font-size:.8rem;font-weight:700}
.rec{display:flex;flex-direction:column;gap:8px;align-items:flex-start;margin:12px 0}
.rec .btn.live{background:#e5484d;color:#fff;animation:rec-pulse 1s ease-in-out infinite}
.rec audio{width:100%;max-width:340px}
@keyframes rec-pulse{50%{box-shadow:0 0 0 8px rgba(229,72,77,.2)}}
.celebrate{position:fixed;inset:0;background:rgba(30,20,10,.55);display:flex;align-items:center;justify-content:center;z-index:50;overflow:hidden}
.celebrate .cbox{background:#fff;border-radius:20px;padding:22px 26px;text-align:center;max-width:320px;animation:pop-in .45s cubic-bezier(.2,1.6,.4,1)}
.celebrate .cbox .char{margin:0 auto}
.confetti i{position:absolute;top:-20px;left:calc(var(--i) * 5.5%);width:10px;height:14px;border-radius:2px;
  background:hsl(calc(var(--i) * 40),85%,60%);animation:confetti 2.4s calc(var(--i) * .07s) ease-in forwards}
@keyframes confetti{to{transform:translateY(110vh) rotate(540deg)}}
@keyframes pop-in{from{transform:scale(.6);opacity:0}}
/* P6: respect the OS "reduce motion" setting — characters stay still, no confetti / pulses / pops */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
  .confetti{display:none}
}

/* P7 social */
.league{display:block;color:inherit;text-decoration:none}
.lb{list-style:none;padding:0;margin:.5rem 0}.lb li{display:flex;gap:.6rem;align-items:center;padding:.5rem .6rem;border-radius:10px}
.lb li span{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lb li i{font-style:normal;color:#555}
.lb li.me{background:#e8f1ff;font-weight:600}.lb.mini li{padding:.25rem .4rem}
.seg{display:flex;gap:.5rem;margin:.5rem 0}.btn.ghost{background:#fff;color:#1f2937;border:1px solid #d1d5db}
.heat{display:grid;grid-template-rows:repeat(7,1fr);grid-auto-flow:column;gap:3px;margin:.5rem 0 1rem}
.heat i{aspect-ratio:1;border-radius:3px;background:#e5e7eb}.heat .h1{background:#bbf7d0}.heat .h2{background:#4ade80}.heat .h3{background:#16a34a}.heat .h4{background:#166534}
.hud.stats{grid-template-columns:repeat(4,1fr)}.links{display:grid;gap:.5rem;margin-top:1rem}
form.row,.row{display:flex!important;flex-direction:row!important;gap:.5rem;margin:.6rem 0;align-items:center}.row input{flex:1;min-width:0;padding:.5rem;border:1px solid #d1d5db;border-radius:10px;font-size:16px}
.fl{list-style:none;padding:0;margin:0}.fl li{display:flex;gap:.4rem;align-items:center;padding:.35rem 0}.fl li span{flex:1;overflow:hidden;text-overflow:ellipsis}
.toggle{display:block;padding:.5rem 0}
.tabbar a{min-width:0}
.toggle input{width:auto;display:inline;margin-right:.4rem}.toggle{display:flex;align-items:center}

/* P9 course switcher */
.ctabs{display:flex;flex-direction:row;gap:6px;margin:4px 0 12px}
.ctabs .crow{flex:1 1 0;min-width:0;display:flex}
.cchip{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;gap:1px;padding:6px 8px;border-radius:14px;border:2px solid #e2e2ea;background:#fff;font:inherit;cursor:pointer;min-height:44px}
.cchip b{font-size:13px;white-space:nowrap}.cchip small{font-size:11px;color:#777;white-space:nowrap}
.cchip.on{border-color:#58cc02;background:#f0fbe6}
.cchip.locked{opacity:.7}
.cchip .cbar{display:block;width:100%;height:6px;border-radius:3px;background:#e8e8ee;overflow:hidden;margin-top:3px}
.cchip .cbar i{display:block;height:100%;border-radius:3px;background:#58cc02}
.cchip .cico{font-size:22px;line-height:1;width:38px;height:38px;display:flex;align-items:center;justify-content:center;border-radius:50%}
.cchip.lv1 .cico{background:#e6f7e6}
.cchip.lv2 .cico{background:#e3f2fd}
.cchip.lv3 .cico{background:#fff3e0}
.cchip.lv0 .cico{background:#f3e8fd}
.clock{background:#fff7e0;border:1px solid #f3d27a;border-radius:12px;padding:10px 12px;font-size:14px;margin:0 0 12px}
.ipa1{margin-left:6px;white-space:nowrap}
.tapword{cursor:pointer;text-decoration:underline dotted}
.punit.soon{opacity:.6;pointer-events:none;text-align:center;border:2px dashed #bbb}

.newtag{display:inline-block;flex:none;align-self:center;font-size:11px;font-weight:700;line-height:1.2;background:#fff3c4;color:#9a6700;border-radius:6px;padding:2px 6px;margin-left:6px;vertical-align:middle}
.opt .newtag{flex:none}
.hintzh{cursor:pointer;border-bottom:1px dashed #8250df;background:transparent;font:inherit;color:inherit;padding:0}
.hintpop{position:absolute;z-index:30;background:#fff;border:1px solid #d0d7de;border-radius:12px;padding:10px 12px;box-shadow:0 8px 24px rgba(0,0,0,.14);min-width:148px;max-width:240px}
.hintpop b{display:block}
.intro .word img.pic{width:72px;height:72px;border-radius:10px;object-fit:contain}

/* boot splash (once per session) */
.boot{position:fixed;inset:0;z-index:9999;background:#000;display:flex;align-items:center;justify-content:center}
.boot[hidden]{display:none}
.boot video{width:100%;height:100%;object-fit:cover}
.boot-skip{position:absolute;top:calc(env(safe-area-inset-top,0px) + 12px);right:12px;padding:6px 14px;border:0;border-radius:16px;background:rgba(0,0,0,.55);color:#fff;font-size:15px}

/* ---------------- handwriting practice on teach cards (L0 + all courses) */
.teach-main{display:flex;gap:12px;align-items:flex-start}
.teach-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:10px}
.ex-body.teach{user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}/* hw-noselect-20261111 */
.ex-body.teach input{user-select:text;-webkit-user-select:text;-webkit-touch-callout:default}
.hw-panel{flex:0 0 150px;width:150px;background:#fff;border:1px solid #d0d7de;border-radius:14px;padding:10px;display:flex;flex-direction:column;gap:8px;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;touch-action:none}
.hw-panel .btn{width:100%}
.hw-title{font-size:14px;font-weight:700;margin:0}
.hw-demo{width:100%;height:auto;display:block;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
.hw-demo text{fill:none;stroke:#1f6feb;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:400;stroke-dashoffset:400;animation:hw-draw 4s linear infinite}
.hw-demo path{fill:none;stroke:#1f6feb;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}/* hw-strokes-20261111 */
.hw-count{font-size:14px;font-weight:600;text-align:center;margin:0}
.hw-count.done{color:#2da44e}
.hw-board{background:#fff;border:1px solid #d0d7de;border-radius:14px;padding:10px;display:flex;flex-direction:column;gap:8px;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;touch-action:none}
.hw-canvas{width:100%;height:140px;border:1px dashed #b6c2cf;border-radius:10px;background:#fffdf5;touch-action:none;display:block;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
.hw-row{display:flex;gap:8px}
.hw-row .btn{flex:1;min-height:44px;font-size:15px}
.hw-hint{font-size:13px;color:var(--muted);margin:0;text-align:center}
@keyframes hw-draw{0%{stroke-dashoffset:400;opacity:1}12%{stroke-dashoffset:0;opacity:1}80%{stroke-dashoffset:0;opacity:1}95%,100%{stroke-dashoffset:0;opacity:0}}
@media (prefers-reduced-motion:reduce){.hw-demo text{animation:none;stroke-dashoffset:0}}
@media (max-width:380px){.hw-panel{flex-basis:132px;width:132px}}

/* "下次写": quiet text-style button under "开始写", does not compete with it */
.hw-panel .hw-next{background:transparent;color:var(--muted);border-color:transparent;font-size:14px;font-weight:500}
