/*
  Styles for the student app (public/index.html). Split out of the page's
  inline <style> so the browser can cache it separately from the HTML: most
  deploys change one of markup/styles/script, and an unchanged file here
  revalidates to a 304 instead of re-downloading with every HTML change.
  Plain CSS, no build step - what's here is what's served (see AGENTS.md).
*/
  :root{
    --navy:#16233F;
    --navy-soft:#22345A;
    --gold:#E7A93C;
    --gold-soft:#F4CE8A;
    --sage:#6E9E82;
    --coral:#D9694F;
    --cream:#FAF7F1;
    --paper:#FFFFFF;
    --ink:#20242C;
    --ink-soft:#5B6270;
    /* --ink-soft is tuned for cream backgrounds; on the navy card it lands
       at 2.54:1, which fails AA for the two blocks that most need reading
       (the ACARA non-affiliation notice and the account-purpose copy). This
       is its on-navy counterpart at 6.35:1. */
    --ink-on-navy:#9AA6BC;
    --line:#E7E1D6;
    --radius:14px;
    /* Radius ramp. --radius stays the mid step so existing usages are
       unaffected; the hero below works from these rather than adding to the
       seven ad-hoc values already in the file. */
    --r-sm:10px;
    --r-lg:20px;
    --r-pill:999px;
    --shadow: 0 10px 30px rgba(22,35,63,0.10);
  }
  *{box-sizing:border-box;}
  html,body{margin:0;padding:0;}
  body{
    background:var(--cream);
    color:var(--ink);
    font-family:'Inter',sans-serif;
    min-height:100vh;
    -webkit-font-smoothing:antialiased;
  }
  h1,h2,h3,.display{
    font-family:'Fraunces',serif;
    font-weight:600;
    letter-spacing:-0.01em;
  }
  #app{max-width:960px;margin:0 auto;padding:28px 20px 80px;}
  .hidden{display:none !important;}

  /* ---------- Top bar ---------- */
  .topbar{
    display:flex;align-items:center;justify-content:space-between;
    margin-bottom:28px;
  }
  .brand{display:flex;align-items:center;gap:10px;}
  .brand-mark{
    width:36px;height:36px;border-radius:10px;
    background:linear-gradient(135deg,var(--gold),var(--coral));
    display:flex;align-items:center;justify-content:center;
    color:white;font-family:'Fraunces',serif;font-weight:700;font-size:18px;
    box-shadow:var(--shadow);
  }
  .brand-name{font-family:'Fraunces',serif;font-weight:600;font-size:19px;color:var(--navy);}
  .brand-name span{color:var(--coral);}
  .student-chip{
    display:flex;align-items:center;gap:8px;
    background:var(--paper);border:1px solid var(--line);
    padding:6px 14px 6px 6px;border-radius:999px;
    font-size:13px;color:var(--ink-soft);
    box-shadow:var(--shadow);
  }
  .student-chip .dot{
    width:26px;height:26px;border-radius:50%;
    background:var(--navy);color:white;
    display:flex;align-items:center;justify-content:center;
    font-size:12px;font-weight:700;font-family:'Fraunces',serif;
  }
  .student-chip .coin-badge{
    display:flex;align-items:center;gap:4px;
    background:var(--gold-soft);color:#7A5710;
    padding:3px 9px;border-radius:999px;font-weight:800;font-size:12.5px;
  }
  .student-chip button{
    background:none;border:none;color:var(--ink-soft);
    cursor:pointer;font-size:12px;text-decoration:underline;padding:0;margin-left:6px;
  }

  /* ---------- Welcome / auth ---------- */
  .welcome{
    background:var(--navy);
    border-radius:20px;
    padding:56px 44px;
    color:var(--cream);
    position:relative;
    overflow:hidden;
    box-shadow:var(--shadow);
  }
  /* Scoped away from the hero (see .welcome-hero below) but left on the
     loading screen, which is app UI and outside this redesign. */
  .welcome:not(.welcome-hero)::before{
    content:"";position:absolute;right:-60px;top:-60px;
    width:280px;height:280px;border-radius:50%;
    background:radial-gradient(circle, rgba(231,169,60,0.35), transparent 70%);
  }
  .welcome .eyebrow{
    text-transform:uppercase;letter-spacing:0.14em;font-size:12px;
    color:var(--gold-soft);font-weight:700;margin-bottom:14px;
  }
  .welcome h1{font-size:38px;line-height:1.15;margin:0 0 14px;max-width:520px;position:relative;}
  .welcome p{color:#C8D0E0;font-size:15.5px;max-width:480px;line-height:1.6;margin:0 0 28px;position:relative;}
  .welcome-form{display:flex;gap:10px;flex-wrap:wrap;position:relative;max-width:360px;}
  .welcome-form.stacked{flex-direction:column;align-items:stretch;}
  .welcome-form input{
    flex:1;min-width:200px;
    padding:13px 16px;border-radius:10px;border:none;
    font-family:'Inter',sans-serif;font-size:15px;
    background:rgba(255,255,255,0.08);color:white;
    border:1px solid rgba(255,255,255,0.18);
  }
  .welcome-form input::placeholder{color:#8E97AC;}
  .welcome-form input:focus{outline:2px solid var(--gold);outline-offset:1px;}
  .auth-buttons{display:flex;gap:10px;}
  .auth-error{color:#F6B4A3;font-size:13px;min-height:18px;}
  .auth-divider{
    display:flex;align-items:center;gap:12px;max-width:360px;
    color:#8E97AC;font-size:12.5px;text-transform:uppercase;letter-spacing:0.06em;
    margin:22px 0 16px;
  }
  .auth-divider::before,.auth-divider::after{content:'';flex:1;height:1px;background:rgba(255,255,255,0.16);}
  .oauth-buttons{display:flex;flex-direction:column;gap:10px;max-width:360px;}
  .btn-oauth{
    display:flex;align-items:center;justify-content:center;gap:10px;
    background:white;color:var(--ink);text-decoration:none;
    border:1.5px solid rgba(255,255,255,0.18);
  }
  .btn-oauth:hover{box-shadow:0 6px 18px rgba(0,0,0,0.25);}
  .btn{
    border:none;border-radius:10px;padding:13px 22px;
    font-family:'Inter',sans-serif;font-weight:700;font-size:14.5px;
    cursor:pointer;transition:transform .12s ease, box-shadow .12s ease;
  }
  .btn:active{transform:translateY(1px);}
  .btn-gold{background:var(--gold);color:var(--navy);}
  .btn-gold:hover{box-shadow:0 6px 18px rgba(231,169,60,0.4);}
  /* A classroom the student has already completed at least once - see
     renderClassroomsHub's `done` check against /api/students/:id/best. */
  .btn-gold.btn-done{background:var(--sage);color:#fff;}
  .btn-gold.btn-done:hover{box-shadow:0 6px 18px rgba(122,168,116,0.4);}
  .btn-outline{background:transparent;border:1.5px solid var(--line);color:var(--ink);}
  .btn-outline:hover{border-color:var(--navy);}
  .btn-outline.on-dark{border-color:rgba(255,255,255,0.35);color:white;}
  .btn-dark{background:var(--navy);color:white;}
  .btn-dark:hover{box-shadow:0 6px 18px rgba(22,35,63,0.35);}
  .btn:disabled{opacity:0.5;cursor:not-allowed;}
  .btn:focus-visible, input:focus-visible, .card:focus-visible{outline:2px solid var(--gold);outline-offset:2px;}

  /* --ink-on-navy, not --ink-soft: the only .disclaimer sits on navy, where
     ink-soft measured 2.54:1 (fails AA) in the landing audit. */
  .disclaimer{
    font-size:11.5px;color:var(--ink-on-navy);margin-top:26px;
    padding-top:18px;border-top:1px solid var(--line);
  }
  .disclaimer a{color:var(--gold-soft);font-weight:600;text-decoration:underline;}

  .auth-purpose{
    font-size:12.5px;line-height:1.5;color:var(--ink-on-navy);
    margin:0 0 12px;text-align:left;
  }

  /* ---------- Landing hero ----------
     A modifier on .welcome rather than a rewrite of it: the loading screen
     reuses .welcome, so the base card stays exactly as it was. Two columns
     because the single 520px column left the right ~45% of a 960px card
     empty; the form now occupies that space instead of a decorative glow. */
  .welcome-hero{
    display:grid;
    grid-template-columns:minmax(0,1.05fr) minmax(320px,0.9fr);
    gap:clamp(28px,4vw,48px);
    /* Centred, not top-aligned: the auth card is the taller column, so
       start-alignment left a tall void under the copy. Centring splits that
       whitespace above and below instead of pooling it in one corner. */
    align-items:center;
    padding:clamp(34px,5vw,58px) clamp(24px,4vw,48px);
    border-radius:var(--r-lg);
  }
  .welcome-hero .eyebrow{margin-bottom:10px;}
  /* Fluid rather than a fixed 38px, which wrapped to five lines at 390px.
     Scale is restrained on purpose; hierarchy comes from weight and colour
     against the muted lead paragraph, not from raw size. */
  .welcome-hero h1{
    font-size:clamp(28px,3.4vw,40px);
    line-height:1.14;
    max-width:15ch;
    margin:0 0 16px;
  }
  .welcome-hero p.lead{
    color:#C8D0E0;font-size:16px;line-height:1.6;
    max-width:44ch;margin:0 0 22px;
  }
  .hero-subjects{
    display:flex;flex-wrap:wrap;gap:8px;margin:0 0 26px;padding:0;list-style:none;
  }
  .hero-subjects li{
    font-size:12.5px;font-weight:600;color:var(--gold-soft);
    border:1px solid rgba(231,169,60,0.32);
    border-radius:var(--r-pill);padding:5px 11px;
  }
  /* The form gets a surface of its own so the right column reads as a
     destination rather than as floating fields on a dark panel. */
  .hero-auth{
    background:rgba(255,255,255,0.05);
    border:1px solid rgba(255,255,255,0.14);
    border-radius:var(--radius);
    padding:22px;
  }
  .hero-auth .welcome-form,
  .hero-auth .auth-divider,
  .hero-auth .oauth-buttons{max-width:none;}
  .hero-offer{
    font-size:12.5px;line-height:1.55;color:var(--gold-soft);
    background:rgba(231,169,60,0.10);
    border:1px solid rgba(231,169,60,0.28);
    border-radius:var(--r-sm);
    padding:10px 12px;margin:0 0 16px;
  }
  .hero-offer b{color:#F8DFB0;}
  /* Secondary feature callout: a full-width band below the two hero columns,
     subordinate to the sign-up form on purpose. The whole band is one link
     (large tap target) to the /guide explainer. Light text on navy so it
     clears WCAG AA, unlike the .disclaimer/.auth-purpose ink-soft-on-navy
     the audit flagged. */
  .hero-ai{
    grid-column:1 / -1;
    display:flex;align-items:center;gap:13px;
    background:rgba(255,255,255,0.05);
    border:1px solid rgba(255,255,255,0.14);
    border-radius:var(--radius);
    padding:13px 16px;
    text-decoration:none;color:#D8DEEA;
    transition:border-color .2s ease, background .2s ease, transform .12s ease;
  }
  .hero-ai:hover{background:rgba(231,169,60,0.08);border-color:rgba(231,169,60,0.40);}
  .hero-ai:active{transform:translateY(1px);}
  .hero-ai-badge{
    flex:none;font-size:10.5px;font-weight:700;letter-spacing:0.05em;text-transform:uppercase;
    color:var(--navy);background:var(--gold);border-radius:var(--r-pill);padding:3px 9px;
  }
  .hero-ai-text{font-size:13.5px;line-height:1.5;}
  .hero-ai-text b{color:#fff;font-weight:600;}
  .hero-ai-link{color:var(--gold-soft);font-weight:600;white-space:nowrap;}
  .hero-ai:hover .hero-ai-link{text-decoration:underline;}
  @media (max-width:860px){ .hero-ai{align-items:flex-start;} }
  /* Below-hero persuasion band (landing IA task 86d4ch80h). Stays on the
     navy card as one more full-width row rather than a new light section,
     so the hero keeps its single-surface identity; separated by a hairline,
     not a second card, to avoid the stacked-card look the audit retired.
     Line SVG icons in gold-soft replace the emoji /about still uses. */
  .landing-more{
    grid-column:1 / -1;
    border-top:1px solid rgba(255,255,255,0.14);
    padding-top:clamp(26px,4vw,40px);
    color:#C8D0E0;
  }
  .landing-more h2{
    font-size:clamp(22px,2.4vw,28px);line-height:1.2;color:#fff;margin:0 0 22px;
  }
  .landing-grid{
    display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,0.9fr);
    gap:clamp(24px,4vw,44px);align-items:start;
  }
  .landing-points{list-style:none;margin:0;padding:0;display:grid;gap:18px;}
  .landing-points li{display:flex;gap:14px;font-size:15px;line-height:1.6;max-width:56ch;}
  .landing-points svg{flex:none;color:var(--gold-soft);margin-top:2px;}
  .landing-points b{color:#fff;font-weight:600;}
  .landing-shots{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:0;}
  .landing-shots figure{margin:0;}
  /* Same crop box for both: the report capture is a 489x1647 strip, so
     it is cut to the question shot's 480:900 from the top, where the
     summary sits. width/height attributes reserve the space (no CLS). */
  .landing-shots img{
    display:block;width:100%;height:auto;aspect-ratio:480 / 900;
    object-fit:cover;object-position:top;
    border-radius:var(--r-sm);border:1px solid rgba(255,255,255,0.14);
    background:rgba(255,255,255,0.05);
  }
  .landing-shots figcaption{font-size:12.5px;color:var(--ink-on-navy);margin-top:8px;}
  .landing-price{
    display:flex;flex-wrap:wrap;gap:10px 28px;
    margin:28px 0 0;padding:14px 16px;
    border:1px solid rgba(231,169,60,0.28);border-radius:var(--r-sm);
    background:rgba(231,169,60,0.08);font-size:14.5px;
  }
  .landing-price b{color:var(--gold-soft);font-weight:700;margin-right:6px;}
  .landing-faq{margin-top:30px;max-width:72ch;}
  .landing-faq h3{font-size:18px;color:#fff;margin:0 0 10px;}
  .landing-faq details{border-bottom:1px solid rgba(255,255,255,0.14);}
  .landing-faq summary{
    cursor:pointer;padding:13px 0;font-weight:600;color:#fff;font-size:15px;
  }
  .landing-faq summary:focus-visible{outline:2px solid var(--gold);outline-offset:2px;}
  .landing-faq details p{margin:0 0 14px;font-size:14.5px;line-height:1.6;}
  .landing-cta{display:inline-block;margin-top:26px;text-decoration:none;}
  @media (max-width:860px){
    .landing-grid{grid-template-columns:1fr;}
    .landing-shots{max-width:420px;}
  }
  .welcome-hero .disclaimer{
    grid-column:1 / -1;
    color:var(--ink-on-navy);
    border-top-color:rgba(255,255,255,0.14);
  }
  .welcome-hero .disclaimer .links{margin-top:6px;display:block;}
  @media (max-width:860px){
    .welcome-hero{grid-template-columns:1fr;gap:26px;}
    .welcome-hero h1{max-width:20ch;}
  }
  /* Motion sits behind no-preference, so reduced-motion users get the page
     with no entrance at all rather than a shortened one. */
  @media (prefers-reduced-motion: no-preference){
    .welcome-hero > *{animation:hero-rise 0.5s cubic-bezier(0.2,0.7,0.3,1) both;}
    .welcome-hero > .hero-auth{animation-delay:0.07s;}
    .welcome-hero > .hero-ai{animation-delay:0.10s;}
    .welcome-hero > .landing-more{animation-delay:0.12s;}
    .welcome-hero > .disclaimer{animation-delay:0.14s;}
  }
  @keyframes hero-rise{from{opacity:0;transform:translateY(10px);}to{opacity:1;transform:none;}}

  /* ---------- Dashboard / grids ---------- */
  .dash-head{display:flex;align-items:baseline;justify-content:space-between;margin:36px 0 18px;flex-wrap:wrap;gap:8px;}
  .dash-head h2{font-size:24px;margin:0;color:var(--navy);}
  .dash-head p{color:var(--ink-soft);font-size:14px;margin:4px 0 0;}

  .domain-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:16px;}
  #classroomsHubGrid.domain-grid{align-items:start;}
  #classroomsHubGrid > .classrooms-section{grid-column:1/-1;}
  .classrooms-section{margin-bottom:12px;}
  .classrooms-section-heading{
    font-size:19px;padding:14px 4px;cursor:pointer;list-style:none;
    display:flex;align-items:center;gap:8px;user-select:none;
  }
  .classrooms-section-heading::-webkit-details-marker{display:none;}
  .classrooms-section-heading::before{content:'▸';font-size:14px;color:var(--sub, #888);transition:transform .15s;}
  details[open] > .classrooms-section-heading::before{transform:rotate(90deg);}
  .classrooms-section-count{font-size:14px;font-weight:400;color:var(--sub, #888);}
  .classrooms-section-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:16px;margin:4px 0 8px;}
  /* "N of M classrooms completed" bar - hub and parent report (classroomProgressEl). */
  .domain-grid > .classroom-progress{grid-column:1/-1;}
  .classroom-progress{margin-bottom:12px;}
  .classroom-progress-head{display:flex;justify-content:space-between;align-items:baseline;gap:12px;margin-bottom:8px;}
  .classroom-progress-track{height:10px;border-radius:999px;background:var(--line);overflow:hidden;}
  .classroom-progress-fill{height:100%;width:0;border-radius:999px;background:var(--sage);transition:width .3s;}
  .card{
    background:var(--paper);border-radius:var(--radius);
    padding:22px;border:1px solid var(--line);
    box-shadow:var(--shadow);
    display:flex;flex-direction:column;gap:12px;
  }
  .card-top{display:flex;align-items:center;justify-content:space-between;}
  .domain-icon{
    width:40px;height:40px;border-radius:10px;
    display:flex;align-items:center;justify-content:center;
    font-size:19px;
  }
  .card h3{font-size:18px;margin:0;color:var(--navy);}
  .card .meta{font-size:12.5px;color:var(--ink-soft);}

  /* Sits under the options on every question. Quiet by design: a child
     should read the question, not the disclaimer - but it is present at the
     moment a wrong answer is actually in front of them, which is the only
     moment it is any use. */
  .ai-footnote{
    margin-top:18px;padding-top:12px;border-top:1px solid var(--line);
    font-size:11.5px;line-height:1.45;color:var(--ink-soft);
  }
  /* The "Question N of M" line, with Report a mistake pinned to its right -
     directly under the progress bar and right-aligned with Exit. It used to
     sit in the footnote just above Back, and students hit it by accident
     when reaching for Back; since reporting also skips the question, a
     mis-click cost them that question. Up here it is far from Back/Next. */
  .q-counter-row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px;}
  .q-counter-row .q-counter{margin-bottom:0;}
  .report-btn[aria-expanded="true"]{border-color:var(--navy);}
  /* "What's wrong?" - opens from Report a mistake. Picking a reason is what
     files the report, so a stray tap on the button alone does nothing. */
  .report-reasons{
    display:flex;align-items:center;justify-content:flex-end;flex-wrap:wrap;gap:6px;
    margin:-2px 0 14px;font-size:12.5px;color:var(--ink-soft);
  }
  .report-reasons.hidden{display:none;}
  .report-reasons .report-reasons-label{font-weight:700;margin-right:2px;}
  .report-reasons .report-btn.cancel{color:var(--ink-soft);font-weight:600;}
  .report-btn{
    flex-shrink:0;
    background:none;border:1px solid var(--line);border-radius:999px;
    padding:5px 12px;font-family:inherit;font-size:11.5px;font-weight:700;
    color:var(--navy);cursor:pointer;
  }
  .report-btn:hover:not(:disabled){border-color:var(--navy);}
  .report-btn:disabled{color:var(--sage);border-color:var(--sage);cursor:default;}
  .ladder{display:flex;gap:4px;margin-top:2px;}
  .rung{flex:1;height:7px;border-radius:4px;background:var(--line);}
  .rung.filled{background:var(--sage);}
  .card-foot{display:flex;align-items:center;justify-content:space-between;margin-top:4px;}
  .best-score{font-size:13px;color:var(--ink-soft);}
  .best-score b{color:var(--ink);}

  /* min-width:0 lets the input shrink inside the 380px card; without it the
     input's intrinsic width pushes the Add/Join button past the card edge. */
  .add-student-card input{
    flex:1;min-width:0;padding:10px 14px;border-radius:10px;border:1.5px solid var(--line);
    font-family:'Inter',sans-serif;font-size:14.5px;
  }
  .add-student-card select{
    flex-shrink:0;padding:10px 12px;border-radius:10px;border:1.5px solid var(--line);
    background:var(--paper);color:var(--ink);font-family:'Inter',sans-serif;font-size:14px;cursor:pointer;
  }
  .add-student-row{display:flex;gap:10px;flex-wrap:wrap;}
  .add-student-row input{flex:1 1 120px;}
  #shareCodeMergeSelect{flex:1 1 100%;min-width:0;}

  .ai-summary-card{margin-bottom:16px;}
  .ai-summary-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:8px;}
  .ai-summary-head h3{font-size:15px;margin:0;color:var(--navy);}
  #aiSummaryText{line-height:1.55;}
  #aiSummaryText.ai-summary-error{color:var(--coral,#D9694F);}

  .student-name-row{display:flex;align-items:center;gap:6px;}
  .rename-btn{background:none;border:none;cursor:pointer;font-size:14px;line-height:1;
    color:var(--ink-soft);padding:2px 4px;border-radius:6px;}
  .rename-btn:hover{color:var(--navy);background:var(--cream);}
  .student-rename-form{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:2px 0 4px;}
  .student-rename-form input{flex:1;min-width:0;padding:8px 10px;border-radius:8px;
    border:1.5px solid var(--line);font-family:'Inter',sans-serif;font-size:14.5px;}
  .btn-compact{padding:8px 14px;font-size:13px;}
  .report-window{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px;}

  /* ---------- Test screen ---------- */
  .test-wrap{background:var(--paper);border-radius:20px;padding:30px 34px;box-shadow:var(--shadow);border:1px solid var(--line);}
  .test-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px;flex-wrap:wrap;gap:10px;}
  .test-title{display:flex;align-items:center;gap:10px;}
  .test-title h2{margin:0;font-size:20px;color:var(--navy);}
  .timer{
    display:flex;align-items:center;gap:7px;
    font-family:'Inter',sans-serif;font-weight:700;font-size:15px;
    padding:7px 14px;border-radius:999px;background:var(--cream);border:1px solid var(--line);
    color:var(--ink);
  }
  .progress-track{height:6px;background:var(--line);border-radius:4px;margin:18px 0 26px;overflow:hidden;}
  .progress-fill{height:100%;background:linear-gradient(90deg,var(--gold),var(--coral));border-radius:4px;transition:width .3s ease;}

  .q-counter{font-size:12.5px;color:var(--ink-soft);text-transform:uppercase;letter-spacing:0.08em;font-weight:700;margin-bottom:10px;}
  .q-stem{font-size:18px;line-height:1.55;margin:0 0 20px;color:var(--ink);}
  .passage{
    background:var(--cream);border-left:3px solid var(--gold);
    padding:16px 18px;border-radius:8px;font-size:14.5px;line-height:1.7;
    color:var(--ink-soft);margin-bottom:22px;max-height:220px;overflow-y:auto;
  }
  .passage h4{margin:0 0 8px;color:var(--ink);font-size:14px;font-family:'Inter',sans-serif;font-weight:700;}
  /* "Text 2 of 5" above the passage in a multi-text genuine Reading sitting. */
  .passage-label{font-size:12.5px;color:var(--ink-soft);font-weight:600;margin:0 0 6px;}

  .chart-box{
    background:var(--cream);border:1px solid var(--line);border-radius:8px;
    padding:18px 20px 14px;margin:0 0 20px;
  }
  .bar-chart{display:flex;align-items:flex-end;gap:18px;min-height:130px;padding-top:22px;}
  .bar-col{display:flex;flex-direction:column;align-items:center;gap:6px;flex:1 1 0;min-width:0;}
  .bar-value{font-size:13px;font-weight:700;color:var(--ink);font-family:'Inter',sans-serif;}
  .bar-fill{width:100%;max-width:28px;background:var(--gold);border-radius:4px 4px 0 0;}
  .bar-cat{font-size:12px;color:var(--ink-soft);text-align:center;line-height:1.3;word-break:break-word;}
  .chart-caption{font-size:12px;color:var(--ink-soft);text-align:center;margin-top:10px;font-style:italic;}
  .data-table{width:100%;border-collapse:collapse;font-size:14px;}
  .data-table th,.data-table td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--line);}
  .data-table th{color:var(--navy);font-family:'Inter',sans-serif;font-weight:700;font-size:12.5px;text-transform:uppercase;letter-spacing:0.04em;}
  .data-table td{color:var(--ink-soft);}
  .data-table tr:last-child td{border-bottom:none;}

  .options{display:flex;flex-direction:column;gap:10px;margin-bottom:26px;}
  .option{
    display:flex;align-items:center;gap:12px;
    padding:14px 16px;border-radius:10px;border:1.5px solid var(--line);
    cursor:pointer;font-size:15px;transition:border-color .12s ease, background .12s ease;
    background:var(--paper);
  }
  .option:hover{border-color:var(--gold);}
  .option.selected{border-color:var(--navy);background:#F1F3F8;}
  /* Locked once instant feedback has revealed the answer (see the click
     handler in renderQuestion) - no hover affordance for a pick that can no
     longer change. */
  .options.locked .option{cursor:default;}
  .option:focus-visible{outline:2px solid var(--gold);outline-offset:2px;}
  .options.locked .option:hover{border-color:var(--line);}
  .option .letter{
    width:26px;height:26px;border-radius:50%;background:var(--cream);border:1px solid var(--line);
    display:flex;align-items:center;justify-content:center;font-size:12.5px;font-weight:700;flex-shrink:0;
  }
  .option.selected .letter{background:var(--navy);color:white;border-color:var(--navy);}

  textarea.writing-box{
    width:100%;min-height:260px;padding:16px;border-radius:10px;border:1.5px solid var(--line);
    font-family:'Inter',sans-serif;font-size:15px;line-height:1.6;resize:vertical;
  }
  textarea.writing-box:focus{outline:none;border-color:var(--navy);}
  .word-count{font-size:12.5px;color:var(--ink-soft);margin-top:8px;}

  .test-foot{display:flex;justify-content:space-between;align-items:center;margin-top:8px;}

  /* "Before you finish" - unanswered questions listed as jump buttons (see
     showUnansweredReminder in app.js). The stem is cut to one line: it's
     there to jog the student's memory, not to be read in full. */
  .unanswered-list{display:flex;flex-direction:column;gap:8px;margin-bottom:12px;}
  .unanswered-jump{display:flex;gap:10px;align-items:baseline;text-align:left;width:100%;min-width:0;}
  .unanswered-jump b{flex:none;}
  .unanswered-jump span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink-soft);font-weight:400;}

  /* "Question reported · Undo" - the grace window after Report a mistake.
     Fixed to the bottom so it survives the question re-render that moves the
     student on; lifted on phones so it clears the Work area button. */
  .undo-toast{
    position:fixed;left:50%;bottom:22px;transform:translateX(-50%);z-index:62;
    display:flex;align-items:center;gap:14px;
    max-width:calc(100vw - 32px);padding:10px 12px 10px 18px;border-radius:999px;
    background:var(--navy);color:white;box-shadow:var(--shadow);
    font-size:14px;font-weight:600;
  }
  .undo-toast.hidden{display:none;}
  .undo-toast button{
    background:none;border:1px solid rgba(255,255,255,.5);border-radius:999px;
    padding:6px 14px;color:white;font-family:inherit;font-size:13.5px;font-weight:700;cursor:pointer;
  }
  .undo-toast button:hover{border-color:white;}
  @media (max-width:640px){ .undo-toast{bottom:84px;} }

  /* ---------- Work area (scratch pad / calculator) ---------- */
  .workarea-fab{
    position:fixed;right:22px;bottom:22px;z-index:60;
    display:flex;align-items:center;gap:8px;padding:12px 18px;border-radius:999px;
    background:var(--navy);color:white;border:none;box-shadow:var(--shadow);
    font-family:'Inter',sans-serif;font-weight:700;font-size:14px;cursor:pointer;
  }
  .workarea-fab:hover{background:var(--navy-soft);}
  .workarea-panel{
    position:fixed;right:22px;bottom:22px;z-index:61;
    width:320px;max-width:calc(100vw - 32px);max-height:min(520px,calc(100vh - 100px));
    background:var(--paper);border-radius:16px;border:1px solid var(--line);box-shadow:var(--shadow);
    display:flex;flex-direction:column;overflow:hidden;
  }
  .workarea-panel.hidden{display:none;}
  /* Expanded mode ("⛶") takes up most of the viewport, centered, so the
     scratch pad/draw pad get real working room instead of a small corner
     widget - toggled via workAreaExpandBtn, see toggleWorkAreaExpand(). */
  .workarea-panel.expanded{
    left:50%;right:auto;top:20px;bottom:20px;transform:translateX(-50%);
    width:min(960px,calc(100vw - 40px));height:calc(100vh - 40px);max-height:calc(100vh - 40px);
  }
  .workarea-head{display:flex;align-items:center;justify-content:space-between;padding:12px 14px;background:var(--navy);color:white;}
  .workarea-head h3{margin:0;font-size:14.5px;font-family:'Inter',sans-serif;}
  .workarea-head-actions{display:flex;align-items:center;gap:4px;}
  .workarea-expand,.workarea-close{background:none;border:none;color:white;font-size:18px;cursor:pointer;line-height:1;padding:2px 6px;}
  .workarea-tabs{display:flex;border-bottom:1px solid var(--line);flex-shrink:0;}
  .workarea-tab{
    flex:1;padding:10px;text-align:center;font-family:'Inter',sans-serif;font-weight:700;font-size:13px;
    color:var(--ink-soft);background:var(--cream);border:none;cursor:pointer;border-bottom:2px solid transparent;
  }
  .workarea-tab.active{color:var(--navy);background:var(--paper);border-bottom-color:var(--gold);}
  .workarea-body{padding:14px;overflow-y:auto;flex:1;display:flex;flex-direction:column;}
  .scratch-textarea{
    width:100%;flex:1;min-height:220px;padding:10px;border-radius:8px;border:1.5px solid var(--line);
    font-family:'Inter',sans-serif;font-size:14px;line-height:1.5;resize:vertical;box-sizing:border-box;
  }
  .scratch-textarea:focus{outline:none;border-color:var(--navy);}
  .calc-display{
    width:100%;box-sizing:border-box;text-align:right;font-family:'Inter',sans-serif;
    font-size:26px;font-weight:700;color:var(--ink);background:var(--cream);
    border-radius:8px;padding:14px 12px;margin-bottom:10px;overflow-x:auto;white-space:nowrap;
  }
  .calc-wrap{width:100%;max-width:360px;margin:0 auto;}
  .calc-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;}
  .calc-btn{
    padding:14px 0;border-radius:8px;border:1px solid var(--line);background:var(--paper);
    font-family:'Inter',sans-serif;font-weight:700;font-size:16px;cursor:pointer;color:var(--ink);
  }
  .calc-btn:hover{border-color:var(--gold);}
  .calc-btn.op{background:var(--cream);color:var(--navy);}
  .calc-btn.eq{background:var(--navy);color:white;grid-column:span 2;}
  .calc-btn.clear{color:var(--coral);}

  .draw-toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:10px;}
  .draw-swatch{
    width:22px;height:22px;border-radius:50%;border:2px solid var(--line);cursor:pointer;padding:0;
  }
  .draw-swatch.active{border-color:var(--navy);box-shadow:0 0 0 2px var(--cream);}
  .draw-size{width:70px;}
  .draw-tool-btn{
    padding:6px 10px;border-radius:8px;border:1px solid var(--line);background:var(--paper);
    font-family:'Inter',sans-serif;font-weight:700;font-size:12.5px;cursor:pointer;color:var(--ink);
  }
  .draw-tool-btn.active{border-color:var(--navy);background:#F1F3F8;color:var(--navy);}
  .draw-canvas-wrap{border:1.5px solid var(--line);border-radius:8px;overflow:hidden;background:#fff;touch-action:none;user-select:none;flex:1;min-height:220px;}
  #drawCanvas{display:block;width:100%;height:100%;cursor:crosshair;touch-action:none;user-select:none;-webkit-user-select:none;}

  /* ---------- Results ---------- */
  .results-hero{
    display:flex;gap:28px;align-items:center;background:var(--navy);
    border-radius:20px;padding:36px;color:white;box-shadow:var(--shadow);flex-wrap:wrap;
  }
  .score-ring{
    width:120px;height:120px;border-radius:50%;
    background:conic-gradient(var(--gold) calc(var(--pct,0)*1%), rgba(255,255,255,0.12) 0);
    display:flex;align-items:center;justify-content:center;flex-shrink:0;
  }
  .score-ring-inner{
    width:94px;height:94px;border-radius:50%;background:var(--navy);
    display:flex;flex-direction:column;align-items:center;justify-content:center;
  }
  .score-ring-inner b{font-size:26px;font-family:'Fraunces',serif;}
  .score-ring-inner span{font-size:11px;color:#B7C0D4;}
  .results-hero h2{margin:0 0 6px;font-size:22px;}
  .band-pill{
    display:inline-block;padding:5px 14px;border-radius:999px;background:var(--gold);
    color:var(--navy);font-weight:700;font-size:12.5px;margin-top:8px;
  }
  .review-list{margin-top:26px;display:flex;flex-direction:column;gap:12px;}
  .review-item{
    background:var(--paper);border:1px solid var(--line);border-radius:12px;padding:16px 18px;
  }
  .review-item .row1{display:flex;gap:10px;align-items:flex-start;margin-bottom:6px;}
  .tag{
    flex-shrink:0;width:22px;height:22px;border-radius:50%;
    display:flex;align-items:center;justify-content:center;font-size:12px;color:white;font-weight:700;
  }
  .tag.correct{background:var(--sage);}
  .tag.incorrect{background:var(--coral);}
  .tag.skipped{background:var(--ink-3, #9aa1ab);}
  .tag.score-pill{width:auto;border-radius:999px;padding:0 8px;background:var(--navy);}
  .review-item .stem{font-size:14.5px;font-weight:600;}
  .review-item .explain{font-size:13.5px;color:var(--ink-soft);margin-left:32px;line-height:1.5;}
  .review-item .your-ans{font-size:13px;margin-left:32px;color:var(--ink-soft);margin-bottom:4px;}
  .review-item .explain-more{margin-left:32px;}

  .attempt-row{cursor:pointer;}
  .attempt-row .row1{justify-content:space-between;}
  .attempt-actions{display:flex;align-items:center;gap:10px;flex-shrink:0;}
  .attempt-toggle{font-size:12px;color:var(--ink-soft);white-space:nowrap;}
  .attempt-expand{margin-top:12px;}
  .btn-mini{
    font-size:11.5px;font-weight:600;padding:4px 9px;border-radius:999px;
    border:1px solid var(--line);background:#fff;color:var(--ink-soft);cursor:pointer;white-space:nowrap;
  }
  .btn-mini:disabled{opacity:.6;cursor:default;}

  .error-banner{
    background:#FBEAE6;border:1px solid #F0C8BE;color:var(--coral);
    padding:14px 18px;border-radius:10px;font-size:14px;margin-bottom:18px;
  }

  .settings-row{display:flex;align-items:center;justify-content:space-between;gap:20px;}
  .switch-toggle{
    flex-shrink:0;width:46px;height:26px;border-radius:999px;
    background:var(--line);border:none;position:relative;cursor:pointer;padding:0;
    transition:background .15s ease;
  }
  .switch-toggle-knob{
    position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;
    background:var(--paper);box-shadow:0 1px 3px rgba(0,0,0,0.2);
    transition:transform .15s ease;
  }
  .switch-toggle[aria-checked="true"]{background:var(--sage);}
  .switch-toggle[aria-checked="true"] .switch-toggle-knob{transform:translateX(20px);}
  /* Genuine (real-exam) countdown, last minute: flag the timer red so the student notices the clock running out. */
  .timer.timer-low{color:#c0392b;font-weight:700;}
  /* Section allowance has run out but the student keeps answering (ClickUp
     task #21) - amber rather than timer-low's alarm red, since nothing is
     about to be cut off; it's just noting the clock kept going. */
  .timer.timer-overtime{color:#b7791f;font-weight:700;}

  /* Instant-feedback reveal state on an answered MCQ option (see
     renderQuestion's revealed[] handling) */
  .option.reveal-correct{border-color:var(--sage);background:#EAF3EE;}
  .option.reveal-incorrect{border-color:var(--coral);background:#FBEDEA;}
  .option.reveal-correct .letter{background:var(--sage);color:white;border-color:var(--sage);}
  .option.reveal-incorrect .letter{background:var(--coral);color:white;border-color:var(--coral);}
  .reveal-explain{
    background:var(--cream);border-left:3px solid var(--sage);padding:12px 16px;
    border-radius:8px;font-size:13.5px;line-height:1.6;color:var(--ink-soft);margin:-10px 0 20px;
  }
  .reveal-explain.is-wrong{border-left-color:var(--coral);}

  /* "Show me the steps" - the interactive wrong-answer explainer under a
     revealed wrong MCQ answer (instant feedback, the results review list,
     and the parent report's per-attempt question list). See
     wireExplainMoreButtons/loadExplainMore/renderExplainSteps. */
  .explain-more{margin-top:10px;}
  .explain-more-btn{
    background:none;border:none;color:var(--navy);font-weight:700;font-size:13px;
    cursor:pointer;padding:4px 0;text-decoration:underline;text-underline-offset:2px;
  }
  .explain-more-btn:disabled{opacity:.6;cursor:default;text-decoration:none;}
  .explain-more-body{margin-top:8px;background:var(--cream);border-radius:8px;padding:12px 16px;font-size:13.5px;line-height:1.6;color:var(--ink-soft);}
  .explain-more-wrong{margin-bottom:8px;}
  .explain-more-steps{margin:0 0 8px;padding-left:20px;}
  .explain-more-steps li{margin-bottom:4px;}
  .explain-more-final{margin-top:8px;font-weight:600;color:var(--ink);}

  /* Classroom widget styles (cw-*) live in classroom-widgets.css. */

  footer.appfoot{margin-top:60px;text-align:center;font-size:12px;color:var(--ink-soft);}
  footer.appfoot a{color:inherit;}
  @media (prefers-reduced-motion: reduce){.btn,.option,.progress-fill{transition:none;}}

  /* ---------- Billing (Foundation/Premium) ---------- */
  #billingBanner{
    max-width:960px;margin:0 auto 18px;padding:12px 16px;border-radius:10px;
    font-size:14px;font-weight:600;display:flex;justify-content:space-between;gap:12px;align-items:center;
  }
  #billingBanner.success{background:#E4F3E9;color:#2A6B45;border:1.5px solid #B7DFC4;}
  #billingBanner.cancelled{background:#F3EEDB;color:#7A6320;border:1.5px solid #E3D8A8;}
  /* Same visual language as #billingBanner.success, as a reusable class -
     that rule is ID-scoped (only applies to #billingBanner itself), so
     the signup promo banner (a different element) needs its own copy. */
  .success-banner{
    max-width:960px;margin:0 auto 18px;padding:12px 16px;border-radius:10px;
    font-size:14px;font-weight:600;
    background:#E4F3E9;color:#2A6B45;border:1.5px solid #B7DFC4;
  }
  #billingBanner button{background:none;border:none;font-size:16px;cursor:pointer;color:inherit;opacity:.6;}
  /* Complimentary Premium countdown (compNudgeBanner). Gold while there's
     time left, coral in the last week so it reads as "act soon" without
     looking like an error. */
  .plan-nudge{
    max-width:960px;margin:0 auto 18px;padding:10px 12px 10px 16px;border-radius:10px;
    display:flex;align-items:center;gap:12px;flex-wrap:wrap;
    font-size:14px;background:#FFF6DE;color:#7A5B0F;border:1.5px solid #F1D98F;
  }
  .plan-nudge.urgent{background:#FBEDEA;color:#9C3D26;border-color:#EBB9AC;}
  .plan-nudge-text{flex:1 1 260px;line-height:1.45;}
  .plan-nudge-cta{padding:8px 14px;font-size:13.5px;}
  .plan-nudge-close{background:none;border:none;font-size:18px;line-height:1;cursor:pointer;color:inherit;opacity:.6;padding:4px;}
  .plan-nudge-close:hover{opacity:1;}
  #billingBanner button:hover{opacity:1;}
  .premium-badge{
    display:inline-block;font-size:10.5px;font-weight:700;text-transform:uppercase;
    letter-spacing:0.05em;color:#7A5B0F;background:#FBE9BE;padding:3px 8px;border-radius:999px;
  }
  .new-badge-mini{
    display:inline-block;font-size:10.5px;font-weight:700;text-transform:uppercase;
    letter-spacing:0.05em;color:#1F6B4A;background:#D8F3E4;padding:3px 8px;border-radius:999px;
  }
  /* .new-badge-hero and .promo-banner-hero removed with the two stacked
     hero announcements they styled; their content lives in .hero-offer. */
  .price-row{
    display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin-bottom:14px;
  }
  .price-now{font-size:22px;font-weight:800;color:var(--navy);}
  .price-now .price-unit{font-size:13px;font-weight:600;color:var(--ink-soft);}
  .price-was{font-size:14px;color:var(--ink-soft);text-decoration:line-through;text-decoration-color:var(--coral);}
  .price-tag{
    font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:0.05em;
    color:#7A5B0F;background:#FBE9BE;padding:3px 8px;border-radius:999px;
  }

  .games-hub-upsell{
    display:flex;align-items:center;gap:20px;flex-wrap:wrap;justify-content:space-between;
    background:var(--paper);border:1.5px solid var(--gold-soft);border-radius:14px;
    padding:18px 22px;margin-bottom:18px;
  }
  .games-hub-upsell strong{display:block;font-size:15px;margin-bottom:2px;}
  @media (max-width:640px){ .games-hub-upsell{flex-direction:column;align-items:flex-start;} }

  /* ---------- Learning Games (hub + Clock Reading) ---------- */
  .soon-badge{
    display:inline-block;font-size:10.5px;font-weight:700;text-transform:uppercase;
    letter-spacing:0.05em;color:var(--ink-soft);background:var(--line);
    padding:3px 8px;border-radius:999px;
  }
  .choice-group{display:flex;gap:8px;flex-wrap:wrap;}
  .choice-btn{
    border:1.5px solid var(--line);background:var(--paper);color:var(--ink);
    border-radius:999px;padding:9px 16px;font-family:'Inter',sans-serif;font-weight:700;
    font-size:13.5px;cursor:pointer;transition:border-color .12s ease, background .12s ease, color .12s ease;
  }
  .choice-btn:hover{border-color:var(--navy);}
  .choice-btn.active{background:var(--navy);border-color:var(--navy);color:white;}
  .choice-btn.chip-static{cursor:default;}
  .choice-btn.chip-static:hover{border-color:var(--line);}
  .choice-btn.chip-home{border-color:var(--gold);border-width:2px;}
  .choice-btn.chip-target{border-color:var(--sage);border-width:2px;}
  .choice-group-label{font-size:12.5px;font-weight:700;color:var(--ink-soft);text-transform:uppercase;letter-spacing:0.06em;margin:4px 0 2px;}

  .clock-svg{width:100%;max-width:320px;height:auto;touch-action:none;user-select:none;}
  .clock-svg .hand{cursor:grab;transition:transform .12s ease-out;}
  /* while dragging, the hand tracks the finger 1:1 - the transition is only
     for programmatic moves (round changes, glide-to-correct feedback) */
  .clock-svg.dragging .hand{transition:none;}
  .clock-svg .hand:active{cursor:grabbing;}
  .clock-svg .hand-hit{fill:transparent;stroke:transparent;stroke-width:22;}
  .clock-svg .hand.selected line:first-child{filter:drop-shadow(0 0 3px rgba(231,169,60,0.9));}
  .hand-select-group{margin:6px 0 2px;}

  /* Twin-clock layout (Timezones): home clock (given) beside target clock (answer) */
  .twin-clocks{display:flex;gap:10px;justify-content:center;align-items:flex-start;flex-wrap:wrap;margin-top:4px;}
  .clock-col{display:flex;flex-direction:column;align-items:center;flex:1 1 140px;max-width:200px;}
  .twin-clocks .clock-svg{max-width:100%;}
  .clock-city-label{font-family:'Fraunces',serif;font-weight:600;font-size:15px;color:var(--navy);margin-bottom:6px;min-height:20px;}
  .clock-city-label.clock-city-target{color:var(--coral);}
  .clock-col-caption{font-size:11.5px;color:var(--ink-soft);margin-top:6px;text-transform:uppercase;letter-spacing:0.05em;font-weight:700;}
  /* "what's happening there" chip - day/night + daily-life context under each clock */
  .day-part{display:inline-block;font-size:11.5px;font-weight:700;line-height:1.3;
    padding:5px 11px;border-radius:12px;margin:5px 2px 0;}
  .day-part.day{background:#FBE7BE;color:#7A5710;}
  .day-part.night{background:var(--navy);color:#DDE4F2;}
  /* spinning globe (day/night + pinned cities) */
  .tz-world-map{width:100%;max-width:230px;margin:2px auto 4px;}
  .tz-world-map svg{width:100%;height:auto;display:block;}
  /* date-boundary: weekday under each clock + the "it's the next day!" callout */
  .clock-weekday{font-size:12.5px;font-weight:700;color:var(--ink-soft);margin:-2px 0 4px;}
  .tz-crossing{display:inline-block;background:#EDE7F6;border:1px solid #C9B8E8;color:#5B3E86;
    border-radius:12px;padding:7px 13px;font-size:13px;font-weight:700;margin:2px auto 8px;}
  .clock-digital-home{color:var(--ink-soft);}
  .clock-static{touch-action:auto;}
  .clock-static .hand{cursor:default;}
  .clock-static .hand.selected line:first-child{filter:none;}

  /* ---------- Money Counting ---------- */
  .money-collection{display:flex;gap:5px;flex-wrap:wrap;justify-content:center;min-height:30px;margin-bottom:6px;}
  .money-collection .slot{width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:19px;background:var(--cream);border:1px dashed var(--line);}
  .money-collection .slot.filled{background:#EAF3EE;border-style:solid;border-color:var(--sage);animation:pop .35s ease;}
  @keyframes pop{0%{transform:scale(0.3);}70%{transform:scale(1.18);}100%{transform:scale(1);}}
  .money-item-card{background:linear-gradient(135deg,#FFF6E6,#FDEBD8);border:1px solid var(--line);border-radius:var(--radius);
    padding:12px 16px;margin:2px auto 8px;max-width:320px;box-shadow:var(--shadow);animation:pop .4s ease;}
  .money-item-emoji{font-size:40px;line-height:1;}
  .money-item-name{font-weight:700;color:var(--navy);font-size:15px;margin-top:2px;}
  .money-target{font-family:'Fraunces',serif;font-size:26px;font-weight:600;color:var(--coral);margin-top:4px;}
  .money-hint{font-size:13px;font-weight:700;color:var(--ink-soft);min-height:18px;margin:2px 0 8px;}
  .money-total-bar{font-family:'Fraunces',serif;font-size:30px;font-weight:600;color:var(--navy);}
  .money-total-bar small{font-family:'Inter',sans-serif;font-size:12.5px;font-weight:700;color:var(--ink-soft);}
  .pay-tray{min-height:56px;display:flex;gap:5px;flex-wrap:wrap;justify-content:center;align-items:center;
    background:var(--cream);border:1.5px dashed var(--line);border-radius:12px;padding:8px;margin:6px auto 4px;max-width:420px;}
  .pay-tray .placeholder{color:var(--ink-soft);font-size:12.5px;}
  .money-tray{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin:6px auto;max-width:440px;}
  .money-piece{background:none;border:none;padding:0;cursor:pointer;line-height:0;transition:transform .08s ease;}
  .money-piece:active{transform:scale(0.9);}
  .money-piece.added{animation:pop .28s ease;}
  .money-piece svg{display:block;}
  .money-teaser{display:inline-block;background:#EDE7F6;border:1px solid #C9B8E8;color:#5B3E86;border-radius:12px;
    padding:8px 14px;font-size:14px;font-weight:700;margin:4px auto;animation:pop .4s ease;}
  .shop-list{display:flex;gap:5px;flex-wrap:wrap;justify-content:center;margin-bottom:4px;}
  .shop-list .tick{width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;
    font-size:14px;background:var(--cream);border:1.5px solid var(--line);color:var(--ink-soft);}
  .shop-list .tick.done{background:var(--sage);border-color:var(--sage);color:#fff;}

  /* ---------- Fraction Blocks ---------- */
  /* Big stacked numerator/denominator glyph (not a slash) - readable before
     a student has learned fraction notation, since the plain-words prompt
     line above it carries the meaning first. */
  .fraction-readout{display:inline-flex;flex-direction:column;align-items:center;line-height:1;margin:2px 0 16px;}
  .fraction-readout .fraction-num,.fraction-readout .fraction-den{
    font-family:'Fraunces',serif;font-size:34px;font-weight:600;color:var(--navy);
  }
  .fraction-readout .fraction-line{width:38px;height:3px;background:var(--navy);border-radius:2px;margin:3px 0;}
  /* Bar of equal blocks (a chocolate-bar strip) - each block is its own
     button so taps are large touch targets even at denominator 12. Wraps
     onto a second row past ~8 blocks rather than shrinking unreadably thin. */
  .fraction-bar{display:flex;flex-wrap:wrap;gap:5px;justify-content:center;align-items:stretch;
    max-width:420px;margin:0 auto;padding:6px;}
  .fraction-block{flex:1 1 34px;min-width:34px;max-width:64px;height:64px;border-radius:10px;
    border:2px solid var(--line);background:var(--paper);cursor:pointer;padding:0;
    transition:transform .08s ease,border-color .15s ease;}
  .fraction-block:active{transform:scale(0.93);}
  .fraction-block.shaded{border-color:transparent;animation:pop .3s ease;}
  /* Name-it's bar is pre-shaded and read-only - no pointer feedback, so it
     doesn't look tappable when it isn't. */
  .fraction-bar.readonly .fraction-block{cursor:default;}
  .fraction-bar.readonly .fraction-block:active{transform:none;}

  /* Name-it: multiple-choice fraction chips, answered by a single tap
     (no separate Check step - unlike Shade-it, there's nothing to build up
     first). */
  .fraction-choices{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin:6px auto 4px;max-width:420px;}
  .frac-chip{font-family:'Fraunces',serif;font-size:22px;font-weight:600;min-width:64px;padding:10px 16px;}
  .frac-chip.correct{background:#EAF3EE;border-color:var(--sage);color:#2E5C42;}
  .frac-chip.wrong{background:#FBEDEA;border-color:var(--coral);color:#9C3D26;}
  .frac-chip:disabled{cursor:default;opacity:0.85;}

  /* Compare-it: two mini bars side by side, each its own tap target ("pick
     the bigger one") plus a separate Equal option below for the cases
     where neither is. */
  .fraction-compare{display:flex;align-items:center;justify-content:center;gap:14px;margin:6px auto 4px;max-width:440px;}
  .fraction-compare-card{background:var(--cream);border:2px solid var(--line);border-radius:var(--radius);
    padding:10px;cursor:pointer;flex:1 1 0;transition:transform .08s ease,border-color .15s ease;}
  .fraction-compare-card:active{transform:scale(0.96);}
  .fraction-compare-card.correct{border-color:var(--sage);background:#EAF3EE;}
  .fraction-compare-card.wrong{border-color:var(--coral);background:#FBEDEA;}
  .fraction-compare-card:disabled{cursor:default;}
  .fraction-vs{font-family:'Fraunces',serif;font-weight:600;color:var(--ink-soft);font-size:15px;}
  .fraction-bar-mini{max-width:none;gap:3px;padding:2px;}
  .fraction-bar-mini .fraction-block{flex:1 1 18px;min-width:18px;max-width:30px;height:30px;border-radius:7px;border-width:1.5px;}

  .clock-digital{
    font-family:'Fraunces',serif;font-size:34px;font-weight:600;color:var(--navy);
    text-align:center;margin:14px 0 4px;
  }

  .game-toast{
    background:var(--cream);border:1px solid var(--line);border-radius:var(--radius);
    padding:12px 16px;font-size:14.5px;font-weight:600;text-align:center;
    margin:14px auto;max-width:420px;transition:background .15s ease, border-color .15s ease;
  }
  .game-toast.good{background:#EAF3EE;border-color:var(--sage);color:#2E5C42;}
  .game-toast.bad{background:#FBEDEA;border-color:var(--coral);color:#9C3D26;}
  /* Distinct celebratory color for Mental Maths Sprint's level-up toast -
     gold rather than the plain "good" green, so a level-up reads as a
     bigger deal than an ordinary correct answer. */
  .game-toast.levelup{background:#FFF6DE;border-color:var(--gold);color:#8A6D1D;}

  .mental-choices{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin:6px auto 4px;max-width:420px;}
  .mental-choice-btn{font-family:'Fraunces',serif;font-size:20px;font-weight:700;min-width:84px;padding:12px 18px;}
  .mental-choice-btn.correct{background:#EAF3EE;border-color:var(--sage);color:#2E5C42;}
  .mental-choice-btn.wrong{background:#FBEDEA;border-color:var(--coral);color:#9C3D26;}
  .mental-choice-btn:disabled{cursor:default;opacity:0.85;}
  /* Word Problem Sprint's prompt is a 1-3 sentence story, not a short
     expression - the 26px display size Mental Maths uses would wrap
     awkwardly, so it drops to a readable body size with a capped line
     length. */
  .word-prompt{font-size:19px;font-weight:600;line-height:1.45;color:var(--navy);max-width:560px;margin:14px auto 18px;font-family:'Fraunces',serif;}
  /* Perimeter & Area Sprint's labelled shape diagram (see shapeFigureSvg).
     Warm fill so the shape reads as a solid region, navy edges/labels to
     match the prompt text. */
  .shape-figure{margin:-6px auto 14px;}
  .shape-figure svg{width:min(320px,88vw);height:auto;display:block;margin:0 auto;}
  .shape-figure polygon{fill:#FFF6DE;stroke:var(--navy);stroke-width:2;stroke-linejoin:round;}
  .shape-figure .shape-tick,.shape-figure .shape-mark{stroke:var(--navy);stroke-width:1.6;fill:none;}
  .shape-figure text{fill:var(--navy);font-family:'Inter',sans-serif;font-size:13px;font-weight:600;}
  /* Chart & Graph Sprint charts (see columnChartSvg etc.). Categorical
     slots in fixed order from the dataviz reference palette, validated
     on white (adjacent CVD dE >= 9.1, normal-vision >= 22.9); slots 3-4
     are under 3:1 contrast, so pies always carry direct labels. Text uses
     ink colours, never the series colour; gridlines stay recessive. */
  .shape-figure{--chart-1:#2a78d6;--chart-2:#eb6834;--chart-3:#1baf7a;--chart-4:#eda100;}
  .shape-figure .chart-s1 path,.shape-figure .chart-s1 rect,.shape-figure .chart-s1-fill{fill:var(--chart-1);}
  .shape-figure .chart-s2 path,.shape-figure .chart-s2 rect,.shape-figure .chart-s2-fill{fill:var(--chart-2);}
  .shape-figure .chart-s3-fill{fill:var(--chart-3);}
  .shape-figure .chart-s4-fill{fill:var(--chart-4);}
  .shape-figure .chart-slice{stroke:#fff;stroke-width:2;stroke-linejoin:round;}
  .shape-figure .chart-grid{stroke:var(--line);stroke-width:1;}
  .shape-figure .chart-base{stroke:var(--ink-soft);}
  .shape-figure .chart-line{fill:none;stroke:var(--chart-1);stroke-width:2;stroke-linejoin:round;stroke-linecap:round;}
  .shape-figure .chart-dot{fill:var(--chart-1);stroke:#fff;stroke-width:2;}
  .shape-figure .chart-title{font-size:13px;font-weight:700;fill:var(--navy);}
  .shape-figure .chart-axis{font-size:11px;font-weight:500;fill:var(--ink-soft);}
  .shape-figure .chart-legend,.shape-figure .chart-label{font-size:12px;fill:var(--navy);}
  /* Probability Sprint's spinner and bag of counters (see spinnerSvg/
     bagSvg). Same palette as the charts; the bag and plain number
     sections stay warm/neutral so the counters and colours carry the
     question, and the arrow is decoration only. */
  .shape-figure .prob-bag{fill:#FFF6DE;stroke:var(--navy);stroke-width:2;stroke-linejoin:round;}
  .shape-figure .prob-tie{fill:none;stroke:var(--navy);stroke-width:2;stroke-linecap:round;}
  .shape-figure .prob-counter{stroke:#fff;stroke-width:1.5;}
  .shape-figure .prob-plain{fill:#FFF6DE;stroke:var(--navy);stroke-width:1.5;}
  .shape-figure .prob-arrow{fill:none;stroke:var(--navy);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;}
  .shape-figure .prob-hub{fill:var(--navy);}
  /* Decimals Sprint strips and hundred squares (see tenthsStripSvg/
     hundredSquareSvg): shaded cells keep their outline so the count stays
     readable where they meet. */
  .shape-figure .dec-cell{stroke:var(--navy);stroke-width:1.5;}
  /* Volume & Capacity Sprint's unit cubes (see cubePrismSvg): opaque
     faces, so nearer cubes hide farther ones and the block reads as
     solid, each outlined so the cubes can be counted. */
  .shape-figure .vol-top{fill:#C9DCF5;stroke:var(--navy);stroke-width:1.2;stroke-linejoin:round;}
  .shape-figure .vol-side{fill:#8FB5E6;stroke:var(--navy);stroke-width:1.2;stroke-linejoin:round;}

  /* Mitosis Multiply's answer choices are styled as petri-dish cell
     colonies (round, soft-green, gently pulsing) rather than plain
     buttons - the pulse is purely decorative flavor for the "cells
     multiply" theme, not a gameplay timer. */
  .mitosis-dish{
    background:radial-gradient(ellipse at center,#F4FBF6 0%,#E4F3E8 70%,#D6ECDC 100%);
    border:1px solid var(--line);border-radius:50%;
    width:min(320px,80vw);height:min(320px,80vw);margin:6px auto 4px;
    display:flex;align-items:center;justify-content:center;
  }
  .mitosis-choices{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;max-width:250px;}
  .mitosis-choice-btn{
    font-family:'Fraunces',serif;font-size:19px;font-weight:700;
    width:78px;height:78px;border-radius:50%;padding:0;
    background:#DCEFE2;border-color:var(--sage);
  }
  /* Motion sits behind no-preference (see .welcome-hero's own comment above) -
     this pulse is purely decorative and runs indefinitely, so a
     reduced-motion viewer gets a plain static colony instead of a WCAG
     2.2.2 auto-playing animation with no way to stop it. */
  @media (prefers-reduced-motion: no-preference){
    .mitosis-choice-btn{ animation:mitosisPulse 2.4s ease-in-out infinite; }
    .mitosis-choice-btn:nth-child(2){animation-delay:.3s;}
    .mitosis-choice-btn:nth-child(3){animation-delay:.6s;}
    .mitosis-choice-btn:nth-child(4){animation-delay:.9s;}
    @keyframes mitosisPulse{0%,100%{transform:scale(1);}50%{transform:scale(1.08);}}
  }
  .mitosis-choice-btn.correct{background:#EAF3EE;border-color:var(--sage);color:#2E5C42;animation:none;}
  .mitosis-choice-btn.wrong{background:#FBEDEA;border-color:var(--coral);color:#9C3D26;animation:none;}
  .mitosis-choice-btn:disabled{cursor:default;opacity:0.85;}

  .game-stats-row{
    display:flex;justify-content:center;gap:22px;margin:6px 0 8px;
    font-size:14px;color:var(--ink-soft);
  }
  .game-stats-row b{color:var(--ink);}
