/* Sofia's paper, type and ink follow the public site. Fonts live on this app's /static. */
@font-face {
  font-family: "Source Serif 4";
  src: url("../fonts/source-serif-4.woff2") format("woff2");
  font-weight: 200 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: Inter;
  src: url("../fonts/inter.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
:root {
  color-scheme: light;
  --paper: #fbfaf7;
  --surface: #ffffff;
  --surface-warm: #f4f1ea;
  --surface-muted: #eee9df;
  --ink: #16202e;
  --ink-soft: #45505f;
  /* AA for small text on paper, warm surfaces, and the legacy --line badge. */
  --ink-mute: #566170;
  --brand: #24408e;
  --brand-hover: #1b3272;
  --brand-soft: #eef1f9;
  --brand-ink: #ffffff;
  --ok: #1b6e44;
  --ok-bg: #eef8f2;
  --danger: #a12c2c;
  --danger-bg: #fdf2f2;
  --warn: #92551b;
  --warn-bg: #fdf6eb;
  --rule: #e2ded4;
  --rule-strong: #cdc7ba;
  --control-rule: #85877f;
  --radius-sm: 4px;
  --radius: 6px;
  --radius-lg: 8px;
  --shadow-card: 0 2px 8px rgba(22, 32, 46, 0.035);
  --shadow-pop: 0 6px 24px rgba(22, 32, 46, 0.1);
  --font-serif: "Source Serif 4", Georgia, serif;
  --font-sans: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  --hp: var(--brand);
  --mfp: #0f766e;
  /* Existing templates and scripts continue to use these names. */
  --bg: var(--paper);
  --card: var(--surface);
  --text: var(--ink);
  --muted: var(--ink-mute);
  --line: var(--rule);
  --border: var(--rule);
  --bad: var(--danger);
  --bad-bg: var(--danger-bg);
  --info-bg: var(--brand-soft);
  --shadow: var(--shadow-card);
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; scroll-padding-block: 90px; }
body {
  font-family: var(--font-sans);
  font-size: 16px; line-height: 1.6; color: var(--ink); background: var(--paper);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh; display: flex; flex-direction: column;
}
main.wrap { flex: 1; padding-top: 30px; }
.wrap { max-width: 1040px; margin: 0 auto; padding: 0 24px; width: 100%; min-width: 0; }
a { color: var(--brand); text-decoration: underline; text-underline-offset: 0.2em; }
a:hover { color: var(--brand-hover); }
h1, h2, h3, h4, h5, h6 { font-family: var(--font-serif); font-weight: 500; line-height: 1.22; letter-spacing: -0.02em; }
h1 { font-size: clamp(1.9rem, 4vw, 2.6rem); margin: 0 0 14px; }
h2 { font-size: 1.5rem; margin: 24px 0 12px; }
h3 { font-size: 1.2rem; margin: 18px 0 8px; }
p { margin: 0 0 10px; }
main > p, .card > p, .report-text, .welcome-card > p { max-width: 68ch; }
.eyebrow { color: var(--brand); text-transform: uppercase; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.12em; }
.muted { color: var(--muted); }
.small { font-size: 0.875rem; }
.tiny { font-size: 0.78rem; }
.right { text-align: right; }
.center { text-align: center; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
/* Let content wrap rather than clip it at the edge of a phone. Maths keeps its own scroll. */
main { overflow-wrap: anywhere; }
.grid > *, .row > *, .split > *, .options label > span { min-width: 0; }
img, video, canvas { max-width: 100%; }
pre { white-space: pre-wrap; overflow-wrap: anywhere; }
.katex-display { max-width: 100%; overflow-x: auto; overflow-y: hidden; padding: 3px 0; }
:focus-visible { outline: 3px solid var(--brand); outline-offset: 3px; }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline-width: 2px; outline-offset: 1px; border-color: var(--brand); }
main:focus { outline: none; }
.skip-link { position: fixed; top: 8px; left: 16px; transform: translateY(-180%); z-index: 100; background: var(--surface); padding: 10px 16px; }
.skip-link:focus { transform: translateY(0); }

/* top bar */
.topbar { background: var(--paper); border-bottom: 1px solid var(--rule); position: sticky; top: 0; z-index: 10; }
.topbar .wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 22px; min-height: 76px; padding-block: 10px; }
.brand { font-family: var(--font-serif); font-weight: 600; font-size: 1.85rem; color: var(--ink); text-decoration: none; min-height: 44px; display: inline-flex; align-items: center; }
.brand__owl { width: 1.6rem; height: 1.6rem; margin-right: 0.5rem; }
.nav { display: flex; flex-wrap: wrap; gap: 2px; flex: 1; }
.nav a { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 8px 10px; border-radius: var(--radius-sm); color: var(--ink-soft); font-size: 0.85rem; text-decoration: none; }
.nav a.active, .nav a:hover { background: var(--brand-soft); color: var(--brand); text-decoration: none; }
.logout { display: flex; align-items: center; gap: 10px; margin: 0; }
.who { color: var(--muted); font-size: 0.9rem; }
button.link { background: none; border: 0; color: var(--brand); cursor: pointer; padding: 8px 0; font: inherit; min-height: 44px; text-decoration: underline; text-underline-offset: 0.2em; }
.logout button.link { font-size: 0.8rem; }
.student-nav { display: none; }
.foot { border-top: 1px solid var(--rule); color: var(--muted); font-size: 0.75rem; padding: 20px 0; margin-top: 40px; }

/* cards */
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 24px; margin: 16px 0; box-shadow: var(--shadow); }
.card > h2:first-child, .card > h3:first-child { margin-top: 0; }
.card > :last-child { margin-bottom: 0; }
.card.narrow { max-width: 460px; margin: 32px auto; padding: 32px; }
.card.tight { padding: 16px 24px; }
.grid { display: grid; gap: 16px; }
.grid:has(> .card) { margin-block: 16px; }
.grid > .card { margin: 0; }
.grid > details.card { align-self: start; }
.grid.two { grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
.grid.three { grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); }
/* Five stat tiles at 200px min left one stranded on its own row on a 950px column. */
.grid.stats { grid-template-columns: repeat(auto-fit, minmax(min(100%, 168px), 1fr)); }
.today-grid, .study-grid { grid-template-columns: minmax(0, 2fr) minmax(220px, 1fr); align-items: start; margin-block: 16px; }
.today-grid > * > .card, .study-grid > * > .card { margin: 0; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.row.between { justify-content: space-between; }
.stack > * + * { margin-top: 10px; }
.welcome-card { background: var(--surface-warm); border: 1px solid var(--rule); border-left: 3px solid var(--brand); border-radius: var(--radius); padding: 22px 24px; margin-bottom: 28px; }
.welcome-title { font-family: var(--font-serif); font-size: 1.5rem; font-weight: 500; line-height: 1.22; margin: 6px 0 12px; }
.welcome-card p:last-child { margin: 0; color: var(--ink-soft); }
.parent-summary { background: var(--surface-warm); }
.parent-summary h2 { margin-top: 6px; }
.report-text { white-space: pre-wrap; color: var(--ink-soft); }
.plan-summary { color: var(--ink-soft); }
.plan-summary strong { color: var(--ink); }
.plan-terms { margin-block: 16px; border-block: 1px solid var(--rule); }
.plan-terms p { font-size: 0.875rem; color: var(--ink-soft); }
.plan-options > .grid { margin-top: 14px; }
.password-login { border-top: 1px solid var(--rule); margin-top: 24px; padding-top: 8px; }
.signup-offer { border-top: 1px solid var(--rule); margin-top: 24px; padding-top: 20px; text-align: center; }
.signup-offer h2 { font-size: 1.05rem; margin: 0 0 4px; }
.signup-offer p { margin: 0 auto 14px; }
.section-row { display: grid; grid-template-columns: 72px minmax(30px, 1fr) 120px; align-items: center; gap: 14px; margin: 10px 0; }
.account-links { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; margin-top: 24px; }
.account-links a { white-space: nowrap; }
.pass-tools { border-top: 1px solid var(--line); margin-top: 8px; gap: 0 16px; }
.pass-tools a { display: inline-flex; align-items: center; min-height: 44px; }
.exam-fields { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr); }

