:root{--navy:#14213d;--ink:#182136;--cream:#f7f3ea;--paper:#fffdfa;--coral:#f27f62;--coral-text:#a95945;--peach:#f7c9b6;--cyan:#4bbac5;--sky:#bfe4e7;--yellow:#f5c95d;--muted:#636974;--line:#dedbd3;--shadow:0 18px 50px rgba(20,33,61,.1);--status-focus:#b3472a;--status-strong:#0d7568}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--cream);color:var(--ink);font-family:"DM Sans",sans-serif}
button{font:inherit;color:inherit}
button:focus-visible{outline:3px solid var(--yellow);outline-offset:3px}
.app-shell{min-height:100vh;display:flex;flex-direction:column}
.topbar{height:86px;display:flex;align-items:center;justify-content:space-between;padding:0 clamp(24px,6vw,88px);border-bottom:1px solid rgba(20,33,61,.1);background:rgba(247,243,234,.92);position:sticky;top:0;z-index:10;backdrop-filter:blur(12px)}
.brand{border:0;background:none;display:flex;align-items:center;gap:12px;font-family:Nunito,sans-serif;font-size:20px;font-weight:900;cursor:pointer;text-align:left}
.brand small{display:block;font:700 9px "DM Sans";letter-spacing:2px;text-transform:uppercase;color:var(--muted)}
.brand-mark{width:40px;height:40px;border-radius:50% 50% 50% 14px;background:var(--coral);color:var(--navy);display:grid;place-items:center;font-size:21px;transform:rotate(-6deg)}
.header-actions{display:flex;align-items:center;gap:16px}.streak{font-size:12px;color:var(--muted);padding:8px 14px;border:1px solid var(--line);border-radius:99px}.streak span{color:var(--coral-text);margin-right:5px}.streak strong{color:var(--ink)}
.icon-button,.quit-button{border:0;background:var(--navy);color:white;width:38px;height:38px;border-radius:50%;cursor:pointer;font-size:19px}
main{flex:1}.screen{width:min(1160px,calc(100% - 40px));margin:0 auto;padding:72px 0 86px}
.home-screen{padding-top:86px}.hero{max-width:820px;margin-bottom:0}.eyebrow{display:inline-flex;align-items:center;gap:9px;text-transform:uppercase;letter-spacing:2.2px;font-size:10px;font-weight:800;color:var(--muted)}.eyebrow>span{width:23px;height:2px;background:var(--coral)}
h1,h2,h3{font-family:Nunito,sans-serif;margin:0;color:var(--navy)}h1{font-size:clamp(54px,8vw,92px);line-height:.93;letter-spacing:-4px;margin:21px 0 25px}h1 em{font-style:normal;color:var(--coral)}.hero>p{font-size:18px;line-height:1.7;color:var(--muted);max-width:610px}
.hero-actions{display:flex;gap:12px;margin-top:32px}.primary,.secondary{border:0;border-radius:8px;padding:14px 22px;font-weight:800;cursor:pointer}.primary{background:var(--navy);color:white;box-shadow:0 8px 18px rgba(20,33,61,.15)}.primary:hover{background:#223456}.secondary{background:transparent;border:1.5px solid var(--navy)}.large{padding:17px 25px}.primary span{margin-left:20px}
.test-note{display:flex;align-items:center;gap:12px;margin-top:19px;font-size:11px;color:var(--muted)}.test-note span{font-weight:800;color:var(--coral)}.test-note i{width:3px;height:3px;border-radius:50%;background:#aaa}

/* Daily Six — the primary hero action. Warm/coral rather than the serious navy of the exam
   banner below it: this is meant to feel like an inviting daily ritual (Wordle-style), not
   another timed obligation. Completing it is never a gate — #daily-six-done only swaps the
   copy, every other practice mode stays fully reachable via the secondary actions underneath. */
/* Three side-by-side choices, with the Daily Six deliberately widest and the only one carrying
   the warm gradient + solid primary button — a reluctant child scanning this row should land on
   the 3-minute option first, with the longer routes present but visibly quieter. */
.action-tiles{display:grid;grid-template-columns:1.35fr 1fr 1fr;gap:16px;margin:34px 0 70px;align-items:stretch}
.action-tile{background:var(--paper);border:1px solid var(--line);border-radius:14px;padding:24px 26px 26px;display:flex;flex-direction:column}
.action-tile.is-primary{background:linear-gradient(135deg,#fff1ea,var(--paper));border:1.5px solid #f6cdb8}
.action-tile>div{display:flex;flex-direction:column;flex:1}
.action-tile-badge{display:inline-block;align-self:flex-start;font:800 11px "DM Sans";letter-spacing:.5px;text-transform:uppercase;background:var(--cream);color:var(--navy);padding:6px 12px;border-radius:99px;margin-bottom:16px}
.action-tile-copy{font-size:13px;color:var(--muted);margin:0 0 12px;line-height:1.55}
/* Pushed to the bottom so every tile's button sits on the same line regardless of copy length. */
.action-tile-meta{display:flex;align-items:center;flex-wrap:wrap;gap:8px;font-size:10px;color:var(--muted);margin:0 0 16px;margin-top:auto}
.action-tile-meta i{width:3px;height:3px;border-radius:50%;background:#c9c4bb;flex:none}
.daily-six-card{border-radius:14px}
.daily-six-badge{display:inline-flex;align-self:flex-start;align-items:center;gap:6px;font:800 11px "DM Sans";letter-spacing:.5px;text-transform:uppercase;background:var(--coral);color:white;padding:6px 12px;border-radius:99px;margin-bottom:16px}
.daily-six-copy{font-size:13px;color:var(--muted);margin:0 0 12px;line-height:1.55}
.daily-six-done-copy{color:#26815b;font-weight:700}
@media(max-width:900px){.action-tiles{grid-template-columns:1fr}}
.exam-banner{display:flex;align-items:center;justify-content:space-between;gap:24px;background:var(--navy);color:white;border-radius:14px;padding:28px 34px;margin:0 0 40px}
.exam-banner-eyebrow{display:block;font-size:9px;letter-spacing:1.8px;font-weight:800;color:var(--yellow);margin-bottom:6px}
.exam-banner h3{color:white;font-size:24px;margin:0 0 6px}
.exam-banner p{color:#b7c0cf;font-size:12px;margin:0;max-width:420px}
.exam-banner .primary{background:var(--coral);flex:none}
.exam-banner .primary:hover{background:#e06a4d}
.exam-rules{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin:8px 0 30px}
.exam-rule{background:var(--paper);border:1px solid var(--line);border-radius:12px;padding:22px;text-align:center}
.exam-rule strong{display:block;font:900 34px Nunito;color:var(--coral)}
.exam-rule span{font-size:11px;color:var(--muted);line-height:1.4}
.exam-notes{margin:0 0 30px;padding-left:20px;color:var(--muted);font-size:13px;line-height:1.7}
.exam-notes li{margin-bottom:8px}
.exam-timer-wrap{text-align:center;padding:0 14px;border-left:1px solid var(--line);border-right:1px solid var(--line)}
.exam-timer-wrap small{display:block;font-size:8px;letter-spacing:1.4px;color:var(--muted)}
.exam-timer-wrap strong{font:900 22px Nunito;font-variant-numeric:tabular-nums}
.exam-timer-wrap strong.urgent{color:var(--coral);animation:examPulse 1s infinite}
@keyframes examPulse{0%,100%{opacity:1}50%{opacity:.45}}
.ghost-indicator{text-align:center;padding:0 14px;border-left:1px solid var(--line);border-right:1px solid var(--line)}
.ghost-indicator small{display:block;font-size:8px;letter-spacing:1.4px;color:var(--muted)}
.ghost-indicator strong{font:900 20px Nunito;color:var(--muted)}

/* Celebration effects (js/celebrate.mjs). The most-repeated moment in the app — a correct
   answer — used to produce small grey text and nothing else; this is what makes it feel like
   something happened. bumpScore/floatPoints/confetti all check prefers-reduced-motion in JS
   before ever adding these classes, so nothing here needs its own reduced-motion guard beyond
   the visual side effect being skipped upstream. */
.live-score strong.score-bump{animation:scoreBump .5s ease}
@keyframes scoreBump{0%{transform:scale(1)}35%{transform:scale(1.35);color:var(--status-strong)}100%{transform:scale(1)}}
.float-points{position:fixed;z-index:80;pointer-events:none;font:900 15px Nunito;color:var(--status-strong);animation:floatPoints 1.1s ease-out forwards}
.float-points.is-good{color:var(--status-strong)}
@keyframes floatPoints{0%{opacity:0;transform:translate(-50%,4px) scale(.9)}18%{opacity:1;transform:translate(-50%,-6px) scale(1.05)}100%{opacity:0;transform:translate(-50%,-46px) scale(1)}}
.confetti-layer{position:fixed;inset:0;pointer-events:none;z-index:90;overflow:hidden}
.confetti-layer i{position:absolute;top:-16px;width:9px;height:14px;border-radius:2px;opacity:.92;animation-name:confettiFall;animation-timing-function:cubic-bezier(.4,.1,.6,.9);animation-fill-mode:forwards}
@keyframes confettiFall{0%{transform:translateY(-16px) rotate(0deg);opacity:.95}100%{transform:translateY(108vh) rotate(340deg);opacity:0}}

/* Beat Your Ghost — a live overtake toast mid-quiz, and a two-bar "then vs now" race on the
   results screen. The only competitive mechanic that's safe for this audience: the opponent is
   always the child's own past attempt, never another pupil. */
.ghost-toast{position:fixed;top:20px;left:50%;transform:translateX(-50%);background:var(--navy);color:white;padding:12px 22px;border-radius:99px;font:800 13px "DM Sans";box-shadow:var(--shadow);z-index:95;animation:ghostToastIn .4s ease,ghostToastOut .4s ease 1.8s forwards}
@keyframes ghostToastIn{0%{opacity:0;transform:translate(-50%,-14px)}100%{opacity:1;transform:translate(-50%,0)}}
@keyframes ghostToastOut{0%{opacity:1}100%{opacity:0;transform:translate(-50%,-14px)}}
.ghost-summary{background:var(--paper);border:1.5px solid var(--line);border-radius:12px;padding:22px 26px;margin:0 0 18px}
.ghost-summary-head{display:flex;align-items:center;gap:8px;margin-bottom:16px}
.ghost-summary-icon{font-size:20px}
.ghost-summary-head small{font-size:9px;letter-spacing:1.6px;font-weight:800;color:var(--muted)}
.ghost-race{display:flex;flex-direction:column;gap:10px;margin-bottom:14px}
.ghost-race-row{display:flex;align-items:center;gap:12px}
.ghost-race-label{flex:0 0 160px;font-size:11px;font-weight:700;color:var(--muted);white-space:nowrap}
.ghost-race-track{flex:1;height:10px;background:#ece7db;border-radius:99px;overflow:hidden}
.ghost-race-bar{display:block;height:100%;width:0;border-radius:99px;transition:width .9s cubic-bezier(.2,.8,.3,1)}
.ghost-race-bar.is-then{background:var(--muted)}
.ghost-race-bar.is-now{background:var(--coral)}
.ghost-outcome{font-size:13px;margin:0;color:var(--ink)}
.ghost-outcome.is-beaten{color:#1f6b40;font-weight:700}
.ghost-outcome.is-tied{color:#8a6416;font-weight:700}
.ghost-outcome.is-behind{color:var(--muted)}
@media(prefers-reduced-motion:reduce){.ghost-toast{animation:none!important}.ghost-race-bar{transition:none!important}}
@media(max-width:640px){.ghost-race-row{flex-direction:column;align-items:stretch;gap:4px}.ghost-race-label{flex:none}}

/* Earned feed — badge/personal-best cards shown on the results screen at the moment they're
   won, instead of being discoverable only by opening the dashboard. */
.earned-feed{display:flex;flex-direction:column;gap:10px;margin-top:16px}
.earned-card{display:flex;align-items:center;gap:14px;background:linear-gradient(135deg,#fff7ec,var(--paper));border:1.5px solid var(--yellow);border-radius:12px;padding:14px 18px;animation:earnedIn .4s ease both}
@keyframes earnedIn{0%{opacity:0;transform:translateY(8px) scale(.98)}100%{opacity:1;transform:translateY(0) scale(1)}}
.earned-icon{font-size:26px;flex:none}
.earned-body{flex:1}.earned-body strong{display:block;font:800 15px Nunito}.earned-body small{color:var(--muted);font-size:11px}
.earned-tag{font-size:9px;font-weight:800;letter-spacing:.6px;text-transform:uppercase;background:var(--yellow);color:#5a3d05;padding:5px 9px;border-radius:9px;white-space:nowrap}

/* Fix-It Five — re-serving exactly what a child just missed, and reporting the repair.
   Cyan-tinted to visually tie to the Smarty Pants helper (same association, "get help right
   here"); the completion card uses the app's existing success-green instead. */
.fixit-offer,.fixit-summary,.dailysix-summary{display:flex;align-items:center;gap:18px;border-radius:12px;padding:20px 26px;margin:0 0 18px}
.fixit-offer{background:#e8f6f7}
.fixit-summary{background:#e3f3ee}
.dailysix-summary{background:#fff1ea}
.fixit-icon,.dailysix-icon{font-size:30px;flex:none}
.fixit-offer>div,.fixit-summary>div,.dailysix-summary>div{flex:1}
.fixit-offer small,.fixit-summary small,.dailysix-summary small{font-size:9px;letter-spacing:1.6px;font-weight:800;color:var(--muted)}
.fixit-offer h3,.fixit-summary h3,.dailysix-summary h3{font-size:18px;margin:4px 0}
.fixit-offer p,.fixit-summary p,.dailysix-summary p{font-size:12px;margin:0;color:#3d5453}
.fixit-summary p{color:#2f5c50}
.dailysix-summary p{color:#8a4a2f}
.fixit-offer .primary{flex:none}
@media(max-width:640px){.fixit-offer,.fixit-summary,.dailysix-summary{flex-direction:column;align-items:flex-start}.fixit-offer .primary{width:100%}}
@media(prefers-reduced-motion:reduce){.live-score strong.score-bump,.float-points,.confetti-layer i,.earned-card{animation:none!important}}
.home-grid{display:grid;grid-template-columns:1.15fr 1fr 1fr;gap:18px}.home-grid article{min-height:290px;border-radius:12px;padding:28px;position:relative}.navy-card{background:var(--navy);color:white}.card-heading{display:flex;gap:12px;align-items:center;font:800 14px Nunito}.card-heading small{font:400 10px "DM Sans";display:block;color:#aeb8c9;margin-top:3px}.mini-icon{width:34px;height:34px;border-radius:50%;display:grid;place-items:center;background:rgba(255,255,255,.12);color:var(--yellow)}
.progress-card{display:flex;flex-direction:column}
.overall-ring{width:112px;height:112px;border-radius:50%;position:relative;display:grid;place-content:center;text-align:center;margin:20px auto 13px;background:conic-gradient(var(--coral) calc(var(--pct,0)*1%),rgba(255,255,255,.12) 0)}.overall-ring::before{content:"";position:absolute;inset:7px;border-radius:50%;background:var(--navy)}.overall-ring strong,.overall-ring small{position:relative;z-index:1}.overall-ring strong{font:900 30px Nunito}.overall-ring small{font-size:9px;color:#aeb8c9}
/* Sits between the ring and the subject split so the percentage is never read alone. Deliberately
   quiet — it frames the number, it does not compete with it. */
.link-button{min-height:24px}
/* WCAG 2.2 2.5.8 — a standalone control needs a 24px target. Inline links inside a sentence are
   exempt; these are not, they sit on their own. */
footer a{display:inline-block;min-height:24px;line-height:24px;padding:0 4px}
.progress-note{margin:0 0 14px;text-align:center;font-size:11px;font-weight:700;color:#cfd6e2;line-height:1.4}
.mini-stats{display:flex;justify-content:center;gap:38px;text-align:center}.mini-stats span{font-size:9px;color:#aeb8c9}.mini-stats b{font:800 16px Nunito;display:block;color:white}.text-button{background:none;border:0;cursor:pointer;font-weight:800;font-size:11px}.text-button.light{color:white;margin-top:auto;padding-top:16px;align-self:flex-end}
.feature-card{display:flex;flex-direction:column;justify-content:flex-end;overflow:hidden}.feature-card.peach{background:var(--peach)}.feature-card.blue{background:var(--sky)}.feature-icon{position:absolute;top:22px;right:25px;font:900 65px Nunito;color:rgba(20,33,61,.16);transform:rotate(-8deg)}.feature-card small,.subject-choice small,.panel-title small,.dashboard-summary small{font-size:9px;letter-spacing:1.8px;font-weight:800}.feature-card h3{font-size:22px;margin:7px 0}.feature-card p{font-size:12px;line-height:1.55;max-width:200px;margin:0}.round-button{position:absolute;right:22px;bottom:22px;width:38px;height:38px;border-radius:50%;border:0;background:var(--navy);color:white;cursor:pointer}
footer{text-align:center;border-top:1px solid var(--line);padding:22px;font-size:10px;letter-spacing:1.5px;text-transform:uppercase;color:var(--muted)}footer span{color:var(--coral-text)}
.compact-screen{max-width:1000px}.back-link{border:0;background:none;font-size:12px;font-weight:700;cursor:pointer;padding:0;margin-bottom:48px}.section-intro{text-align:center;margin-bottom:44px}.section-intro h1,.section-intro h2{font-size:48px;letter-spacing:-2px;margin:12px 0 8px}.section-intro p{color:var(--muted)}
.subject-grid{display:grid;grid-template-columns:1fr 1fr;gap:22px}.subject-choice{border:0;min-height:360px;border-radius:14px;padding:35px;text-align:left;cursor:pointer;display:flex;flex-direction:column;justify-content:flex-end;position:relative;overflow:hidden}.english-choice{background:var(--peach)}.maths-choice{background:var(--sky)}.choice-art{position:absolute;right:35px;top:10px;font:900 130px Nunito;color:rgba(20,33,61,.13);transform:rotate(-7deg)}.subject-choice strong{font:900 28px Nunito;margin:8px 0 20px}.subject-choice em{font-style:normal;font-size:12px;font-weight:800}
.topics-screen{max-width:1000px}.topic-hero{display:flex;align-items:center;justify-content:space-between;background:var(--navy);color:white;border-radius:14px;padding:38px 42px;margin-bottom:16px;overflow:hidden}.topic-hero h2{color:white;font-size:42px;margin:10px 0 5px}.topic-hero p{color:#b7c0cf;font-size:13px;max-width:610px}.topic-hero-art{font:900 92px Nunito;color:var(--coral);transform:rotate(-8deg);opacity:.85}.all-topics-card{width:100%;border:0;background:var(--peach);border-radius:12px;padding:24px 28px;display:flex;align-items:center;text-align:left;cursor:pointer}.all-topics-card span{display:flex;flex-direction:column}.all-topics-card small,.topic-menu-heading{font-size:9px;letter-spacing:1.6px;font-weight:800}.all-topics-card strong{font:900 22px Nunito;margin:5px 0}.all-topics-card em{font-style:normal;font-size:11px;color:var(--muted)}.all-topics-card b{margin-left:auto;width:40px;height:40px;border-radius:50%;display:grid;place-items:center;background:var(--navy);color:white}.topic-menu-heading{display:flex;justify-content:space-between;margin:35px 2px 13px;color:var(--muted)}.topic-menu{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}.topic-choice{border:1px solid var(--line);background:var(--paper);border-radius:10px;padding:18px;text-align:left;cursor:pointer;min-height:96px;display:flex;flex-direction:column;justify-content:space-between}.topic-choice:hover{border-color:var(--coral);box-shadow:0 8px 20px rgba(20,33,61,.08)}.topic-choice strong{font:800 14px Nunito}.topic-choice span{display:flex;justify-content:space-between;color:var(--muted);font-size:9px}.topic-choice span b{color:var(--coral)}
.topic-choice.recommended{border-color:var(--coral);background:#fff4f0}
.topic-recommended{margin-bottom:6px}
.quiz-screen{max-width:900px;padding-top:38px}.quiz-top{display:flex;align-items:center;gap:24px;margin-bottom:36px}.quit-button{background:white;color:var(--ink);border:1px solid var(--line)}.quiz-progress-wrap{flex:1}.quiz-meta{display:flex;justify-content:space-between;font-size:11px;margin-bottom:8px}.quiz-meta span{text-transform:uppercase;letter-spacing:1.3px;font-weight:800}.progress-track{height:5px;background:#ddd9d0;border-radius:9px;overflow:hidden}.progress-track span{height:100%;display:block;background:var(--coral);width:0;transition:width .3s}.live-score{text-align:center}.live-score small{display:block;font-size:8px;letter-spacing:1.4px;color:var(--muted)}.live-score strong{font:900 22px Nunito}
.question-card{background:var(--paper);border:1px solid var(--line);box-shadow:var(--shadow);border-radius:14px;padding:clamp(26px,5vw,52px)}.question-label{display:flex;gap:10px;align-items:center;font-size:10px;text-transform:uppercase;letter-spacing:1.3px;color:var(--muted)}#subject-pill,.subject-pill{background:var(--peach);padding:6px 10px;border-radius:4px;color:var(--ink);font-weight:800}.question-card h2{font-size:clamp(25px,4vw,38px);line-height:1.22;margin:22px 0 9px;letter-spacing:-.7px}.instruction{font-size:12px;color:var(--muted);margin-bottom:26px}.answers{display:grid;gap:10px}.answer{border:1.5px solid var(--line);background:white;border-radius:9px;padding:15px 18px;display:flex;align-items:center;gap:14px;text-align:left;cursor:pointer;transition:.15s}.answer:hover{border-color:var(--cyan);transform:translateX(3px)}.answer.selected{border-color:var(--navy);background:#f0f2f5}.answer.correct{border-color:#42a67a;background:#eaf7f1}.answer.correct::after{content:"✓";margin-left:auto;color:#26815b;font-weight:800;font-size:16px}.answer.wrong{border-color:var(--coral);background:#fff0ec}.answer.wrong::after{content:"✗";margin-left:auto;color:var(--coral);font-weight:800;font-size:16px}.answer-key{display:grid;place-items:center;width:26px;height:26px;border-radius:50%;background:var(--cream);font-weight:800;font-size:11px;flex:none}.feedback{min-height:28px;margin:16px 0 5px;font-size:12px;font-weight:700}.feedback.good{color:#26815b}.feedback.bad{color:#bd4e36}
.wrong-explanation{background:var(--cream);border-radius:9px;padding:13px 17px;margin:0 0 14px}
.wrong-explanation .label{display:block;font:800 9px "DM Sans";letter-spacing:1.3px;text-transform:uppercase;color:var(--muted);margin-bottom:6px}
.wrong-explanation .body{display:block;font-size:13px;line-height:1.55;color:var(--ink)}
.wrong-explanation .source{display:block;font-size:10px;color:var(--muted);margin-top:7px}.next-button{display:block;margin-left:auto;min-width:150px}.next-button:disabled{opacity:.4;cursor:not-allowed}
.loading-state{text-align:center;color:var(--muted);font-size:13px;padding:60px 20px}
.passage-panel{background:var(--paper);border:1px solid var(--line);border-radius:12px;padding:18px 22px;margin-bottom:16px}.passage-panel summary{cursor:pointer;list-style:none;font-weight:800;font-size:12px;color:var(--navy)}.passage-panel summary::-webkit-details-marker{display:none}.passage-panel[open] summary::after{content:" (collapse)";color:var(--muted);font-weight:400;font-size:10px}.passage-panel h3{font-size:16px;margin:10px 0 8px}.passage-body{font-size:13px;line-height:1.8;color:var(--ink);max-height:260px;overflow-y:auto;padding-right:6px}.line-num{display:inline-block;width:22px;color:var(--muted);font-size:10px;user-select:none}.blank-active{background:var(--yellow);padding:1px 6px;border-radius:4px;font-weight:800}.blank-placeholder{color:var(--muted);font-weight:700}
.question-media{margin:14px 0}.question-table{border-collapse:collapse;font-size:13px}.question-table th,.question-table td{border:1px solid var(--line);padding:8px 12px;text-align:left}.question-table th{background:var(--cream)}.question-diagram{max-width:320px}.question-diagram svg{width:100%;height:auto}.question-image{max-width:100%;border-radius:8px}
.free-response{margin:8px 0 16px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}.free-response input{flex:1;min-width:140px;border:1.5px solid var(--line);border-radius:9px;padding:13px 16px;font-size:15px}.free-response input:disabled{background:var(--cream)}.free-response #free-response-unit,.free-response .free-response-unit{font-size:13px;color:var(--muted);font-weight:700}.free-response #free-response-feedback,.free-response .free-response-feedback{flex-basis:100%;font-size:12px;color:var(--navy);font-weight:700;margin:0}
.helper-button{border:0;background:#e8f6f7;color:var(--navy);border-radius:99px;padding:10px 15px;font-size:11px;font-weight:800;cursor:pointer;margin:3px 0 13px}.helper-button span{color:var(--coral);margin-right:5px}.helper{background:#f2f8f7;border:1px solid #c9e3e3;border-radius:12px;margin:12px 0 16px;overflow:hidden}.helper-heading{display:flex;align-items:center;gap:10px;padding:13px 15px;border-bottom:1px solid #d6e8e6}.helper-face{position:relative;width:40px;height:34px;flex:none}.pants-mascot{background:var(--coral);border-radius:6px 6px 12px 12px;clip-path:polygon(0 8%,100% 8%,92% 100%,62% 100%,50% 65%,38% 100%,8% 100%)}.pants-mascot:before,.pants-mascot:after{content:"";position:absolute;top:10px;width:5px;height:5px;border-radius:50%;background:var(--navy)}.pants-mascot:before{left:11px}.pants-mascot:after{right:11px}.pants-mascot i{position:absolute;left:17px;top:19px;width:7px;height:4px;border-bottom:2px solid var(--navy);border-radius:0 0 8px 8px}.helper-heading strong{display:block;font:800 13px Nunito}.helper-heading small{display:block;color:var(--muted);font-size:9px}.helper-heading button{margin-left:auto;border:0;background:none;font-size:19px;cursor:pointer}.helper-messages{padding:14px 15px;max-height:260px;overflow:auto}.helper-message{font-size:12px;line-height:1.55;border-radius:9px;padding:10px 12px;margin:0 0 9px;white-space:pre-wrap}.helper-message.smarty{background:white;border:1px solid #dbe9e7;margin-right:25px}.helper-message.pupil{background:var(--navy);color:white;margin-left:45px}.helper-message.loading{color:var(--muted)}.helper-form{display:flex;padding:10px;border-top:1px solid #d6e8e6;background:white}.helper-form input{flex:1;border:0;outline:0;padding:8px;font:12px "DM Sans"}.helper-form button{border:0;background:var(--navy);color:white;width:34px;height:34px;border-radius:50%;cursor:pointer}.helper-hint{margin:0;padding:0 15px 12px;font-size:10.5px;color:var(--muted);background:white}
.results-screen{max-width:1060px}.result-hero{background:var(--navy);color:white;border-radius:14px;padding:42px 48px;display:flex;align-items:center;gap:28px;position:relative;overflow:hidden}.result-star{font-size:34px;color:var(--yellow)}.result-hero h2{color:white;font-size:40px;margin:7px 0}.result-hero p{color:#aeb8c9;margin:0}.score-circle{margin-left:auto;border:7px solid var(--coral);width:130px;height:130px;border-radius:50%;display:grid;place-content:center;text-align:center;flex:none}.score-circle strong{font:900 34px Nunito}.score-circle small{font-size:10px;color:#aeb8c9}.result-layout,.dashboard-panels{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:18px}.panel{background:var(--paper);border:1px solid var(--line);border-radius:12px;padding:27px}.panel-title{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:22px}.panel-title h3{font-size:21px;margin-top:5px}.panel-title>span{font-size:10px;color:var(--muted)}.subject-result,.topic-row{margin-bottom:17px}.bar-label{display:flex;justify-content:space-between;font-size:11px;margin-bottom:7px}.bar-label strong{font-size:12px}.stat-bar{height:6px;background:#e7e3dc;border-radius:5px;overflow:hidden}.stat-bar span{display:block;height:100%;background:var(--cyan);width:0}.stat-bar.coral span{background:var(--coral)}.topic-row.focus .stat-bar span{background:var(--status-focus)}.topic-row.focus .bar-label:after{content:"🌱 GROWING";font-size:7px;background:#fde1d8;color:var(--status-focus);padding:3px 6px;border-radius:9px;margin-left:6px}.topic-row.strong .stat-bar span{background:var(--status-strong)}.topic-row.strong .bar-label:after{content:"🚀";font-size:10px;margin-left:6px}.topic-row.insufficient .stat-bar.track-only{background:transparent;border:1px dashed var(--line)}.topic-row.insufficient .bar-label strong{color:var(--muted);font-weight:700}.bar-label span:first-child{margin-right:auto}.full{width:100%;margin-top:12px}
.coach-card{display:flex;align-items:center;gap:18px;background:var(--yellow);border-radius:12px;padding:23px 27px;margin-top:18px}.coach-mascot{font-size:34px}.coach-card>div{flex:1}.coach-card small,.recommendations small{font-size:9px;letter-spacing:1.6px;font-weight:800}.coach-card h3{font-size:19px;margin:4px 0}.coach-card p{font-size:11px;margin:0;color:#56523f}
.dashboard-screen{max-width:1100px}.dashboard-title{text-align:left}.dashboard-summary{display:grid;grid-template-columns:1.25fr repeat(3,1fr);gap:12px;margin-bottom:18px}.dashboard-summary article,.dashboard-summary button.dash-tile{background:var(--paper);border:1px solid var(--line);padding:24px;border-radius:10px}.dashboard-summary .summary-primary,.dashboard-summary button.dash-tile.summary-primary{background:var(--navy);color:white}
button.dash-tile{font-family:inherit;text-align:left;cursor:pointer;transition:border-color .15s,box-shadow .15s}
button.dash-tile:hover{border-color:var(--coral)}
button.dash-tile:focus-visible{outline:2px solid var(--navy);outline-offset:2px}
button.dash-tile.is-active{border-color:var(--navy);box-shadow:0 0 0 1.5px var(--navy) inset}
button.dash-tile.summary-primary.is-active{border-color:var(--coral);box-shadow:0 0 0 1.5px var(--coral) inset}
.trend-arrow-slot .trend-arrow{font-size:.55em;vertical-align:middle}.dashboard-summary strong{font:900 31px Nunito;display:block;margin:10px 0 7px}.dashboard-summary p{font-size:10px;color:var(--muted);margin:0}.summary-primary p{color:#aeb8c9}.dashboard-panels{grid-template-columns:1.3fr .7fr}.legend{display:flex;align-items:center;gap:5px}.legend i{width:7px;height:7px;background:var(--status-focus);border-radius:50%}.history-item{display:grid;grid-template-columns:42px 1fr auto;align-items:center;gap:12px;padding:14px 0;border-bottom:1px solid var(--line);width:100%;background:none;border-left:0;border-right:0;border-top:0;font-family:inherit;text-align:left;cursor:pointer}.history-item:hover .history-score{color:var(--coral)}.history-item:focus-visible{outline:2px solid var(--navy);outline-offset:-2px}.history-icon{width:38px;height:38px;border-radius:50%;background:var(--cream);display:grid;place-items:center;font-weight:800}.history-item b{display:block;font-size:12px}.history-item small{font-size:9px;color:var(--muted)}.history-score{font:900 18px Nunito}.empty-state{text-align:center;background:white;border:1px solid var(--line);border-radius:14px;padding:70px 20px}.empty-state>span{font-size:42px;color:var(--coral)}.empty-state h3{font-size:28px}.empty-state p{color:var(--muted);margin-bottom:25px}.hidden{display:none!important}
.recommendations{background:#e8f6f7;border:1px solid #c9e3e3;border-radius:12px;padding:23px 26px;margin-bottom:18px;display:flex;align-items:center;gap:25px}.recommendations>div:first-child{flex:1}.recommendations h3{font-size:20px;margin:5px 0}.recommendations p{font-size:10px;color:var(--muted);margin:0}.recommendations #recommendation-buttons{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end}.recommendation-button{border:1px solid var(--navy);background:white;border-radius:8px;padding:10px 13px;cursor:pointer;font-size:10px;font-weight:800}.recommendation-button span{display:block;color:var(--coral);font-size:8px;margin-top:2px}
.most-improved{background:#e9f7f0;border:1px solid #bfe4d0;border-radius:12px;padding:23px 26px;margin-bottom:18px;display:flex;align-items:center;gap:20px}.most-improved-icon{font-size:30px}.most-improved small{font-size:9px;letter-spacing:1.6px;font-weight:800;color:var(--status-strong)}.most-improved h3{font-size:19px;margin:5px 0;color:var(--navy)}.most-improved p{font-size:12px;color:#2a6b4c;margin:0;font-weight:700;font-variant-numeric:tabular-nums}
.weekly-digest{background:linear-gradient(135deg,#fff1ea,var(--paper));border:1.5px solid #f6cdb8;border-radius:12px;padding:20px 26px;margin-bottom:18px;display:flex;align-items:center;gap:18px}.weekly-digest-icon{font-size:26px}.weekly-digest small{font-size:9px;letter-spacing:1.6px;font-weight:800;color:var(--coral)}.weekly-digest p{font-size:14px;font-weight:700;color:var(--navy);margin:4px 0 0;font-variant-numeric:tabular-nums}
.speed-insight{background:var(--paper);border:1px solid var(--line);border-radius:12px;padding:18px 24px;margin-bottom:18px;display:flex;flex-direction:column;gap:10px}
.speed-insight-row{display:flex;align-items:center;gap:14px}
.speed-insight-icon{font-size:20px;flex:none}
.speed-insight-row p{margin:0;font-size:12px;color:var(--ink);line-height:1.5}
.data-panel{margin-top:18px;display:flex;align-items:center;gap:30px}.data-panel>div:first-child{flex:1}.data-panel h3{margin:5px 0}.data-panel p{color:var(--muted);font-size:11px;margin:5px 0}.data-actions{display:flex;gap:9px}.file-button{display:inline-flex;align-items:center;cursor:pointer}.file-button input{display:none}.data-status{min-width:120px;color:#26815b!important;font-weight:700}
.topic-group{margin-bottom:20px}.topic-group h4{font-size:11px;letter-spacing:.3px;color:var(--muted);margin:0 0 10px;text-transform:uppercase;font-weight:800}.topic-empty{font-size:11px;color:var(--muted);margin:0 0 12px}
.topic-all{margin-top:6px;border-top:1px solid var(--line);padding-top:14px}.topic-all summary{cursor:pointer;list-style:none;font-size:12px;font-weight:800;color:var(--navy)}.topic-all summary::-webkit-details-marker{display:none}.topic-all summary::after{content:"▾";float:right;transition:transform .15s}.topic-all[open] summary::after{transform:rotate(180deg)}.topic-all[open] summary{margin-bottom:16px}
.trend-panel .panel-title{margin-bottom:12px}.trend-key{display:flex;align-items:center;gap:14px;font-size:10px;color:var(--muted)}.trend-key i{display:inline-block;margin-right:4px;width:8px;height:8px}.trend-key i.dot{border-radius:50%;background:var(--coral)}.trend-key i.diamond{background:var(--coral);transform:rotate(45deg)}
.trend-panel svg{width:100%;height:auto;display:block}.trend-line{fill:none;stroke:var(--coral);stroke-width:2;stroke-linejoin:round;stroke-linecap:round}.trend-mark{fill:var(--coral);stroke:var(--paper);stroke-width:2;cursor:pointer}.trend-mark:focus-visible{outline:2px solid var(--navy);outline-offset:2px}.trend-gridline{stroke:var(--line);stroke-width:1}
.trend-tooltip{position:absolute;transform:translate(-50%,-100%);background:var(--navy);color:white;font-size:11px;padding:6px 10px;border-radius:6px;pointer-events:none;white-space:nowrap;z-index:50}
.trend-empty{text-align:center;padding:26px 20px;color:var(--muted)}.trend-empty span{font-size:26px;color:var(--coral);display:block;margin-bottom:8px}.trend-empty p{margin:0;font-size:12px}
.trend-best-marker{font-size:16px}.trend-best{margin:14px 0 0;font-size:12px;font-weight:800;color:var(--navy);text-align:center}
.trend-panel>.trend-key{margin-top:12px;justify-content:center}
.countdown-panel{margin-top:18px}
.countdown-copy{font-size:12px;color:var(--muted);line-height:1.6;margin:0 0 14px}
.countdown-date-form{display:flex;gap:9px;align-items:center}
.countdown-date-form input{border:1.5px solid var(--line);border-radius:8px;padding:10px 12px;font:13px "DM Sans"}
.countdown-change{color:var(--coral);display:block;margin:14px auto 0}
.countdown-passed{text-align:center;padding:20px 10px}
.countdown-passed span{font-size:34px;display:block;margin-bottom:8px}
.countdown-passed h4{font-family:Nunito,sans-serif;font-size:19px;margin:0 0 8px}
.countdown-passed p{color:var(--muted);font-size:12px;margin:0 0 16px}
.countdown-stats{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:14px}
.countdown-stat{flex:1;min-width:150px;background:var(--cream);border-radius:10px;padding:14px 18px}
.countdown-stat strong{display:block;font:900 26px Nunito;color:var(--navy);font-variant-numeric:tabular-nums;line-height:1.1}
.countdown-stat .of{font-size:16px;color:var(--muted)}
.countdown-stat span{font-size:10px;text-transform:uppercase;letter-spacing:.6px;color:var(--muted);font-weight:800}
.countdown-stat.is-lead{background:var(--navy)}
.countdown-stat.is-lead strong{color:white;font-size:34px}
.countdown-stat.is-lead span{color:#aeb8c9}
.countdown-stat.is-date strong{font-size:15px;line-height:1.35}
.countdown-thisweek{font-size:12px;color:var(--ink);background:#fff4f0;border-radius:8px;padding:10px 14px;margin:0 0 16px}
.countdown-thisweek strong{font-weight:800}
/* Capped so a wide dashboard doesn't scale the SVG (and every circle in it) up absurdly. */
#countdown-path svg{width:100%;max-width:660px;height:auto;display:block;margin:0 auto}
.path-line{fill:none;stroke:var(--line);stroke-width:3;stroke-linecap:round}
.path-stop{stroke-width:2;cursor:default}
.path-stop.is-future{fill:var(--paper);stroke:var(--line)}
.path-stop.is-quiet{fill:var(--cream);stroke:var(--line)}
.path-stop.is-done{fill:var(--status-strong);stroke:var(--status-strong)}
.path-stop.is-current{fill:var(--coral);stroke:var(--coral)}
.path-stop.is-exam{fill:var(--navy);stroke:var(--navy)}
.path-stop:focus-visible{outline:2px solid var(--navy);outline-offset:2px}
.path-stop-glyph{pointer-events:none;user-select:none;fill:white;text-anchor:middle;font-weight:800}
.path-stop-caption{font:700 9px "DM Sans";fill:var(--muted);pointer-events:none;user-select:none}
.path-stop-caption.is-exam-caption{fill:var(--navy);font-weight:800}
.countdown-legend{display:flex;flex-wrap:wrap;justify-content:center;gap:14px;margin-top:16px;font-size:10px;color:var(--muted)}
.countdown-legend span{display:inline-flex;align-items:center;gap:5px}
.key-stop{width:11px;height:11px;border-radius:50%;display:inline-block;border:1.5px solid var(--line);background:var(--paper)}
.key-stop.is-done{background:var(--status-strong);border-color:var(--status-strong)}
.key-stop.is-current{background:var(--coral);border-color:var(--coral)}
.key-stop.is-quiet{background:var(--cream)}
.key-stop.is-exam{background:var(--navy);border-color:var(--navy)}
@media(prefers-reduced-motion:reduce){.trend-line{transition:none!important}}
.streak-banner{display:flex;align-items:center;gap:10px;background:linear-gradient(90deg,#ffe1a8,#ffd1c2);border-radius:12px;padding:16px 22px;margin-bottom:18px;font-size:13px;color:var(--ink)}.streak-flame{font-size:22px}.streak-banner strong{font:800 15px Nunito}
.streak-body{display:flex;flex-direction:column;gap:3px}
.streak-sub{font-weight:700;opacity:.85}
.streak-rest-note{font-size:11px;color:#6b5a2e}
.badges-panel{margin-bottom:18px}.badges-grid{display:flex;flex-wrap:wrap;gap:10px}
.badge{display:flex;flex-direction:column;align-items:center;gap:6px;width:84px;padding:12px 6px;border-radius:10px;background:var(--cream);text-align:center;cursor:default}
.badge-icon{font-size:26px}.badge-name{font-size:9px;font-weight:800;color:var(--ink);line-height:1.3}
.badge.earned{background:#fff3e2;box-shadow:0 0 0 1.5px var(--yellow) inset}
.badge.next-up{background:var(--paper);border:1.5px dashed var(--line);width:auto;min-width:120px;padding:12px 16px}
.badge-next-label{font-size:8px;letter-spacing:1.2px;text-transform:uppercase;font-weight:800;color:var(--muted)}
.badge.next-up .badge-hint{font-size:9px;color:var(--muted);line-height:1.3}
.avatar-coral{background:var(--coral)}.avatar-cyan{background:var(--cyan)}.avatar-yellow{background:var(--yellow);color:var(--ink)}.avatar-peach{background:var(--peach);color:var(--ink)}.avatar-sky{background:var(--sky);color:var(--ink)}.avatar-navy{background:var(--navy)}
.profile-chip{display:flex;align-items:center;gap:8px;border:1px solid var(--line);background:white;border-radius:99px;padding:6px 14px 6px 6px;cursor:pointer;font-size:12px;font-weight:800;color:var(--ink)}.profile-chip-avatar{width:26px;height:26px;border-radius:50%;display:grid;place-items:center;color:white;font:800 11px Nunito}
.profile-gate-screen{max-width:760px}.profile-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:14px;margin-bottom:22px}
.profile-card{border:1px solid var(--line);background:var(--paper);border-radius:12px;padding:18px;display:flex;flex-direction:column;gap:10px}
.profile-card-main{border:0;background:none;cursor:pointer;text-align:left;padding:0;display:flex;flex-direction:column;gap:8px}
.profile-avatar{width:44px;height:44px;border-radius:50%;display:grid;place-items:center;color:white;font:800 18px Nunito}
.profile-card-main strong{font:800 15px Nunito;display:flex;align-items:center;gap:8px}
.profile-card-main small{color:var(--muted);font-size:10px}
.rename-badge{font-size:8px;background:var(--peach);color:#aa442e;padding:3px 7px;border-radius:9px;font-weight:800}
.profile-card-actions{display:flex;gap:8px;border-top:1px solid var(--line);padding-top:10px}
.profile-card-actions button{border:1px solid var(--line);background:white;border-radius:6px;width:30px;height:30px;cursor:pointer;font-size:12px}
.profile-add-form{display:flex;gap:8px;margin-bottom:12px}.profile-add-form input{flex:1;border:1px solid var(--line);border-radius:8px;padding:10px 12px;font:12px "DM Sans"}
.overview-screen{max-width:1100px}.overview-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:14px;margin-top:18px}
.overview-card{border:1px solid var(--line);background:var(--paper);border-radius:12px;padding:20px;display:flex;flex-direction:column;gap:12px}
.overview-card-head{display:flex;align-items:center;gap:10px}.overview-card-head strong{display:block;font:800 14px Nunito}.overview-card-head small{color:var(--muted);font-size:9px}
.overview-card-spark{height:44px}.overview-card-spark svg{width:100%;height:100%;display:block}.spark-empty{height:100%;display:flex;align-items:center;justify-content:center;font-size:9px;color:var(--muted);font-style:italic}
.overview-card-stat{background:var(--cream);border-radius:8px;padding:12px;text-align:center}.overview-card-stat strong{font:900 24px Nunito;display:block}.overview-card-stat span{font-size:9px;color:var(--muted);text-transform:uppercase;letter-spacing:.5px}
.trend-arrow{font-size:15px;vertical-align:middle}.trend-arrow.trend-up{color:var(--status-strong)}.trend-arrow.trend-down{color:var(--status-focus)}.trend-arrow.trend-flat{color:var(--muted)}
.overview-card-focus{display:flex;flex-wrap:wrap;gap:6px}.overview-focus-chip{font-size:9px;background:#fde1d8;color:var(--status-focus);padding:4px 8px;border-radius:9px;font-weight:700}.overview-focus-chip.ok{background:#e3f3ee;color:var(--status-strong)}
.overview-card>button{margin-top:auto}
@media(max-width:800px){.topbar{height:72px}.streak{padding:6px 9px;font-size:10px}.streak span{margin-right:3px}.profile-chip{padding:4px}.profile-chip #profile-chip-name{display:none}.profile-grid,.overview-grid{grid-template-columns:1fr 1fr}.screen{width:min(100% - 24px,650px);padding-top:45px}.home-grid,.subject-grid,.result-layout,.dashboard-panels{grid-template-columns:1fr}.home-grid article{min-height:250px}.dashboard-summary{grid-template-columns:1fr 1fr}.result-hero{padding:32px;align-items:flex-start}.score-circle{width:100px;height:100px}.result-star{display:none}.hero-actions{flex-direction:column;align-items:stretch}.test-note{flex-wrap:wrap}h1{letter-spacing:-2px}.section-intro h2{font-size:38px}.data-panel{align-items:flex-start;flex-direction:column}.data-actions{flex-wrap:wrap}.topic-menu{grid-template-columns:1fr 1fr}.topic-hero{padding:30px}.topic-hero-art{font-size:60px}.coach-card,.recommendations{align-items:flex-start;flex-direction:column}.exam-banner{flex-direction:column;align-items:flex-start;text-align:left}.exam-rules{grid-template-columns:1fr}}
@media(max-width:480px){.screen{width:calc(100% - 20px)}.topbar{padding:0 15px}.result-hero{display:grid}.score-circle{margin:10px 0 0}.dashboard-summary{grid-template-columns:1fr}.question-card{padding:24px 18px}.quiz-top{gap:12px}.subject-choice{min-height:290px}.hero{margin-bottom:45px}.topic-menu{grid-template-columns:1fr}.topic-hero-art{display:none}}

.secondary.small{padding:9px 14px;font-size:11px;font-weight:800;border-radius:7px;white-space:nowrap}
.overview-card-actions{display:flex;gap:8px;margin-top:auto}.overview-card-actions button.secondary{flex:1}.overview-print{flex:none;width:38px;height:38px;font-size:15px}

/* ============ Printable progress report ============
   Built as a detached overlay (js/report.mjs) rather than a router screen, so printing
   never navigates the parent away from whatever they were looking at. Hidden on screen;
   the print media query below hides the rest of the app and shows only this. */
/* .report-* rules moved to report.css, a small self-contained stylesheet shared with
   console.html — extracted so console.mjs's print path doesn't need to load this whole
   stylesheet (and its unrelated global resets) just to render a report fragment. */
#print-report{display:none}

/* ============ In-app modal (replaces prompt()/confirm()) ============ */
.modal-overlay{position:fixed;inset:0;background:rgba(20,33,61,.45);display:flex;align-items:center;justify-content:center;z-index:200;padding:20px;animation:modalFadeIn .15s ease}
.modal-box{background:var(--paper);border-radius:14px;box-shadow:var(--shadow);padding:28px 30px;max-width:380px;width:100%;animation:modalPopIn .18s ease}
.modal-box h3{font-size:19px;margin:0 0 10px}
.modal-box p{font-size:13px;color:var(--muted);line-height:1.6;margin:0 0 18px}
.modal-input{width:100%;box-sizing:border-box;border:1.5px solid var(--line);border-radius:9px;padding:12px 14px;font:14px "DM Sans";margin-bottom:18px}
.modal-actions{display:flex;justify-content:flex-end;gap:10px}
.modal-actions button{padding:11px 18px;font-size:12px;border-radius:8px}
button.danger{border:0;background:var(--coral);color:white;font-weight:800;cursor:pointer}
button.danger:hover{background:#e06a4d}
@keyframes modalFadeIn{from{opacity:0}to{opacity:1}}
@keyframes modalPopIn{from{opacity:0;transform:scale(.96) translateY(6px)}to{opacity:1;transform:scale(1) translateY(0)}}
@media(prefers-reduced-motion:reduce){.modal-overlay,.modal-box{animation:none!important}}

/* ============ Session Replay ============ */
.replay-list{display:flex;flex-direction:column;gap:22px}
.replay-card{padding-top:22px}
.replay-card-head{display:flex;align-items:center;gap:12px;margin-bottom:14px}
.replay-q-num{font:800 12px Nunito;color:var(--muted)}
.replay-card .question-label{margin-left:auto;margin-right:0}
.replay-outcome{font-size:11px;font-weight:800;padding:4px 10px;border-radius:99px}
.replay-outcome.is-correct{background:#eaf7f1;color:#26815b}
.replay-outcome.is-incorrect{background:#fff0ec;color:var(--coral)}
.replay-drifted{color:var(--muted);font-size:12px;font-style:italic;margin:0}

/* ============ Practice calendar heatmap ============ */
.heatmap-panel{margin-top:18px}
.heatmap-stats{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:18px}
.heatmap-stat{flex:1;min-width:130px;background:var(--cream);border-radius:10px;padding:14px 18px}
.heatmap-stat strong{display:block;font:900 26px Nunito;color:var(--navy);font-variant-numeric:tabular-nums;line-height:1.1}
.heatmap-stat span{font-size:10px;text-transform:uppercase;letter-spacing:.6px;color:var(--muted);font-weight:800}
/* Centred rather than stretched: cells are capped so they stay square and legible, so on a wide
   dashboard with only a few weeks of history the grid would otherwise sit marooned hard-left. */
.heatmap-scroll{overflow-x:auto;padding-bottom:4px;display:flex;justify-content:center}
.heatmap-inner{min-width:min-content}
/* The day-label gutter is reserved on the months row too, so month labels stay aligned to the
   column they actually belong to rather than drifting left by the width of that gutter. */
.heatmap-months{display:flex;gap:4px;margin-left:34px;margin-bottom:5px}
.heatmap-month{width:28px;flex:none;font-size:9px;font-weight:700;color:var(--muted);white-space:nowrap}
.heatmap-body{display:flex;gap:6px}
.heatmap-days{display:flex;flex-direction:column;gap:4px;width:28px;flex:none}
/* flex:1 makes each label share the column's height exactly as the seven cells do, so labels
   line up with their own row instead of drifting as cell size changes with the week count. */
.heatmap-days span{flex:1;font-size:9px;color:var(--muted);line-height:1;display:flex;align-items:center}
.heatmap-grid{display:flex;gap:4px;min-width:0}
/* Fixed rather than flexible: cells must stay square and legible, and the whole grid is centred,
   so a short history reads as a neat compact block instead of stretched-out oversized squares. */
.heatmap-col{display:flex;flex-direction:column;gap:4px;width:28px;flex:none}
.heatmap-cell{width:100%;aspect-ratio:1;border-radius:3px;background:var(--cream);display:block}
.heatmap-cell.is-empty{background:var(--cream)}
.heatmap-cell.is-one{background:#f7c2ac}
.heatmap-cell.is-two{background:#f5966d}
.heatmap-cell.is-many{background:var(--coral)}
.heatmap-cell.is-future{visibility:hidden}
.heatmap-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;margin-top:16px}
.heatmap-explain{font-size:11px;color:var(--muted);margin:0;max-width:520px;line-height:1.5}
.heatmap-legend{display:flex;align-items:center;gap:5px;font-size:9px;color:var(--muted)}
.heatmap-legend .heatmap-cell{width:11px;height:11px;flex:none;aspect-ratio:auto}

/* Connecting a device to a tutor. A quiet, optional path — the app is complete without it, so
   nothing here competes with the practice buttons for attention. */
.link-button{display:block;margin:18px auto 0;border:0;background:none;color:var(--muted);
  font:600 13px/1.5 inherit;text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.link-button:hover{color:var(--ink)}
.enrol-form{max-width:340px;margin:0 auto;display:flex;flex-direction:column;gap:14px}
.enrol-label{font-size:12px;font-weight:700;color:var(--muted);text-align:center}
/* Wide letter-spacing and a monospace face because this is transcribed character by character
   from a card, and the usual proportional face makes similar glyphs harder to tell apart. */
.enrol-code{font:800 26px/1 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:6px;
  text-align:center;text-transform:uppercase;padding:16px 12px;border:2px solid var(--line);
  border-radius:14px;background:var(--paper);color:var(--ink)}
.enrol-code:focus{outline:none;border-color:var(--cyan)}
.enrol-message{min-height:20px;text-align:center;font-size:13px;font-weight:600;color:var(--muted);margin:0}
/* A code that did not work is not an error state. It gets the same warm accent as the rest of the
   app rather than red, because the usual cause is an expired code, which is an adult's oversight. */
.enrol-message-soft{color:var(--coral)}
.enrol-message-good{color:var(--status-strong)}
.enrol-footnote{max-width:340px;margin:26px auto 0;text-align:center;font-size:12px;
  line-height:1.7;color:var(--muted)}
@media(max-width:480px){
  .enrol-code{font-size:22px;letter-spacing:4px}
}

/* The print media rule itself also moved to report.css, alongside the classes it governs. */

/* The Warm-Up invitation on the home screen. Sits below the practice tiles as a quiet aside,
   not a fourth tile: a minute of number facts is a different offer from a test, and it must never
   out-shout the Daily Six. Peach rather than navy for the same reason — present, not urgent. */
.warmup-invite{display:flex;align-items:center;gap:16px;width:100%;text-align:left;cursor:pointer;
  border:1.5px solid var(--peach);background:var(--paper);border-radius:12px;padding:16px 20px;
  margin:0 0 40px}
.warmup-invite:hover{border-color:var(--coral);box-shadow:0 8px 20px rgba(20,33,61,.08)}
.warmup-invite-mark{display:grid;place-items:center;width:38px;height:38px;flex:none;border-radius:50%;
  background:var(--peach);font-size:17px}
.warmup-invite-text{display:flex;flex-direction:column;gap:3px}
.warmup-invite-text strong{font:800 15px Nunito;color:var(--navy)}
.warmup-invite-text small{font-size:12px;color:var(--muted);line-height:1.5}
.warmup-invite-go{margin-left:auto;color:var(--coral);font-weight:800;font-size:18px}
@media(max-width:700px){.warmup-invite-text small{display:none}}

/* ---------- The Warm-Up ----------
   Sixty seconds of mental arithmetic. The visual brief is the opposite of a game show: nothing
   here counts down in numerals, nothing turns red, nothing flashes on a wrong answer, and the
   only motion during play is the clock quietly getting shorter. See js/warmup.mjs for why. */
.warmup-screen{max-width:720px;margin:0 auto;padding-top:26px}
.warmup-top{display:flex;align-items:center;gap:18px;margin-bottom:38px}

/* The soft clock. A single bar that shrinks — no ticks, no numerals, no colour change as it runs
   down. It stays --cyan the whole way: a bar that turns red near the end is a countdown telling a
   child they are running out, which is exactly the pressure this round refuses to apply. */
.warmup-clock{flex:1;height:8px;border-radius:99px;background:#ddd9d0;overflow:hidden}
.warmup-clock span{display:block;height:100%;border-radius:99px;background:var(--cyan);
  width:calc(var(--warmup-left,1) * 100%)}
.warmup-tally{text-align:center;min-width:58px}
.warmup-tally small{display:block;font-size:8px;letter-spacing:1.4px;text-transform:uppercase;color:var(--muted)}
.warmup-tally strong{font:900 24px Nunito;color:var(--navy)}

.warmup-stage{background:var(--paper);border:1px solid var(--line);box-shadow:var(--shadow);
  border-radius:14px;padding:34px 30px 30px;text-align:center;margin-bottom:20px}
.warmup-smarty{display:flex;justify-content:center;margin-bottom:6px;min-height:84px}
.warmup-sum{display:flex;align-items:center;justify-content:center;gap:14px;margin:6px 0 4px;
  font:900 clamp(38px,8vw,60px) Nunito;color:var(--navy);letter-spacing:-2px;
  /* Digits must not shuffle sideways as they are typed. */
  font-variant-numeric:tabular-nums}
.warmup-typed{min-width:1.6em;padding:0 10px;border-bottom:4px solid var(--peach);color:var(--coral)}
.warmup-typed[data-empty="true"]::after{content:"\00a0"}
.warmup-note{min-height:22px;margin:14px 0 0;font-size:13px;font-weight:700;color:var(--muted)}

.warmup-keypad{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;max-width:340px;margin:0 auto}
.warmup-keypad button{border:1.5px solid var(--line);background:var(--paper);border-radius:12px;
  padding:18px 0;font:800 22px Nunito;color:var(--navy);cursor:pointer;font-variant-numeric:tabular-nums}
.warmup-keypad button:hover{border-color:var(--cyan)}
.warmup-keypad button:active{background:var(--cream)}
.warmup-keypad .warmup-key-go{background:var(--navy);color:white;border-color:var(--navy)}
.warmup-keypad .warmup-key-wide{color:var(--muted);font-size:18px}

.warmup-results{max-width:620px;margin:0 auto;text-align:center;padding-top:40px}
.warmup-result-smarty{display:flex;justify-content:center;margin-bottom:10px}
.warmup-result-count{margin:0;display:flex;align-items:baseline;justify-content:center;gap:10px}
.warmup-result-count strong{font:900 clamp(56px,12vw,86px) Nunito;color:var(--navy);letter-spacing:-3px}
.warmup-result-count small{font:800 15px "DM Sans";color:var(--muted)}
.warmup-result-line{margin:12px auto 26px;max-width:44ch;font-size:15px;line-height:1.6;color:var(--ink)}
.warmup-revisit{background:var(--paper);border:1px solid var(--line);border-radius:12px;
  padding:18px 22px;margin:0 auto 26px;max-width:44ch}
.warmup-revisit-label{display:block;font:800 9px "DM Sans";letter-spacing:1.6px;text-transform:uppercase;
  color:var(--muted);margin-bottom:8px}
.warmup-revisit p{margin:0;font:800 17px Nunito;color:var(--navy);font-variant-numeric:tabular-nums}
.warmup-result-actions{display:flex;gap:12px;justify-content:center;flex-wrap:wrap}

/* Smarty Pants. Colours come from the theme, so a white-labelled tutor gets their own character
   with no second asset. Every animation below is decoration on a working feature and is switched
   off entirely under prefers-reduced-motion — for some children that is the difference between
   usable and not, which is why it is a media query and not a preference buried in a menu. */
.smarty{display:block;overflow:visible}
.smarty-body{fill:var(--coral)}
.smarty-waistband{fill:var(--navy);opacity:.9}
.smarty-eye-white{fill:#fffdfa}
.smarty-pupil{fill:var(--navy)}
.smarty-mouth{stroke:var(--navy);stroke-width:3;stroke-linecap:round}
.smarty[data-expression="surprised"] .smarty-mouth{fill:var(--navy);stroke-width:0}
.smarty-eye{transform-box:fill-box;transform-origin:center;animation:smartyBlink 6.5s infinite}
.smarty-face{transform-box:fill-box;transform-origin:center;animation:smartyBreathe 4.5s ease-in-out infinite}
@keyframes smartyBlink{0%,94%,100%{transform:scaleY(1)}97%{transform:scaleY(.12)}}
@keyframes smartyBreathe{0%,100%{transform:translateY(0)}50%{transform:translateY(1px)}}
/* Talking. The mouth works and the face nods — enough to read as addressing the child rather
   than merely being present. Higher specificity than the resting breathe above, so it takes over
   cleanly. Only ever set between rounds, at the end, and while teaching: see js/smarty.mjs. */
.smarty-mouth{transform-box:fill-box;transform-origin:center}
.smarty[data-talking="true"] .smarty-mouth{animation:smartyTalk .3s ease-in-out infinite alternate}
.smarty[data-talking="true"] .smarty-face{animation:smartyNod 1.05s ease-in-out infinite}
@keyframes smartyTalk{from{transform:scaleY(.5)}to{transform:scaleY(1.7)}}
@keyframes smartyNod{0%,100%{transform:translateY(0) rotate(0deg)}50%{transform:translateY(-1.5px) rotate(-1.5deg)}}

@media(prefers-reduced-motion:reduce){
  .smarty-eye,.smarty-face,.smarty-mouth{animation:none!important}
  .warmup-clock span{transition:none!important}
}

@media(max-width:700px){
  .warmup-screen{padding-top:14px}
  .warmup-stage{padding:24px 18px 22px}
}

/* ---------- Trick of the Day, and the demonstrations ----------
   The teaching half of the Warm-Up. Quiet and roomy on purpose: this screen is read, not raced,
   and it is the one moment in the feature where nothing is being timed. */
.warmup-intro{max-width:600px;margin:0 auto;text-align:center;padding-top:38px}
.warmup-intro-smarty{display:flex;justify-content:center;margin-bottom:12px}
.warmup-intro-eyebrow{display:block;font:800 9px "DM Sans";letter-spacing:1.8px;text-transform:uppercase;
  color:var(--muted);margin-bottom:10px}
.warmup-intro-headline{font-size:clamp(24px,4.6vw,33px);line-height:1.2;letter-spacing:-1px;
  margin:0 auto 18px;max-width:20ch;text-wrap:balance}
.warmup-intro-example{margin:16px auto 6px;max-width:38ch;font-size:15px;line-height:1.6;color:var(--ink);
  font-variant-numeric:tabular-nums}
.warmup-intro-pick{margin:0 auto 26px;max-width:40ch;font-size:13px;color:var(--muted);line-height:1.55}
.warmup-intro-actions{display:flex;gap:12px;justify-content:center;flex-wrap:wrap}

/* The demonstration. Dots that do the thing the sentence describes — ten becoming five, ten lots
   becoming nine — because a child who SEES why the shortcut works remembers the shortcut. */
.trick-demo{margin:6px auto 4px;max-width:340px}
.trick-demo-svg{width:100%;height:auto;overflow:visible}
.trick-dot{fill:var(--cyan)}
.trick-dot.is-leaving{fill:var(--coral);animation:trickLeave 2.6s ease-in-out infinite}
.trick-dot.is-arriving{fill:var(--coral);animation:trickArrive 2.6s ease-in-out infinite}
@keyframes trickLeave{0%,22%{opacity:1;transform:translateY(0)}52%,88%{opacity:.12;transform:translateY(-9px)}100%{opacity:1;transform:translateY(0)}}
@keyframes trickArrive{0%,22%{opacity:.12;transform:translateY(-9px)}52%,88%{opacity:1;transform:translateY(0)}100%{opacity:.12;transform:translateY(-9px)}}
.trick-demo-svg .trick-dot{transform-box:fill-box;transform-origin:center}
/* Static variant: the end state, drawn once. The lesson still reads; only the movement is gone. */
.trick-demo-svg.is-static .trick-dot.is-leaving{animation:none;opacity:.12}
.trick-demo-svg.is-static .trick-dot.is-arriving{animation:none;opacity:1}

/* One true thing, and the rescue. */
.warmup-truething{margin:0 auto 22px;max-width:40ch;font-size:14.5px;line-height:1.6;color:var(--ink);
  font-weight:700;min-height:1.2em}
.warmup-rescue-ask{display:inline-block;margin-top:12px;color:var(--coral);font-size:12px}
.warmup-rescue{margin-top:14px;padding-top:14px;border-top:1px dashed var(--line);text-align:left}
.warmup-rescue-headline{margin:0 0 8px;font:800 15px Nunito;color:var(--navy)}
.warmup-rescue-body{margin:8px 0 0;font-size:13.5px;line-height:1.65;color:var(--ink);white-space:pre-wrap}

@media(prefers-reduced-motion:reduce){
  .trick-dot{animation:none!important}
}

/* The offline note that stands in for the Smarty Pants button. Deliberately quiet — it is a
   statement of fact, not a warning, and a child offline has done nothing wrong. */
.helper-offline-note{margin:3px 0 13px;font-size:11.5px;line-height:1.5;color:var(--muted);max-width:46ch}
.helper-form.is-offline input{background:var(--cream);cursor:not-allowed}
.helper-form.is-offline button{opacity:.4;pointer-events:none}

/* The install invitation. Same quiet register as the Warm-Up strip: an aside, never a banner, and
   it disappears for good the moment somebody says no. */
.install-invite{display:flex;align-items:center;gap:16px;flex-wrap:wrap;border:1px dashed var(--line);
  background:var(--paper);border-radius:12px;padding:14px 18px;margin:0 0 40px}
.install-invite-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:220px}
.install-invite-text strong{font:800 14px Nunito;color:var(--navy)}
.install-invite-text small{font-size:12px;color:var(--muted);line-height:1.5}
.install-invite-actions{display:flex;align-items:center;gap:10px}
.install-invite-actions .secondary{padding:9px 16px;font-size:13px}
.install-invite-actions .text-button{color:var(--muted);font-size:12px}
