/* ============================================================
   Sparks Academy — Learning Portal stylesheet
   Colour, type and layout tokens (UK English throughout)
   ============================================================ */

:root{
  /* Colour palette */
  --ink:        #1C2240;  /* deep exam-paper navy */
  --ink-soft:   #3A4166;
  --paper:      #F5F6FB;  /* cool paper */
  --card:       #FFFFFF;
  --line:       #E3E6F2;
  --spark:      #FFB300;  /* signature amber spark */
  --spark-deep: #E68A00;
  --violet:     #4F46B8;  /* primary action */
  --violet-soft:#EEEDFB;
  --green:      #178A5E;
  --green-soft: #E4F5EE;
  --red:        #C93A3A;
  --red-soft:   #FBEAEA;
  --muted:      #6A7090;

  --radius: 14px;
  --radius-sm: 9px;
  --shadow: 0 1px 2px rgba(28,34,64,.06), 0 8px 24px rgba(28,34,64,.07);
  --font-display: "Bricolage Grotesque", "Trebuchet MS", system-ui, sans-serif;
  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
}

*{ box-sizing:border-box; }
html,body{ margin:0; padding:0; }
body{
  font-family:var(--font-body);
  background:var(--paper);
  color:var(--ink);
  font-size:15px;
  line-height:1.55;
}
h1,h2,h3,h4{ font-family:var(--font-display); line-height:1.15; margin:0 0 .5em; letter-spacing:-.01em; }
h1{ font-size:1.7rem; font-weight:800; }
h2{ font-size:1.3rem; font-weight:700; }
h3{ font-size:1.05rem; font-weight:700; }
p{ margin:0 0 .8em; }
a{ color:var(--violet); }
code{ font-family:var(--font-mono); font-size:.85em; background:var(--violet-soft); padding:.1em .35em; border-radius:5px; }
.muted{ color:var(--muted); }
.small{ font-size:.85rem; }
.mono{ font-family:var(--font-mono); }
[hidden]{ display:none !important; }

:focus-visible{ outline:3px solid var(--spark); outline-offset:2px; border-radius:4px; }

/* ---------- App shell ---------- */
.app-shell{ display:grid; grid-template-columns:250px 1fr; min-height:100vh;
  transition:grid-template-columns .22s ease; }
.main-col{ display:flex; flex-direction:column; min-width:0; }
/* v11.60.0: less gutter, more page. 30px each side on a 1900px screen is
   dead space either side of content that wants to be wide. */
.view{ padding:20px 22px 56px; width:100%; margin:0 auto; }

/* Sidebar */
.sidebar{
  background:var(--ink); color:#fff;
  display:flex; flex-direction:column;
  padding:2px 4px; position:sticky; top:0; height:100vh;
}
.brand{ display:flex; gap:10px; align-items:center; margin-bottom:26px; }
.brand-mark{
  font-size:1.5rem; background:var(--spark); color:var(--ink);
  width:42px; height:42px; display:grid; place-items:center;
  border-radius:12px; box-shadow:0 3px 0 var(--spark-deep);
}
.brand-name{ font-family:var(--font-display); font-weight:800; font-size:1.05rem; line-height:1.05; }
.brand-name em{ font-style:normal; color:var(--spark); }
.brand-lg .brand-mark{ width:54px; height:54px; font-size:1.9rem; }
.brand-lg .brand-name{ font-size:1.3rem; }

/* v7.30: real logo image (Bright Sparks) — sits in the mark slot, shown in
   every theme. Contained so the full logo is visible, not cropped. */