/* forms */
.form label { display: block; margin-bottom: 12px; font-size: 0.9rem; font-weight: 500; }
button, input, select, textarea { font: inherit; color: inherit; }
input:not([type=checkbox], [type=radio], [type=hidden], [type=submit], [type=button]), select, textarea {
  max-width: 100%; min-width: 0; min-height: 44px; padding: 10px 12px; border: 1px solid var(--control-rule);
  border-radius: var(--radius-sm); background: var(--surface); accent-color: var(--brand);
}
.form input:not([type=checkbox], [type=radio], [type=hidden], [type=submit], [type=button]), .form select, .form textarea,
input.answer, textarea.answer, select.answer { display: block; width: 100%; margin: 4px 0 14px; }
.form .grid { margin-bottom: 16px; }
.form .grid > label, .form .grid > label > input, .form .grid > label > select { margin-bottom: 0; }
.form p.small { margin: -8px 0 16px; }
.form input[type=date], .form input[type=number] { max-width: 340px; }
.form .choices { border: 0; padding: 0; margin: 0 0 16px; display: flex; flex-wrap: wrap; gap: 0 24px; }
.form .choices legend { padding: 0; margin-bottom: 4px; font-size: 0.9rem; font-weight: 500; }
.form .choices label { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; margin: 0; font-weight: 400; }
input::placeholder, textarea::placeholder { color: var(--muted); opacity: 1; }
input[type=radio], input[type=checkbox] { accent-color: var(--brand); width: 18px; height: 18px; vertical-align: middle; flex-shrink: 0; }
fieldset { min-width: 0; }
.form textarea, textarea.answer { min-height: 90px; }
.inline { display: inline-flex; flex-wrap: wrap; gap: 8px; align-items: center; }
/* A card's actions: one row of buttons under the text, the same gap on every page. */
.actions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin: 16px 0 0; }
.actions > form { margin: 0; }
.actions + p, .form + p { margin-top: 16px; }
.order + .order { border-top: 1px solid var(--line); margin-top: 16px; padding-top: 16px; }
.order > p { margin: 0; }
.order > p.small { margin-top: 8px; }
.order:last-of-type + p { margin-top: 20px; }
.nowrap { white-space: nowrap; }
.btn { display: inline-flex; justify-content: center; align-items: center; gap: 6px; min-height: 44px; max-width: 100%; padding: 10px 16px; border-radius: var(--radius-sm); border: 1px solid var(--control-rule); background: var(--surface); color: var(--ink); font: inherit; font-weight: 500; line-height: 1.45; text-align: center; cursor: pointer; text-decoration: none; }
.btn:hover { background: var(--surface-warm); border-color: var(--ink-soft); color: var(--ink); text-decoration: none; }
.btn.primary { background: var(--brand); color: var(--brand-ink); border-color: var(--brand); }
.btn.primary:hover { background: var(--brand-hover); border-color: var(--brand-hover); }
.btn.ghost { background: transparent; }
.btn.ghost:hover { background: var(--brand-soft); }
.btn.danger { color: var(--bad); border-color: var(--bad); }
.btn.small { padding: 8px 12px; font-size: 0.8rem; }
.btn.block { display: block; width: 100%; text-align: center; }
.btn[disabled], .btn[disabled]:hover { opacity: 1; cursor: not-allowed; color: var(--ink-mute); background: var(--surface-muted); border-color: var(--control-rule); }
.settings-inline { border-top: 1px solid var(--rule); padding-top: 18px; margin-top: 18px; }
.settings-inline:first-of-type { border-top: 0; padding-top: 0; margin-top: 0; }
.settings-inline select { max-width: 340px; }
.save-feedback:not(:empty) { padding: 12px 16px; background: var(--ok-bg); color: var(--ok); border-radius: var(--radius); }
.save-feedback:empty { margin: 0; }

/* flashes / badges */
.flash { padding: 14px 18px; border: 1px solid var(--rule); border-radius: var(--radius); margin: 16px 0; background: var(--surface-warm); }
.flash.error, .flash.bad { background: var(--bad-bg); color: var(--bad); }
.flash.ok { background: var(--ok-bg); color: var(--ok); }
.flash.warn { background: var(--warn-bg); color: var(--warn); }
.flash.info { background: var(--info-bg); color: var(--brand); }
.confirm-banner p { margin: 0 0 10px; }
.badge { display: inline-block; padding: 3px 8px; border-radius: var(--radius-sm); font-size: 0.75rem; font-weight: 600; background: var(--line); color: var(--ink); vertical-align: middle; }
button.badge { min-width: 44px; min-height: 44px; }
.badge.hp { background: var(--brand-soft); color: var(--hp); }
.badge.mfp { background: #e9f4f1; color: var(--mfp); }
.badge.ok { background: var(--ok-bg); color: var(--ok); }
.badge.bad { background: var(--bad-bg); color: var(--bad); }
.badge.warn { background: var(--warn-bg); color: var(--warn); }
.badge.muted { background: var(--line); color: var(--muted); }

/* tables */
table { max-width: 100%; }
table.data { width: 100%; border-collapse: collapse; font-size: 0.875rem; }
table.data th, table.data td { padding: 8px 10px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
table.data th { font-weight: 500; color: var(--muted); font-size: 0.75rem; background: var(--surface-warm); }
table.data tr:hover td { background: var(--paper); }
table.data a { display: inline-flex; min-height: 44px; align-items: center; }
.scroll-x { max-width: 100%; overflow-x: auto; }

/* progress bars */
.bar { height: 6px; background: var(--line); border-radius: var(--radius-sm); overflow: hidden; }
.bar > span { display: block; height: 100%; background: var(--brand); border-radius: var(--radius-sm); }
.bar.mfp > span { background: var(--mfp); }
.bar.ok > span { background: var(--ok); }
.bar.warn > span { background: var(--warn); }
.bar.bad > span { background: var(--bad); }
.stat { display: flex; flex-direction: column; }
.stat .v { font-size: 1.5rem; font-weight: 500; font-variant-numeric: tabular-nums; }
.stat .l { color: var(--muted); font-size: 0.8rem; }

/* plan list */
.plan-item { display: flex; align-items: center; gap: 12px; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.plan-item.done { background: var(--paper); color: var(--ink-soft); }
.plan-item.current { border-color: var(--brand); background: var(--brand-soft); }
.plan-item .num { width: 26px; height: 26px; border-radius: 50%; background: var(--bg); display: inline-flex; align-items: center; justify-content: center; font-size: 0.8rem; font-weight: 600; }
.plan-item .title { flex: 1; }
.block-head { display: flex; justify-content: space-between; align-items: baseline; margin: 16px 0 6px; }
.block-head h3 { margin: 0; }

/* problem */
.problem .stem { font-size: 1.2rem; margin: 8px 0 4px; }
.question-blank { display: inline-block; min-width: 3em; margin: 0 0.12em; border-bottom: 2px solid currentColor; color: var(--brand); font-size: 0.8em; font-weight: 700; line-height: 1.2; text-align: center; vertical-align: 0.08em; }
.problem .passage { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; max-height: 420px; overflow: auto; margin-bottom: 12px; }
.problem img.figure { max-width: 100%; height: auto; border: 1px solid var(--line); border-radius: var(--radius); margin: 8px 0; }
.options { list-style: none; padding: 0; margin: 12px 0; }
.options li { margin: 6px 0; }
.options label { display: flex; gap: 12px; align-items: flex-start; min-height: 44px; padding: 8px 12px; border: 1px solid var(--control-rule); border-radius: var(--radius); cursor: pointer; }
.options label:hover { background: var(--paper); }
.options label:has(input:checked) { border-color: var(--brand); background: var(--brand-soft); }
.options input { margin: 4px 0 0; }
.options label > span > p:first-of-type { display: inline; margin: 0; }
/* Letter in its own column, so a wrapped answer lines up with its first line, not under the letter. */
.options .opt { display: grid; grid-template-columns: 1.4em minmax(0, 1fr); column-gap: 6px; align-items: baseline; }
.options .opt-key { font-size: 0.875em; color: var(--ink-soft); }
.options .opt-text > p { margin: 0; }
.options .opt-text > p + p { margin-top: 6px; }
.options label > span > :last-child { margin-bottom: 0; }
.options label > span > strong:first-child { font-size: 0.875em; color: var(--ink-soft); }
.options label:not(:has(input))::before { content: ""; flex: 0 0 18px; text-align: center; font-weight: 700; }
.options label.correct::before { content: "✓"; color: var(--ok); }
.options label.wrong::before { content: "✗"; color: var(--bad); }
.options label.correct { border-color: var(--ok); background: var(--ok-bg); }
.options label.wrong { border-color: var(--bad); background: var(--bad-bg); }
.feedback { border-radius: var(--radius); border-left: 3px solid var(--rule-strong); padding: 16px 18px; margin-top: 16px; }
.feedback.ok { background: var(--ok-bg); border-color: var(--ok); }
.feedback.bad { background: var(--bad-bg); border-color: var(--bad); }
.feedback.info { background: var(--info-bg); border-color: var(--brand); }
.solution { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; margin-top: 12px; }
.timer { font-variant-numeric: tabular-nums; font-weight: 500; color: var(--ink-soft); }
.timer.low { color: var(--bad); }
/* Three equal choices in one row, at every width. */
.self-report { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin: 18px 0 8px; padding: 0; border: 0; max-width: 30rem; }
.self-report legend { margin-bottom: 8px; }
.self-report label { display: flex; justify-content: center; gap: 6px; align-items: center; min-height: 44px; border: 1px solid var(--control-rule); border-radius: var(--radius-sm); padding: 8px 6px; font-size: 0.85rem; white-space: nowrap; cursor: pointer; }
.self-report label:has(input:checked) { border-color: var(--brand); background: var(--brand-soft); color: var(--brand); }
.self-report input { margin: 0; flex: none; }
.katex-preview { min-height: 28px; padding: 6px 0; color: var(--muted); }
.kbd { font-family: ui-monospace, monospace; background: var(--bg); padding: 1px 5px; border-radius: 4px; border: 1px solid var(--line); font-size: 0.85em; }

/* review editor */
.split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; }
@media screen and (max-width: 860px) { .split { grid-template-columns: 1fr; } }
.page-image { position: relative; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.page-image img { display: block; width: 100%; height: auto; user-select: none; -webkit-user-drag: none; }
.page-image .crop { position: absolute; border: 2px dashed var(--brand); background: rgba(36, 64, 142, 0.12); pointer-events: none; }
.tabs { display: flex; flex-wrap: wrap; gap: 6px; border-bottom: 1px solid var(--line); margin: 12px 0; }
.tabs a { display: inline-flex; align-items: center; min-height: 44px; padding: 8px 12px; border-radius: var(--radius) var(--radius) 0 0; color: var(--ink); }
.tabs a.active { background: var(--card); border: 1px solid var(--line); border-bottom-color: var(--card); margin-bottom: -1px; }
.htmx-indicator { display: none; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { display: inline; }
.sparkline { display: flex; gap: 3px; align-items: flex-end; height: 40px; }
.sparkline span { flex: 1; background: var(--brand); border-radius: 2px 2px 0 0; min-height: 2px; }
.sparkline span.zero { background: var(--line); }
details summary { cursor: pointer; font-weight: 500; color: var(--brand); min-height: 44px; padding-block: 10px; }
details[open] > summary { margin-bottom: 12px; }
details.card:not([open]) { padding-block: 8px; }
.hero { display: flex; justify-content: space-between; align-items: flex-end; flex-wrap: wrap; gap: 12px; }
.hero > div > :last-child { margin-bottom: 0; }


/* ------------------------------------------------- reading texts (LÄS) and their questions
   She has to see the text and the alternatives at the same time. On the paper provpass the
   text is on the left page and the questions on the right; stacking them with the text in a
   420px scroll box meant picking an answer from memory, and she said as much: in this format
   eight minutes is not enough because you cannot see everything. */
.card.reading { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: 22px; align-items: start; }
.card.reading .reading-text {
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px;
  position: sticky; top: 12px; max-height: calc(100vh - 130px); overflow: auto;
  font-size: 0.97rem; line-height: 1.6;
}
.card.reading .reading-main { min-width: 0; }
.card.reading .reading-main .problem { margin-bottom: 4px; }

.reading-tabs { display: none; }

@media screen and (max-width: 900px) {
  /* One column, and the two panes become tabs. Scrolling past 7000 characters to reach the
     alternatives is exactly what made a timed pass impossible; a nested scroll box inside a
     scrolling page is no better on a touch screen. */
  .card.reading { display: block; }
  .card.reading .reading-text { position: static; max-height: none; overflow: visible; margin-bottom: 14px; }
  .problem .passage { max-height: none; overflow: visible; }

  .reading-tabs { display: flex; gap: 6px; margin-bottom: 12px; }
  .reading-tabs button {
    flex: 1; min-height: 44px; padding: 9px 12px; border: 1px solid var(--control-rule); background: var(--card);
    color: var(--muted); border-radius: var(--radius-sm); font: inherit; font-size: 0.95rem; cursor: pointer;
  }
  .reading-tabs button.active { background: var(--brand); border-color: var(--brand); color: #fff; }
  .card.reading[data-tabs-ready] .reading-text { display: block; }
  .card.reading[data-tabs-ready] .reading-main { display: none; }
  .card.reading[data-tabs-ready].show-question .reading-text { display: none; }
  .card.reading[data-tabs-ready].show-question .reading-main { display: block; }
}

/* ---------------------------------------------------------------- phones (≤ 640px) */
@media screen and (max-width: 640px) {
  html { scroll-padding-bottom: 100px; }
  body:has(.student-nav) { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
  body:has(.student-nav) .topbar { position: static; }
  html:has(.student-nav) { scroll-padding-top: 16px; }
  .wrap { padding: 0 20px; }
  main.wrap { padding-top: 22px; }
  h1 { font-size: 2rem; }
  .topbar .wrap { min-height: 56px; gap: 8px 12px; padding-block: 6px; }
  .brand { font-size: 1.4rem; }
  .desktop-nav, .desktop-logout { display: none; }
  .role-nav { flex-basis: 100%; order: 3; }
  .role-nav:not(:has(> :nth-child(4))) { flex-basis: auto; order: 0; }
  /* A single native details menu keeps every secondary destination usable with no JS. */
  .student-nav {
    display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0;
    position: fixed; inset: auto 0 0; z-index: 30; padding: 6px 10px calc(6px + env(safe-area-inset-bottom));
    background: var(--paper); border-top: 1px solid var(--rule); box-shadow: 0 -3px 14px rgba(22, 32, 46, 0.04);
  }
  .student-nav > a, .nav-more > summary { min-height: 52px; font-size: 0.72rem; padding: 10px 2px; }
  .nav-more { min-width: 0; }
  .nav-more > summary { display: flex; align-items: center; justify-content: center; list-style: none; border-radius: var(--radius-sm); color: var(--ink-soft); margin: 0; font-weight: 400; }
  .nav-more > summary::-webkit-details-marker { display: none; }
  .nav-more[open] > summary, .nav-more > summary.active { color: var(--brand); background: var(--brand-soft); }
  .nav-more-panel { position: absolute; bottom: calc(100% + 8px); right: 12px; width: min(300px, calc(100vw - 24px)); max-height: calc(100dvh - 110px); overflow-y: auto; background: var(--surface); border: 1px solid var(--rule); border-radius: var(--radius-lg); box-shadow: var(--shadow-pop); padding: 10px; }
  .nav-more-panel a, .nav-more-panel button { display: flex; justify-content: flex-start; width: 100%; min-height: 48px; padding: 12px; font-size: 0.9rem; text-decoration: none; }
  .nav-more-panel form { margin: 6px 0 0; border-top: 1px solid var(--rule); }
  /* Leave the visual viewport to the answer and keyboard, including without JavaScript. */
  body:has(main input:not([type=checkbox], [type=radio], [type=hidden], [type=submit], [type=button]):focus, main textarea:focus, main select:focus) .student-nav { display: none; }
  input, select, textarea { font-size: 1rem; }
  .logout { margin-left: auto; }
  .who { display: none; }
  .hero { flex-direction: column; align-items: stretch; gap: 8px; }
  .hero-actions { display: flex; flex-wrap: wrap; gap: 6px; }
  .hero-actions .btn { flex: 1 1 auto; text-align: center; }
  /* session first, overview underneath as a compact strip */
  .grid { gap: 12px; }
  .grid:has(> .card), .today-grid, .study-grid { margin-block: 12px; }
  .today-grid, .study-grid { grid-template-columns: minmax(0, 1fr); }
  .today-grid #overview { order: 2; }
  .today-grid #stage { order: 1; }
  .card { padding: 16px; margin: 12px 0; }
  .card.narrow { background: none; border: 0; box-shadow: none; padding: 8px 0; margin: 0 auto; }
  .card.tight { padding: 12px 16px; }
  .welcome-card { padding: 20px; }
  .btn { min-height: 44px; }
  .row.between { flex-wrap: wrap; gap: 4px; }
  .grid.three, .grid.stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid.stats > :last-child:nth-child(odd) { grid-column: 1 / -1; }
  .exam-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .exam-fields > label:first-child { grid-column: 1 / -1; }
  .form .choices { flex-direction: column; }
  .stat .v { font-size: 1.25rem; }
  table.data { font-size: 0.85rem; }
  .scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  /* Keep real table semantics/column labels while presenting wide histories as rows. */
  table.mobile-stack, .mobile-stack tbody { display: block; width: 100%; }
  .mobile-stack thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .mobile-stack tr { display: block; padding: 12px 0; border-bottom: 1px solid var(--rule); }
  /* Keep each cell's inline text, maths and badges together in one formatting context. */
  table.mobile-stack td { display: block; padding: 6px 0; border: 0; }
  .mobile-stack td::before { display: block; margin-bottom: 4px; content: attr(data-label); color: var(--muted); font-size: 0.75rem; }
  .mobile-stack td > * { min-width: 0; }
  .mobile-stack td[colspan]::before { content: none; }
  .section-row { grid-template-columns: 50px minmax(24px, 1fr) 100px; gap: 10px; }
  .problem .stem { font-size: 1.1rem; }
  .figure { max-width: 100%; height: auto; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; animation: none !important; transition: none !important; }
}

/* Printable worksheets have their own standalone print.css. Keep app chrome off other prints. */
@media print {
  :root {
    --paper: #fff; --surface: #fff; --surface-warm: #fff; --surface-muted: #fff;
    --ink: #000; --ink-soft: #333; --ink-mute: #333;
    --brand: #000; --brand-hover: #000; --brand-ink: #000; --brand-soft: #fff;
    --ok: #000; --ok-bg: #fff; --danger: #000; --danger-bg: #fff; --warn: #000; --warn-bg: #fff;
    --mfp: #000;
    --rule: #ddd; --rule-strong: #aaa; --control-rule: #777;
  }
  .topbar, .student-nav, .skip-link, .foot { display: none !important; }
  body:has(.student-nav) { padding-bottom: 0; }
  body { background: #fff; }
  .card { box-shadow: none; break-inside: avoid; }
  .btn.primary, .badge.mfp { background: #fff; }
  .scroll-x { overflow: visible; }
  .card.reading { display: block; }
  .card.reading .reading-text { position: static; max-height: none; overflow: visible; }
  .reading-tabs { display: none; }
}