.brand-logo-img{ width:42px; height:42px; object-fit:contain; display:block; border-radius:10px; background:#fff; padding:3px; }
.brand-lg .brand-logo-img{ width:56px; height:56px; }
.sidebar .brand-logo-img{ box-shadow:0 2px 6px rgba(0,0,0,.12); }

.side-nav{ display:flex; flex-direction:column; gap:2px; flex:1; overflow-y:auto; }
.side-nav .nav-group{ font-size:.68rem; text-transform:uppercase; letter-spacing:.12em; color:#9aa1c9; margin:16px 10px 4px; }
.side-nav a{
  display:flex; align-items:center; gap:10px;
  color:#d9dcf0; text-decoration:none; padding:9px 12px;
  border-radius:10px; font-weight:500; font-size:.92rem;
}
.side-nav a .ico{ width:22px; text-align:center; }
.side-nav a:hover{ background:rgba(255,255,255,.08); }
.side-nav a.active{ background:var(--spark); color:var(--ink); font-weight:700; box-shadow:0 2px 0 var(--spark-deep); }

.sidebar-foot{ margin-top:14px; border-top:1px solid rgba(255,255,255,.12); padding-top:14px; }
.me-chip{ font-size:.85rem; margin-bottom:10px; color:#d9dcf0; }
.me-chip b{ display:block; color:#fff; }

/* Topbar */
.topbar{
  display:flex; align-items:center; gap:14px;
  background:var(--card); border-bottom:1px solid var(--line);
  padding:12px 30px; position:sticky; top:0; z-index:20;
}
.topbar-title{ font-family:var(--font-display); font-weight:700; font-size:1.05rem; flex:1; }
.topbar-right{ display:flex; gap:10px; align-items:center; }
.hamburger{ display:none; background:none; border:1px solid var(--line); border-radius:8px; font-size:1.1rem; padding:4px 10px; cursor:pointer; }

/* Spark meter in topbar */
.spark-meter{
  display:flex; align-items:center; gap:8px;
  background:var(--ink); color:#fff; border-radius:999px;
  padding:5px 14px 5px 8px; font-size:.85rem;
}
.spark-meter .flame{ font-size:1rem; }
.spark-meter b{ color:var(--spark); font-family:var(--font-mono); }

/* ---------- Cards, grids ---------- */
.card{ background:var(--card); border:1px solid var(--line); border-radius:var(--radius); box-shadow:var(--shadow); padding:20px; }
.card + .card{  }
.card-head{ display:flex; justify-content:space-between; align-items:center; gap:12px; margin-bottom:12px; flex-wrap:wrap; }
.grid{ display:grid; gap:18px; }
.grid-2{ grid-template-columns:repeat(2,1fr); }
.grid-3{ grid-template-columns:repeat(3,1fr); }
.grid-4{ grid-template-columns:repeat(4,1fr); }
.stat-card{ background:var(--card); border:1px solid var(--line); border-radius:var(--radius); padding:16px 18px; box-shadow:var(--shadow); }
/* v11.23.0: sentence case. The caps-and-tracking label is a 2019 dashboard
   tic and it reads as shouting to a child. */
.stat-card .stat-label{ font-size:.82rem; font-weight:600; letter-spacing:0; color:var(--muted); }
.stat-card .stat-value{ font-family:var(--font-display); font-weight:800; font-size:1.7rem; margin-top:2px; }
.stat-card .stat-sub{ font-size:.8rem; color:var(--muted); }
.stat-spark .stat-value{ color:var(--spark-deep); }

/* ---------- Buttons, chips, badges ---------- */
.btn{
  font:inherit; font-weight:600; cursor:pointer;
  border-radius:10px; padding:9px 16px; border:1px solid transparent;
  display:inline-flex; align-items:center; gap:8px; text-decoration:none;
  transition:transform .06s ease, box-shadow .06s ease;
}
.btn:active{ transform:translateY(1px); }
.btn-primary{ background:var(--violet); color:#fff; box-shadow:0 2px 0 #38317f; }
.btn-primary:hover{ background:#453cab; }
.btn-spark{ background:var(--spark); color:var(--ink); box-shadow:0 2px 0 var(--spark-deep); }
.btn-ghost{ background:transparent; color:inherit; border-color:var(--line); }
.sidebar .btn-ghost{ color:#d9dcf0; border-color:rgba(255,255,255,.25); }
.btn-danger{ background:var(--red); color:#fff; }
.btn-sm{ padding:5px 11px; font-size:.83rem; border-radius:8px; }
.btn-block{ width:100%; justify-content:center; }
.btn[disabled]{ opacity:.5; cursor:not-allowed; }

.chip{
  font:inherit; font-size:.8rem; font-weight:600; cursor:pointer;
  background:var(--violet-soft); color:var(--violet);
  border:1px solid transparent; border-radius:999px; padding:4px 12px;
}
.chip:hover{ border-color:var(--violet); }

.tag{ display:inline-block; font-size:.72rem; font-weight:700; border-radius:999px; padding:2px 10px; }
.tag-subject{ background:var(--violet-soft); color:var(--violet); }
.tag-green{ background:var(--green-soft); color:var(--green); }
.tag-amber{ background:#FFF3D6; color:var(--spark-deep); }
.tag-red{ background:var(--red-soft); color:var(--red); }
.tag-grey{ background:#EEF0F7; color:var(--muted); }

/* ---------- Forms ---------- */
.field{ display:block; margin-bottom:14px; }
.field > span{ display:block; font-size:.82rem; font-weight:600; margin-bottom:5px; }
.field input, .field select, .field textarea{
  width:100%; font:inherit; padding:9px 12px;
  border:1px solid var(--line); border-radius:var(--radius-sm);
  background:#fff; color:inherit;
}
.field input:focus, .field select:focus, .field textarea:focus{ border-color:var(--violet); outline:2px solid var(--violet-soft); }
.form-row{ display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.form-error{ background:var(--red-soft); color:var(--red); border-radius:var(--radius-sm); padding:9px 12px; font-size:.85rem; margin-bottom:12px; }

/* ---------- Tables ---------- */
.table-wrap{ overflow-x:auto; }
table.data{ width:100%; border-collapse:collapse; font-size:.9rem; }
table.data th{ text-align:left; font-size:.72rem; text-transform:uppercase; letter-spacing:.08em; color:var(--muted); padding:8px 10px; border-bottom:2px solid var(--line); }
table.data td{ padding:10px; border-bottom:1px solid var(--line); vertical-align:middle; }
table.data tr:hover td{ background:#FAFBFE; }

/* ---------- Progress ---------- */
.progress{ background:#EBEDF6; border-radius:999px; height:10px; overflow:hidden; }
.progress > i{ display:block; height:100%; background:linear-gradient(90deg,var(--spark),var(--spark-deep)); border-radius:999px; transition:width .4s ease; }
.progress.violet > i{ background:var(--violet); }

/* ---------- Lesson cards ---------- */
.lesson-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(250px,1fr)); gap:16px; }
.lesson-card{
  background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
  overflow:hidden; box-shadow:var(--shadow); display:flex; flex-direction:column;
  cursor:pointer; transition:transform .08s ease;
}
.lesson-card:hover{ transform:translateY(-2px); }
.lesson-thumb{
  aspect-ratio:16/9; display:grid; place-items:center; font-size:2rem;
  background:linear-gradient(135deg,var(--ink),var(--ink-soft)); color:var(--spark); position:relative;
}
.lesson-thumb .dur{ position:absolute; right:8px; bottom:8px; font-size:.7rem; font-family:var(--font-mono); background:rgba(0,0,0,.55); color:#fff; padding:2px 7px; border-radius:6px; }
.lesson-body{ padding:12px 14px 14px; display:flex; flex-direction:column; gap:6px; flex:1; }
.lesson-body h3{ margin:0; font-size:.95rem; }
.lesson-meta{ margin-top:auto; display:flex; justify-content:space-between; align-items:center; font-size:.78rem; color:var(--muted); }
.done-tick{ color:var(--green); font-weight:700; }

.video-frame{ width:100%; aspect-ratio:16/9; border:0; border-radius:var(--radius); background:#000; }

/* ---------- Quiz / exam player ---------- */
.q-option{
  display:flex; gap:12px; align-items:flex-start;
  border:2px solid var(--line); border-radius:var(--radius-sm);
  padding:12px 14px; margin-bottom:10px; cursor:pointer; background:#fff;
}
.q-option:hover{ border-color:var(--violet); }
.q-option.selected{ border-color:var(--violet); background:var(--violet-soft); }
.q-option.correct{ border-color:var(--green); background:var(--green-soft); }
.q-option.wrong{ border-color:var(--red); background:var(--red-soft); }
.q-option .key{
  font-family:var(--font-mono); font-weight:700; flex:0 0 26px; height:26px;
  display:grid; place-items:center; border-radius:7px; background:var(--paper); font-size:.8rem;
}
.q-progress-label{ font-size:.8rem; color:var(--muted); font-family:var(--font-mono); }

.exam-timer{
  font-family:var(--font-mono); font-weight:700; font-size:1rem;
  background:var(--ink); color:var(--spark); border-radius:10px; padding:6px 14px;
}
.exam-timer.low{ background:var(--red); color:#fff; animation:pulse 1s infinite; }
@keyframes pulse{ 50%{ opacity:.65; } }
.palette{ display:flex; flex-wrap:wrap; gap:6px; }
.palette button{
  width:34px; height:34px; border-radius:8px; border:1px solid var(--line);
  background:#fff; font-family:var(--font-mono); font-size:.78rem; cursor:pointer;
}
.palette button.answered{ background:var(--violet); color:#fff; border-color:var(--violet); }
/* v11.2.18: answered-but-locked keeps its colour, so a finished section still
   shows what was done. A skipped question in a finished section is marked as
   missed rather than being given a tick it never earned. */
#exam-palette button.locked.answered{ opacity:1; background:var(--violet); color:#fff; border-color:var(--violet); }
#exam-palette button.missed{
  background:#FFF4F4; border-color:#F3C9C9; color:#B4433F; text-decoration:line-through;
  opacity:.85;
}
.palette button.flagged{ outline:2px solid var(--spark); }
.palette button.current{ box-shadow:0 0 0 3px var(--spark); }

.score-ring{ font-family:var(--font-display); font-weight:800; font-size:2.4rem; }

/* ---------- Badges ---------- */
.badge-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(130px,1fr)); gap:12px; }
.badge-card{ text-align:center; border:1px solid var(--line); border-radius:var(--radius); padding:14px 8px; background:var(--card); }
.badge-card .badge-ico{ font-size:1.9rem; }
.badge-card.locked{ opacity:.38; filter:grayscale(1); }
.badge-card b{ display:block; font-size:.8rem; margin-top:4px; }
.badge-card span{ font-size:.7rem; color:var(--muted); }

/* Leaderboard */
.lb-row{ display:flex; align-items:center; gap:12px; padding:10px 6px; border-bottom:1px solid var(--line); }
.lb-rank{ font-family:var(--font-mono); font-weight:700; width:34px; text-align:center; }
.lb-row.top1 .lb-rank{ color:var(--spark-deep); font-size:1.15rem; }
.lb-row.me{ background:var(--violet-soft); border-radius:10px; }
.lb-name{ flex:1; font-weight:600; }
.lb-sp{ font-family:var(--font-mono); font-weight:700; color:var(--spark-deep); }

/* ---------- Auth screen ---------- */
.auth-shell{ display:grid; grid-template-columns:1.1fr 1fr; min-height:100vh; }
.auth-hero{ background:var(--ink); color:#fff; display:flex; align-items:center; padding:50px; position:relative; overflow:hidden; }
.auth-hero::after{
  content:"⚡"; position:absolute; font-size:26rem; right:-70px; bottom:-100px;
  opacity:.07; transform:rotate(-14deg); pointer-events:none;
}
.auth-hero-inner{ max-width:520px; position:relative; z-index:1; }
.auth-strap{ font-size:2.4rem; font-weight:800; margin:34px 0 14px; }
.spark-word{ color:var(--spark); }
.auth-sub{ color:#c9cde8; font-size:1.02rem; }
.auth-points{ list-style:none; padding:0; margin:22px 0 0; }
.auth-points li{ padding:7px 0 7px 30px; position:relative; color:#e3e5f5; }
.auth-points li::before{ content:"⚡"; position:absolute; left:0; color:var(--spark); }
.auth-panel{ display:flex; flex-direction:column; align-items:center; justify-content:center; gap:20px; padding:40px 24px; }
.auth-card{ width:100%; max-width:400px; }
.demo-accounts{ margin-top:18px; border-top:1px dashed var(--line); padding-top:12px; }
.demo-grid{ display:flex; gap:8px; flex-wrap:wrap; }

/* ---------- Toasts / modal ---------- */
/* v11.85.0: toasts shared 200 with the viewer, so "Time's up" and every error
   raised during a full-screen paper was hidden behind it. */
.toast-stack{ position:fixed; bottom:20px; right:20px; z-index:520; display:flex; flex-direction:column; gap:10px; }
.toast{
  background:var(--ink); color:#fff; border-radius:12px; padding:12px 18px;
  box-shadow:var(--shadow); font-size:.9rem; display:flex; gap:10px; align-items:center;
  animation:toast-in .25s ease;
}
.toast .flame{ color:var(--spark); }
@keyframes toast-in{ from{ transform:translateY(12px); opacity:0; } }

/* v11.85.0 — a modal must sit above everything it can be opened from.

   It was z-index:150, and the full-screen item viewer is 200. So from the
   moment a mock moved into that viewer (v11.82.2), the "Submit paper?"
   confirmation opened BEHIND the sheet and was invisible: pressing Submit
   paper looked like it did nothing at all.

   It was never only the exam. Any dialog raised from inside the full-screen
   viewer — a lesson, a quiz, a deck — was opening behind it.

   500 clears the viewer (200), the drag ghost (220) and the teach layer (200),
   and stays below the confetti and the boot ring at 9999, which are meant to
   be over everything including this. */
.modal-scrim{ position:fixed; inset:0; background:rgba(20,24,48,.55); z-index:500; display:grid; place-items:center; padding:20px; }
/* v11.0.4: 1100px — interactive explanations and section previews are wide,
   and 640px was cropping them into a scrollbar. */
.modal{ background:var(--card); border-radius:var(--radius); max-width:1100px; width:100%; max-height:88vh; overflow:auto; padding:24px; box-shadow:var(--shadow); }
.modal h3{ margin-top:0; }
.modal-actions{ display:flex; justify-content:flex-end; gap:10px; margin-top:18px; }

/* Filters bar */
.filter-bar{ display:flex; gap:10px; flex-wrap:wrap; align-items:center; margin-bottom:18px; }
.filter-bar select, .filter-bar input{ font:inherit; padding:8px 12px; border:1px solid var(--line); border-radius:var(--radius-sm); background:#fff; }

/* Announcement */
.announce{ border-left:4px solid var(--spark); background:#FFFBEF; border-radius:var(--radius-sm); padding:12px 16px; margin-bottom:18px; }
.announce b{ display:block; }

/* Streak flame widget */
.streak-flame{ display:flex; align-items:center; gap:12px; }
.streak-flame .big{ font-size:2.2rem; }
.streak-days{ display:flex; gap:5px; margin-top:5px; }
.streak-days i{ width:20px; height:20px; border-radius:6px; background:#EBEDF6; display:grid; place-items:center; font-style:normal; font-size:.65rem; color:var(--muted); }
.streak-days i.lit{ background:var(--spark); color:var(--ink); font-weight:700; }

/* Empty state */
.empty{ text-align:center; padding:40px 20px; color:var(--muted); }
.empty .ico{ font-size:2.4rem; display:block; margin-bottom:8px; }

/* ---------- Responsive ---------- */
@media (max-width: 940px){
  .app-shell{ grid-template-columns:1fr; }
  .sidebar{ position:fixed; z-index:100; width:260px; height:100vh; transform:translateX(-100%); transition:transform .2s ease; }
  .sidebar.open{ transform:none; box-shadow:0 0 0 100vmax rgba(0,0,0,.35); }
  .hamburger{ display:block; }
  .grid-3, .grid-4{ grid-template-columns:repeat(2,1fr); }
  .auth-shell{ grid-template-columns:1fr; }
  .auth-hero{ padding:34px 24px; }
  .auth-strap{ font-size:1.7rem; }
  .view{ padding:18px 16px 60px; }
  .form-row{ grid-template-columns:1fr; }
}
@media (max-width: 560px){
  .grid-2, .grid-3{ grid-template-columns:1fr; }
  /* v11.23.0 — the four dashboard stats stay 2x2 on a phone. One per row put
     a screen and a half of numbers between a child and the first thing they
     could actually press. */
  .grid-4{ grid-template-columns:repeat(2,1fr); gap:10px; }
  .grid-4 .stat-card{ padding:12px 12px 14px; }
  .grid-4 .stat-card .stat-value{ font-size:1.35rem; }
  .grid-4 .stat-card .stat-label{ font-size:.76rem; }
  .grid-4 .stat-card .stat-sub{ font-size:.72rem; }
  /* the seven-day strip has to fit half a phone now */
  .grid-4 .streak-days{ gap:3px; }
  .grid-4 .streak-days i{ width:14px; height:14px; font-size:.55rem; }
  .grid-4 .streak-flame .big{ font-size:1.5rem; }
  .grid-4 .stat-card .stat-sub{ font-size:.7rem; line-height:1.35; }
  /* the hello banner: the button gets its own line rather than wrapping to
     two words inside a squeezed column */
  .hello-banner{ flex-wrap:wrap; }
  .hello-banner .btn{ margin-left:0 !important; width:100%; text-align:center; box-sizing:border-box; }
}

/* ============================================================
   v11.23.0 — the tidy-up
   ============================================================ */
/* (5) "This week" rows kept the tick, the icon and the title on one line;
   they used to wrap into three ragged lines on a phone because the emoji
   were inline text with their own line boxes. */
.tw-item{ align-items:center; }
.tw-item .tw-tick{ width:18px; height:18px; flex:none; display:inline-flex; align-items:center;
  justify-content:center; border:1.5px solid var(--line); border-radius:6px; color:transparent; }
.tw-item.done .tw-tick{ background:var(--green,#22a06b); border-color:transparent; color:#fff; }
.tw-item .tw-tick .sa-ico{ width:12px; height:12px; }
.tw-item .tw-ico{ flex:none; display:inline-flex; color:var(--muted); }
.tw-item .tw-name{ flex:1 1 auto; min-width:0; }
.tw-item.done .tw-name{ text-decoration:line-through; text-decoration-color:var(--line); }
.tw-item .ci-due{ flex:none; margin-left:auto; }

/* (4) the phone tab bar: five places, always one tap. Above 940px it does
   not exist; in focus mode (a lesson, a quiz, a timed mock) it gets out of
   the way like every other piece of chrome. */
.tabbar{ display:none; }
@media (max-width:940px){
  .tabbar{
    display:grid; grid-template-columns:repeat(5,1fr);
    position:fixed; left:0; right:0; bottom:0; z-index:90;
    background:var(--card); border-top:1px solid var(--line);
    padding:6px 4px calc(6px + env(safe-area-inset-bottom, 0px));
    box-shadow:0 -6px 20px rgba(28,34,64,.06);
  }
  .tabbar a{
    display:flex; flex-direction:column; align-items:center; gap:3px;
    padding:6px 2px; text-decoration:none; color:var(--muted);
    font:600 10.5px/1 var(--font-body,inherit); border-radius:12px;
  }
  .tabbar a .sa-ico{ width:22px; height:22px; }
  .tabbar a.active{ color:var(--violet); }
  .tabbar a.active .tb-ico{ background:var(--violet-soft); }
  .tabbar .tb-ico{ display:inline-flex; padding:5px 12px; border-radius:999px; }
  /* room above the bar so the last card is never trapped under it */
  .view{ padding-bottom:96px; }
  body.focus-mode .tabbar{ display:none; }
}

/* (6) one elevation per surface. A card inside a card inside a card was
   three shadows deep, which reads as clutter rather than depth. */
.card .card, .card .stat-card, .card .mc-card{ box-shadow:none; border:1px solid var(--line); }
.card .card:hover, .card .mc-card:hover{ box-shadow:none; transform:none; }
.card .mc-card{ background:var(--paper,#fbfbfe); }
/* the accent rule belongs to the row of stats, not to each card in it */
.grid-4 .stat-card::after{ opacity:.55; }
.card > .card-head + .mc-row .mc-card{ border-radius:12px; }
@media (prefers-reduced-motion: reduce){
  *{ animation:none !important; transition:none !important; }
}

/* ============================================================
   Phase 2 — exam engine v2 & topic analytics
   ============================================================ */
.section-banner{background:var(--violet-soft);color:var(--violet);font-weight:700;font-size:.85rem;
  padding:7px 12px;border-radius:8px;margin-bottom:10px;letter-spacing:.02em}
.stimulus{background:#FFFDF4;border:1px solid #F0E6C8;border-radius:10px;padding:12px 14px;margin-bottom:12px;line-height:1.55}
.stimulus p{margin:0 0 8px}.stimulus p:last-child{margin:0}
.q-option img,.stimulus img,#q-body img,#exam-body img{max-width:100%;max-height:220px;display:block;margin-top:6px;border-radius:8px}
.q-option.multi .key{border-radius:6px}
.fib-body{line-height:2.1;font-size:1.02rem}
.fib-input{font:inherit;padding:4px 8px;margin:0 3px;border:2px solid var(--violet);border-radius:8px;
  min-width:110px;background:var(--violet-soft)}
.fib-input:focus{outline:2px solid var(--spark)}
.fib-review{display:inline-block;padding:2px 8px;border-radius:6px;font-weight:700;margin:0 2px}
.fib-review.ok{background:var(--green-soft);color:var(--green)}
.fib-review.bad{background:var(--red-soft);color:var(--red);text-decoration:line-through}
.fib-expected{color:var(--green);font-weight:700}

.donut{width:120px;height:120px}
.stat-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:10px;margin-top:16px}
.stat-strip>div{background:var(--paper);border:1px solid var(--line);border-radius:10px;padding:10px 14px;text-align:center}
.stat-strip span{display:block;letter-spacing:.08em}
.stat-strip b{font-size:1.25rem}

.topic-table .progress{height:8px;margin:0}
.progress.rag-green i{background:var(--green)}
.progress.rag-amber i{background:var(--spark)}
.progress.rag-red i{background:var(--red)}
.tag.rag-green{background:var(--green-soft);color:var(--green)}
.tag.rag-amber{background:#FFF4DB;color:#9A6B00}
.tag.rag-red{background:var(--red-soft);color:var(--red)}
.dot{display:inline-block;width:10px;height:10px;border-radius:50%;margin-right:6px}
.dot.rag-green{background:var(--green)}.dot.rag-amber{background:var(--spark)}.dot.rag-red{background:var(--red)}
.radar{width:100%;max-width:320px;display:block;margin:0 auto}

.next-steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}
.next-step{border:1px solid var(--line);border-left:4px solid var(--red);border-radius:10px;padding:12px}
.next-step .step-no{display:inline-flex;width:24px;height:24px;border-radius:50%;background:var(--red-soft);
  color:var(--red);font-weight:800;align-items:center;justify-content:center;margin-bottom:6px}
.next-step b{display:block;margin-bottom:4px}

.trend{display:flex;gap:14px;align-items:flex-end;height:120px;padding:6px 2px}
.trend-bar{display:flex;flex-direction:column;align-items:center;justify-content:flex-end;height:100%;width:44px}
.trend-bar i{display:block;width:26px;border-radius:6px 6px 0 0;min-height:4px}
.trend-bar.current i{outline:3px solid var(--spark)}
.trend-bar span{margin-top:4px}

/* ============================================================
   Phase 3 — shop & commerce
   ============================================================ */
.shop-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:16px}
.shop-card h3{margin:6px 0 2px}
.price{font-size:1.5rem;font-weight:800;color:var(--ink)}
.price .small{font-weight:600}
#paypal-zone{min-height:44px}

/* v5.2 — dashboard greeting banner */
.hello-banner{display:flex;gap:14px;align-items:center;background:#fff;border:1px solid var(--line);
  border-radius:14px;padding:14px 18px;margin-bottom:16px}
.hello-ava{width:52px;height:52px;border-radius:50%;background:var(--violet-soft);color:var(--violet);
  display:inline-flex;align-items:center;justify-content:center;font-weight:800;font-size:1.4rem;flex:none}
.hello-level{font-size:.95rem;background:#FFF4DB;color:#9A6B00;border-radius:999px;padding:3px 10px;vertical-align:middle}

/* v5.2 — lesson content blocks */
.lesson-text{line-height:1.7}
.lesson-text ul,.lesson-text ol{padding-left:22px}
.lesson-text img{max-width:100%;border-radius:10px}
.lesson-block h3{margin:0 0 10px}
.code-frame,.embed-frame{width:100%;border:1px solid var(--line);border-radius:12px;background:#fff;display:block}
/* v11.61.0 — "fill" activities. On the course page they take most of the
   window; inside the sheet they take what the sheet has, less its own header
   and the lesson's title row. */
.code-frame.is-fill{ height:calc(100vh - 320px); min-height:460px; max-height:1100px; }
.wk-viewer.is-full .code-frame.is-fill{ height:calc(100vh - 300px); }
@media (max-width:640px){ .code-frame.is-fill{ height:calc(100vh - 260px); min-height:420px; } }

/* v11.61.0 — inside the sheet, the lesson does not repeat its own name. The
   sheet header already says "Week 1 · Maths · Lesson — Place value, rounding
   and estimating"; the card below it said all of that again at h1 size, which
   is 120px of the screen spent on a second copy of the title. */
.wk-viewer-body .course-body > .card:first-child{ padding:10px 14px; }
.wk-viewer-body .course-body > .card:first-child h1{ font-size:1.05rem; margin:.15em 0; }
.wk-viewer-body .course-body > .card:first-child .tag{ display:none; }
.wk-viewer-body .course-body > .card:first-child .card-head{ margin-top:0 !important; align-items:center; }
.lb-row{border:1px solid var(--line);border-radius:10px;padding:10px;margin-bottom:10px;background:var(--paper)}
.lb-head{display:flex;gap:6px;align-items:center;margin-bottom:8px}
.lb-head .lb-type{font:inherit;padding:6px 8px;border:1px solid var(--line);border-radius:8px}
.lb-editor textarea,.lb-editor input[type=text],.lb-editor input:not([type]){width:100%;font:inherit;border:1px solid var(--line);
  border-radius:8px;padding:8px;margin-bottom:6px;box-sizing:border-box}
.lbe-code{font-family:var(--font-mono,monospace);font-size:.85rem}

/* ============================================================
   v6 — Seneca-style app shell: light collapsible sidebar,
   Nunito, blue actives, split question layouts, richer reviews.
   ============================================================ */
body{ font-family:'Nunito','Segoe UI',system-ui,sans-serif; }
.app-shell{ background:#F4F7FC; }
.view h1,.view h2,.view h3{ font-family:'Nunito',sans-serif; font-weight:800; letter-spacing:-.01em; }

/* ---- sidebar: Seneca light ---- */
.sidebar{
  background:#fff; color:#3D4B66; border-right:1px solid #E8EDF5;
  width:236px; transition:width .18s ease;
  /* above the topbar (z-index:20), so anything the sidebar puts near its own
     edge is drawn over the header rather than under it */
  z-index:30;
}
.sidebar .brand{ color:#26304e; text-decoration:none; display:flex; align-items:center; gap:10px; }
.sidebar .brand:hover .brand-name{ color:#4076F6; }
.sidebar .brand-name em{ color:#4076F6; }
.sidebar .brand-mark{ box-shadow:0 3px 8px rgba(255,179,0,.35); }
.side-nav a{
  color:#5A6B8C; border-radius:12px;  font-size:.8rem;
  display:flex; align-items:center; gap:11px; padding:10px 12px; margin:2px 4px;
}
.side-nav a:hover{ background:#F2F6FF; color:#26304e; }
.side-nav a.active{ background:#EAF1FF; color:#2F63E0; }
.side-nav a .ico{ font-size:1.12rem; width:22px; text-align:center; }
.side-nav .nav-group{ color:#9AA6BF; font-size:.66rem; margin:18px 20px 4px; }
.sidebar-foot{ border-top:1px solid #E8EDF5; }
.me-chip{ color:#26304e; }
.me-chip .small{ color:#8A96AF; }
.sidebar .btn-ghost{ color:#5A6B8C; border-color:#DCE3EF; }
.sidebar .btn-ghost:hover{ border-color:#4076F6; color:#2F63E0; }
/* v11.2.17 — the collapse control, where it can actually be seen.

   It used to hang half outside the sidebar (right:-13px) with z-index:5. But
   .sidebar is position:sticky, which creates a stacking context, so that 5 is
   measured INSIDE the sidebar and can never rise above the topbar's z-index:20
   — and the overhanging half sat exactly where the topbar's opaque white
   background is painted. Collapsed to a 74px rail, that is most of the button:
   a control the user is told to click, with half of it drawn over.

   It is now a normal item in the sidebar's flow, tucked into the gap under the
   brand. Nothing overlaps it, so nothing can hide it, and it grows a label
   when there is room for one. */
.collapse-btn{
  position:static; align-self:flex-end; margin:-16px 6px 12px;
  display:inline-flex; align-items:center; gap:6px; height:30px; padding:0 10px;
  border-radius:16px; border:1px solid #DCE3EF; background:#fff; color:#5A6B8C;
  font-family:inherit; font-size:.72rem; font-weight:700; cursor:pointer;
  box-shadow:0 2px 8px rgba(61,75,102,.14); line-height:1; white-space:nowrap;
}
.collapse-btn .cb-mark{ font-weight:900; font-size:.92rem; line-height:1; }
.collapse-btn:hover{ color:#2F63E0; border-color:#4076F6; background:#F2F6FF; }
.collapse-btn:focus-visible{ outline:2px solid #4076F6; outline-offset:2px; }
/* collapsed: a round icon button centred in the rail, still fully inside it */
.side-collapsed .collapse-btn{ align-self:center; margin:-16px 0 12px; width:30px; padding:0; justify-content:center; }
.side-collapsed .collapse-btn .cb-label{ display:none; }

/* collapsed state: icon rail, labels hidden.
   v7.18.1: the GRID column collapses too, so the page content slides left and
   actually uses the reclaimed space (previously only the sidebar element
   shrank inside a fixed 250px track, leaving a dead gutter). */
@media (min-width:941px){ .app-shell.side-collapsed{ grid-template-columns:74px 1fr; } }
.side-collapsed .sidebar{ width:74px; }
.side-collapsed .side-nav a{ justify-content:center; padding:11px 0; margin:2px 10px; }
.side-collapsed .side-nav a .ico{ width:auto; }
.side-collapsed .side-nav a span + *,
.side-collapsed .side-nav a{ font-size:0; }
.side-collapsed .side-nav a .ico{ font-size:1.3rem; }
.side-collapsed .brand-name, .side-collapsed .nav-group,
.side-collapsed .me-chip, .side-collapsed #btn-logout{ display:none; }
.side-collapsed .brand{ justify-content:center; }
.side-collapsed .sidebar-foot{ border-top:0; }
@media (max-width:900px){ .collapse-btn{ display:none; } .side-collapsed .sidebar{ width:260px; } }

/* ---- topbar: light ---- */
.topbar{ background:#fff; border-bottom:1px solid #E8EDF5; color:#26304e; }
.topbar-title{ font-family:'Nunito',sans-serif; font-weight:800; }

/* ---- cards ---- */
.card{ border:1px solid #E8EDF5; border-radius:16px; box-shadow:0 4px 14px rgba(61,75,102,.05); }
.btn-primary{ background:#4076F6; border-radius:12px; }
.btn-primary:hover{ background:#2F63E0; }

/* ---- v6 split question layout ---- */
.q-split{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:22px; align-items:start; }
.q-side-q .stimulus{ margin-top:0; }
.q-side-q img, .q-side-a img{ max-width:100%; border-radius:10px; }
@media (max-width:860px){ .q-split{ grid-template-columns:1fr; gap:10px; } }

/* ---- v6 review cards ---- */
.review-q{ border:1px solid #E8EDF5; border-radius:14px; padding:16px 18px; margin-bottom:22px; background:#fff; }
.review-explain{
  margin-top:14px; background:#F6F8FF; border-left:4px solid #4F46B8;
  padding:12px 16px; border-radius:0 10px 10px 0; font-size:.95rem; line-height:1.6;
}
.explain-video{ display:block; width:100%; max-width:560px; aspect-ratio:16/9; border:0; border-radius:10px; margin-top:10px; }
.sample-answer{
  margin-top:10px; background:#FFFDF4; border:1px dashed #FFB300; border-radius:10px; padding:12px 16px;
}
.sample-answer b{ display:block; margin-bottom:6px; }
.creative-note{
  background:#FFF7E6; border:1px solid #FFE1A6; border-radius:12px; padding:14px 16px;
}
.creative-note p{ margin:6px 0 0; }
#exam-palette button.na{ background:#F2F6FF; color:#4076F6; border-color:#C9D9FB; }

/* dashboard greeting inherits the lighter look */
.hello-banner{ border:1px solid #E8EDF5; box-shadow:0 4px 14px rgba(61,75,102,.05); }

/* v6.1 — card payments */
.pay-divider{ display:flex; align-items:center; gap:10px; margin:14px 0 10px; color:#8A96AF; font-size:.8rem; font-weight:700; }
.pay-divider::before,.pay-divider::after{ content:""; flex:1; height:1px; background:#E8EDF5; }
#stripe-pay.btn-block{ width:100%; }

/* v6.2 — course home: tree, status, hero */
.course-hero{ display:flex; gap:18px; align-items:center; flex-wrap:wrap; }
.course-hero .course-thumb.lg{ width:92px; height:92px; border-radius:16px; background:#EAF1FF;
  display:flex; align-items:center; justify-content:center; overflow:hidden; flex:none; }
.course-hero .course-thumb.lg img{ width:100%; height:100%; object-fit:cover; }
.course-hero .course-emoji{ font-size:2.6rem; }
/* v11.44.2 — the contents rail is 20% wider (320px to 384px). Item titles are
   ellipsised to one line, so width is the only thing that buys more of the
   title, and "Place value, rounding and…" was cutting off the part that tells
   two weeks apart. */
.course-layout{ display:grid; grid-template-columns:384px minmax(0,1fr); gap:18px; margin-top:16px; align-items:start; }
@media (max-width:900px){ .course-layout{ grid-template-columns:1fr; } }

/* v11.49.0 — the method, shown after two goes. Numbered, because the order is
   the whole point of the card. */
.cb-method{ text-align:left; margin:8px 0 12px; padding-left:20px; }
.cb-method li{ margin:0 0 6px; font-size:.9rem; line-height:1.45; }

/* v11.48.1 — the default course mark. It replaced an emoji, which sized
   itself from the font; an <img> does not, so without this it drew at its
   natural size inside a 52px tile and read as a blank square. */
.course-mark{ width:60%; height:60%; object-fit:contain; display:block; margin:auto; opacity:.85; }
.course-thumb .course-mark{ width:58%; height:58%; }

/* ============================================================
   v11.46.0 — the course page: a slim header, seasons that fold, and the item
   opening under the week instead of on a page of its own.
   ============================================================ */
/* the header was a card the height of a lesson to say a title and a number */
/* v11.50.0: smaller again. It is a label on a page whose subject is the week
   below it, not a title page. */
.course-hero.is-slim{ padding:10px 14px; gap:12px; align-items:center; }
.course-hero.is-slim .course-thumb.lg{ width:42px; height:42px; flex:none; }
.course-hero.is-slim h1{ font-size:1.05rem; margin:0; }
.course-hero.is-slim .small{ font-size:.78rem; }
.course-hero.is-slim .progress{ height:5px; }
.course-hero.is-slim .rich-desc{ display:none; }
.course-hero.is-slim .progress{ max-width:220px; margin-top:6px; }
.course-hero.is-slim .tag{ display:none; }

/* v11.46.0: named wk-current, not wk-now — .wk-now is the legend dot and the
   cell state, and sharing the name turned the dot into a flex box with
   padding, i.e. a purple oval. */
.wk-current{ display:flex; align-items:center; gap:10px; padding:10px 14px; margin-top:12px; cursor:pointer; }
.wk-current:hover{ border-color:var(--violet); }
.wk-current-ico{ display:inline-flex; color:var(--violet); }
.wk-season{ margin-top:8px; padding:0; overflow:hidden; }
.wk-season-head{ display:flex; align-items:center; gap:10px; width:100%; padding:10px 14px;
  background:none; border:0; font:inherit; text-align:left; cursor:pointer; color:var(--ink); }
.wk-season-head:hover{ background:var(--soft); }
.wk-season-head .sa-ico{ width:14px; height:14px; color:var(--muted); transition:transform .18s ease; }
.wk-season.is-open .wk-season-head .sa-ico{ transform:rotate(90deg); }
.wk-season .wk-grid{ padding:0 14px; }
.wk-season .wk-legend{ margin:0 14px; padding:10px 0 12px; }

.wk-detail{ padding:0; margin-top:12px; }
.wk-detail-head{ display:flex; align-items:center; gap:10px; width:100%; padding:10px 14px;
  background:none; border:0; font:inherit; text-align:left; cursor:pointer; color:var(--ink); }
.wk-detail-head:hover{ background:var(--soft); }
.wk-detail-head .sa-ico{ width:14px; height:14px; color:var(--muted); transform:rotate(90deg); transition:transform .18s ease; }
.wk-detail.is-folded .wk-detail-head .sa-ico{ transform:none; }
.wk-detail .wk-detail-line{ padding:0 14px; }
.wk-detail .wk-sessions{ padding:0 14px 14px; }
.wk-detail.is-folded .wk-detail-line,
.wk-detail.is-folded .wk-sessions{ display:none; }

/* the viewer: the item, under the week it belongs to */
.wk-viewer{ margin-top:12px; padding:0; }
.wk-viewer-head{ display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:10px 14px; border-bottom:1px solid var(--line); }
.wk-viewer-tools{ margin-left:auto; display:flex; gap:6px; align-items:center; flex-wrap:wrap; }
.wk-viewer-body{ padding:14px; }
/* the players still render their own back-link and contents rail; inside the
   viewer neither has a job, because the week is directly above it */
.wk-viewer-body .course-layout{ grid-template-columns:1fr; }
.wk-viewer-body .course-tree,
.wk-viewer-body .rail-toggle,
.wk-viewer-body > p:first-child > a[href^="#/course/"]{ display:none; }
/* v11.50.0 — full screen means full screen.

   It was inset by 12px over a page that was still there, and the app's own
   chrome only disappeared when the toggle button had been pressed, so opening
   an item straight into full screen left the course showing round the edges
   and through the card. It now covers the viewport, opaquely, with its own
   scroll. */
/* v11.51.0 — full screen is a SHEET, not a replacement page.

   Covering the viewport edge to edge read as "you have navigated somewhere",
   which is wrong: the child is still in their week, looking at one thing from
   it. It now floats over the page with the page dimmed behind, the way a phone
   presents a sheet — the app is visibly still there, so Close obviously
   returns to it rather than going somewhere new. The height fits the content
   up to 92vh, so a short quiz is a short sheet rather than a screen of white. */
.wk-viewer.is-full{
  position:fixed; z-index:200; margin:0;
  /* v11.60.0 — a frame, not a column. The sheet was capped at 1320px and sat
     4vh from the top, so on a wide screen most of the page was scrim and the
     thing being read was a narrow strip. The dimmed border is now ~40px: it
     still reads as an overlay, and the content gets the rest. */
  top:36px; left:50%; transform:translateX(-50%);
  width:calc(100vw - 80px); max-height:calc(100vh - 72px); height:auto; overflow:auto;
  border-radius:16px; border:0;
  background:var(--card);
  box-shadow:0 24px 70px rgba(15,20,45,.34), 0 2px 10px rgba(15,20,45,.12);
  animation:sheet-in .18s ease-out;
}
@keyframes sheet-in{ from{ opacity:0; transform:translateX(-50%) translateY(10px) scale(.985); } }
.wk-viewer.is-full .wk-viewer-head{
  position:sticky; top:0; z-index:2; background:var(--card); border-bottom:1px solid var(--line);
  border-radius:18px 18px 0 0;
}
/* v11.60.0: no second cap. The padding already keeps text off the edges, and
   1000px inside a 1320px sheet inside a 1900px screen was three margins deep. */
.wk-viewer.is-full .wk-viewer-body{ padding:18px 22px 28px; }
/* the page behind, dimmed: it stays visible on purpose */
body.item-full::before{
  content:""; position:fixed; inset:0; z-index:190;
  background:radial-gradient(120% 100% at 50% 0%, rgba(18,22,48,.42), rgba(10,14,32,.62));
  backdrop-filter:blur(2px);
  animation:scrim-in .18s ease-out;
}
@keyframes scrim-in{ from{ opacity:0; } }
body.item-full{ overflow:hidden; }
@media (max-width:1560px){
  .wk-viewer.is-full{ width:calc(100vw - 60px); top:24px; max-height:calc(100vh - 48px); }
}
@media (max-width:640px){
  /* on a phone the sheet takes the width and rises from the bottom edge */
  .wk-viewer.is-full{ top:auto; bottom:0; width:100%; max-height:94vh; transform:translateX(-50%);
    border-radius:18px 18px 0 0; animation:sheet-up .2s ease-out; }
  @keyframes sheet-up{ from{ transform:translateX(-50%) translateY(24px); opacity:0; } }
  .wk-viewer.is-full .wk-viewer-body{ padding:14px 14px 32px; }
}

/* ============================================================
   v11.45.0 — the course page: a year of weeks, and one week open
   ============================================================ */
.wk-grid-card{ margin-top:16px; }
.wk-term{ margin:10px 0 6px; font-size:.82rem; color:var(--muted); }
.wk-grid{ display:grid; grid-template-columns:repeat(7, minmax(0,1fr)); gap:6px; margin-bottom:10px; }
.wk-cell{
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1px;
  padding:7px 2px; border:1px solid var(--line); border-radius:10px; background:var(--card);
  cursor:pointer; font:inherit; color:var(--ink); text-align:center;
}
.wk-cell:hover{ border-color:var(--violet); }
.wk-cell.is-picked{ outline:2px solid var(--violet); outline-offset:-2px; }
.wk-n{ font-size:.95rem; font-weight:700; line-height:1.15; }
.wk-d{ font-size:.7rem; color:var(--muted); }
/* the four states, filled rather than outlined, so the colour reads at a glance */
.wk-cell.wk-done{ background:#E2F7EF; border-color:#B9EAD9; color:#12795A; }
.wk-cell.wk-done .wk-d{ color:#1D8F69; }
.wk-cell.wk-now{ background:var(--violet); border-color:var(--violet); color:#fff; }
.wk-cell.wk-now .wk-d{ color:#DCD8F7; }
.wk-cell.wk-mock{ background:#E6F1FB; border-color:#BBD8F2; color:#175A9C; }
.wk-cell.wk-mock .wk-d{ color:#2C77C4; }
.wk-cell.wk-lock{ color:var(--muted); background:var(--paper); }
.wk-legend{ display:flex; gap:16px; flex-wrap:wrap; padding-top:10px; border-top:1px solid var(--line);
  font-size:.78rem; color:var(--muted); }
.wk-legend span{ display:inline-flex; align-items:center; gap:6px; }
.wk-dot{ width:11px; height:11px; border-radius:50%; display:inline-block; }
.wk-dot.wk-done{ background:#2FBF8F; }
.wk-dot.wk-now{ background:var(--violet); }
.wk-dot.wk-mock{ background:#378ADD; }
.wk-dot.wk-lock{ background:#C9D4E5; }
.wk-mocktag{ color:#175A9C; font-weight:600; }

.wk-detail{ margin-top:14px; }
/* v12.12.0 — two columns, not five.

   auto-fit at 240px put all five subjects plus the weekly quiz in one row on a
   wide screen, and every title truncated: "Comprehension: informa…",
   "Type 5 missing letter in cl…". A week is six cards, so two columns by three
   rows gives each card roughly double the width and the titles fit. */
.wk-sessions{ display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:12px; }
@media (max-width:900px){ .wk-sessions{ grid-template-columns:1fr; } }
/* v12.12.0 — the slot label sits BESIDE its row, not above it.

   Every activity took two lines: "HOMEWORK DAY 1" on one, the title on the
   next. Five activities became ten lines, so a week of six cards could not be
   seen without scrolling. The card is a two-column grid — label, then row —
   which halves the height and needs no change to either row variant.

   min-content on the first column lets the widest label ("CLASSWORK (LIVE)")
   set it, so the titles all start in the same place down the card. */
.wk-session{ box-shadow:none; border:1px solid var(--line); padding:10px 12px; margin:0;
  display:grid; grid-template-columns:max-content minmax(0,1fr);
  column-gap:10px; row-gap:1px; align-items:center; }
.wk-session > h4,
.wk-session > .wk-paper-toggle{ grid-column:1 / -1; }
.wk-session h4{ margin:0 0 2px; font-size:.95rem; display:flex; gap:8px; align-items:baseline; }
.wk-slot{ grid-column:1; margin:0; font-size:.62rem; font-weight:800; letter-spacing:.06em;
  text-transform:uppercase; color:#9AA6BF; white-space:nowrap; }
.wk-session > .wk-row,
.wk-session > a.wk-row,
.wk-session > span.wk-row{ grid-column:2; }

/* the class this pair of subjects is taught in */
.wk-classline{ margin:2px 0 6px; font-size:.82rem; }
.wk-classline + .wk-sessions{ margin-bottom:12px; }
.wk-row{ display:flex; gap:8px; align-items:center; padding:5px 6px; border-radius:8px;
  text-decoration:none; color:var(--ink); }
a.wk-row:hover{ background:#EAF1FF; }
.wk-row.is-done{ color:#8A96AF; }
.wk-row.is-locked{ color:var(--muted); }
.wk-tick{ width:16px; height:16px; border-radius:50%; border:2px solid #C9D4E5; flex:none;
  display:inline-flex; align-items:center; justify-content:center; font-size:.6rem; color:#fff; }
.wk-row.is-done .wk-tick{ background:#2FBF8F; border-color:#2FBF8F; }
.wk-title{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  font-size:.86rem; font-weight:600; }
.wk-meta{ flex:none; font-size:.75rem; color:var(--muted); }
.wk-tools{ margin:2px 0 0 24px; display:flex; gap:6px; align-items:center; flex-wrap:wrap; }
@media (max-width:640px){
  .wk-grid{ grid-template-columns:repeat(4, minmax(0,1fr)); }
}

/* v11.42.0 — the week's publish button sits in its summary row without
   stealing the click that opens the week. */
.ci-week-pub{ margin-left:10px; padding:2px 10px; font-size:11.5px; }

/* v11.39.0 — the instructor's tools sit apart from the child's button, so
   nobody presses Edit meaning Open. */
.staff-tools{ display:inline-flex; gap:6px; margin-left:14px; padding-left:14px;
  border-left:1px solid var(--line); }
@media (max-width:640px){
  .staff-tools{ margin:8px 0 0; padding:0; border-left:0; width:100%; }
}

/* v11.32.0 — Weekly progress, grouped the same way as the contents. */
.wp-row{ display:flex; gap:10px; align-items:center; margin:8px 0; }
.wp-week > summary.wp-row{ cursor:pointer; list-style:none; padding:2px 0; }
.wp-week > summary::-webkit-details-marker{ display:none; }
.wp-week > summary:hover{ opacity:.85; }
.wp-week[open] > summary{ margin-bottom:4px; }
.wp-sub{ margin:6px 0 6px 16px; padding-left:10px; border-left:2px solid var(--line); }

/* v11.31.0 — a week and its sessions.
   The week is the outer level and carries the week's whole ring; the sessions
   sit inside it, indented by a hairline so the nesting is legible without a
   second box drawn round everything. */
.ci-week{ border-bottom:1px solid var(--line); }
.ci-week > summary{
  display:flex; align-items:center; gap:10px; padding:10px 12px; cursor:pointer;
  font-weight:600; font-size:.95rem; list-style:none;
}
.ci-week > summary::-webkit-details-marker{ display:none; }
.ci-week > summary:hover{ background:var(--soft); }
.ci-week[open] > summary{ background:var(--soft); }
.ci-week-body{ padding:2px 0 6px 10px; border-left:2px solid var(--line); margin-left:20px; }
.ci-week-body .ci-section{ border-bottom:0; }
.ci-week-body .ci-section > summary{ padding:7px 10px; font-weight:600; font-size:.88rem; }
.ci-week-body .ci-section > summary b{ font-weight:600; }
.ci-week.is-locked .ci-week-head{
  display:flex; align-items:center; gap:10px; padding:11px 12px; color:var(--muted);
}
body.rail-folded .ci-week-body{ margin-left:0; padding-left:0; border-left:0; }
body.rail-folded .ci-week > summary b,
body.rail-folded .ci-week > summary .small{ display:none; }

/* v11.23.0 — the contents rail folds away, v11.24.1 — from inside itself.

   In a lesson the rail takes a third of the width and the video takes what is
   left; on a 14" laptop that is a small video. Folded, the rail becomes a
   narrow spine that still shows each week's ring and each item's tick, so a
   child can see where they are and reopen it in one press. The button lives
   inside the rail: as a sibling it was a third child of a two-column grid,
   and grids do not care what you meant. */
.course-layout{ transition:grid-template-columns .22s ease; }
.course-tree .rail-toggle{
  display:flex; align-items:center; gap:6px; width:100%; margin:0 0 10px;
  background:transparent; border:0; border-bottom:1px solid var(--line);
  padding:0 0 9px; font:600 12px/1 inherit; letter-spacing:.04em;
  text-transform:uppercase; color:var(--muted); cursor:pointer;
}
.course-tree .rail-toggle:hover{ color:var(--violet); }
/* v11.30.0 — the chevron points where pressing it goes. Open, the rail folds
   to the LEFT, so it points left; folded, it points right to open again. It
   used to sit at the default (right) while open, which read as "expand" on a
   rail that was already expanded. */
.course-tree .rail-toggle .sa-ico{ width:14px; height:14px; transition:transform .2s ease;
  transform:rotate(180deg); }
body.rail-folded .course-tree .rail-toggle{ justify-content:center; }
body.rail-folded .course-tree .rail-toggle .sa-ico{ transform:rotate(0deg); }
body.rail-folded .course-tree .rt-lbl{ display:none; }

@media (min-width:901px){
  body.rail-folded .course-layout{ grid-template-columns:64px minmax(0,1fr); }
  /* below 1200px the wider rail would squeeze the lesson, so it steps back */
  @media (max-width:1200px){ .course-layout{ grid-template-columns:320px minmax(0,1fr); } }
  body.rail-folded .course-tree{ padding:12px 8px; overflow:hidden; }
  /* the spine keeps the rings and the ticks; the words go */
  body.rail-folded .course-tree .ci-course-head b,
  body.rail-folded .course-tree .ci-title,
  body.rail-folded .course-tree .ci-meta,
  body.rail-folded .course-tree .ci-extra,
  body.rail-folded .course-tree .ci-sub,
  body.rail-folded .course-tree summary b,
  body.rail-folded .course-tree summary .small,
  body.rail-folded .course-tree p{ display:none; }
  body.rail-folded .course-tree .ci-course-head{ justify-content:center; padding:4px 0 10px; }
  /* the spine carries the tick and the kind, and nothing that needs reading:
     a "due Sun 10:26" chip or a "0/8" counter in a 64px column is a smear */
  body.rail-folded .course-tree .ci-due,
  body.rail-folded .course-tree .ci-cb,
  body.rail-folded .course-tree .ci-best,
  body.rail-folded .course-tree .tag{ display:none; }
  body.rail-folded .course-tree .ci-item{ justify-content:center; gap:4px; padding:9px 0; }
  body.rail-folded .course-tree .ci-item.active{ border-radius:8px; }
  body.rail-folded .course-tree summary{ justify-content:center; padding:8px 0; }
  body.rail-folded .course-tree .ci-section[open] > summary{ margin-bottom:2px; }
}
/* below 900px the layout is already one column: the rail sits above the
   lesson, so folding it there is a real saving too — but it folds to a strip,
   not a spine, because there is no column to shrink. */
@media (max-width:900px){
  body.rail-folded .course-tree > *:not(.rail-toggle){ display:none; }
}
.course-tree{ padding:10px; position:sticky; top:74px; max-height:calc(100vh - 100px); overflow:auto; }
.ci-section{ border-bottom:1px solid #EEF2F8; padding:4px 0; }
.ci-section:last-child{ border-bottom:0; }
.ci-section summary{ display:flex; gap:10px; align-items:center; cursor:pointer; list-style:none;
  padding:8px; border-radius:10px; font-size:.9rem; }
.ci-section summary:hover{ background:#F5F8FE; }
.ci-section summary::-webkit-details-marker{ display:none; }
.ci-ring{ width:20px; height:20px; border-radius:50%; flex:none;
  background:conic-gradient(#4076F6 calc(var(--p) * 1%), #E3E9F4 0); position:relative; }
.ci-ring::after{ content:""; position:absolute; inset:4px; background:#fff; border-radius:50%; }
.ci-ring.full{ background:#2FBF8F; }
.ci-ring.full::after{ content:"✓"; inset:0; background:none; color:#fff; font-size:.7rem; font-weight:900;
  display:flex; align-items:center; justify-content:center; }
.ci-sub{ font-size:.64rem; font-weight:800; text-transform:uppercase; letter-spacing:.08em; color:#9AA6BF; margin:8px 8px 2px; }
/* v11.44.2 — the rail was set larger than the menu beside it, which made the
   secondary navigation shout over the primary one. Everything here now sits a
   step below the sidebar's .92rem. */
.ci-item{ display:flex; gap:8px; align-items:center; padding:7px 8px; border-radius:10px; text-decoration:none;
  color:#3D4B66; font-weight:600; font-size:.86rem; }
.ci-item:hover{ background:#EAF1FF; }
.ci-item.is-done{ color:#8A96AF; }
.ci-ico{ flex:none; }
.ci-title{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ci-meta{ flex:none; font-size:.8rem; }
.ci-dot{ width:14px; height:14px; border-radius:50%; border:2px solid #C9D4E5; flex:none; display:inline-flex;
  align-items:center; justify-content:center; font-size:.62rem; color:#fff; }
.ci-dot.done{ background:#2FBF8F; border-color:#2FBF8F; }
.ci-best{ flex:none; font-size:.7rem; font-weight:900; border-radius:999px; padding:2px 8px; }
.ci-best.ok{ background:#E2F7EF; color:#1D8F69; }
.ci-best.warn{ background:#FDF1DA; color:#A06B00; }
.cf-row{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; padding:3px 0; border-bottom:1px dashed #EEF2F8; }
.cf-structure{ display:flex; gap:6px; }
.cf-structure input{ font:inherit; font-size:.82rem; padding:5px 8px; border:1px solid var(--line); border-radius:8px; width:190px; }

/* v6.3 — course-first navigation */
/* v7.8: long course titles wrap (max 3 lines) instead of truncating with "…" —
   the sidebar stays the same width; the row simply grows a little taller. */
.side-nav a{ align-items:flex-start; }
.side-nav a .ico{ margin-top:1px; flex:0 0 auto; }
.side-nav a .lbl{ white-space:normal; overflow-wrap:anywhere; line-height:1.25;
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; }
/* the collapsed (icon-only) sidebar keeps hiding labels exactly as before */
.ci-course-head{ display:block; padding:10px 8px; border-bottom:1px solid #EEF2F8; margin-bottom:4px;
  text-decoration:none; color:#26304e; font-size:.95rem; }
.ci-course-head:hover{ color:#2F63E0; }
.ci-item.active{ background:#EAF1FF; color:#2F63E0; font-weight:800; }
.course-navbar{ display:flex; justify-content:space-between; gap:10px; margin-top:18px; flex-wrap:wrap; }
.course-navbar .btn{ max-width:46%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lesson-in-course .course-tree{ top:74px; }
@media (max-width:900px){ .course-navbar .btn{ max-width:100%; flex:1 1 100%; } }

/* v6.5 — GL/FSCE sectioned mocks */
.sec-count{ font-weight:700; opacity:.8; font-size:.82em; }
#exam-palette button.locked{ opacity:.45; cursor:not-allowed; background:#F2F4F9; }
.exam-break{ text-align:center; padding:34px 16px; }
.eb-ico{ font-size:2.6rem; display:block; margin-bottom:6px; }
.exam-break h2{ margin:.2em 0; }
.eb-next{ font-size:1.05rem; }
.eb-count{ width:76px; height:76px; border-radius:50%; margin:14px auto; background:#EAF1FF; color:#2F63E0;
  display:flex; align-items:center; justify-content:center; font-size:2rem; font-weight:900;
  border:3px solid #C9D9FB; animation:ebpulse 1s ease-in-out infinite; }
@keyframes ebpulse{ 0%,100%{ transform:scale(1); } 50%{ transform:scale(1.07); } }
.st-box{ border:1px dashed var(--line); border-radius:10px; padding:10px 12px; margin:8px 0; }
.st-row-wrap{ margin-bottom:8px; }
.st-row{ display:flex; gap:8px; align-items:center; margin-bottom:6px; }
/* v11.2.17 — the section's comprehension passage, edited on its own section */
.st-passage{ margin:0 0 10px 2px; padding:10px 12px; background:var(--paper,#FAFBFF);
  border:1px solid var(--line); border-radius:10px; }
.st-passage textarea{ width:100%; font:inherit; font-size:.88rem; line-height:1.5;
  padding:9px 11px; border:1px solid var(--line); border-radius:8px; resize:vertical; }
.st-p-toggle[aria-expanded="true"]{ border-color:var(--violet); color:var(--violet); }
.st-row .st-name{ flex:1; font:inherit; padding:7px 10px; border:1px solid var(--line); border-radius:8px; }
.st-row .st-mins{ width:64px; font:inherit; padding:6px; border:1px solid var(--line); border-radius:8px; }

/* v6.6 — content protection (students only, admin-toggleable) */
body.cp-on{ -webkit-user-select:none; user-select:none; }
body.cp-on input, body.cp-on textarea, body.cp-on select, body.cp-on [contenteditable]{ -webkit-user-select:text; user-select:text; }
body.cp-on img{ -webkit-user-drag:none; user-drag:none; }
@media print{ body.cp-on #app{ display:none !important; } }

/* ============================================================
   v7 — sectioned exam pages (one page per timed section)
   ============================================================ */
.sec-page-banner{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:10px;
  position:sticky; top:0; z-index:5; box-shadow:0 4px 12px rgba(28,34,64,.06); }
.qblock{ background:var(--card); border:1.5px solid var(--line); border-radius:var(--radius);
  padding:16px 18px; margin-bottom:14px; scroll-margin-top:64px; transition:box-shadow .2s, border-color .2s; }
.qblock.is-flagged{ border-color:var(--spark); box-shadow:0 0 0 1px var(--spark); }
.qblock.q-pulse{ border-color:var(--violet); box-shadow:0 0 0 3px var(--violet-soft); }
.qblock-head{ display:flex; align-items:center; gap:10px; margin-bottom:10px; }
.qblock-num{ font-family:var(--font-display); font-weight:800; color:var(--violet);
  background:var(--violet-soft); border-radius:8px; padding:2px 10px; }
.qflag{ margin-left:auto; border:1.5px solid var(--line); background:var(--card); border-radius:8px;
  width:32px; height:32px; cursor:pointer; font-size:1rem; color:var(--muted); }
.qflag:hover{ border-color:var(--spark); color:var(--spark-deep); }
.qblock.is-flagged .qflag{ background:var(--spark); border-color:var(--spark); color:#fff; }
.sec-foot{ margin-top:18px; padding-top:14px; border-top:1.5px dashed var(--line);
  display:flex; flex-direction:column; gap:8px; align-items:flex-end; }
.sec-foot p{ margin:0; }
.sec-track{ height:8px; background:var(--line); border-radius:99px; overflow:hidden; }
.sec-track i{ display:block; height:100%; background:linear-gradient(90deg,var(--violet),#8F93E8); border-radius:99px; transition:width .3s; }
:root{ --stick-top:72px; }   /* topbar is 56px; 16px of air under it */
/* v11.89.0 — Submit paper must never be the thing that has to be scrolled to.

   The whole panel was one scrolling box. On a sixty-question paper the palette
   fills it, so the submit button sat below the fold INSIDE that box. Pressing
   a partly-visible button makes the browser scroll it into view on mousedown;
   the button then moves out from under the pointer, mouseup lands somewhere
   else, and no click event is ever fired. From a chair that is "I press
   Submit and nothing happens, but it works the second time" — because by then
   the button has stopped moving.

   So only the PALETTE scrolls now. The progress line and the submit button are
   pinned below it and are always fully visible, whatever the paper's length. */
.exam-side-inner{
  position:sticky; top:var(--stick-top);
  max-height:calc(100vh - var(--stick-top) - 16px);
  display:flex; flex-direction:column; overflow:hidden;
}
.exam-side-inner > h3{ flex:0 0 auto; }
.exam-side-inner > #exam-palette{ flex:1 1 auto; min-height:0; overflow:auto; align-content:flex-start; }
.exam-side-inner > #exam-sec-progress,
.exam-side-inner > #exam-submit{ flex:0 0 auto; }
/* a little air so the last palette row never looks clipped by the button */
.exam-side-inner > #exam-sec-progress{ padding-top:8px; }
#exam-palette button.locked{ opacity:.45; cursor:not-allowed; }

/* ============================================================
   v11.2.17 — comprehension passages

   Questions | palette is the normal paper. A section WITH a passage becomes
   passage | questions | palette, and the passage column is sticky with its
   own scroll: it stays put for the whole section, which is the point of
   putting the passage on the section rather than on each question.

   The line breaks are decided on the server so that "in line 12" is the same
   line here, in the PDF and in the Word document — hence white-space:nowrap.
   The column scrolls sideways rather than rewrapping if it is ever too narrow;
   a rewrapped passage is a passage whose line numbers are lies.
   ============================================================ */
.exam-layout{ grid-template-columns:minmax(0,1fr) 200px; }
.exam-layout.has-passage{ grid-template-columns:minmax(0,45fr) minmax(0,40fr) minmax(190px,15fr); }
.exam-passage[hidden]{ display:none; }
/* v11.2.19a: NO align-self here. A sticky child can only travel inside its
   own container, and `align-self:start` shrinks this column to the height of
   the passage itself — so the panel had nowhere to stick and scrolled away
   with the page. Stretching the column to the full row height is what gives
   sticky its runway. */
.passage-panel{ position:sticky; top:var(--stick-top); background:var(--card); border:1.5px solid var(--line);
  border-radius:var(--radius); padding:14px 16px;
  display:flex; flex-direction:column; }
/* v11.2.18: no height cap and no inner scrollbar — the passage is as long as it
   is, and stays on screen with the questions. A passage taller than the window
   gets its sticky offset set in script so it pins by its BOTTOM edge, which is
   the only way the end of a long passage is ever reachable while it is pinned. */
.passage-panel.inline{ position:static; margin:0 0 14px; }
.passage-head{ display:flex; flex-direction:column; gap:2px; padding-bottom:8px; margin-bottom:8px;
  border-bottom:1.5px dashed var(--line); }
.passage-scroll{ padding-right:4px; }
.passage-panel.inline .passage-scroll{ overflow-x:auto; }
.passage-scroll .pl{ margin:0; white-space:nowrap; line-height:1.62; font-size:.94rem; }
.passage-scroll .pl.para{ margin-top:9px; }
/* v13.21.2: a table or picture inside a passage, whole, lined up with the text (no line number) */
.passage-scroll .pl-block{ margin:10px 0 4px 34px; overflow-x:auto; white-space:normal; }
.passage-scroll .pl-block table{ border-collapse:collapse; font-size:.88rem; line-height:1.35; min-width:60%; }
.passage-scroll .pl-block th, .passage-scroll .pl-block td{ border:1px solid var(--line, #E3E3E7); padding:5px 8px; text-align:left; vertical-align:top; }
.passage-scroll .pl-block th{ background:#F3F0FC; font-weight:700; }
.passage-scroll .pl-block img, .passage-scroll .pl-block svg{ max-width:100%; height:auto; }
.passage-scroll .ln{ display:inline-block; width:22px; margin-right:12px; text-align:right;
  color:var(--muted); font-size:.72rem; -webkit-user-select:none; user-select:none; }

@media (max-width:1100px){
  /* three columns stop being three columns long before a phone: the passage
     goes above the questions, still one per section, still numbered */
  .exam-layout.has-passage{ grid-template-columns:minmax(0,1fr) 200px; }
  .exam-layout.has-passage .exam-passage{ grid-column:1 / -1; }
  .exam-layout.has-passage .passage-panel{ position:static; }
}
@media (max-width:760px){
  .exam-layout{ grid-template-columns:1fr !important; }
  .exam-side{ order:-1; }
  /* v11.89.0 — on a phone the panel is not sticky, so it must not keep the
     height cap and the hidden overflow the sticky version needs: those would
     clip it against a viewport it is no longer pinned to. It flows normally
     here, and the palette scrolls sideways (below), so nothing is out of
     reach and the submit button is simply the next thing down the page. */
  .exam-side-inner{ position:static; display:block; max-height:none; overflow:visible; }
  .exam-side-inner > #exam-palette{ overflow-x:auto; overflow-y:visible; }
}

/* v7.1: reCAPTCHA slot */
.captcha-slot{ margin:6px 0 10px; min-height:0; }
.taster-form .captcha-slot{ width:100%; display:flex; justify-content:center; }

/* v7.2 — paused accounts */
.paused-banner{ background:#FFF6DE; border:2px solid #F0C948; border-radius:var(--radius);
  padding:14px 18px; margin-bottom:16px; }
.paused-banner p{ margin:6px 0 0; color:#7A5C00; }
tr.row-paused td{ background:#FFFBEE; }
.check.small{ font-size:.85rem; }

/* v7.7 — bank transfer checkout */
.bank-details{ width:100%; border-collapse:collapse; margin-top:8px; }
.bank-details td{ padding:7px 10px; border-bottom:1px solid var(--line); }
.bank-details td:first-child{ width:130px; }
.bank-details tr:last-child td{ border-bottom:none; background:#FFF9E8; border-radius:8px; }

/* ============================================================
   v7.8 — mobile-friendly app
   ============================================================ */
/* v11.2.18: overflow-x:hidden on html/body makes BODY the scroll container,
   and position:sticky then has nothing to stick to — which is why the question
   palette and the comprehension passage scrolled away off the top of the page
   instead of staying put. `clip` cuts the horizontal overflow exactly the same
   way WITHOUT creating a scroll container, so sticky works again. The hidden
   rule stays as the fallback for anything too old to know `clip`. */
html,body{overflow-x:hidden}
@supports (overflow:clip){ html,body{overflow-x:clip} }
#view img{max-width:100%;height:auto}
@media (max-width:760px){
  input,select,textarea{font-size:16px}
  table.data,table.table,.topic-table{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%}
  table.data th,table.data td,table.table th,table.table td{white-space:nowrap}
  /* toasts live bottom-right, so the exam clock pins bottom-left */
  .exam-timer{position:fixed;bottom:14px;left:12px;z-index:120;box-shadow:0 6px 18px rgba(20,24,48,.25)}
  .exam-side .palette{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:6px}
  #exam-palette button{min-width:36px;min-height:36px;flex:0 0 auto}
  .q-option{padding:12px 12px;min-height:44px}
}
@media (max-width:560px){
  .modal-scrim{padding:10px}
  .modal{padding:18px 14px;max-height:94dvh;border-radius:14px}
  .modal-actions{flex-wrap:wrap}
  .modal-actions .btn{flex:1 1 auto}
  .view{padding:14px 12px 70px}
  .card{padding:14px}
  .filter-bar select,.filter-bar input{flex:1 1 100%;width:100%}
  .topbar h1,#topbar-title{font-size:1.05rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .auth-hero{padding:24px 18px}
  .auth-strap{font-size:1.35rem}
  .auth-card{padding:20px 16px}
}
@media (max-width:940px){
  .sidebar{height:100dvh}
}
@media (max-width:900px){
  .course-tree{position:static;max-height:280px}
}

/* v7.9 — one-question-per-page mock exams */
.qnav-row{ display:flex; justify-content:space-between; gap:10px; margin:16px 0 4px; }
.qnav-row .btn{ min-width:120px; }

/* v7.9 — traceability watermark (content protection on, students only) */
#cp-watermark{ position:fixed; inset:0; z-index:2147483000; pointer-events:none; background-repeat:repeat; }   /* v13.52.0: above every window (the vocab Learn and practice windows sat on top of it at 95); it never takes a click */
@media print{ #cp-watermark{ position:absolute; } } /* belt & braces — printing is already blocked */

/* ============================================================
   v7.11 — Concept Builder
   ============================================================ */
.cb-card{ max-width:980px; margin:0 auto; }
.cb-head{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
.cb-title{ margin:0; flex:1; }
.cb-sp{ background:var(--violet-soft); border:2px solid var(--violet); border-radius:999px; padding:4px 12px; font-weight:800; color:var(--violet); }
.cb-example{ background:#EDF2FF; border:2px solid #C9D6F5; border-radius:14px; padding:12px 14px; margin:12px 0 4px; }
.cb-badge{ display:inline-block; background:var(--violet); color:#fff; font-size:.7rem; font-weight:900;
  letter-spacing:.06em; border-radius:999px; padding:3px 10px; margin-bottom:6px; }
.cb-badge.sensei{ background:#4F46B8; color:#fff; }
.cb-badge.hint{ background:#FFD6E7; }
.cb-instr{ margin:10px 0 4px; }
.cb-label{ letter-spacing:.08em; font-weight:800; margin:8px 0 6px; }
.cb-slots{ display:flex; flex-direction:column; gap:8px; }
.cb-slot{ display:flex; align-items:center; gap:10px; border:2px dashed var(--line); border-radius:14px;
  padding:8px 10px; min-height:52px; background:#fff; }
.cb-slot.filled{ border-style:solid; }
.cb-slot.cb-right{ border-color:#2E9E5B; background:#F0FAF3; }
.cb-slot.cb-wrong{ border-color:#D64562; background:#FDF1F4; animation:cbshake .3s; }
@keyframes cbshake{ 25%{transform:translateX(-4px)} 75%{transform:translateX(4px)} }
.cb-num{ flex:0 0 26px; height:26px; border-radius:50%; background:var(--ink); color:#fff;
  display:flex; align-items:center; justify-content:center; font-weight:800; font-size:.85rem; }
.cb-ghost{ color:#9AA4BC; font-size:.92rem; }
.cb-pool{ display:flex; flex-wrap:wrap; gap:10px; }
.cb-step{ font:inherit; text-align:left; background:#E7EEFF; border:2px solid var(--ink); border-radius:12px;
  padding:12px 14px; cursor:grab; box-shadow:2px 3px 0 rgba(20,24,48,.35); max-width:100%; min-height:44px;
  touch-action:none; user-select:none; -webkit-user-select:none; }
.cb-step:hover{ transform:translateY(-1px); }
.cb-step.placed{ background:#fff; box-shadow:none; flex:1; }
.cb-actions{ margin-top:16px; display:flex; flex-direction:column; gap:8px; align-items:center; }
.cb-actions .btn{ max-width:420px; }
.cb-actions .linky{ background:none; border:0; cursor:pointer; color:var(--muted); font:inherit; }
.cb-pop-scrim{ position:fixed; inset:0; background:rgba(43,46,90,.45); z-index:140; }
.cb-pop{ position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); z-index:145; background:#fff;
  border-radius:18px; padding:22px; width:min(460px,94vw); max-height:90dvh; overflow:auto; text-align:center;
  box-shadow:0 18px 50px rgba(20,24,48,.35); animation:cbpop .25s; }
@keyframes cbpop{ from{ transform:translate(-50%,-46%); opacity:0 } }
.cb-pop-ico{ font-size:2.6rem; }
.cb-pop.good h3{ color:#2E9E5B; margin:6px 0; }
.cb-pop.tryagain h3{ color:#D64562; margin:6px 0; }
.cb-sp-flash{ font-weight:900; color:#B8860B; font-size:1.15rem; margin:4px 0 10px; }
.cb-sensei{ text-align:left; background:#F4F3FF; border:2px solid #DDD9F5; border-radius:14px; padding:12px 14px; margin:10px 0 14px; }
.cb-sensei.hint{ background:#FFF5F9; border-color:#F6D5E3; }
.cb-finish{ text-align:center; padding:26px 10px; }
.cb-finish-ico{ font-size:3.2rem; }
.ci-cb{ font-size:.72rem; font-weight:800; background:#EEF1F8; border-radius:999px; padding:2px 7px; color:var(--muted); }
.ci-cb.part{ background:var(--violet-soft); color:var(--violet); }
@media (max-width:560px){ .cb-step{ width:100%; } }


/* v7.12 — drag & drop for Concept Builder */
.cb-step.cb-dragging{ opacity:.35; }
.cb-drag-ghost{ position:fixed; z-index:220; pointer-events:none; transform:rotate(3deg); opacity:.95;
  box-shadow:0 10px 24px rgba(20,24,48,.35); }
.cb-slot.cb-over{ border-color:var(--violet); border-style:solid; background:var(--violet-soft); }
.cb-pool.cb-over{ outline:3px dashed var(--violet); outline-offset:4px; border-radius:12px; }

/* ============================================================
   v7.13 — Weekly Classroom
   ============================================================ */
.ci-section.ci-locked summary{ opacity:.65; cursor:pointer; }
.ci-due{ font-size:.7rem; font-weight:800; background:var(--violet-soft); color:var(--violet);
  border-radius:999px; padding:2px 8px; margin-left:auto; white-space:nowrap; }
.ci-due.late{ background:var(--red-soft); color:var(--red); }
.ci-item .ci-due{ margin-left:6px; }
.tw-card{ margin-bottom:16px; }
.tw-head{ display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; }
.tw-head h3{ margin:0; }
.tw-items{ display:flex; flex-direction:column; gap:6px; margin-top:10px; }
.tw-item{ display:flex; align-items:center; gap:8px; padding:9px 12px; border:1px solid var(--line);
  border-radius:12px; text-decoration:none; color:inherit; }
.tw-item:hover{ border-color:var(--violet); background:var(--violet-soft); }
.tw-item.done{ opacity:.7; }
.tw-late{ color:var(--red); font-weight:700; }
.ws-row{ display:flex; gap:12px; align-items:center; flex-wrap:wrap; padding:6px 0; border-bottom:1px dashed var(--line); }
.ws-row input{ font:inherit; padding:6px 8px; border:1px solid var(--line); border-radius:8px; }
.cf-hw{ display:inline-flex; gap:4px; align-items:center; white-space:nowrap; }

/* v7.15 — activity audit */
.act-list{ max-height:420px; overflow:auto; border:1px solid var(--line); border-radius:12px; padding:6px 12px; }
.act-day{ font-weight:800; font-size:.8rem; color:var(--muted); letter-spacing:.04em; margin:10px 0 4px; border-bottom:1px dashed var(--line); padding-bottom:2px; }
.act-row{ display:flex; gap:10px; padding:4px 0; align-items:baseline; }
/* v13.20.0: the Activity window's Everything / Learning only / Sign-ins only */
.act-row[hidden], .act-day[hidden]{ display:none; }
.act-filter{ display:flex; gap:6px; flex-wrap:wrap; margin:0 0 8px; }
.act-time{ flex:0 0 44px; font-family:var(--font-mono); }
.act-row code{ background:var(--paper); padding:1px 6px; border-radius:6px; font-size:.82rem; }

/* ---------- v7.16: course order modal + dashboard "My courses" ---------- */
#co-list{ max-height:min(58vh,520px); overflow:auto; border:1px solid var(--line); border-radius:12px; padding:8px; }
.co-section{ border:1px solid var(--line); border-radius:12px; margin:0 0 10px; overflow:hidden; background:#fff; }
.co-section:last-child{ margin-bottom:0; }
.co-sec-head{ display:flex; align-items:center; gap:8px; padding:8px 10px; background:var(--paper); border-bottom:1px solid var(--line); }
.co-sec-items{ padding:6px; display:flex; flex-direction:column; gap:4px; min-height:20px; }
.co-item{ display:flex; align-items:center; gap:8px; padding:6px 8px; border:1px solid var(--line); border-radius:10px; background:#fff; }
.co-grip{ color:var(--muted); cursor:default; font-size:.9rem; }
.co-title{ flex:1; min-width:0; font-size:.9rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.co-btns{ display:flex; gap:2px; margin-left:auto; }
.co-btns .btn{ padding:2px 8px; line-height:1.2; }
.co-moved{ outline:2px solid var(--violet); outline-offset:1px; transition:outline-color .3s; }

.mc-row{ display:flex; flex-direction:column; gap:10px; }
.mc-card{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.mc-card .course-thumb.sm{ width:56px; height:56px; border-radius:12px; background:#EAF1FF; display:flex; align-items:center; justify-content:center; font-size:1.6rem; flex:none; overflow:hidden; }
.mc-card .course-thumb.sm img{ width:100%; height:100%; object-fit:cover; }
.mc-body{ flex:1; min-width:220px; }
.mc-body h3{ margin:0 0 4px; }
.mc-body .progress{ max-width:420px; }
/* v12.51.2: Continue course and Course guide side by side */
.mc-actions{ display:flex; gap:8px; flex-wrap:wrap; }
@media (max-width:640px){ .mc-card{ align-items:flex-start; } .mc-card .btn{ width:100%; text-align:center; } .mc-actions{ width:100%; } }

/* ============ v7.17: celebrations + futuristic polish ============ */

/* confetti */
#confetti-layer{ position:fixed; inset:0; pointer-events:none; z-index:9999; overflow:hidden; }
.confetti-piece{ position:absolute; top:-18px; border-radius:2px; opacity:.95;
  animation:confetti-fall linear forwards; will-change:transform,opacity; }
.confetti-piece.round{ border-radius:50%; }
@keyframes confetti-fall{
  0%{ transform:translate3d(0,-20px,0) rotate(0deg); opacity:1; }
  100%{ transform:translate3d(var(--drift,40px),105vh,0) rotate(var(--spin,540deg)); opacity:.85; } }

/* personal-best ribbon */
.pb-ribbon{ display:inline-block; margin:0 auto 12px; padding:8px 22px; border-radius:999px;
  font-weight:800; letter-spacing:.06em; color:#5C3A00;
  background:linear-gradient(110deg,#FFD34D,#FFB300 40%,#FFE9A8 50%,#FFB300 60%,#FFD34D);
  background-size:220% 100%; animation:pb-shimmer 2.4s linear infinite;
  box-shadow:0 4px 18px rgba(255,179,0,.45), inset 0 1px 0 rgba(255,255,255,.6); }
@keyframes pb-shimmer{ to{ background-position:-220% 0; } }
.celebrate-card{ position:relative; overflow:hidden; }
.celebrate-card::before{ content:""; position:absolute; inset:-40% -10% auto; height:70%;
  background:radial-gradient(ellipse at 50% 0%, rgba(79,70,184,.10), transparent 65%); pointer-events:none; }

/* streak freeze banner */
.announce-freeze{ background:linear-gradient(100deg,#E8F4FF,#F2FBFF); border-left:4px solid #4DA3FF; }

/* futuristic polish — glassy cards, gradient accents, gentle motion */
.stat-card{ position:relative; overflow:hidden; transition:transform .18s ease, box-shadow .18s ease; }
.stat-card::after{ content:""; position:absolute; inset:0 0 auto; height:3px;
  background:linear-gradient(90deg,var(--violet),#7C74E0 45%,var(--spark)); opacity:.85; }
.stat-card:hover{ transform:translateY(-2px); box-shadow:0 10px 28px rgba(28,34,64,.10); }
/* v11.27.0 — the rule on a stat card means something now.
   Four cards carried three different rules in no pattern, which reads as four
   cards styled on four different days. Gold is the game (points, streak);
   violet is the work (lessons done, rank). */
.stat-spark::after,.stat-game::after{ background:linear-gradient(90deg,var(--spark),#FFD34D); }
.stat-work::after{ background:linear-gradient(90deg,var(--violet),#7C74E0); }
.card{ transition:box-shadow .18s ease; }
.btn-primary, .btn-spark{ position:relative; transition:transform .12s ease, box-shadow .18s ease; }
.btn-primary:hover{ transform:translateY(-1px); box-shadow:0 6px 20px rgba(79,70,184,.35); }
.btn-spark:hover{ transform:translateY(-1px); box-shadow:0 6px 20px rgba(194,35,127,.34); }
.progress i{ position:relative; overflow:hidden; }
.progress i::after{ content:""; position:absolute; inset:0;
  background:linear-gradient(100deg,transparent 30%,rgba(255,255,255,.5) 50%,transparent 70%);
  background-size:220% 100%; animation:bar-shine 2.6s ease-in-out infinite; }
@keyframes bar-shine{ 0%{ background-position:180% 0; } 100%{ background-position:-80% 0; } }
.score-ring{ box-shadow:0 0 0 6px rgba(79,70,184,.08), 0 8px 30px rgba(79,70,184,.18); }
.mc-card{ transition:transform .18s ease, box-shadow .18s ease; }
.mc-card:hover{ transform:translateY(-2px); box-shadow:0 10px 28px rgba(28,34,64,.10); }
@media (prefers-reduced-motion: reduce){
  .confetti-piece, .pb-ribbon, .progress i::after{ animation:none !important; }
  .stat-card, .btn-primary, .btn-spark, .mc-card{ transition:none !important; } }

/* v7.17: dashboard progress snapshot */
.snap-grid{ display:grid; grid-template-columns:1fr 1fr; gap:22px; }
@media (max-width:820px){ .snap-grid{ grid-template-columns:1fr; } }
.rag-chips{ display:flex; flex-wrap:wrap; gap:6px; }
.mock-hist{ display:flex; flex-direction:column; gap:6px; }
.mock-hist-row{ display:flex; align-items:center; gap:10px; padding:8px 12px; border:1px solid var(--line);
  border-radius:10px; text-decoration:none; color:inherit; transition:border-color .15s, background .15s; }
.mock-hist-row:hover{ border-color:var(--violet); background:var(--violet-soft); }
.mock-hist-row .mh-title{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-weight:600; }

/* v7.18: question title label above the content */
.q-title{ font-weight:700; color:var(--ink-soft); margin-bottom:4px; }

/* ============ v7.18.1: focus mode (full screen) + button ============ */
.btn-fullscreen{ width:34px; height:34px; border-radius:10px; border:1px solid var(--line);
  background:#fff; color:var(--ink-soft); font-size:1.05rem; line-height:1; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center; flex:none;
  transition:transform .12s ease, box-shadow .15s ease, border-color .15s; }
.btn-fullscreen:hover{ border-color:var(--violet); color:var(--violet);
  transform:translateY(-1px); box-shadow:0 4px 14px rgba(79,70,184,.22); }
body.focus-mode .sidebar, body.focus-mode .topbar{ display:none !important; }
body.focus-mode .app-shell{ grid-template-columns:1fr !important; }
body.focus-mode #view{ padding-top:14px; }

/* v11.21.0 — project mode: the live board on the classroom screen. Rides on
   focus-mode (menus away, fullscreen); this makes it readable from the back
   row and strips the teacher-only clutter. */
body.lb-project #view{ max-width:none; }
body.lb-project .live-grid{ font-size:1.12rem; }
body.lb-project .live-grid .lb-cell{ padding:10px 8px; font-size:1.05rem; }
body.lb-project .live-grid th{ font-size:1rem; }
body.lb-project .lb-name{ font-size:1.1rem; }
body.lb-project .live-player{ font-size:1.1rem; }
body.lb-project [data-live-nudge],
body.lb-project [data-bq-toggle] td:first-child{ }
body.lb-project .card-head h2{ font-size:1.6rem; }
body.focus-mode .btn-fullscreen{ border-color:var(--violet); color:var(--violet); background:var(--violet-soft); }

/* ============ v7.22: PowerPoint slide decks in lessons ============ */
.slide-deck{ padding-bottom:8px; }
.slide-stage{ position:relative; border:1px solid var(--line); border-radius:14px; background:#fff;
  padding:clamp(16px,3vw,32px); min-height:260px; overflow:hidden;
  background-image:radial-gradient(ellipse at 50% 0%, rgba(79,70,184,.045), transparent 70%); }
.slide-title{ margin:0 0 14px; font-size:clamp(1.2rem,2.4vw,1.75rem); color:var(--violet);
  border-bottom:2px solid var(--violet-soft); padding-bottom:8px; }
.slide-body{ font-size:clamp(1rem,1.5vw,1.12rem); line-height:1.65; }
.slide-body p{ margin:0 0 10px; }
.slide-body img{ max-width:100%; height:auto; border-radius:10px; margin:8px 0; display:block; }
.slide-body video{ width:100%; max-height:58vh; border-radius:10px; background:#000; margin:8px 0; display:block; }
.slide-body iframe{ width:100%; aspect-ratio:16/9; border:0; border-radius:10px; margin:8px 0; display:block; }
.slide-body table{ width:100%; border-collapse:collapse; margin:8px 0; }
.slide-body td, .slide-body th{ border:1px solid var(--line); padding:6px 10px; }
/* v7.24 — "Original design" slides: the rendered picture is the slide; video
   players are absolutely positioned over it in percent coordinates, so they
   stay glued to their spot at any width. */
.slide-deck-visual .slide-stage{ padding:0; border:0; background:#0b0d17; }
.slide-visual{ position:relative; width:100%; }
.slide-visual .slide-shot{ display:block; width:100%; height:100%; object-fit:contain; }
.slide-overlay{ position:absolute; border-radius:6px; overflow:hidden; box-shadow:0 4px 18px rgba(0,0,0,.35); }
.slide-overlay video, .slide-overlay iframe{ width:100%; height:100%; display:block; border:0; background:#000; }
.slide-below-video{ padding:10px clamp(10px,2vw,16px) 4px; }
.slide-below-video video, .slide-below-video iframe{ width:100%; aspect-ratio:16/9; border:0; border-radius:10px; background:#000; display:block; }
.slide-nav{ display:flex; align-items:center; gap:12px; margin-top:12px; flex-wrap:wrap; }
.slide-dots{ display:flex; gap:6px; flex:1; justify-content:center; flex-wrap:wrap; }
.slide-dot{ width:9px; height:9px; border-radius:50%; border:0; padding:0; cursor:pointer;
  background:var(--line); transition:transform .15s, background .15s; }
.slide-dot:hover{ transform:scale(1.35); background:#B9B4E8; }
.slide-dot.on{ background:var(--violet); transform:scale(1.25); }
.slide-count{ min-width:52px; text-align:right; }
.slide-deck [data-slide-prev]:disabled, .slide-deck [data-slide-next]:disabled{ opacity:.4; cursor:default; }
@media (max-width:640px){
  .slide-nav .btn{ flex:1; }
  .slide-dots{ order:3; width:100%; flex-basis:100%; margin-top:6px; }
  .slide-count{ order:2; }
}
@media (prefers-reduced-motion: reduce){ .slide-dot{ transition:none; } }

/* ============================================================
   v7.25 — Bright Sparks Education palette (BRAND=bright).
   The branding middleware adds .brand-bright to <body>; these
   variable overrides recolour the whole app: blue = primary
   action (BRIGHT), red = accent/highlight (SPARKS). Layout,
   spacing and components are untouched.
   ============================================================ */
body.brand-bright{
  /* v7.31: Kitsu-inspired look — white paper, emerald-green primary,
     sky-blue secondary, sunny accents, soft serif display type,
     rounded Quicksand body */
  --violet:      #0FA97E;  /* primary action — emerald green */
  --violet-soft: #E7F9F1;
  --spark:       #FFCC33;  /* sunny yellow accent */
  --spark-deep:  #E68A00;
  --paper:       #FAFDFC;  /* near-white with a whisper of mint */
  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  font-family:"Quicksand","Nunito","Trebuchet MS",system-ui,sans-serif;
}
body.brand-bright .btn-primary{ position:relative; overflow:hidden;
  background:linear-gradient(180deg, rgba(255,255,255,.26), rgba(255,255,255,0) 46%), var(--violet);
  box-shadow:0 2px 0 #0B8A66, 0 8px 18px rgba(15,169,126,.28); border-radius:999px; transition:transform .14s, box-shadow .14s; }
body.brand-bright .btn-primary:hover{ background:linear-gradient(180deg, rgba(255,255,255,.26), rgba(255,255,255,0) 46%), #0C9873;
  transform:translateY(-1px); box-shadow:0 2px 0 #0B8A66, 0 12px 24px rgba(15,169,126,.36); }
body.brand-bright .btn-primary::after{ content:""; position:absolute; top:-40%; bottom:-40%; left:-70%; width:38%;
  background:linear-gradient(105deg, transparent, rgba(255,255,255,.5), transparent); transform:skewX(-22deg);
  transition:left .5s ease; pointer-events:none; }
body.brand-bright .btn-primary:hover::after{ left:135%; }
body.brand-bright .btn{ border-radius:999px; }
body.brand-bright .brand-logo{ height:40px; width:auto; display:block; }

/* sidebar: fresh active pill */
body.brand-bright .side-nav a.active{
  background:linear-gradient(90deg,#0FA97E,#22D3EE); color:#fff;
  box-shadow:0 6px 16px rgba(15,169,126,.32); border-radius:12px; }
body.brand-bright .side-nav a{ transition:background .15s, transform .12s; border-radius:12px; }
body.brand-bright .side-nav a:hover{ transform:translateX(3px); }
body.brand-bright .brand-name{ font-family:var(--font-display); }
body.brand-bright .brand-name em{ color:var(--violet); font-style:italic; }

/* login page: drifting green→sky lagoon panel with twinkles */
body.brand-bright .auth-hero{
  background:
    linear-gradient(105deg, rgba(255,255,255,0) 42%, rgba(255,255,255,.28) 50%, rgba(255,255,255,0) 58%),
    linear-gradient(118deg, rgba(16,185,129,.9) 0%, rgba(16,185,129,0) 55%),
    linear-gradient(296deg, rgba(79,141,249,.9) 0%, rgba(79,141,249,0) 55%),
    linear-gradient(150deg,#10B981,#22D3EE 40%,#38BDF8 68%,#4F8DF9);
  background-size:320% 100%, 240% 240%, 240% 240%, 220% 220%;
  background-position:-120% 0, 0% 0%, 100% 100%, 0% 0%;
  animation:bsAuthWave 20s ease-in-out infinite alternate;
  position:relative; overflow:hidden; }
body.brand-bright .auth-hero::before, body.brand-bright .auth-hero::after{
  content:"✦"; position:absolute; color:#EAFFF6; opacity:.85; font-size:22px;
  animation:bsAuthTwinkle 3.6s ease-in-out infinite; }
body.brand-bright .auth-hero::before{ top:14%; left:12%; }
body.brand-bright .auth-hero::after{ bottom:16%; right:14%; font-size:30px; animation-delay:-1.6s; }
body.brand-bright .auth-strap{ font-family:var(--font-display); font-weight:700; letter-spacing:-.01em; }
body.brand-bright .auth-strap .spark-word{ font-style:italic; font-weight:800;
  background:linear-gradient(92deg,#EAFFF6,#FFF6C9); -webkit-background-clip:text; background-clip:text; color:transparent; }
body.brand-bright .auth-panel{ background:#fff; }
body.brand-bright .auth-card{ border:1px solid #E3EDEA; border-radius:20px;
  box-shadow:0 20px 50px rgba(21,80,90,.10); }
body.brand-bright .auth-card h2{ font-family:var(--font-display); }
body.brand-bright .auth-card input, body.brand-bright .auth-card select{ border-radius:12px; }
body.brand-bright .auth-card input:focus, body.brand-bright .auth-card select:focus{
  border-color:var(--violet); box-shadow:0 0 0 3px rgba(15,169,126,.18); }
@keyframes bsAuthWave{
  0%  { background-position:-120% 0,   0% 0%,  100% 100%,   0% 0%; }
  33% { background-position:  50% 0,  45% 30%,  55% 55%,   40% 35%; }
  66% { background-position: 150% 0,  70% 60%,  30% 30%,   75% 70%; }
  100%{ background-position: 230% 0,  90% 45%,  10% 80%,  100% 100%; }
}
@keyframes bsAuthTwinkle{ 0%,100%{ opacity:.35; transform:scale(.85); } 50%{ opacity:1; transform:scale(1.2); } }
@media (prefers-reduced-motion:reduce){ body.brand-bright .auth-hero,
  body.brand-bright .auth-hero::before, body.brand-bright .auth-hero::after{ animation:none; } }


/* v8.3.5: emojis swapped for the academy's own icons at render time */
.emoji-ic { height: 1.05em; width: 1.05em; object-fit: contain;
  vertical-align: -0.15em; display: inline-block; }
button .emoji-ic, .btn .emoji-ic { margin-right: 2px; }

/* ============================================================
   v9.1 — Vocabulary (Learn + Test)
   ============================================================ */
.vocab-card{ position:relative; }

/* tabs */
.vc-tabs{ display:inline-flex; gap:4px; padding:4px; background:var(--paper); border:1px solid var(--line);
  border-radius:999px; margin:2px 0 18px; }
.vc-tab{ border:0; background:transparent; color:var(--muted); font-weight:700; font-size:.9rem;
  padding:8px 20px; border-radius:999px; cursor:pointer; transition:all .18s ease; }
.vc-tab:hover{ color:var(--ink); }
.vc-tab.is-on{ background:var(--card); color:var(--ink); box-shadow:0 1px 4px rgba(28,34,64,.12); }

/* learn grid */
.vocab-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:12px; }
.vocab-set-tile{ display:flex; flex-direction:column; align-items:flex-start; gap:3px; text-align:left;
  padding:16px; border:1px solid var(--line); border-radius:var(--radius); background:var(--card);
  cursor:pointer; transition:transform .16s ease, box-shadow .16s ease, border-color .16s ease; }
.vocab-set-tile:hover{ transform:translateY(-3px); box-shadow:0 10px 24px rgba(28,34,64,.13); border-color:transparent; }
.vst-no{ font-size:1.7rem; font-weight:800; line-height:1; color:transparent;
  /* --a1/--a2 are the per-brand accents, defined in app-theme.css: Sparks
     violet-to-magenta, Bright blue-to-green. Hard-coding either would break
     the other brand. */
  background:linear-gradient(120deg,var(--a1),var(--a2)); -webkit-background-clip:text; background-clip:text; }
.vst-title{ font-weight:700; color:var(--ink); }
.vst-words{ font-size:.78rem; color:var(--muted); }

/* learn frame */
.vocab-frame-wrap{ border:1px solid var(--line); border-radius:var(--radius); overflow:hidden;
  box-shadow:0 6px 20px rgba(28,34,64,.10); }
.vocab-frame{ width:100%; height:78vh; min-height:520px; border:0; display:block; background:#fff; }

/* self-test controls */
.vc-selftest-controls{ display:flex; gap:12px; flex-wrap:wrap; align-items:flex-end; }
.vc-selftest-controls .field{ min-width:150px; }
.vc-selftest-controls select{ min-width:150px; }

/* self-test session */
.vc-st-head{ display:flex; align-items:center; gap:12px; margin-bottom:8px; }
.vc-st-prog{ font-family:var(--font-display); font-weight:600; font-size:.95rem; color:var(--ink); }
.vc-st-score-mini{ margin-left:auto; font-size:.85rem; color:var(--muted); }
.vc-st-bar{ height:5px; border-radius:999px; background:var(--line); overflow:hidden; margin-bottom:14px; }
.vc-st-bar > span{ display:block; height:100%; background:linear-gradient(90deg,var(--a1),var(--a2));
  border-radius:999px; transition:width .35s ease; }

/* v11.60.0 — the instructor's one line. It says what is different about this
   view without becoming a different view. */
.instructor-strip{ margin:0 0 10px; font-size:.82rem; color:var(--muted);
  display:flex; gap:14px; align-items:baseline; flex-wrap:wrap; }
.instructor-strip b{ color:var(--ink); }
.instructor-strip .linky{ margin-left:auto; }
.instructor-strip .linky + .linky{ margin-left:0; }

/* v11.58.0 — the Vocabulary loading state. A bar that moves and a line that
   changes, because "Loading…" for four seconds reads as broken. */
.vocab-loading{ text-align:center; padding:34px 16px 40px; }
.vl-ico{ font-size:2rem; animation:vl-bob 1.4s ease-in-out infinite; }
@keyframes vl-bob{ 50%{ transform:translateY(-6px); } }
.vl-msg{ margin:8px 0 14px; font-family:var(--font-display); font-size:1rem; color:var(--ink); }
.vl-bar{ max-width:320px; margin:0 auto; height:8px; border-radius:999px;
  background:var(--line); overflow:hidden; }
.vl-bar > i{ display:block; height:100%; width:6%; border-radius:999px;
  background:linear-gradient(90deg,var(--a1),var(--a2)); transition:width .25s ease; }
@media (prefers-reduced-motion:reduce){ .vl-ico{ animation:none; } }

/* v11.57.0 — the per-course set toggles: sixteen small targets that have to
   stay readable in a table cell. */
.vset-chips{ display:flex; flex-wrap:wrap; gap:4px; }
.vset-chip{ min-width:28px; padding:3px 7px; border:1px solid var(--line); border-radius:8px;
  background:var(--card); color:var(--muted); font:600 12px/1 var(--font-mono); cursor:pointer; }
.vset-chip:hover{ border-color:var(--violet); }
.vset-chip.is-on{ background:var(--violet); border-color:var(--violet); color:#fff; }

/* v11.55.0 — the same card as everywhere else. It had its own radius, its own
   shadow and its own type scale, so Practice and Test read as a different
   product bolted on beside the app. */
.vc-st-card{ border:1px solid var(--line); border-radius:var(--radius); padding:18px 20px;
  background:var(--card); box-shadow:var(--shadow); position:relative; }
.vc-mode-chip{ position:absolute; top:14px; right:16px; font-size:.68rem; font-weight:800; letter-spacing:.06em;
  text-transform:uppercase; color:var(--a1); background:rgba(63,39,189,.08); padding:4px 10px; border-radius:999px; }
.vc-q{ font-family:var(--font-display); font-size:1.05rem; font-weight:600; line-height:1.4;
  color:var(--ink); margin:4px 0 14px; padding-right:96px; }
.vc-scenario{ font-style:italic; }
.vt-blank-inline,.vt-skel{ font-style:normal; font-weight:800; letter-spacing:.14em;
  font-family:var(--font-mono); color:var(--a2); background:rgba(210,44,178,.08);
  padding:1px 8px; border-radius:6px; }

.vc-opts{ display:flex; flex-direction:column; gap:8px; }
.vc-opt{ text-align:left; padding:11px 14px; border:1px solid var(--line); border-radius:10px;
  background:var(--card); color:var(--ink); font-family:var(--font-body); font-size:.92rem;
  line-height:1.45; cursor:pointer; transition:border-color .14s ease, background .14s ease; }
.vc-opt:not(:disabled):hover{ border-color:var(--a1); background:var(--paper); transform:none; }
.vc-opt.is-correct{ border-color:var(--green); background:rgba(23,138,94,.10); color:var(--green); font-weight:700; }
.vc-opt.is-wrong{ border-color:var(--red); background:rgba(201,58,58,.08); color:var(--red); }
.vc-opt:disabled{ cursor:default; }

.vc-spell-row{ display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
.vc-spell-input{ flex:1 1 220px; padding:11px 14px; border:1px solid var(--line); border-radius:10px;
  font-family:var(--font-body); font-size:.98rem; letter-spacing:.04em; color:var(--ink); background:var(--card); }
.vc-spell-input:focus{ outline:none; border-color:var(--a1); box-shadow:0 0 0 3px rgba(63,39,189,.14); }
.vc-spell-input:disabled{ background:var(--paper); }

.vc-fb{ margin:14px 0 0; font-weight:700; }
.vc-fb.ok{ color:var(--green); }
.vc-fb.no{ color:var(--red); }

.vc-st-done{ text-align:center; padding:30px 10px; }
.vc-st-score{ font-size:2.4rem; font-weight:800; color:var(--ink); margin:0; }

@media (max-width:560px){
  .vocab-grid{ grid-template-columns:repeat(auto-fill,minmax(120px,1fr)); }
  .vc-q{ padding-right:0; margin-top:26px; }
  .vc-mode-chip{ top:-6px; }
  .vocab-frame{ height:72vh; }
}

/* v9.2 — Flourish billing admin */
.fc-runbar{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; padding:12px;
  background:var(--paper); border:1px solid var(--line); border-radius:var(--radius); }
.fc-badge{ display:inline-block; font-size:.72rem; font-weight:700; padding:2px 9px; border-radius:999px;
  text-transform:capitalize; background:#eee; color:#555; }
.fc-badge.fc-draft{ background:#eef0f6; color:#5b6180; }
.fc-badge.fc-issued{ background:#fff3d6; color:#8a6100; }
.fc-badge.fc-paid{ background:rgba(23,138,94,.14); color:var(--green); }
.fc-badge.fc-part_paid{ background:#e0f0ff; color:#0a5aa0; }
.fc-badge.fc-failed{ background:rgba(201,58,58,.12); color:var(--red); }
.fc-badge.fc-void, .fc-badge.fc-refunded{ background:#eee; color:#777; }
.fc-badge.fc-scheduled{ background:#eef0f6; color:#5b6180; }
.fc-badge.fc-cancelled_by_parent{ background:#fde8e8; color:#a03030; }
.fc-badge.fc-cancelled_by_hickies{ background:#e9e4fb; color:#5a3fb0; }
.fc-badge.fc-held{ background:rgba(23,138,94,.14); color:var(--green); }
tr.fc-sess-cancelled_by_parent td, tr.fc-sess-cancelled_by_hickies td, tr.fc-sess-skipped td{ opacity:.7; }

/* v9.4 — Flourish enrolment form sections */
.fc-sec{ margin:20px 0 8px; padding-bottom:5px; border-bottom:2px solid var(--line);
  font-size:.95rem; font-weight:800; color:var(--ink); }
.fc-sec:first-of-type{ margin-top:6px; }
fieldset.fc-radio{ border:1px solid var(--line); border-radius:12px; padding:10px 14px; margin:10px 0; }
fieldset.fc-radio legend{ font-size:.85rem; font-weight:700; padding:0 6px; color:var(--ink); }
fieldset.fc-radio .consent-row{ margin:4px 0; }

/* v9.7 — Family billing (who-owes + ledger) */
.fc-fam-summary{display:flex;gap:24px;align-items:center;flex-wrap:wrap;padding:14px 16px;background:var(--paper);border:1px solid var(--line);border-radius:var(--radius)}
.fc-fam-summary > div{min-width:90px}
.fc-fam-row{cursor:pointer}
.fc-fam-row:hover td{background:#FAFBFE}
.fc-badge.fc-fam-failed{background:rgba(201,58,58,.14);color:var(--red)}
.fc-badge.fc-fam-overdue{background:#fff3d6;color:#8a6100}
.fc-badge.fc-fam-pending{background:#eef0f6;color:#5b6180}
.fc-badge.fc-fam-no_mandate{background:#f0e9fb;color:#6a4fb0}
.fc-badge.fc-fam-clear{background:rgba(23,138,94,.14);color:var(--green)}
.fc-ledger{margin-top:8px}
.fc-ledger-head{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;flex-wrap:wrap;padding-bottom:12px;border-bottom:1px solid var(--line)}
.fc-ledger-bal{text-align:right;display:flex;flex-direction:column;gap:4px}
.fc-owes{font-size:1.3rem;font-weight:800;color:var(--red)}
.fc-clear{font-size:1.1rem;font-weight:700;color:var(--green)}
.fc-credit{font-size:.85rem;color:var(--green)}
.fc-standing{margin:14px 0;padding:12px;background:#fffdf3;border:1px solid #f0e6c8;border-radius:12px}
.fc-standing textarea{width:100%;margin:4px 0 8px;border:1px solid var(--line);border-radius:8px;padding:8px;font:inherit;resize:vertical}
.fc-addcomment{display:flex;gap:8px;margin:12px 0}
.fc-addcomment input{flex:1;border:1px solid var(--line);border-radius:8px;padding:9px 12px;font:inherit}
.fc-timeline{margin-top:10px;border-left:2px solid var(--line);padding-left:14px}
.fc-tl{position:relative;padding:8px 0 8px 4px;font-size:.92rem;border-bottom:1px dashed var(--line)}
.fc-tl:last-child{border-bottom:0}
.fc-tl-dt{display:inline-block;min-width:96px;color:var(--muted);font-size:.8rem}
.fc-tl-comment{background:#fbfcff}
.fc-tl-invoice{font-weight:500}
.btn-xs{padding:2px 8px;font-size:.72rem;border-radius:6px}

/* ---- v10.1: Practice page — course-style sidebar + topic grid ---- */
.pr-layout{ display:grid; grid-template-columns:280px minmax(0,1fr); gap:18px; align-items:start; }
.pr-layout.pr-solo{ grid-template-columns:minmax(0,1fr); }
.pr-layout.pr-solo .pr-side{ display:none; }
.pr-side{ padding:14px; position:sticky; top:74px; max-height:calc(100vh - 100px); overflow:auto; }
.pr-side:empty{ display:none; }
.pr-main{ margin:0; }
@media (max-width:900px){
  .pr-layout{ grid-template-columns:1fr; }
  .pr-side{ position:static; max-height:none; }
}
.pr-side-head{ font-size:1.05rem; padding:2px 6px 10px; }
.pr-side-title{ font-size:.78rem; text-transform:uppercase; letter-spacing:.04em;
  color:var(--muted); margin:14px 6px 6px; }
.pr-side-block{ border-top:1px solid #EEF2F8; padding-top:4px; }
.pr-nav{ display:flex; flex-direction:column; gap:2px; }
.pr-nav-item{ display:flex; align-items:center; gap:8px; padding:8px 10px; border-radius:10px;
  text-decoration:none; color:inherit; font-size:.92rem; }
.pr-nav-item span{ flex:1; }
.pr-nav-item b{ color:var(--muted); font-weight:600; font-size:.82rem; }
.pr-nav-item:hover{ background:#F5F8FE; }
.pr-nav-item.on{ background:var(--brand); color:#fff; }
.pr-nav-item.on b{ color:#fff; opacity:.85; }
.pr-weak{ display:flex; align-items:center; gap:8px; padding:7px 10px; border-radius:10px;
  text-decoration:none; color:inherit; font-size:.9rem; }
.pr-weak span{ flex:1; }
.pr-weak:hover{ background:#F5F8FE; }
.pr-weak-lvl{ font-size:.8rem; background:#FFF4E5; color:#8A5300; border-radius:999px; padding:1px 8px; }
.pr-locked-mini{ padding:7px 10px; border-radius:10px; background:var(--paper); margin-bottom:6px; }
.pr-topic.locked{ opacity:.75; border:1px dashed #D6DEEA; box-shadow:none; }
.pr-topic.spent{ opacity:.7; }
.pr-allow{ font-size:.78rem; margin-top:8px; background:#EAF6EC; color:#1E6B33;
  border-radius:999px; padding:2px 10px; display:inline-block; }
.pr-allow.used{ background:#FDECEC; color:#95291F; }
.pr-empty{ text-align:center; padding:34px 18px 26px; max-width:520px; margin:0 auto; }
.pr-empty-ico{ font-size:2.6rem; line-height:1; margin-bottom:10px; }
.pr-empty h2{ margin:0 0 8px; }
.pr-empty-list{ margin-top:16px; text-align:left; }
.pt-grant{ padding:3px 0; }
.pt-grant + .pt-grant{ border-top:1px solid #F1F5FA; }
.btn-link{ background:none; border:0; cursor:pointer; padding:0 4px; font-size:.85rem; }
.btn-link.danger{ color:#95291F; }

/* ---- v10.4: Vocabulary practice rows + test clock ---- */
.vc-pr-set{ border:1px solid var(--line); border-radius:14px; padding:12px 14px; margin-bottom:12px; }
.vc-pr-set-head{ display:flex; align-items:baseline; gap:10px; margin-bottom:8px; }
.vc-pr-rows{ display:flex; flex-direction:column; gap:6px; }
.vc-pr-row{ display:flex; align-items:center; gap:10px; width:100%; text-align:left;
  background:var(--paper); border:1px solid transparent; border-radius:10px;
  padding:9px 12px; cursor:pointer; font:inherit; }
.vc-pr-row:hover{ background:#F0F5FF; border-color:var(--brand); }
.vc-pr-row.is-loading{ opacity:.6; pointer-events:none; }
.vc-pr-ico{ font-size:1.05rem; }
.vc-pr-name{ flex:1; font-weight:600; }
.vc-pr-go{ font-size:.82rem; color:var(--brand); font-weight:600; }
.vc-st-clock{ margin-left:auto; font-variant-numeric:tabular-nums; font-weight:700;
  background:var(--paper); border-radius:999px; padding:3px 12px; }
.vc-st-clock.low{ background:#FDECEC; color:#95291F; }
@media (max-width:600px){
  .vc-pr-row{ flex-wrap:wrap; }
  .vc-pr-name{ flex:1 0 100%; }
}

/* ---- v10.8: short course descriptions carry inline HTML/CSS ----
   These sit inside fixed-size cards and a narrow table cell, so the container
   is fenced: long unbroken words wrap rather than widening the grid column, and
   anything that still overflows is clipped instead of overlapping its
   neighbours. The sanitiser already removes position/z-index/transform, so this
   is belt-and-braces against ordinary over-large styling rather than attack. */
.rich-desc{ overflow-wrap:anywhere; overflow:hidden; }
.rich-desc > *{ margin:0; }
.rich-desc *{ max-width:100%; font-size:inherit !important; line-height:inherit !important; }
.rich-desc b, .rich-desc strong{ font-weight:700; }
.rich-desc ul, .rich-desc ol{ margin:4px 0; padding-left:18px; }
.rich-desc a{ text-decoration:underline; }

/* ---- v10.9: clickable course card thumbnail + title ---- */
.course-thumb{ display:block; overflow:hidden; }
a.course-thumb img{ transition:transform .25s ease; }
a.course-thumb:hover img{ transform:scale(1.04); }
.course-title-link{ color:inherit; text-decoration:none; }
.course-title-link:hover{ text-decoration:underline; }
/* Card descriptions stay uniform however much text is pasted in. */
.course-card .rich-desc{
  display:-webkit-box; -webkit-line-clamp:4; -webkit-box-orient:vertical;
  overflow:hidden; max-height:6.5em;
}

/* v10.14.2: an Olympiad place held past its window — visible at a glance in the
   Held places table without needing to read the age column. */
tr.oly-stale{background:rgba(224,82,82,.06)}
td.oly-overdue{color:#c0392b}

/* ============================================================
   v10.16 — TED-Ed Student Talks, the family's page in the app.
   Each row is one session: when it is, what it is, and the two
   ticks that record whether the child is coming and whether that
   session may be filmed. The consent controls sit on the same
   row as the date deliberately — a permission detached from the
   thing it permits is the kind that gets given by accident.
   ============================================================ */
.ted-row{
  display:grid;grid-template-columns:170px 1fr auto;gap:16px;align-items:center;
  padding:14px 16px;margin-bottom:10px;
  border:1px solid var(--line,#e6e6ef);border-radius:10px;background:#fff;
  border-left:4px solid var(--brand,#6C5CE7);
}
.ted-row.is-past{opacity:.6;border-left-color:#bbb}
.ted-row-when{display:flex;flex-direction:column;gap:2px}
.ted-row-what{display:flex;flex-direction:column;gap:2px}
.ted-row-consent{display:flex;flex-direction:column;gap:4px;align-items:flex-start;min-width:170px}
.ted-row-consent .check{margin:0;font-size:.9rem}

/* v10.16: a plain ticked list, used for the TED-Ed speaking tips. */
.tick-list{list-style:none;padding:0;margin:8px 0}
.tick-list li{position:relative;padding:6px 0 6px 26px}
.tick-list li::before{content:"✓";position:absolute;left:2px;color:#17DA9B;font-weight:700}

@media (max-width:720px){
  .ted-row{grid-template-columns:1fr;gap:8px}
  .ted-row-consent{flex-direction:row;flex-wrap:wrap;gap:12px}
}

/* ============================================================
   v10.17 — interactive explanations.
   The frame is sandboxed and opaque-origin, so it cannot be
   styled from here: everything below is the hole it sits in,
   never its contents. Height is set in JS from the height the
   document reports about itself, because a cross-origin parent
   cannot measure it.
   ============================================================ */
iframe.explain-frame{
  display:block;width:100%;border:0;height:120px;   /* replaced on first report */
  background:transparent;
  margin:8px 0 0;transition:height .18s ease;
}
/* v11.0.3: capped at 600px. Past that the frame scrolls internally rather than
   growing — an explanation should never push the next question off the screen.
   The rule below marks a clipped one so it reads as scrollable rather than as
   something that has been cut off. */
iframe.explain-frame.is-clipped{
  border:1px solid var(--line,#e6e6ef);border-radius:10px;
  box-shadow:inset 0 -14px 14px -14px rgba(0,0,0,.22);
}
.review-explain iframe.explain-frame{margin-top:10px}
.explain-preview{
  max-height:60vh;overflow:auto;border:1px solid var(--line,#e6e6ef);
  border-radius:10px;padding:12px;background:#fff;
}

/* v11.0: previewing a programme's custom HTML block in the admin. */
iframe.pg-preview-frame{
  display:block;width:100%;height:60vh;border:1px solid var(--line,#e6e6ef);
  border-radius:10px;background:#fff;
}
/* v11.0.4: the explanation preview gets the room the wider modal now allows —
   it was the cramped one that prompted the change. */
.explain-preview{max-height:none}
.explain-preview iframe.explain-frame{max-height:70vh}

/* v11.1.1 — review pane. */
/* The answer, stated before the explanation argues towards it. */
.review-answer{
  margin:0 0 8px;padding:6px 12px;display:inline-block;
  background:rgba(23,218,155,.12);border-left:3px solid #17DA9B;border-radius:6px;
  font-size:.95rem;color:var(--ink,#222);
}
.review-answer b{font-size:1.05rem}
/* Figures imported as inline SVG: the picture IS the question.

   v11.2.4: laid out as a ROW. An "answer figures (A) to (E)" strip stacked one
   per line filled the whole screen and made the five impossible to compare —
   which is the entire task in a non-verbal reasoning question. Scoped to
   .q-side-q, the container both exam mode and review actually use. */
/* v11.2.12: the figures are sized to be LOOKED AT.

   An authored figure carries width="86" height="86" — a thumbnail, chosen so a
   whole paper fits a printed page. On screen that is far too small to compare
   five ladders rung by rung, which is the entire task. The explanation renders
   them large and legible; the question was rendering the same drawings at a
   third of that. CSS overrides the intrinsic attributes, so the figure scales
   to the space instead of to the number the author happened to write. */
.q-side-q svg, .stimulus svg{max-width:100%;height:auto}
.q-side-q .figrow{
  display:flex;flex-wrap:wrap;gap:12px;align-items:flex-start;margin:8px 0 12px;
}
.q-side-q .figrow figure{
  margin:0;flex:1 1 128px;max-width:176px;min-width:104px;
}
.q-side-q figure{
  display:inline-block;margin:0 12px 10px 0;text-align:center;vertical-align:top;
}
/* a figure standing alone (the "problem figure") gets more room than one of five */
.q-side-q .fig > svg, .q-side-q > svg, .stimulus > svg{max-height:260px}
.q-side-q .figrow svg{width:100%;height:auto;max-height:none}
.q-side-q figcaption{
  font-size:.84rem;font-weight:600;margin-top:3px;color:var(--muted,#666);
}
/* options are figures too on a non-verbal paper, and were the smallest of all */
.q-option svg{max-width:100%;height:auto;max-height:150px}
/* the "Problem figure" / "Answer figures" labels the importer keeps */
.q-side-q .figlabel{
  margin:10px 0 2px;font-size:.78rem;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted,#666);
}
@media (max-width:640px){
  .q-side-q .figrow{gap:8px}
  .q-side-q .figrow figure{flex:1 1 88px;min-width:80px;max-width:130px}
}

/* v11.2.9 — timed sections: how many questions each timer governs.
   A timer is matched to questions by NAME, so a typo produces a timed part
   with nothing in it — discovered only when a child sits the paper. The count
   makes that visible while it is still being typed. */
.st-count{
  min-width:96px;text-align:right;font-size:.82rem;color:var(--muted,#666);
  font-weight:600;white-space:nowrap;
}
.st-count.is-empty{color:#c0392b}
.st-warn{color:#c0392b;font-weight:600}
#st-summary{color:var(--muted,#666)}

/* v11.2.10 — the typed delete confirmation. */
.cd-loses{margin:6px 0 10px;padding-left:20px;color:var(--muted,#666);font-size:.9rem}
.cd-loses li{margin:2px 0}
#cd-input{font:600 15px ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.02em}

/* v11.2.12 — the download-format chooser. */
.dl-grid{display:grid;gap:8px}
.dl-btn{display:block;width:100%;text-align:left;padding:12px 14px;line-height:1.35}
.dl-btn b{display:block;font-size:.98rem}
.dl-btn span{display:block;font-size:.82rem;opacity:.85;font-weight:400;margin-top:2px}

/* v11.2.13 — built-in line icons (emoji-icons.js).
   Drawn in the current text colour so one icon serves a heading, a red warning
   and a white button; sized to the text it sits beside rather than to a fixed
   pixel count, so it scales with the type. */
svg.ic{
  width:1.05em;height:1.05em;vertical-align:-0.15em;flex:none;
  display:inline-block;margin-right:.12em;
}
h1 svg.ic,h2 svg.ic,h3 svg.ic{width:1em;height:1em;vertical-align:-0.1em}
.btn svg.ic{margin-right:.3em}

/* v11.2.16 — the full-screen control says what it is.
   A bare ⛶ went unnoticed: an icon only works when its meaning is already
   known, and this one is met once per paper by a child who has not seen it
   before. The word is dropped only on a narrow phone, where there is no room
   and the icon must carry it alone. */
.btn-fullscreen{
  display:inline-flex;align-items:center;gap:7px;width:auto;padding:8px 14px;
  font:600 13px 'Poppins',sans-serif;white-space:nowrap;
}
.btn-fullscreen .fs-ic{width:17px;height:17px;flex:none}
.btn-fullscreen .fs-label{display:inline}
@media (max-width:520px){ .btn-fullscreen .fs-label{display:none} .btn-fullscreen{padding:8px 10px} }

/* v11.2.19 — the page-block editor in the programme admin */
.pb-edit{ border:1px solid var(--line); border-radius:12px; padding:14px 16px; margin-bottom:10px; background:var(--paper); }
.pb-edit-head{ display:flex; gap:8px; align-items:center; margin-bottom:8px; }
.pb-edit-head .pb-type{ flex:0 0 240px; }
.pb-edit-head .pb-title-in{ flex:1 1 auto; }
.pb-edit input, .pb-edit select, .pb-edit textarea{
  font:inherit; padding:9px 11px; border:1px solid var(--line); border-radius:8px; width:100%; background:#fff;
}
.pb-edit .pb-lead-in{ margin-bottom:8px; }
.pb-edit textarea{ font:12.5px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace; resize:vertical; }

/* v11.2.21 — the TED-Ed overview numbers */
.ted-stats{ display:flex; flex-wrap:wrap; gap:10px; margin-top:12px; }
.ted-stat{ background:var(--paper); border:1px solid var(--line); border-radius:12px;
  padding:12px 16px; min-width:104px; }
.ted-stat b{ display:block; font-size:1.4rem; line-height:1.1; color:var(--ink); }
.ted-stat span{ font-size:.76rem; color:var(--muted); }
.ted-stat.warn{ background:#FFF6E6; border-color:#F3D9A6; }
.ted-stat.warn b{ color:#8A5A00; }
.tag-amber{ background:#FFF1D6; color:#8A5A00; border:1px solid #F3D9A6; }

/* v11.2.33 — two clocks: the section, and the whole paper */
.exam-clocks{ display:flex; align-items:center; gap:12px; }
.exam-timer-total{
  display:flex; flex-direction:column; align-items:flex-end; line-height:1.1;
  padding-left:12px; border-left:1px solid var(--line);
}
.exam-timer-total .ett-label{
  font:500 .62rem/1 var(--mono,ui-monospace,monospace); letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted);
}
.exam-timer-total .ett-value{ font:700 1rem/1.2 ui-monospace,SFMono-Regular,Menlo,monospace; color:var(--ink); }
@media (max-width:560px){ .exam-timer-total{ display:none } }

/* v11.2.33 — the break between the top five and your own place */
.lb-gap{ display:flex; justify-content:center; padding:6px 0; color:var(--muted); letter-spacing:.4em; }

/* v11.2.34 — choosing which leaderboard */
.lb-scopes{ display:flex; flex-wrap:wrap; gap:6px; margin:0 0 12px; }

/* v11.2.36 — the course item panel */
.ci-panel-head{ display:flex; align-items:flex-start; gap:12px; margin-bottom:10px; }
.ci-panel-ico{ font-size:1.6rem; line-height:1; }
.ci-facts{ display:grid; grid-template-columns:repeat(auto-fit,minmax(140px,1fr)); gap:10px;
  margin:14px 0 0; padding:14px 0 0; border-top:1px solid var(--line); }
.ci-facts div{ margin:0; }
.ci-facts dt{ font:500 .68rem/1 ui-monospace,SFMono-Regular,Menlo,monospace; letter-spacing:.12em;
  text-transform:uppercase; color:var(--muted); }
.ci-facts dd{ margin:6px 0 0; font-weight:700; color:var(--ink); }
.ci-note{ margin:14px 0 0; padding:10px 12px; border-radius:10px;
  background:#FFF6E6; border:1px solid #F3D9A6; color:#7A5200; }
.ci-panel-cta{ display:flex; gap:10px; flex-wrap:wrap; margin-top:16px; }
/* the contents rows are buttons on the course home, links elsewhere — they
   must look identical either way */
button.ci-item{ width:100%; text-align:left; background:none; border:0; font:inherit; cursor:pointer; }

/* ============================================================
   v11.3 — live activities
   ============================================================ */
/* the grid: a column per question, a row per student */
.live-wrap{ max-height:70vh; overflow:auto; }
.live-grid{ border-collapse:separate; border-spacing:0; }
.live-grid th{ position:sticky; top:0; z-index:2; background:var(--card); }
.live-grid th.lb-name,.live-grid td.lb-name{ position:sticky; left:0; z-index:3; background:var(--card);
  min-width:180px; text-align:left; }
.live-grid th.lb-name{ z-index:4; }
.live-grid th.lb-q{ width:34px; padding:6px 0; text-align:center; font:600 11px/1 ui-monospace,monospace; }
.live-grid td.lb-cell{ width:34px; padding:0; height:32px; text-align:center;
  font:700 11px/1 ui-monospace,SFMono-Regular,Menlo,monospace; border:1px solid var(--line); }
.live-grid td.lb-cell.right{ background:#E7F8F1; color:#0B7A55; }
.live-grid td.lb-cell.wrong{ background:#FDECEC; color:#B4433F; }
.live-grid td.lb-cell.here{ background:#EEF0FF; color:#3F27BD; box-shadow:inset 0 0 0 2px #3F27BD; }
.live-grid tr.is-finished td.lb-name{ opacity:.75; }
.live-grid td.lb-done{ font:600 12px/1 ui-monospace,monospace; color:var(--muted); text-align:center; }
.is-low{ color:#B4433F; font-weight:700; }
.is-right{ color:#0B7A55; }
.is-wrong{ color:#B4433F; }

/* the student's player: one question, big targets */
.live-player{ max-width:760px; margin:0 auto; }
.live-stem{ font-size:1.12rem; line-height:1.6; color:var(--ink); margin:0 0 16px; }
.live-opts{ display:grid; gap:10px; }
.live-opt{ display:flex; align-items:center; gap:14px; width:100%; text-align:left; cursor:pointer;
  padding:14px 16px; border-radius:14px; border:2px solid var(--line); background:var(--card);
  font:inherit; color:var(--ink); transition:border-color .15s, background .15s, transform .12s; }
.live-opt:hover{ border-color:var(--violet); transform:translateY(-1px); }
.live-opt.on{ border-color:var(--violet); background:#F2EFFE; }
.live-letter{ display:inline-flex; align-items:center; justify-content:center; width:30px; height:30px;
  border-radius:50%; background:var(--paper); font:700 13px/1 ui-monospace,monospace; color:var(--violet); }
.live-opt.on .live-letter{ background:var(--violet); color:#fff; }
.live-nav{ display:flex; align-items:center; justify-content:space-between; gap:14px; margin-top:22px;
  flex-wrap:wrap; }
@media (max-width:560px){ .live-nav{ flex-direction:column-reverse; align-items:stretch }
  .live-nav .btn{ width:100% } }

/* v11.3.1 — going through a question with the class */
.lq-opts{ display:grid; gap:8px; margin:14px 0 18px; }
.lq-opt{ display:grid; grid-template-columns:32px 1fr auto auto; gap:10px; align-items:center;
  padding:12px 14px; border-radius:12px; border:1px solid var(--line); background:var(--paper); }
.lq-opt.right{ border-color:#0B7A55; background:#E7F8F1; }
.lq-opt.wrong{ border-color:#E7B4B2; background:#FDECEC; }
.lq-letter{ display:inline-flex; align-items:center; justify-content:center; width:28px; height:28px;
  border-radius:50%; background:var(--card); font:700 12px/1 ui-monospace,monospace; }
.lq-count{ font:600 12px/1 ui-monospace,monospace; white-space:nowrap; }
.lq-who{ grid-column:1 / -1; padding-left:42px; }
.lq-explain{ margin-top:18px; padding:16px; border-radius:12px; background:var(--paper);
  border-left:3px solid var(--violet); }
.lq-explain-h{ margin:0 0 10px; font-weight:700; color:var(--ink); }
tr.is-clickable{ cursor:pointer; }
tr.is-clickable:hover{ background:var(--paper); }
.live-grid td.lb-cell[data-live-q]{ cursor:pointer; }
.live-grid th.lb-q[data-live-q]{ cursor:pointer; }

/* ============================================================
   v11.3.2 — teach mode: the question, full screen, for a class
   ============================================================ */
body.teach-on{ overflow:hidden; }
#teach-layer{ position:fixed; inset:0; z-index:200; background:#fff; display:flex; }
#teach-layer:empty{ display:none; }
.teach{ display:flex; flex-direction:column; width:100%; height:100%; }
.teach-bar{ display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:12px 20px; border-bottom:1px solid var(--line); background:var(--paper); }
.teach-title{ font:700 .95rem/1 'Poppins',sans-serif; color:var(--ink); }
.teach-tools{ display:flex; align-items:center; gap:6px; }
.tt{ display:inline-flex; align-items:center; justify-content:center; min-width:38px; height:34px;
  border:1px solid var(--line); background:#fff; border-radius:9px; cursor:pointer;
  font:700 14px/1 'Poppins',sans-serif; color:var(--ink); }
.tt:hover{ border-color:var(--violet); }
.tt.on{ border-color:var(--violet); box-shadow:0 0 0 2px rgba(63,39,189,.18); }
.tt .sw{ width:16px; height:16px; border-radius:4px; display:block; }
.sw.y{ background:#FFE682; } .sw.p{ background:#FFC2E0; } .sw.g{ background:#B9F3D8; }
.teach-sep{ width:1px; height:22px; background:var(--line); margin:0 4px; }

.teach-body{ flex:1; overflow:auto; padding:34px 6vw; max-width:1100px; margin:0 auto; width:100%; }
.teach-stem{ font:700 clamp(1.3rem,2.4vw,1.9rem)/1.4 'Poppins',sans-serif; color:var(--ink); margin:0 0 20px; }
.teach-img{ max-width:100%; border-radius:12px; margin-bottom:20px; }
.teach-opts{ display:grid; gap:10px; margin-bottom:26px; }
.teach-opt{ display:flex; align-items:center; gap:14px; padding:14px 18px; border-radius:12px;
  border:2px solid var(--line); font-size:1.1rem; color:var(--ink); }
.teach-opt.right{ border-color:#0B7A55; background:#E7F8F1; }
.teach-letter{ display:inline-flex; align-items:center; justify-content:center; width:34px; height:34px;
  border-radius:50%; background:var(--paper); font:700 15px/1 ui-monospace,monospace; }
.teach-count{ margin-left:auto; font:700 13px/1 ui-monospace,monospace; color:var(--muted); }

.teach-steps{ display:grid; gap:16px; }
.teach-step{ font-size:clamp(1.05rem,1.7vw,1.3rem); line-height:1.7; color:var(--ink);
  padding:16px 20px; border-radius:14px; background:var(--paper); border-left:4px solid var(--violet); }
.teach-step.is-new{ animation:teach-in .35s cubic-bezier(.2,.9,.3,1) both; }
@keyframes teach-in{ from{ opacity:0; transform:translateY(10px) } to{ opacity:1; transform:none } }
.teach-step mark.hl-y{ background:#FFE682; } .teach-step mark.hl-p{ background:#FFC2E0; }
.teach-step mark.hl-g{ background:#B9F3D8; }
.teach-step u{ text-decoration-thickness:3px; text-underline-offset:4px; text-decoration-color:var(--violet); }

.teach-foot{ display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:14px 20px; border-top:1px solid var(--line); background:var(--paper); }
.teach-count-label{ font:600 .8rem/1 ui-monospace,monospace; color:var(--muted); }
@media (prefers-reduced-motion:reduce){ .teach-step.is-new{ animation:none } }

/* v11.5.6 — attempt review palette: correct greyed, wrong in red, one
   question fetched at a time (see /papers/:id/review/:pos) */
.rev-pal{ display:flex; flex-wrap:wrap; gap:8px; margin:4px 0 14px }
.rev-cell{ width:42px; height:42px; border-radius:10px; font:inherit; font-weight:700;
  border:1.5px solid var(--line); background:#f1f2f6; color:#6a7090; cursor:pointer }
.rev-cell.ok{ opacity:.55 }
.rev-cell.bad{ background:#fdecec; border-color:#e5a8a8; color:var(--red, #c0392b) }
.rev-cell.cw{ background:#fff7e8; border-color:#e8cf9d; color:#a06e00 }
.rev-cell:hover{ transform:translateY(-1px) }
.rev-cell.active{ outline:2.5px solid var(--brand, #4F46B8); outline-offset:1px }

/* v11.6.0 — live board + progress review */
.live-grid tr.flash td{ animation:lb-flash 1.2s ease 2 }
@keyframes lb-flash{ 0%,100%{ background:transparent } 50%{ background:#fff3d6 } }
.bq-names td{ background:#fafbfe }

/* v11.7.0 — confetti on released scores */
.confetti-holder{ position:fixed; inset:0; pointer-events:none; z-index:9999; overflow:hidden }
.confetti-holder i{ position:absolute; top:-4vh; display:block; border-radius:2px; opacity:.95;
  animation:confetti-fall linear forwards }
@keyframes confetti-fall{ to{ transform:translateY(110vh) rotate(720deg); opacity:.7 } }

/* v11.7.1 — the teacher's pen over the teach screen */
.teach{ position:relative }
.ink-canvas{ position:absolute; inset:0; z-index:6; pointer-events:none; touch-action:none }
.ink-canvas.on{ pointer-events:auto; cursor:crosshair }
.teach-bar, .teach-foot{ position:relative; z-index:7 }   /* the tools stay clickable above the ink */
.sw.pr{ background:#d23f3f } .sw.pb{ background:#2f6fd8 }

/* ============================================================
   v11.11.0 — the clock stays on screen.

   The paper's header scrolled away with everything else, so a child reading a
   passage or working down a section could not see how long was left without
   scrolling back up — the one thing a timed paper must never make them do.
   The header now sticks to the top of the window: section clock, whole-paper
   clock, progress and the close button all stay reachable.

   Only the header sticks, not the palette: pinning both would eat a phone
   screen. The card carries no overflow of its own, so sticky works inside it.
   ============================================================ */
.card-head.paper-head{
  /* the app's own topbar is sticky at top:0 and about 49px tall, so the paper
     header parks directly beneath it rather than sliding under it */
  position:sticky; top:var(--topbar-h,49px); z-index:40;
  margin:-20px -20px 12px;            /* out to the card's edges, over its padding */
  padding:12px 20px;
  background:var(--card,#fff);
  border-bottom:1px solid var(--line,#e8edf5);
  border-radius:var(--radius,16px) var(--radius,16px) 0 0;
}
/* the title may wrap on a phone; the clocks must not be pushed off */
.card-head.paper-head h2{ font-size:clamp(1rem,2.6vw,1.35rem); margin-bottom:0 }
@media (max-width:640px){
  .card-head.paper-head{ gap:8px; padding:10px 14px; margin:-20px -20px 10px }
  .card-head.paper-head .muted.small{ display:none }   /* keep the clocks in view */
}
/* full screen hides the topbar, so the header pins to the very top instead */
.fs-on .card-head.paper-head{ top:0 }

/* v11.12.0 — elective work, plainly marked and quietly styled: it should read
   as an offer, not as another thing owed. */
.ci-extra{ margin-left:6px; font-size:.68rem; font-weight:700; letter-spacing:.04em;
  text-transform:uppercase; color:var(--grey,#7a869a);
  background:var(--soft,#f4f6fb); border-radius:999px; padding:2px 7px }

/* v11.16.0 — the contents of a week that has not opened yet: visible, so a
   child can see what is coming, but plainly not a button. */
.ci-item-locked{ opacity:.5; cursor:default; pointer-events:none; background:transparent }
.ci-item-locked .ci-title{ text-decoration:none }

/* ============================================================
   v11.68.0 — the boot ring

   An admin's /api/bootstrap takes several seconds on a full year of content,
   and until it returned the page was simply blank: no logo, no message,
   nothing to say the site was working. This is what fills that gap, on the
   app and on the public pages alike.

   It is the real sidebar logo with a gradient arc sweeping round it, and the
   arc deliberately STOPS SHORT of a full circle. There is no progress to
   report — one request either returns or it does not — and an arc that
   completed would be claiming knowledge it does not have, then sitting at 100%
   for four seconds.

   The overlay is removed by script. If that script never runs the site would
   be bricked behind a spinner, so app.js and public.js both carry a timeout
   that clears it regardless (see bootFail).
   ============================================================ */
#boot{
  position:fixed; inset:0; z-index:9999; display:grid; place-items:center;
  background:var(--paper,#FBFAFE); transition:opacity .3s ease;
}
#boot.boot-gone{ opacity:0; pointer-events:none; }
.boot-inner{ display:flex; flex-direction:column; align-items:center; }
.boot-ring{ position:relative; width:132px; height:132px; display:grid; place-items:center; }
.boot-ring .boot-tile{
  width:76px; height:76px; border-radius:20px; display:grid; place-items:center;
  background:linear-gradient(135deg,var(--a1,#3F27BD),var(--a2,#D22CB2));
  box-shadow:0 6px 20px rgba(63,39,189,.32);
}
.boot-ring .boot-tile svg{ width:38px; height:38px; fill:#fff; animation:bootBreathe 1.6s ease-in-out infinite; }
.boot-ring svg.boot-arc-svg{ position:absolute; inset:0; width:132px; height:132px; transform:rotate(-90deg); }
.boot-ring .boot-track{ fill:none; stroke:#EDE9FB; stroke-width:5; }
.boot-ring .boot-arc{
  fill:none; stroke:url(#bootGrad); stroke-width:5; stroke-linecap:round;
  stroke-dasharray:390; stroke-dashoffset:390; animation:bootSweep 2.4s ease-in-out infinite;
}
@keyframes bootBreathe{ 0%,100%{ transform:scale(1); opacity:.92 } 50%{ transform:scale(1.1); opacity:1 } }
@keyframes bootSweep{ 0%{ stroke-dashoffset:390 } 60%{ stroke-dashoffset:70 } 100%{ stroke-dashoffset:70; opacity:.6 } }
.boot-cap{
  margin:26px 0 0; font-size:13.5px; font-weight:600; letter-spacing:.2px;
  color:var(--muted,#6B6790); text-align:center;
}
.boot-slow{ margin:8px 0 0; font-size:12.5px; color:var(--muted,#6B6790); opacity:.85; text-align:center; }

/* A spinner that never stops is the worst thing to show someone who cannot
   tolerate motion. The arc holds still and the caption carries the message. */
@media (prefers-reduced-motion: reduce){
  .boot-ring .boot-tile svg, .boot-ring .boot-arc{ animation:none; }
  .boot-ring .boot-arc{ stroke-dashoffset:120; }
}

/* ============================================================
   v11.75.0 — settings tabs

   The settings page was ten unrelated sections stacked in one 720px column,
   with the email fields split across three of them and the Vocabulary block
   structurally nested inside the email row. Four panels behind a tab bar.

   Every input stays inside the one form, so a hidden panel still saves: the
   handler walks input[name] and does not care what is on screen. That is why
   these are `hidden` panels rather than separate forms.
   ============================================================ */
.set-tabs{ display:flex; flex-wrap:wrap; gap:6px; margin:0 0 16px;
  border-bottom:1px solid var(--line,#E3E3E7); padding-bottom:10px; }
.set-tab{ font:inherit; font-size:13.5px; font-weight:700; cursor:pointer;
  padding:7px 14px; border-radius:99px; border:1px solid transparent;
  background:transparent; color:var(--muted,#6A7090); }
.set-tab:hover{ background:var(--violet-soft,#F1EEFC); color:var(--a1,#3F27BD); }
.set-tab.is-on{ background:var(--a1,#3F27BD); color:#fff; }
.set-tab:focus-visible{ outline:2px solid var(--a2,#D22CB2); outline-offset:2px; }
.set-panel > h3:first-child{ margin-top:2px; }

/* ============================================================
   v11.76.1 — a button that says what it is doing

   Signing in disabled the button and nothing else, so it greyed out and sat
   there. `Store.login()` runs the auth request AND the whole bootstrap before
   it resolves, which on a full year of content is several seconds — long
   enough for a parent to decide the click never landed and press again.
   ============================================================ */
.btn.is-busy{ opacity:1; cursor:progress; }
.btn.is-busy > span:last-child{ vertical-align:middle; }
.btn-spin{
  display:inline-block; width:15px; height:15px; margin-right:9px; vertical-align:middle;
  border:2px solid currentColor; border-right-color:transparent; border-radius:50%;
  animation:btnSpin .7s linear infinite;
}
@keyframes btnSpin{ to{ transform:rotate(360deg) } }
/* A disabled button is normally dimmed to say "you cannot press this". A busy
   one is different: it IS doing the thing, so it keeps its colour and the
   spinner carries the message. */
.btn.is-busy[disabled]{ filter:none; }
@media (prefers-reduced-motion: reduce){
  .btn-spin{ animation:none; border-right-color:currentColor; opacity:.55; }
}

/* v11.79.0 — a paused paper on the week card. Amber rather than green: it is
   not finished, and a ten-year-old reads colour before text. */
.wk-row.is-part{ background:#FFF8E8; }
.wk-row.is-part .wk-tick{ color:#B26A00; }
/* v11.79.2 — the state chip. Amber for part done, green for marked, so the
   three states of a week read at a glance without being read at all. */
.wk-state{ display:inline-block; margin-left:8px; padding:1px 8px; border-radius:99px;
  font-size:11.5px; font-weight:800; white-space:nowrap; }
.wk-state.is-part{ background:#FFE9BF; color:#8A5200; }
.wk-state.is-marked{ background:#DFF3E4; color:#186A3B; }
.quiz-foot{ display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  margin-top:16px; padding-top:12px; border-top:1px solid var(--line,#E3E3E7); }
.quiz-foot .small{ margin-left:auto; }

/* ============================================================
   v11.80.0 — "this week", over the page

   The course page leads with the season grid, so the week a child is meant to
   be doing sits below the fold. This lifts it on top on arrival, once.
   ============================================================ */
.wk-pop{ position:fixed; inset:0; z-index:80; display:flex; align-items:flex-start;
  justify-content:center; padding:5vh 16px 16px; overflow:auto; }
.wk-pop-back{ position:fixed; inset:0; background:rgba(20,14,50,.45); backdrop-filter:blur(2px); }
.wk-pop-sheet{ position:relative; width:min(1400px,100%); background:var(--card,#fff);
  border-radius:18px; box-shadow:0 24px 70px rgba(30,20,70,.35); overflow:hidden;
  animation:wkPopIn .18s ease-out; }
@keyframes wkPopIn{ from{ transform:translateY(10px); opacity:0 } to{ transform:none; opacity:1 } }
.wk-pop-head{ display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:14px 18px; border-bottom:1px solid var(--line,#E3E3E7); }
.wk-pop-head b{ font-size:1.05rem; }
.wk-pop-head .btn{ margin-left:auto; }
/* v12.12.0 — the week now OPENS here rather than arriving here by accident,
   and it holds six cards in two columns, so give it more of the screen. */
.wk-pop-body{ padding:14px 18px 20px; max-height:86vh; overflow:auto; }
/* the week inside the panel has no card chrome of its own: the panel IS the card */
.wk-detail-bare{ box-shadow:none; border:0; padding:0; background:transparent; }
@media (prefers-reduced-motion: reduce){ .wk-pop-sheet{ animation:none } }
@media (max-width:700px){
  .wk-pop{ padding:0; }
  .wk-pop-sheet{ border-radius:0; min-height:100dvh; }
  .wk-pop-body{ max-height:none; }
}

/* ============================================================
   v11.82.0 — Vocabulary Learn, rendered natively

   Three columns on a laptop, stacked on a phone. The old screen was a fixed
   1200px HTML document in an iframe, so on a tablet it was scrolled sideways.
   ============================================================ */
.vl-top{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-bottom:8px; }
.vl-count{ margin-left:auto; font-family:ui-monospace,monospace; font-size:13px; color:var(--muted,#6A7090); }
.vl-bar{ height:7px; border-radius:99px; background:#EDE9FB; overflow:hidden; }
.vl-bar i{ display:block; height:100%; background:linear-gradient(90deg,#3F27BD,#D22CB2); transition:width .3s ease; }
.vl-sub{ margin:6px 0 12px; }
.vl-grid{ display:grid; grid-template-columns:1fr 1fr 1fr; gap:14px; align-items:start; }
.vl-col{ background:var(--card,#fff); border:1px solid var(--line,#E3E3E7); border-radius:14px; padding:14px; }
.vl-theme{ margin:0 0 10px; font-size:1.05rem; }
.vl-q{ background:#FFF4DB; border-left:4px solid #E9A825; border-radius:10px; padding:10px 12px; margin:0 0 12px; }
.vl-q p{ margin:4px 0 0; }
.vl-clue{ background:#F7F7FB; border-radius:8px; padding:8px 10px; margin:0 0 6px; font-size:.95rem; }
.vl-clue b{ color:var(--a1,#3F27BD); }

.vl-pick{ background:#F2EEFC; border-radius:12px; padding:12px; margin:0 0 12px; }
.vl-opt{ display:flex; align-items:center; gap:10px; background:#fff; border:2px solid transparent;
  border-radius:10px; padding:10px 12px; margin-top:8px; cursor:pointer; }
.vl-opt.is-picked{ border-color:var(--a1,#3F27BD); }
.vl-opt.is-right{ border-color:#1B8A4B; background:#EEF9F1; }
.vl-opt.is-wrong{ border-color:#C43D3D; background:#FDF0F0; }
.vl-word{ text-align:center; font-weight:800; letter-spacing:.06em; padding:10px;
  border-radius:10px 10px 0 0; background:linear-gradient(135deg,#3F27BD,#D22CB2); color:#fff; }
.vl-mean{ border:1px solid var(--line,#E3E3E7); border-top:0; border-radius:0 0 10px 10px; padding:12px; }
.vl-eg{ background:#FFF4DB; border-left:4px solid #E9A825; border-radius:8px;
  padding:8px 10px; margin:10px 0 0; font-style:italic; font-size:.93rem; }
.vl-actions{ display:flex; gap:8px; flex-wrap:wrap; margin-top:10px; }

.vl-zone{ border:2px dashed #BFD8C6; border-radius:12px; padding:10px; margin:0 0 10px; background:#F4FBF6; }
.vl-zone + .vl-zone{ border-color:#E3C7C7; background:#FDF6F6; }
.vl-drop{ min-height:46px; display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
.vl-hint{ color:#9aa; font-size:.85rem; }
.vl-bank{ display:flex; flex-wrap:wrap; gap:6px; margin-top:4px; }
.vl-chip{ font:inherit; font-size:.88rem; font-weight:700; cursor:pointer;
  padding:7px 13px; border-radius:99px; border:0; color:#fff;
  background:linear-gradient(135deg,#5B46C8,#8E5BC8); }
/* a tap target a child can actually hit, which is the whole point of the change */
.vl-chip{ min-height:38px; }
.vl-chip.is-placed{ background:linear-gradient(135deg,#3F27BD,#D22CB2); }
.vl-chip.is-ok{ background:#1B8A4B; }
.vl-chip.is-bad{ background:#C43D3D; }
.vl-zonehint{ margin:8px 0 0; }
.vl-foot{ display:flex; align-items:center; gap:12px; margin-top:14px;
  padding-top:12px; border-top:1px solid var(--line,#E3E3E7); }
.vl-foot .muted{ margin-left:auto; margin-right:auto; }
@media (max-width:980px){
  .vl-grid{ grid-template-columns:1fr; }
  .vl-count{ margin-left:0; }
}

/* v11.86.0 — the build stamp in the sidebar foot. Small and quiet: it is a
   diagnostic, not a feature, but it has to be readable in a screenshot. */
.side-build{ margin:8px 0 0; font-size:11px; line-height:1.2; text-align:center;
  color:var(--muted,#6A7090); opacity:.75; font-family:ui-monospace,monospace; }

/* v11.90.0 — which box is armed, and the mouse hint.

   The selected box is outlined so a child can see where a tap will land
   before they make it. The drag line is hidden on touch, where dragging does
   not work and mentioning it would only confuse. */
.vl-zone.is-armed{ box-shadow:0 0 0 2px var(--a1,#3F27BD) inset; }
.vl-zone.is-armed .vl-hint{ color:var(--a1,#3F27BD); font-style:normal; font-weight:700; }
@media (hover:none), (pointer:coarse){ .vl-mousehint{ display:none; } }

/* v11.91.0 — practice in four parts. The row header names the skill; the four
   buttons under it are the parts, sized for a thumb. */
.vc-pr-row-head{ display:flex; align-items:center; gap:10px; padding:10px 4px 4px; }
.vc-pr-row-head .vc-pr-name{ font-weight:700; }
.vc-pr-row-head .small{ margin-left:auto; }
.vc-pr-parts{ display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:8px; padding:0 4px 12px; }
.vc-pr-part{ font:inherit; cursor:pointer; text-align:left; min-height:58px;
  display:flex; flex-direction:column; gap:2px; padding:9px 12px; border-radius:12px;
  border:1px solid var(--line,#E3E3E7); background:var(--card,#fff); }
.vc-pr-part:hover{ border-color:var(--a1,#3F27BD); }
.vc-pr-part.is-part{ background:#FFF8E8; border-color:#E9C77A; }
.vc-pr-part-state{ font-size:11.5px; font-weight:800; color:#8A5200; }

/* v11.92.0 — the leaderboard's own explanation. Quiet, and above the table, so
   it is read before the numbers rather than after them. */
.lb-note{ background:var(--violet-soft,#F1EEFC); border-radius:12px;
  padding:10px 14px; margin:0 0 14px; line-height:1.55; color:var(--ink,#1A1040); }
.lb-note b{ display:inline; }
.lb-row.me .lb-rank{ font-size:1.05rem; }

/* v12.13.0 — the home page order, as a list you can rearrange */
.land-order{ list-style:none; margin:0 0 8px; padding:0; max-width:560px;
  border:1px solid var(--line); border-radius:10px; overflow:hidden; }
.land-row{ display:flex; align-items:center; gap:10px; padding:5px 10px;
  border-bottom:1px solid var(--line); background:#fff; }
.land-row:last-child{ border-bottom:0; }
.land-row.is-prog{ background:#F7F5FF; font-weight:600; }
.land-row .check{ flex:1; margin:0; }
.land-arrows{ display:flex; gap:4px; }
.land-arrows .btn{ padding:2px 9px; min-width:0; }

/* v12.16.0 — course billing. Only the options for the chosen type show. */
.cf-billing{ border:1px solid var(--line); border-radius:10px; padding:8px 14px 12px; margin:12px 0; }
.cf-billing legend{ padding:0 6px; }
.cf-billing .cf-pay{ display:none; gap:14px; align-items:center; flex-wrap:wrap; margin-top:6px; }
.cf-billing[data-mode="oneoff"] .cf-pay-oneoff,
.cf-billing[data-mode="monthly"] .cf-pay-monthly{ display:flex; }
.cf-billing[data-mode="free"] .cf-price,
.cf-billing[data-mode="freejoin"] .cf-price,   /* v12.47.0 */
.cf-billing[data-mode=""] .cf-price{ display:none; }

/* v12.21.0 — the level meter inside the greeting, where the four-card
   stats strip used to say it in a quarter of the screen. */
.hello-banner .hello-progress{ margin-top:6px; max-width:260px; height:6px; }

/* v12.21.0 — "How it works": tabbed slideshows */
.guide-tabs{ display:flex; gap:6px; flex-wrap:wrap; margin-top:4px; }
.guide-show{ position:relative; margin-top:12px; outline:none; }
.guide-show:focus-visible{ box-shadow:0 0 0 3px rgba(63,39,189,.3); border-radius:12px; }
.guide-slide{ display:none; margin:0; }
.guide-slide.on{ display:block; }
.guide-slide img{ width:100%; height:auto; border:1px solid var(--line); border-radius:12px; display:block; }
.guide-slide figcaption{ margin-top:8px; font-size:.95rem; }
.guide-controls{ display:flex; align-items:center; gap:8px; justify-content:center; margin-top:10px; }
.guide-dots{ display:flex; gap:6px; }
.guide-dot{ width:10px; height:10px; padding:0; border-radius:999px; cursor:pointer;
  border:1.5px solid var(--line); background:#fff; }
.guide-dot.on{ background:var(--a1); border-color:var(--a1); }

/* the editor */
.gd-slides{ list-style:none; margin:6px 0 0; padding:0; }
.gd-slide{ display:flex; gap:10px; align-items:center; padding:6px 0; border-bottom:1px solid var(--line); }
.gd-slide img{ width:96px; height:54px; object-fit:cover; border-radius:6px; border:1px solid var(--line); }
.gd-slide-body{ flex:1; }
.gd-slide-body input{ width:100%; }
.gd-arrows{ display:flex; gap:4px; }
@media (prefers-reduced-motion: reduce){ .guide-slide{ transition:none; } }

/* v12.22.0 — video slides */
.guide-embed,.guide-video{ width:100%; aspect-ratio:16/9; border:1px solid var(--line);
  border-radius:12px; display:block; background:#000; }
.guide-embed{ border:0; }
.gd-slide .gd-kind{ font-size:.75rem; color:var(--muted); white-space:nowrap; }
.gd-slide .gd-thumb-vid{ width:96px; height:54px; border-radius:6px; border:1px solid var(--line);
  display:flex; align-items:center; justify-content:center; background:#111; color:#fff; }

/* v12.22.0 — the public top menu editor */
.lm-list .lm-row{ display:flex; gap:8px; align-items:center; padding:5px 10px;
  border-bottom:1px solid var(--line); background:#fff; }
.lm-list .lm-row:last-child{ border-bottom:0; }
.lm-row .lm-label{ flex:0 0 38%; }
.lm-row .lm-href{ flex:1; }

/* v12.23.0 — a vocabulary set the course does not include */
.vocab-set-tile.is-locked{ opacity:.55; background:#FAFAFC; cursor:help; }
.vocab-set-tile.is-locked .vst-no{ color:var(--muted); }
.vocab-set-tile.is-locked:hover{ opacity:.75; }

/* ============================================================
   v12.28.0 — a lesson in full screen gets the screen
   ------------------------------------------------------------
   The frame was 100vh - 300px. That 300px was a 36px dimmed
   border top and bottom, a padded header, padded body, a padded
   card round the lesson, and a row for the pen — about a third
   of a laptop screen spent around the thing being taught.

   Only when the sheet holds a frame that FILLS: a written lesson
   or a quiz in full screen keeps the reading margins it had.
   (:has() is in every current browser; an older one simply keeps
   the old spacing, which is where it was yesterday.)
   ============================================================ */
.wk-viewer.is-full:has(.code-frame.is-fill){
  top:12px; width:calc(100vw - 24px); max-height:calc(100dvh - 24px); overflow:hidden;
}
.wk-viewer.is-full:has(.code-frame.is-fill) .wk-viewer-head{ padding-top:8px; padding-bottom:8px; }
.wk-viewer.is-full:has(.code-frame.is-fill) .wk-viewer-body{ padding:8px 10px 10px; }
.wk-viewer.is-full:has(.code-frame.is-fill) .lesson-block{
  padding:0; margin:0; border:0; box-shadow:none; background:transparent;
}
.wk-viewer.is-full:has(.code-frame.is-fill) .lesson-block > h3{ display:none; }
.wk-viewer.is-full:has(.code-frame.is-fill) .code-frame.is-fill{
  height:calc(100dvh - var(--lesson-chrome, 104px)); min-height:420px; max-height:none;
}
/* a self-designed deck has its own frame, header and footer */
.code-frame.own-design{ border:0; border-radius:10px; background:transparent; }

/* v12.29.0 — TED-Ed registrations (staff) */
.ti-group > summary{ cursor:pointer; list-style:none; }
.ti-group > summary::-webkit-details-marker{ display:none; }
.ti-group > summary::before{ content:"\25B8"; display:inline-block; width:1.2em; transition:transform .15s; }
.ti-group[open] > summary::before{ transform:rotate(90deg); }
.ti-cohorts input{ width:100%; }
.ti-form h4{ margin:16px 0 6px; }
.ti-form .table th{ font-weight:600; color:var(--muted); }
.ti-agreed{ margin:0 0 8px; padding-left:0; list-style:none; }
.ti-agreed li{ margin:0 0 4px; }

/* v12.30.0 — the TED-Ed consent form wording editor */
.tfe-list{ list-style:none; margin:0; padding:0; }
.tfe-row{ display:grid; grid-template-columns:180px 1fr auto; gap:8px; align-items:start;
  padding:6px 0; border-bottom:1px solid var(--line); }
/* the page's own type, not the browser's monospace default for textarea */
.tfe-row textarea{ width:100%; font:inherit; line-height:1.45; padding:6px 10px;
  border:1px solid var(--line); border-radius:10px; }
.tfe-row select{ font:inherit; padding:5px 8px; border:1px solid var(--line); border-radius:10px; }
.tfe-choice{ border:1px solid var(--line); border-radius:12px; padding:8px 12px; margin:0 0 10px; }
/* wide enough for the longest heading ("Sparks Academy website & social media") */
.tfe-choice legend{ width:min(100%, 440px); }
.tfe-choice legend input{ font:inherit; font-weight:700; width:100%; padding:4px 8px;
  border:1px solid var(--line); border-radius:8px; }
@media (max-width:700px){ .tfe-row{ grid-template-columns:1fr auto; } .tfe-row .tfe-sec{ grid-column:1 / -1; } }

/* v12.33.0 — User group email: the To list (one row per address) */
.grp-to{margin:0 0 14px;background:#fff;border:1px solid var(--line);border-radius:12px;padding:10px 12px}
.grp-to-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:8px}
.grp-to-label{font-weight:700;font-size:.9rem}
.grp-to-tools{margin-left:auto;display:flex;gap:6px;align-items:center}
.grp-to-tools input[type=search]{width:180px;padding:5px 10px;font-size:.85rem}
.grp-to-list{max-height:260px;overflow:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:2px 16px}
.grp-to-row{display:flex;align-items:flex-start;gap:10px;padding:6px 6px;border-radius:8px;cursor:pointer;min-width:0}
.grp-to-row:hover{background:var(--soft,#F4F5FB)}
.grp-to-row input{flex:none;margin:3px 0 0}
.grp-to-who{display:flex;flex-direction:column;min-width:0;line-height:1.3}
.grp-to-names,.grp-to-addr{overflow-wrap:anywhere}
.grp-to-row:has(input:not(:checked)) .grp-to-who{opacity:.45;text-decoration:line-through}
.grp-to-cannot{margin:8px 0 0}

/* v12.34.0 — Parent vocabulary checks (admin page + dashboard card) */
.vcx-course .card-head{align-items:flex-start}
.vcx-body{border-top:1px solid var(--line);margin-top:12px;padding-top:14px}
.vcx-switch{display:flex;gap:10px;align-items:center;margin-bottom:12px;cursor:pointer}
.vcx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:4px 14px}
.vcx-modes{display:flex;flex-wrap:wrap;gap:4px 14px;padding-top:6px}
.vcx-modes label{display:flex;gap:6px;align-items:center;font-size:.9rem;cursor:pointer}
.vcx-weeks input,.vcx-weeks select{padding:6px 8px}
.vcx-previewbox{margin-top:12px;background:var(--soft,#F4F5FB);border:1px solid var(--line);border-radius:12px;padding:12px 14px}
.vcx-previewbox ol{margin:6px 0 0;padding-left:20px}
.vcx-previewbox li{margin:0 0 10px}
.vcx-right{color:#15803D;font-weight:700}
.vcx-msg{white-space:pre-wrap;background:#F0FDF4;border:1px solid #BBF7D0;border-radius:12px;padding:10px 12px;
  font-size:.9rem;margin:8px 0 10px}
.vcx-ready{border:2px solid #BBF7D0}
.vcx-readyrow{padding:12px 0;border-top:1px solid var(--line)}
.vcx-readyrow:first-of-type{border-top:0}
.vcx-readyrow.overdue .vcx-msg{border-color:#FCD34D;background:#FFFBEB}
.vcx-readyhead{display:flex;gap:10px;flex-wrap:wrap;align-items:center}

/* v12.35.3 — a marked quiz or mock in the week: See results + Redo */
.wk-row.wk-row-marked{ flex-wrap:wrap; }
.wk-act{ display:inline-flex; align-items:center; gap:4px; padding:3px 12px; border-radius:99px; font-size:12.5px;
  font-weight:800; text-decoration:none; white-space:nowrap; border:2px solid #E7E1FA; background:#fff; color:#4C1D95; }
.wk-act:hover{ border-color:#7C3AED; background:#F0EAFF; }
.wk-act-results{ color:#fff; border-color:transparent; background:linear-gradient(135deg,#7C3AED,#C026D3); }
.wk-act-results:hover{ color:#fff; border-color:transparent; filter:brightness(1.07); background:linear-gradient(135deg,#7C3AED,#C026D3); }

/* v12.36.0 — a quiz's timed sections: no passages (a mock's mechanic) */
.st-box.st-quiz .st-p-toggle, .st-box.st-quiz .st-passage{ display:none !important; }

/* v12.37.0 — Weekly Vocab Booster admin */
.vb-lists{ display:grid; grid-template-columns:repeat(auto-fit,minmax(360px,1fr)); gap:14px; }
.vb-list{ border:1px solid var(--line); border-radius:12px; padding:12px 14px; background:#fff; }
.vb-report{ margin-top:6px; padding:8px 10px; border-radius:10px; background:var(--soft,#F7F6FC); }
.vb-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); gap:4px 14px; }
.vb-words td{ vertical-align:top; }

/* v12.38.0 — search and filters above staff lists */
.tt-bar{ display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin:4px 0 10px; }
.tt-bar .tt-q{ flex:1 1 240px; max-width:360px; padding:8px 12px; border:1.5px solid var(--line); border-radius:999px; font:inherit; background:#fff; }
.tt-bar .tt-f{ padding:7px 10px; border:1.5px solid var(--line); border-radius:999px; font:inherit; font-size:.88rem; background:#fff; max-width:240px; }
.tt-bar .tt-f:not([value=""]):has(option:checked:not([value=""])){ border-color:var(--violet); background:var(--violet-soft); }
.tt-bar .tt-count{ font-size:.85rem; color:var(--muted); margin-left:auto; }
.tt-empty{ margin:8px 0; }
.vb-cover{ display:flex; flex-wrap:wrap; gap:4px; }
.vb-cell{ width:30px; height:26px; display:grid; place-items:center; border-radius:6px; font-size:12px; font-weight:700;
  background:#F4F5FB; color:#9A97B5; border:1px solid var(--line); }
.vb-cell.full{ background:#DCFCE7; color:#166534; border-color:#86EFAC; }
.vb-cell.part{ background:#FEF3C7; color:#92400E; border-color:#FCD34D; }

/* v12.49.0 — the email composer for admins */
.rm-wrap{ border:1.5px solid var(--line); border-radius:12px; background:#fff; overflow:hidden; }
.rm-wrap.rm-drop{ border-color:var(--violet); box-shadow:0 0 0 3px var(--violet-soft); }
.rm-bar{ display:flex; flex-wrap:wrap; gap:4px; align-items:center; padding:6px 8px; border-bottom:1px solid var(--line); background:#FAFAFE; }
.rm-bar button{ font:inherit; font-size:.85rem; padding:4px 9px; border:1px solid var(--line); border-radius:8px; background:#fff; cursor:pointer; color:var(--ink); }
.rm-bar button:hover{ border-color:var(--violet); background:var(--violet-soft); }
.rm-sep{ width:1px; height:20px; background:var(--line); margin:0 4px; }
.rm-edit{ min-height:160px; max-height:480px; overflow:auto; padding:10px 12px; line-height:1.55; outline:none; }
.rm-edit:empty::before{ content:attr(data-placeholder); color:var(--muted); }
.rm-edit img{ max-width:100%; height:auto; border-radius:6px; }
.rm-edit p{ margin:0 0 .6em; }
.rm-uploading{ font-size:.85rem; color:var(--muted); }
.rm-atts{ display:flex; flex-wrap:wrap; gap:6px; align-items:center; padding:6px 8px; border-top:1px dashed var(--line); }
.rm-att{ display:inline-flex; gap:6px; align-items:center; padding:3px 6px 3px 10px; border-radius:999px; background:var(--violet-soft); font-size:.85rem; }
.rm-att small{ color:var(--muted); }
.rm-att button{ border:0; background:none; cursor:pointer; font-size:.8rem; color:var(--muted); }
.rm-total{ color:var(--muted); margin-left:auto; }
.rm-hint{ margin:0; padding:4px 10px 6px; font-size:.78rem; color:var(--muted); }

/* v12.50.0 — Course info ("Read me") above the weeks */
details.ci-info{ padding:0; }
details.ci-info > summary{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:14px 18px; cursor:pointer; list-style:none; }
details.ci-info > summary::-webkit-details-marker{ display:none; }
details.ci-info > summary::before{ content:"›"; font-weight:700; color:var(--muted); transition:transform .15s; }
details.ci-info[open] > summary::before{ transform:rotate(90deg); }
details.ci-info .ci-info-ico{ font-size:1.1rem; }
details.ci-info .ci-info-tog::after{ content:"show"; }
details.ci-info[open] .ci-info-tog::after{ content:"hide"; }
details.ci-info .ci-info-tog{ margin-left:auto; }
details.ci-info .ci-info-body{ padding:0 18px 16px; border-top:1px solid var(--line); }
details.ci-info .ci-info-text{ padding-top:12px; line-height:1.6; }
details.ci-info .ci-info-text img{ max-width:100%; height:auto; }
details.ci-info .ci-info-text table{ border-collapse:collapse; max-width:100%; }
details.ci-info .ci-info-text td, details.ci-info .ci-info-text th{ border:1px solid var(--line); padding:6px 10px; }

/* ============ v12.51.0 — the Course guide ============ */
.cg{ --cg-head:#3B1C8C; --cg-line:#E7E1FA; --cg-soft:#F6F3FF; --cg-violet:#6D28D9; font-size:15.5px; }
.cg .muted{ color:var(--muted); }
.cg-hero{ padding:16px 20px; border-radius:18px; background:linear-gradient(120deg,#4C1D95 0%,#7C3AED 55%,#C026D3 100%); color:#fff; margin-bottom:12px; }
.cg-hero h2{ margin:0; font-size:1.35rem; color:#fff; } .cg-hero p{ margin:4px 0 0; opacity:.92; }
.cg-now{ display:grid; grid-template-columns:1.2fr 1fr; gap:12px; margin:12px 0; }
.cg-now.one{ grid-template-columns:1fr; }
@media (max-width:760px){ .cg-now{ grid-template-columns:1fr; } }
.cg-box{ border:2px solid var(--cg-line); border-radius:16px; padding:12px 16px; background:#fff; }
.cg-cap{ margin:0 0 6px; font-size:.75rem; font-weight:800; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
.cg-next{ font-size:1.18rem; font-weight:900; color:var(--cg-head); }
.cg-yearbar{ position:relative; display:flex; height:12px; border-radius:999px; overflow:hidden; margin:12px 0 6px; background:#EEE9FB; }
.cg-yearbar span{ display:block; height:100%; opacity:.75; }
.cg-yearbar i{ position:absolute; left:0; top:0; bottom:0; background:rgba(33,26,62,.18); border-right:3px solid #211A3E; }
.cg-ylegend{ display:flex; justify-content:space-between; font-size:.78rem; color:var(--muted); }
.cg-exam{ display:flex; align-items:center; gap:12px; padding:8px 0; border-bottom:1px dashed var(--cg-line); }
.cg-exam:last-child{ border-bottom:0; }
.cg-big{ min-width:60px; text-align:center; font-weight:900; font-size:1.3rem; color:var(--cg-violet); line-height:1; }
.cg-big small{ display:block; font-size:.66rem; font-weight:700; color:var(--muted); }
.cg-tabs{ display:flex; gap:8px; flex-wrap:wrap; margin:14px 0 10px; }
.cg-tab{ flex:1 1 150px; display:flex; flex-direction:column; align-items:flex-start; gap:2px; padding:9px 13px; border-radius:14px;
  border:2px solid var(--cg-line); background:#fff; cursor:pointer; text-align:left; font:inherit; color:inherit; }
.cg-tab small{ color:var(--muted); font-weight:600; }
.cg-here{ font-size:.7rem; font-weight:800; padding:1px 8px; border-radius:999px; background:#211A3E; color:#fff; margin-top:3px; }
.cg-tab[data-term="autumn"][aria-selected="true"]{ border-color:#EA580C; background:#FFF4EC; }
.cg-tab[data-term="spring"][aria-selected="true"]{ border-color:#16A34A; background:#EFFBF2; }
.cg-tab[data-term="summer"][aria-selected="true"]{ border-color:#0284C7; background:#EAF6FD; }
.cg-tab[data-term="year"][aria-selected="true"]{ border-color:var(--cg-violet); background:var(--cg-soft); }
.cg-panel{ display:none; } .cg-panel.on{ display:block; }
.cg-lead{ font-size:1.02rem; margin:0 0 10px; }
.cg-h{ display:flex; align-items:center; gap:10px; margin:18px 0 8px; }
.cg-h h3{ margin:0; font-size:1.08rem; color:var(--cg-head); }
.cg-cal{ display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:10px; }
.cg-month{ border:2px solid var(--cg-line); border-radius:14px; padding:9px 11px; background:#fff; }
.cg-month h4{ margin:0 0 7px; font-size:.92rem; }
.cg-days{ display:flex; flex-wrap:wrap; gap:6px; }
.cg-day{ position:relative; min-width:38px; height:38px; padding:0 6px; display:grid; place-items:center; border-radius:10px; font-weight:800;
  background:var(--cg-soft); color:var(--cg-head); border:2px solid transparent; }
.cg-day.mock{ border-color:#F9A8D4; }
.cg-day.past{ background:#ECFDF5; color:#059669; }
.cg-day.past::after{ content:"✓"; position:absolute; top:-6px; right:-5px; width:16px; height:16px; border-radius:50%; background:#059669; color:#fff; font-size:.62rem; display:grid; place-items:center; }
.cg-day.next{ background:var(--cg-violet); color:#fff; box-shadow:0 0 0 4px rgba(124,58,237,.18); }
.cg-day.off{ background:#F3F3F6; color:#A7A3B8; text-decoration:line-through; font-weight:700; }
.cg-day[data-tip]:hover::before, .cg-day[data-tip]:focus::before{ content:attr(data-tip); position:absolute; bottom:calc(100% + 6px); left:50%;
  transform:translateX(-50%); white-space:nowrap; background:#211A3E; color:#fff; font-size:.74rem; font-weight:700; padding:4px 8px; border-radius:8px; z-index:5; text-decoration:none; }
.cg-key{ display:flex; gap:14px; flex-wrap:wrap; margin:10px 0 0; font-size:.8rem; color:var(--muted); }
.cg-key i{ display:inline-block; width:12px; height:12px; border-radius:4px; margin-right:5px; vertical-align:-1px; }
.cg-key .k-past{ background:#ECFDF5; border:2px solid #059669; } .cg-key .k-next{ background:#6D28D9; }
.cg-key .k-up{ background:#F6F3FF; border:2px solid #E7E1FA; } .cg-key .k-mock{ background:#F6F3FF; border:2px solid #F9A8D4; } .cg-key .k-off{ background:#F3F3F6; }
.cg-subjects{ display:grid; gap:8px; }
.cg-subj{ border:2px solid var(--cg-line); border-radius:14px; overflow:hidden; background:#fff; }
.cg-subj > button{ width:100%; display:flex; align-items:center; gap:12px; padding:10px 14px; border:0; background:none; cursor:pointer; text-align:left; font:inherit; color:inherit; }
.cg-ico{ width:38px; height:38px; flex:0 0 auto; border-radius:11px; display:grid; place-items:center; font-size:1.25rem; background:var(--cg-soft); }
.cg-t{ flex:1; } .cg-t b{ display:block; } .cg-t small{ color:var(--muted); font-weight:600; }
.cg-chev{ font-weight:900; color:var(--muted); transition:transform .2s; }
.cg-subj.open .cg-chev{ transform:rotate(90deg); }
.cg-body{ display:none; padding:0 14px 12px; } .cg-subj.open .cg-body{ display:block; }
.cg-chips{ display:flex; flex-wrap:wrap; gap:6px; margin:4px 0 10px; }
.cg-chip{ padding:3px 11px; border-radius:999px; font-size:.86rem; font-weight:700; background:var(--cg-soft); color:var(--cg-head); border:1px solid var(--cg-line); }
.cg-why{ display:flex; gap:10px; padding:9px 12px; border-radius:12px; background:#FEF6E7; color:#5A3A06; border-left:5px solid #F59E0B; }
.cg-why b{ color:#B45309; }
.cg-grid2{ display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-top:16px; }
@media (max-width:760px){ .cg-grid2{ grid-template-columns:1fr; } }
.cg-list{ list-style:none; margin:0; padding:0; display:grid; gap:8px; }
.cg-list li{ display:flex; gap:10px; align-items:flex-start; }
.cg-list .cg-i{ color:var(--cg-violet); font-weight:900; }
.cg-list b{ color:var(--cg-head); }
.cg-check li{ cursor:pointer; padding:7px 10px; border-radius:12px; border:2px solid var(--cg-line); user-select:none; }
.cg-tick{ flex:0 0 auto; width:22px; height:22px; border-radius:7px; border:2px solid #C4B5FD; display:grid; place-items:center; color:#fff; font-weight:900; }
.cg-check li.done{ background:#ECFDF5; border-color:#A7F3D0; }
.cg-check li.done .cg-tick{ background:#059669; border-color:#059669; } .cg-check li.done .cg-tick::after{ content:"✓"; }
.cg-mocks{ display:flex; flex-wrap:wrap; gap:8px; margin:0 0 12px; }
.cg-mock{ padding:5px 11px; border-radius:12px; background:#FDF0F7; color:#DB2777; font-weight:800; font-size:.86rem; border:2px solid #FBCFE8; }
.cg-mock.past{ opacity:.55; text-decoration:line-through; }
.cg-mock small{ display:block; font-weight:700; color:#9D174D; font-size:.7rem; max-width:180px; }
.cg-pick{ display:flex; flex-wrap:wrap; gap:8px; margin:0 0 10px; }
.cg-pick button{ padding:7px 13px; border-radius:999px; border:2px solid var(--cg-line); background:#fff; cursor:pointer; font-weight:800; color:var(--cg-head); font:inherit; font-weight:800; }
.cg-pick button[aria-pressed="true"]{ background:var(--cg-violet); border-color:var(--cg-violet); color:#fff; }
.cg-journey{ display:grid; grid-template-columns:repeat(3,1fr); gap:10px; }
@media (max-width:760px){ .cg-journey{ grid-template-columns:1fr; } }
.cg-stage{ border-radius:14px; padding:11px 13px; border:2px solid var(--cg-line); }
.cg-stage[hidden]{ display:none; }
.cg-stage h4{ margin:0 0 6px; }
.cg-stage.autumn{ background:#FFF4EC; border-color:#FED7AA; } .cg-stage.spring{ background:#EFFBF2; border-color:#BBF7D0; } .cg-stage.summer{ background:#EAF6FD; border-color:#BAE6FD; }
.cg-stage .cg-chip{ background:#fff; }
.cg-whyline{ font-size:.85rem; color:#5A3A06; margin-top:6px; }
.cg-filter{ display:flex; gap:6px; flex-wrap:wrap; margin-bottom:8px; }
.cg-filter button{ padding:4px 12px; border-radius:999px; border:2px solid var(--cg-line); background:#fff; cursor:pointer; font:inherit; font-weight:700; font-size:.84rem; }
.cg-filter button[aria-pressed="true"]{ border-color:var(--cg-violet); background:var(--cg-soft); color:var(--cg-violet); }
.cg-timeline{ position:relative; padding-left:22px; }
.cg-timeline::before{ content:""; position:absolute; left:8px; top:4px; bottom:4px; width:3px; border-radius:3px; background:var(--cg-line); }
.cg-tl{ position:relative; padding:3px 0 9px; }
.cg-tl::before{ content:""; position:absolute; left:-19px; top:8px; width:12px; height:12px; border-radius:50%; background:#fff; border:3px solid #8B5CF6; }
.cg-tl.past{ opacity:.55; } .cg-tl.past::before{ background:#059669; border-color:#059669; }
.cg-tl.exam::before{ border-color:#DB2777; background:#DB2777; }
.cg-tl b{ color:var(--cg-head); }
/* v12.51.2: weekly classes in Key dates sit quieter than term starts, mocks and exams */
.cg-tl.cls b{ font-weight:600; font-size:.9rem; } .cg-tl.cls::before{ width:8px; height:8px; left:-17px; top:9px; border-width:2px; }
.cg-when{ display:block; font-weight:800; font-size:.83rem; color:var(--muted); }
.cg-contact{ margin-top:16px; display:flex; gap:10px; flex-wrap:wrap; align-items:center; padding:12px 16px; border-radius:16px; background:var(--cg-soft); }
.cg-contact a{ padding:6px 13px; border-radius:999px; background:#fff; border:2px solid var(--cg-line); color:var(--cg-head); font-weight:800; text-decoration:none; }
/* v12.51.1 — the pointer to the Course guide in the course editor */
.ci-guide-hint{ display:flex; gap:12px; align-items:center; flex-wrap:wrap; justify-content:space-between; padding:10px 14px; margin:4px 0 12px;
  border-radius:12px; background:var(--violet-soft, #F0EAFF); border:1.5px solid #D6CCF7; font-size:.92rem; }

/* v12.51.3: the Course guide as a pop-up from the dashboard */
.modal .cg-pop{ margin-top:6px; }
.modal .cg-pop .cg-hero{ margin-right:28px; }

/* v12.52.0: the weekly answer sheet (OMR) */
.womr h3{ margin:0 0 10px; padding-right:30px; }
.womr-steps{ padding-left:20px; margin:0 0 12px; } .womr-steps li{ margin:6px 0; }
.womr-pick{ display:flex; gap:14px; align-items:flex-start; flex-wrap:wrap; }
.womr-pages{ list-style:none; margin:0; padding:0; } .womr-pages li{ margin:3px 0; } .womr-pages li.ok{ color:#047857; font-weight:700; } .womr-pages li.bad{ color:#B45309; }
.womr-group{ margin:14px 0 6px; } .womr-group h4{ margin:0 0 6px; font-size:1rem; }
.womr-paper{ border:1px solid var(--line,#e5e7eb); border-radius:12px; padding:10px 12px; margin:8px 0; }
.womr-paper.is-done{ background:#f6f7fb; }
.womr-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(178px,1fr)); gap:4px 14px; margin-top:8px; }
.womr-q{ display:flex; align-items:center; gap:4px; padding:2px 4px; border-radius:8px; }
.womr-q.is-flag{ background:#FEF3C7; outline:2px solid #F59E0B; }
.womr-n{ width:22px; text-align:right; font-weight:700; font-size:.82rem; margin-right:2px; }
.womr-b{ width:26px; height:26px; border-radius:50%; border:1.5px solid #9ca3af; background:#fff; font:inherit; font-size:.72rem; font-weight:700; color:#6b7280; cursor:pointer; padding:0; }
.womr-b.on{ background:#3F27BD; border-color:#3F27BD; color:#fff; }
.womr-warn{ color:#B45309; }
.womr-foot{ display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-top:14px; position:sticky; bottom:-24px; background:var(--card,#fff); padding:10px 0; }
.womr-total{ font-size:1.6rem; font-weight:800; margin:4px 0 8px; } .womr-total small{ font-size:.9rem; font-weight:600; color:var(--muted,#6b7280); }
.womr-res{ border:1px solid var(--line,#e5e7eb); border-radius:10px; padding:8px 12px; margin:6px 0; }
.womr-res summary{ cursor:pointer; display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
.womr-score{ font-weight:800; padding:2px 10px; border-radius:999px; font-size:.86rem; }
.womr-score.hi{ background:#D1FAE5; color:#065F46; } .womr-score.mid{ background:#FEF3C7; color:#92400E; } .womr-score.lo{ background:#FEE2E2; color:#991B1B; }
.womr-marks{ display:flex; flex-wrap:wrap; gap:4px; margin-top:8px; }
.womr-marks span{ font-size:.78rem; padding:2px 7px; border-radius:6px; font-weight:700; }
.womr-marks .ok{ background:#ECFDF5; color:#047857; } .womr-marks .no{ background:#FEF2F2; color:#B91C1C; }
.womr-chips{ display:flex; flex-wrap:wrap; gap:4px; margin-top:4px; }
.womr-chip{ font-size:.74rem; padding:2px 8px; border-radius:999px; background:#f3f4f6; color:#374151; }
.womr-chip.hi{ background:#D1FAE5; color:#065F46; } .womr-chip.mid{ background:#FEF3C7; color:#92400E; } .womr-chip.lo{ background:#FEE2E2; color:#991B1B; } .womr-chip.off{ color:#6b7280; }
/* v12.53.0: the written answers step, the staff tick lists */
.womr-wlist{ display:flex; flex-direction:column; gap:8px; margin-top:8px; }
.womr-w{ display:grid; grid-template-columns:30px minmax(0,auto) minmax(150px,240px); justify-content:start; align-items:center; gap:10px; }
.womr-w img{ height:40px; width:auto; max-width:100%; border-radius:6px; border:1px solid var(--line,#e5e7eb); background:#fff; }
.womr-w input{ font:inherit; font-weight:700; letter-spacing:.06em; text-transform:uppercase; padding:6px 10px; border:1.5px solid #c7c9d9; border-radius:8px; }
.womr-w input:focus{ outline:none; border-color:#3F27BD; box-shadow:0 0 0 3px rgba(63,39,189,.15); }
@media (max-width:640px){ .womr-w{ grid-template-columns:26px 1fr; } .womr-w input{ grid-column:2; } }
.womr-marks .wr{ font-weight:700; }
.womr-sec{ border:1px solid var(--line,#e5e7eb); border-radius:12px; padding:12px 14px; margin:12px 0; }
.womr-sec h4{ margin:0 0 8px; }
.womr-ticks{ display:flex; flex-direction:column; gap:4px; }
.womr-tick{ display:flex; gap:8px; align-items:baseline; padding:4px 6px; border-radius:8px; cursor:pointer; }
.womr-tick:hover{ background:#f6f7fb; } .womr-tick.is-off{ opacity:.55; cursor:default; }

/* v12.56.0: the admin's own Course guide */
.acg-own.is-on{ border:2px solid #8B5CF6; }
.acg-built.is-off > .card{ opacity:.55; }
.acg-built-note{ background:#F5F3FF; border-radius:10px; padding:8px 12px; margin:0 0 10px; }
.cg-custom .explain-frame{ width:100%; border:0; }

/* v12.58.0: Year 4 / Year 5 tabs on the Weekly Vocab Booster */
.vb-tabs{ display:flex; gap:8px; margin:0 0 12px; flex-wrap:wrap; }
.vb-tab{ font:inherit; font-weight:800; padding:8px 20px; border-radius:999px; border:2px solid #e4def8; background:#fff; color:#4c3a99; cursor:pointer; }
.vb-tab[aria-selected="true"]{ background:linear-gradient(135deg,#4F46E5,#9333EA); border-color:transparent; color:#fff; box-shadow:0 6px 16px rgba(79,70,229,.25); }

/* v12.64.0: Website security, audit and governance page */
.sec-tab{ font:inherit; font-size:13.5px; font-weight:700; cursor:pointer; padding:7px 14px; border-radius:99px;
  border:1px solid transparent; background:transparent; color:var(--muted,#6A7090); }
.sec-tab:hover{ background:var(--violet-soft,#F1EEFC); color:var(--a1,#3F27BD); }
.sec-tab.is-on{ background:var(--a1,#3F27BD); color:#fff; }
.sec-tab:focus-visible{ outline:2px solid var(--a2,#D22CB2); outline-offset:2px; }
.sec-bar{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:0 0 12px; }
.sec-note{ display:flex; flex-wrap:wrap; align-items:center; gap:10px; margin:0 0 8px; padding:10px 12px; border-radius:12px; background:var(--violet-soft,#F1EEFC); }
.sec-note .check{ margin:0; }
.sec-tiles{ display:grid; grid-template-columns:repeat(auto-fit,minmax(140px,1fr)); gap:10px; margin:0 0 18px; }
.sec-tile{ border:1px solid var(--line,#e6e4ef); border-radius:14px; padding:12px 14px; display:flex; flex-direction:column; gap:2px; }
.sec-tile b{ font-size:1.6rem; line-height:1.1; }
.sec-tile span{ font-size:12.5px; color:var(--muted,#6b6b80); font-weight:600; }
.sec-tile.is-warn{ border-color:var(--red,#d33); background:var(--red-soft,#fdeeee); }
.sec-h{ margin:22px 0 4px; font-size:1.02rem; }
.sec-p{ margin:0 0 8px; }
.sec-actions{ display:flex; flex-wrap:wrap; gap:4px; min-width:180px; }
.sec-fields{ max-width:420px; word-break:break-word; }

/* v12.65.0: the sign-up email code under the parent email box */
.ec-box{ margin:-4px 0 10px; grid-column:1 / -1; }   /* own full row on the two-column pop-up */
.ec-hint{ margin:0 0 6px; padding:8px 10px; border-radius:10px; background:var(--violet-soft,#F1EEFC); color:var(--ink,#26243a); line-height:1.4; }
.ec-row{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:0 0 6px; }
.ec-msg{ color:var(--muted,#6b6b80); }
.ec-code input{ font-size:1.25rem; letter-spacing:6px; max-width:180px; font-variant-numeric:tabular-nums; }

/* v12.66.0: Vocab Usage tracker */
.vu-chart{ display:grid; grid-template-columns:repeat(12,1fr); gap:6px; align-items:end; height:170px; margin:6px 0 18px;
  padding:10px 10px 0; border:1px solid var(--line,#e6e4ef); border-radius:14px; }
.vu-bar{ display:flex; flex-direction:column; align-items:center; justify-content:flex-end; height:100%; min-width:0; }
.vu-bar i{ display:block; width:70%; max-width:34px; min-height:2px; border-radius:6px 6px 0 0; background:var(--a1,#3F27BD); }
.vu-n{ font-size:12px; font-weight:700; margin-bottom:3px; }
.vu-w{ font-size:11px; color:var(--muted,#6b6b80); padding:5px 0 6px; white-space:nowrap; }
.vu-table td{ vertical-align:top; }

/* v12.67.0: the short privacy note above the sign-up consent boxes */
.reg-privacy{ grid-column:1 / -1; margin:8px 0 6px; padding:8px 10px; border-radius:10px; background:var(--violet-soft,#F1EEFC); line-height:1.45; }

/* v12.68.0: the user card (Website security, Vocab Usage tracker) */
.uc-table{ width:100%; border-collapse:collapse; font-size:14px; }
.uc-table th{ text-align:left; font-weight:600; color:var(--muted,#6b6b80); padding:5px 12px 5px 0; width:150px; vertical-align:top; }
.uc-table td{ padding:5px 0; }
.uc-list{ margin:4px 0 0; padding-left:18px; } .uc-list li{ margin:3px 0; }
.uc-actions{ display:flex; flex-wrap:wrap; gap:8px; margin-top:16px; padding-top:12px; border-top:1px solid var(--line,#e6e4ef); }
button.linky[data-user-card]{ background:none; border:0; padding:0; font:inherit; color:var(--a1,#3F27BD); cursor:pointer; text-align:left; text-decoration:underline; text-decoration-color:rgba(63,39,189,.35); text-underline-offset:3px; }
button.linky[data-user-card]:hover{ text-decoration-color:currentColor; }
.user-card .sec-h{ margin:18px 0 6px; }

/* v12.69.0: Upload this week */
.modal.wu-modal{ max-width:min(1100px,96vw); width:96vw; }
.wu-drop{ display:block; border:2px dashed var(--line2,#cfc8ef); border-radius:14px; padding:22px; text-align:center; cursor:pointer; background:var(--violet-soft,#F7F5FF); }
.wu-drop.is-over{ border-color:var(--a1,#3F27BD); background:#efeafe; }
.wu-opts{ display:flex; flex-wrap:wrap; gap:4px 18px; margin:10px 0 12px; }
.wu-bar{ display:flex; align-items:center; gap:12px; margin:6px 0 8px; }
.wu-table td{ vertical-align:top; } .wu-table select{ max-width:360px; }
.wu-name{ word-break:break-all; } .wu-err{ color:var(--red,#c0392b); margin:4px 0 0; padding-left:16px; } .wu-warn{ color:#9a6700; margin-top:3px; }
.wu-slots{ display:grid; grid-template-columns:repeat(auto-fill,minmax(250px,1fr)); gap:10px; }
.wu-slot-group ul{ list-style:none; margin:4px 0 0; padding:0; font-size:13.5px; } .wu-slot-group li{ margin:2px 0; color:var(--muted,#6b6b80); }
.wu-slot-group li.is-full{ color:var(--ink,#26243a); }
.wu .sec-h{ margin:22px 0 8px; }

/* v13.8.0: the week pages' extras on the Learn slide: the word's picture, hear it, a memory tip, and the spelling check */
.vl-pic{ position:relative; margin:0 0 12px; border-radius:12px; overflow:hidden; max-width:100%; background:#F7F7FB; }
.vl-pic img, #view .vl-pic img{ display:block; width:100%; height:auto; max-height:440px; object-fit:contain; margin:0 auto; }
.vl-pic.pop{ animation:vlpop .6s cubic-bezier(.3,1.6,.5,1); }
.vl-pic-tag{ position:absolute; left:8px; top:8px; background:rgba(255,255,255,.92); color:#3F27BD; font-size:12px; font-weight:800; border-radius:99px; padding:3px 10px; }
@keyframes vlpop{ from{ transform:scale(.96); } to{ transform:none; } }
.vl-say{ font:inherit; font-size:13px; font-weight:800; border:0; border-radius:99px; padding:3px 10px; margin-left:8px; background:rgba(255,255,255,.22); color:inherit; cursor:pointer; letter-spacing:0; vertical-align:middle; }
.vl-tip{ margin:10px 0 0; background:#F4FBF6; border:1px dashed #BFD8C6; border-radius:8px; padding:8px 10px; font-size:.93rem; }
.vl-sp-ov{ position:fixed; inset:0; z-index:1200; display:grid; place-items:center; padding:16px; background:rgba(20,16,50,.86); backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px); animation:vlspfade .25s ease; }
.vl-sp-card{ width:min(460px,100%); background:#fff; color:#22213A; border-radius:20px; padding:22px 22px 18px; text-align:center; box-shadow:0 24px 60px rgba(0,0,0,.35); animation:vlsppop .45s cubic-bezier(.3,1.5,.5,1); }
.vl-sp-ico{ font-size:44px; line-height:1; }
.vl-sp-card h3{ font-family:Poppins,system-ui,sans-serif; font-size:1.5rem; color:#3F27BD; margin:6px 0 2px; }
.vl-sp-card p{ margin:6px 0; }
.vl-sp-clue{ background:#FFF4DB; border-left:4px solid #E9A825; border-radius:10px; padding:8px 12px; text-align:left; }
.vl-sp-row{ display:flex; gap:8px; justify-content:center; align-items:center; flex-wrap:wrap; margin:12px 0 6px; }
.vl-sp-in{ font:inherit; font-family:Poppins,system-ui,sans-serif; font-size:1.6rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase; text-align:center; width:100%; max-width:340px; padding:8px 10px; border:3px solid #3F27BD; border-radius:12px; background:#fff; color:#22213A; }
.vl-sp-in:focus{ outline:3px solid #E9A825; outline-offset:2px; }
.vl-sp-boxes{ display:flex; gap:4px; justify-content:center; flex-wrap:wrap; margin:6px 0 2px; }
.vl-sp-boxes i{ display:block; width:16px; height:5px; border-radius:3px; background:#E3E3E7; }
.vl-sp-boxes i.on{ background:#3F27BD; }
.vl-sp-msg{ min-height:1.4em; font-weight:800; margin:8px 0; }
.vl-sp-msg.ok{ color:#1B8A4B; }
.vl-sp-ans{ font-family:Poppins,system-ui,sans-serif; font-size:1.5rem; letter-spacing:.1em; font-weight:700; }
.vl-sp-ans b{ color:#1B8A4B; }
.vl-sp-ans u{ color:#C9661A; text-decoration:none; background:#FFF4DB; border-radius:4px; padding:0 2px; }
.vl-sp-acts{ display:flex; gap:8px; justify-content:center; flex-wrap:wrap; margin-top:10px; }
.vl-sp-later{ font:inherit; background:none; border:0; color:#6A7090; text-decoration:underline; cursor:pointer; margin-top:8px; }
@keyframes vlspfade{ from{ opacity:0; } to{ opacity:1; } }
@keyframes vlsppop{ from{ transform:scale(.9); opacity:0; } to{ transform:none; opacity:1; } }
@media (prefers-reduced-motion:reduce){ .vl-pic.pop, .vl-sp-ov, .vl-sp-card{ animation:none; } }

/* v13.23.0 — papers on paper: the amber of the week's "on paper" line, so
   staff can tell them apart at a glance and a child sees what to do */
.wk-row.wk-row-paper{ background:#FFFBEB; border-color:#FCD34D; box-shadow:inset 4px 0 0 #FBBF24; flex-wrap:wrap; }
.wk-row.wk-row-paper:hover{ background:#FEF3C7; }
.wk-paper-tag{ display:inline-block; margin-left:8px; padding:1px 9px; border-radius:99px; font-size:11.5px; font-weight:800;
  background:#FEF3C7; color:#8A5A00; border:1px solid #FCD34D; vertical-align:middle; white-space:nowrap; }
.wk-row-onpaper .wk-tick{ border-color:#FCD34D; background:#fff; font-size:13px; }
button.wk-act{ font:inherit; font-size:12.5px; font-weight:800; cursor:pointer; }
.wk-act-upload{ color:#fff; border-color:transparent; background:linear-gradient(135deg,#F59E0B,#EA580C); }
.wk-act-upload:hover{ color:#fff; border-color:transparent; filter:brightness(1.06); background:linear-gradient(135deg,#F59E0B,#EA580C); }
.wk-paper-card{ padding:6px 2px; }
.wk-paper-card > p{ margin:0 0 10px; }
.womr-review{ text-decoration:none; }
/* v13.23.0 — the week's answer sheets, under the "on paper" message: one row,
   a button (and a phone QR) per sheet */
.wk-sheets{ display:flex; flex-wrap:wrap; gap:8px 10px; margin:-4px 0 14px; }
.wk-sheet{ display:inline-flex; gap:6px; align-items:center; }
.wk-sheets-none{ margin:0; font-size:13px; color:#8A5A00; }
.wk-state-sheet{ font-size:12px; font-weight:700; color:#8A5A00; white-space:nowrap; }
/* v13.24.0 — change a week's dates from the week */
.wk-date-edit{ margin-left:8px; padding:1px 10px !important; font-size:12px !important; vertical-align:baseline; }
.wd-form .wd-secs{ display:flex; flex-wrap:wrap; gap:4px 14px; margin:6px 0 12px; }
.wd-form .wd-field{ display:block; margin:0 0 10px; }
.wd-form .wd-field input{ display:block; margin-top:4px; max-width:260px; }
.wd-form .wd-shift{ display:block; margin-top:6px; }
.wk-sheets:empty{ display:none; }   /* v13.24.0 */

/* v13.27.1: a lesson's header is one row: where it sits and its title (cut short,
   whole on hover), the Learn with us switch, then Mark as complete and Close.
   The lesson gets the space the two extra rows took. */
.wk-viewer.is-full .wk-viewer-head{ flex-wrap:nowrap; }
.wk-vh-title{ flex:1 1 auto; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.wk-vh-title b{ margin-left:8px; }
.wk-viewer.is-full .wk-viewer-tools{ flex:0 0 auto; flex-wrap:nowrap; }
.wk-lwu{ flex:0 0 auto; display:inline-flex; gap:3px; padding:3px; border-radius:999px; background:#F0EAFF; border:2px solid #D6CCF7; }
.wk-lwu[hidden]{ display:none; }
.wk-lwu button{ display:inline-flex; align-items:center; gap:7px; border:0; background:transparent; color:#5B21B6; font:800 14px Nunito,system-ui,sans-serif; padding:4px 14px 4px 6px; border-radius:999px; cursor:pointer; white-space:nowrap; }
.wk-lwu button[aria-pressed="true"]{ background:linear-gradient(135deg,#7C3AED,#C026D3); color:#fff; box-shadow:0 2px 8px rgba(124,58,237,.3); }
.wk-lwu button svg{ width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; margin-left:4px; }
.wk-lwu .lw-duo{ display:inline-flex; }
.wk-lwu .lw-duo img{ width:24px; height:24px; border-radius:50%; border:2px solid #fff; background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.18); }
.wk-lwu .lw-duo img + img{ margin-left:-9px; }
@media (max-width:1100px){
  .wk-viewer.is-full .wk-viewer-head{ flex-wrap:wrap; }
  .wk-vh-title{ flex-basis:100%; }
}

/* v13.29.3: "Question 4 of 30" was small and grey; now a clear chip, easy to read at a glance */
.q-progress-label{ font-size:1.05rem; font-weight:800; color:#3B0F86; font-family:var(--font-display, inherit);
  background:#F0EAFF; border:2px solid #D6CCF7; border-radius:999px; padding:4px 14px; white-space:nowrap; }
html body #quiz-box[data-nb] .q-progress-label{ font-size:1.05rem; font-weight:800; color:#3B0F86; }

/* v13.29.5: the passage in the attempt review */
.rev-passage{ margin:0 0 12px; border:1px solid var(--line); border-radius:12px; background:#FFFDF5; padding:8px 12px; }
.rev-passage > summary{ cursor:pointer; font-weight:800; color:#3B0F86; padding:2px 0; }
.rev-passage .passage-panel{ margin-top:8px; }
.rev-passage .passage-scroll{ max-height:440px; overflow:auto; }

/* v13.29.6: the FSCE paper breakdown's tips, and every skill on the paper */
.paper-tip{ margin:10px 0 0; padding:10px 14px; border-radius:12px; background:#FFF7ED; border:1px solid #FED7AA; color:#7C2D12; font-size:.95rem; }
.paper-tip.is-first{ background:#FEF2F2; border-color:#FECACA; color:#7F1D1D; }
.skill-detail{ margin-top:12px; }
.skill-detail > summary{ cursor:pointer; font-weight:800; color:#3B0F86; }
.skill-detail .topic-table{ margin-top:8px; }

/* v13.31.0: Users → Edit → Weeks they can see */
.uf-weeks .uf-wk { border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; margin: 0 0 8px; }
.uf-wk-head { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.uf-wk-head input[type="date"] { width: auto; padding: 2px 6px; }
.uf-wk-all { display: flex; gap: 6px; align-items: center; margin: 4px 0; }
.uf-wk-weeks { display: flex; flex-wrap: wrap; gap: 4px 10px; }
.uf-wk-n { display: inline-flex; gap: 4px; align-items: center; font-size: 13px; }

/* v13.43.0 — the chat editor (Site content > Programmes > 💬 Chat) */
.pcx-modal{max-width:860px}
.pcx-msg{border:1px solid var(--line);border-radius:12px;padding:10px 12px;margin:0 0 10px;background:var(--card);border-left:5px solid #C4B5FD}
.pcx-msg[data-who="r"]{border-left-color:#FDBA8C}
.pcx-top{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin:0 0 6px}
.pcx-top select{font:inherit;padding:5px 8px;border:1px solid var(--line);border-radius:8px}
.pcx-n{min-width:22px;height:22px;border-radius:50%;background:#EDE9FE;color:#5B21B6;display:inline-grid;place-items:center;font-size:12px}
.pcx-sp{flex:1}
.pcx-text{width:100%;font:inherit;padding:7px 9px;border:1px solid var(--line);border-radius:8px;resize:vertical}
.pcx-pic{display:flex;gap:10px;align-items:center;margin:8px 0 2px}
.pcx-thumb{flex:0 0 64px;width:64px;height:64px;border-radius:10px;overflow:hidden;background:#F3F0FF;display:grid;place-items:center;font-size:10px;color:var(--muted,#888);text-align:center}
.pcx-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.pcx-picside{display:flex;gap:6px;align-items:center;flex-wrap:wrap;flex:1}
.pcx-lbl{font-size:12.5px;font-weight:700;width:100%}
.pcx-tag,.pcx-o{font:inherit;padding:5px 8px;border:1px solid var(--line);border-radius:8px;min-width:0}
.pcx-tag{flex:1;max-width:260px}
.pcx-q{display:none;margin-top:8px;padding-top:8px;border-top:1px dashed var(--line)}
.pcx-msg[data-kind="question"] .pcx-q{display:block}
.pcx-opts{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin:4px 0 6px}
.pcx-opt{display:flex;gap:6px;align-items:center}.pcx-opt .pcx-o{flex:1}
@media (max-width:600px){.pcx-opts{grid-template-columns:1fr}}

/* v13.45.0 — the Year overview (#/year-overview/<course>) */
.yo-top{display:flex;justify-content:space-between;align-items:flex-end;gap:14px;flex-wrap:wrap;margin:0 0 12px}
.yo-top h1{margin:4px 0 2px;font-size:1.5rem}.yo-top p{margin:0;max-width:720px}
.yo-acts{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.yo-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(118px,1fr));gap:8px;margin:0 0 10px}
.yo-tile{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:9px 12px}
.yo-tile b{display:block;font-size:1.25rem;line-height:1.2}.yo-tile span{font-size:12px;color:var(--muted,#6b7280)}
.yo-tile.is-ok{border-color:#86EFAC;background:#F0FDF4}.yo-tile.is-warn{border-color:#FCD34D;background:#FFFBEB}.yo-tile.is-bad{border-color:#FCA5A5;background:#FEF2F2}
.yo-key{display:flex;flex-wrap:wrap;gap:4px 10px;align-items:center;margin:0 0 8px;color:var(--muted,#6b7280)}
.yo-sw{display:inline-block;width:14px;height:14px;border-radius:4px;vertical-align:-2px;margin-right:-6px;border:1px solid transparent}
.yo-scroll{overflow:auto;max-height:calc(100vh - 250px);border:1px solid var(--line);border-radius:12px;background:var(--card)}
.yo-table{border-collapse:separate;border-spacing:0;width:100%;font-size:13px}
.yo-table th,.yo-table td{border-bottom:1px solid var(--line);border-right:1px solid var(--line);padding:5px 4px;text-align:center;white-space:nowrap}
.yo-table thead th{position:sticky;top:0;background:#F8F7FF;z-index:2;font-size:12px;font-weight:700}
.yo-table thead tr:nth-child(2) th{top:29px}
.yo-table thead th small{display:block;font-weight:500;color:var(--muted,#6b7280);font-size:10.5px}
.yo-g{font-size:12.5px!important;letter-spacing:.02em}
.yo-g.is-maths{background:#EFF6FF!important}.yo-g.is-english{background:#FFF1F2!important}.yo-g.is-vr{background:#F5F3FF!important}
.yo-g.is-nvr{background:#ECFDF5!important}.yo-g.is-fsce{background:#FFF7ED!important}.yo-g.is-side,.yo-g.is-tot{background:#F1F5F9!important}
.yo-wk{position:sticky;left:0;background:var(--card);z-index:1;text-align:left!important;min-width:78px}
thead .yo-wk{z-index:3;background:#F8F7FF}
.yo-wk b{display:block}.yo-wk small{color:var(--muted,#6b7280);font-weight:500}
.yo-wup{border:0;background:none;cursor:pointer;color:#6D28D9;font-size:12px;padding:0 0 0 4px}
.yo-c{min-width:40px}
.yo-c.is-ok,.yo-sw.is-ok{background:#DCFCE7}.yo-c.is-over,.yo-sw.is-over,.yo-line.is-over{background:#E9D5FF}.yo-c.is-low,.yo-sw.is-low{background:#FEF3C7}
.yo-c.is-zero,.yo-c.is-miss,.yo-sw.is-zero{background:#FEE2E2}.yo-c.is-na,.yo-sw.is-na{background:#F1F5F9}
.yo-sw.has-draft{border:1.5px dashed #7C3AED;background:#fff}
.yo-n{font-weight:800;color:#1E1B4B;text-decoration:none;border-radius:6px;padding:1px 3px}
a.yo-n:hover{background:rgba(124,58,237,.14);text-decoration:underline}
.yo-n.is-draft{outline:1.5px dashed #7C3AED;outline-offset:1px}
.yo-up{border:0;background:none;cursor:pointer;color:#B91C1C;font:700 11.5px inherit;font-family:inherit;text-decoration:underline}
.yo-plus{color:var(--muted,#6b7280);font-size:11px;padding:0 1px}
.yo-x{display:block;font-size:10.5px;line-height:1.3}.yo-x a{color:#5B21B6;text-decoration:none;font-weight:700}
.yo-fs{padding:3px!important;text-align:left!important}
.yo-line{display:flex;justify-content:space-between;gap:4px;align-items:center;border-radius:5px;padding:1px 5px;margin:1px 0}
.yo-line i{font-style:normal;font-size:10.5px;color:#7C2D12;max-width:66px;overflow:hidden;text-overflow:ellipsis}
.yo-line.is-ok{background:#DCFCE7}.yo-line.is-low{background:#FEF3C7}.yo-line.is-zero,.yo-line.is-miss{background:#FEE2E2}.yo-line.is-na{background:#F1F5F9}
.yo-t{font-weight:700;min-width:40px}.yo-t.is-short{color:#B45309;background:#FFFBEB}.yo-t.is-done{color:#15803D}
tr.is-gap .yo-wk{box-shadow:inset 4px 0 0 #F59E0B}tr.is-full .yo-wk{box-shadow:inset 4px 0 0 #22C55E}
.yo-none{padding:24px!important;color:var(--muted,#6b7280)}
.yo-tf{margin:0 0 10px;padding:12px 14px}
.yo-tgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px}
.yo-tgrid .field input{width:100%}
.ct-tab-ov{text-decoration:none;display:inline-flex;align-items:center}

/* v13.46.0 — the Year overview full screen */
#yo-root.is-full{position:fixed;inset:0;z-index:9000;background:var(--bg,#F8F7FF);padding:14px 18px;overflow:auto}
#yo-root.is-full .yo-scroll{max-height:calc(100vh - 200px)}
#yo-root:fullscreen{background:var(--bg,#F8F7FF)}
/* v13.47.0 — Balance */
.yo-bal-modal{max-width:860px}
.yo-bl-scroll{max-height:50vh;overflow:auto;border:1px solid var(--line);border-radius:10px}
.yo-bl{width:100%;border-collapse:collapse;font-size:13px}
.yo-bl th{position:sticky;top:0;background:#F8F7FF;text-align:left;padding:6px 8px;font-size:12px}
.yo-bl td{padding:5px 8px;border-top:1px solid var(--line)}
.yo-bl-t{max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.yo-wbal{color:#7C3AED}

/* v13.50.0: choosing where a file goes in the bulk upload dry run */
.bu-place { margin-top: 6px; }
.bu-place label { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; color: var(--muted, #6b7280); }
.bu-place select { max-width: 100%; min-width: 240px; font-size: 13px; padding: 4px 6px; border-radius: 8px; border: 1px solid var(--line, #d9d6ef); background: var(--card, #fff); color: inherit; }
.ct-herobtns .ct-bulk { margin-left: 8px; vertical-align: middle; }

/* v13.51.0: the open vocab preview's message */
.vb-preview-note { border-left: 4px solid #D22CB2; display: flex; flex-wrap: wrap; gap: 14px 22px; align-items: center; justify-content: space-between; }
.vb-preview-note .vb-pv-text { flex: 1 1 420px; }
.vb-preview-note .vb-pv-cta { flex: 0 1 auto; max-width: 100%; white-space: normal !important; text-align: center; line-height: 1.3; height: auto; }
@media (max-width: 640px) { .vb-preview-note .vb-pv-cta { flex-basis: 100%; } }

/* v13.53.0: all the questions of a quiz on one page (staff, on demand) */
.q-allview-btn { margin-right: 8px; }
.q-all .q-all-note { margin: 0 0 12px; }
.q-all .q-all-item { margin: 0 0 18px; padding: 14px 16px; border: 1px solid var(--line, #e6e3f3); border-radius: 14px; background: var(--card, #fff); }
.q-all .q-all-num { font-weight: 700; color: #5b35d5; margin: 0 0 8px; font-size: .92rem; }
.q-all .q-all-sec { margin: 22px 0 10px; }
.q-all .q-all-psg { margin: 0 0 14px; }
.q-all .q-all-blank { display: inline-block; min-width: 3em; padding: 0 6px; border-bottom: 2px solid #22a06b; color: #137a4f; font-weight: 700; }
.q-all .q-all-explain { margin-top: 8px; }
.q-all .q-all-explain summary { cursor: pointer; font-weight: 600; color: #5b35d5; }

/* v13.54.0: reviewing a paper (admins): Keep / Simplify / Drop */
.q-rev-panel { margin: 0 0 16px; padding: 14px 16px; border-radius: 14px; background: #F4F0FF; border: 1px solid #DCD2FB; }
.q-rev-panel .q-rev-head { margin: 0 0 8px; }
.q-rev-panel .q-rev-pnote-l { display: block; }
.q-rev-panel textarea { width: 100%; box-sizing: border-box; margin-top: 4px; padding: 8px 10px; border-radius: 10px; border: 1px solid #D5CEF0; font: inherit; resize: vertical; }
.q-rev-panel .q-rev-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-top: 10px; }
.q-rev-panel .q-rev-foot [data-qrev-brief] { margin-left: auto; }
.q-rev { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; padding-top: 10px; border-top: 1px dashed #E3DDF6; }
.q-rev-btn { border: 1.5px solid #D9D2F2; background: #fff; color: #3d3666; border-radius: 999px; padding: 5px 13px; font: inherit; font-size: .9rem; font-weight: 600; cursor: pointer; }
.q-rev-btn.q-rev-keep.on { background: #DDF7EA; border-color: #22A06B; color: #0F6B45; }
.q-rev-btn.q-rev-simplify.on { background: #FFF1D6; border-color: #E5A100; color: #8A5A00; }
.q-rev-btn.q-rev-drop.on { background: #FFE1E1; border-color: #D64545; color: #9B1C1C; }
.q-rev .q-rev-note { flex: 1 1 240px; min-width: 0; padding: 6px 10px; border-radius: 10px; border: 1px solid #DDD7F2; font: inherit; font-size: .92rem; }
.q-all .q-all-item.rev-keep { border-left: 5px solid #22A06B; }
.q-all .q-all-item.rev-simplify { border-left: 5px solid #E5A100; }
.q-all .q-all-item.rev-drop { border-left: 5px solid #D64545; opacity: .92; }

/* v13.55.0: Rework with AI (the draft beside the original) */
.rw-panel { margin: 0 0 18px; padding: 14px 16px; border-radius: 14px; background: #FBFAFF; border: 1.5px solid #CFC2FA; }
.rw-panel.rw-bad { border-color: #F0B4B4; background: #FFF7F7; }
.rw-panel .rw-head { display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; margin-bottom: 10px; }
.rw-item { border: 1px solid #E6E1F7; border-radius: 12px; padding: 12px 14px; margin: 0 0 12px; background: #fff; }
.rw-item.rw-bad { border-color: #F0B4B4; }
.rw-item.rw-applied { border-color: #9BD8BC; background: #F6FFFA; }
.rw-q-head { margin-bottom: 8px; display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: baseline; }
.rw-mark { font-size: .82rem; font-weight: 700; padding: 1px 9px; border-radius: 999px; }
.rw-mark.rw-simplify { background: #FFF1D6; color: #8A5A00; }
.rw-mark.rw-drop { background: #FFE1E1; color: #9B1C1C; }
.rw-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 760px) { .rw-cols { grid-template-columns: 1fr; } }
.rw-col { padding: 10px 12px; border-radius: 10px; background: #F7F6FB; }
.rw-col.rw-new { background: #F1ECFF; }
.rw-col-h { font-size: .75rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: #6b6491; margin-bottom: 4px; }
.rw-col p { margin: 0 0 6px; }
.rw-opts { margin: 0; padding-left: 22px; }
.rw-opts .rw-right { font-weight: 700; color: #0F6B45; }
.rw-ex summary { cursor: pointer; color: #5b35d5; font-weight: 600; font-size: .9rem; margin-top: 4px; }
.rw-checks { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: .86rem; }
.rw-checks .ok { color: #137a4f; } .rw-checks .bad { color: #B42318; font-weight: 700; } .rw-checks .warn { color: #8A5A00; }
.rw-actions { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; margin-top: 10px; }
.rw-retry { display: inline-flex; gap: 6px; flex: 1 1 280px; }
.rw-retry .rw-note { flex: 1; min-width: 0; padding: 5px 9px; border-radius: 9px; border: 1px solid #DDD7F2; font: inherit; font-size: .9rem; }
.rw-foot { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 4px; }
.rw-done { color: #137a4f; font-weight: 700; margin: 8px 0 0; }
.rw-panel .spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid #CFC2FA; border-top-color: #5b35d5; border-radius: 50%; animation: rwspin 1s linear infinite; vertical-align: -2px; margin-right: 6px; }
@keyframes rwspin { to { transform: rotate(360deg); } }
/* v13.57.0: the parent login / children links in User management and Edit user */
.uf-famlink{ padding:0; color:var(--violet); text-decoration:underline; font-size:inherit; }
.uf-family .uf-fam-row{ display:flex; flex-wrap:wrap; gap:6px 12px; align-items:center; justify-content:space-between; padding:6px 10px; border:1px solid var(--line); border-radius:8px; margin:0 0 6px; }
.uf-family .uf-fam-warn{ background:#FFF4E0; border:1px solid #F0D9A8; border-radius:8px; padding:6px 10px; margin:0 0 6px; }
/* v13.59.1: "already signed in on another device" asked under the Sign in button (not a pop-up) */
.form-error.tk-ask{ background:#FFF7E6; color:var(--ink); border:2px solid #F5C77E; font-size:.95rem; }
