/* Memory & Storage — OCR J277 1.2
 *
 * Every font size is in em, never px, so the "Text size" control (which sets
 * --ui-scale on :root) actually scales the whole interface. A px size
 * anywhere is a control that silently stops working for the pupil who needs
 * it most.
 *
 * No inline styles and no external fonts: the Caddy CSP for this host is
 * style-src 'self' with no unsafe-inline.
 */

:root {
  --ui-scale: 1;

  --ink: #17202a;
  --ink-soft: #4a5866;
  --muted: #6b7885;
  --line: var(--line);
  --line-soft: #e8edf2;
  --paper: #ffffff;
  --ground: #f4f7fa;

  --brand: #1c5c9e;
  --brand-dark: #14456f;
  --good: #1c7a4a;
  --good-bg: #e8f6ee;
  --part: #8a6100;
  --part-bg: #fdf4e0;
  --bad: #a32929;
  --bad-bg: #fdeded;
  --prov: #5b4b8a;
  --prov-bg: #f1ecfa;
  /* Accent surfaces, named so a theme can move them. Before these, a
     dark theme produced pale boxes with pale text inside them. */
  --warn-bg: #fffaf0;
  --warn-line: #e6d089;
  --tint-brand: #e8f0f9;

  font-size: calc(16px * var(--ui-scale));
}

* { box-sizing: border-box; }

/* The hidden ATTRIBUTE has to beat every display rule further down this file.
   The UA stylesheet gives [hidden] display:none, but any author rule outranks
   it — so .login-wrap (display:flex) stayed on screen behind the exam after a
   pupil signed in, and a filtered-out result card would not have hidden
   either. Everything in this interface is toggled with .hidden = true/false,
   so it has to mean what it says. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 1em;
  line-height: 1.55;
}

.skip {
  position: absolute; left: -9999px;
  background: var(--brand); color: #fff; padding: .6em 1em;
}
.skip:focus { left: .5em; top: .5em; z-index: 50; }

/* ── header ──────────────────────────────────────────────────────────── */
.top {
  display: flex; flex-wrap: wrap; gap: .75em;
  align-items: center; justify-content: space-between;
  padding: .7em 1.1em;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}
.brand { color: var(--brand); text-decoration: none; font-weight: 600; font-size: .92em; }
.brand:hover { text-decoration: underline; }
.top-right { display: flex; align-items: center; gap: 1em; flex-wrap: wrap; }
.scale-control { display: flex; align-items: center; gap: .5em; font-size: .82em; color: var(--muted); }
.scale-control input { width: 7em; }
.who { font-weight: 600; font-size: .9em; }

/* ── buttons ─────────────────────────────────────────────────────────── */
.btn-primary, .btn-quiet, .btn-mark, .certificate-btn {
  font: inherit; cursor: pointer; border-radius: .4em;
  padding: .5em 1em; border: 1px solid transparent;
  /* A button with no colour of its own takes the browser's, which is dark
     text — invisible on a dark theme. The mark buttons lost their numbers
     entirely this way. Rules below still override where they mean to. */
  color: var(--ink);
}

/* Same trap for form controls: a native select or date field with no colour
   set renders with the UA's, which does not follow the theme. Checkboxes,
   radios and ranges are left alone — they are drawn by the browser. */
select,
input[type="text"], input[type="number"], input[type="search"],
input[type="password"], input[type="date"], input[type="datetime-local"],
textarea {
  background: var(--paper);
  color: var(--ink);
}
.btn-primary { background: var(--brand); color: #fff; font-weight: 600; }
.btn-primary:hover { background: var(--brand-dark); }
.btn-primary:disabled { background: var(--muted); cursor: default; }
.btn-quiet { background: var(--paper); color: var(--ink-soft); border-color: var(--line); }
.btn-quiet:hover { border-color: var(--brand); color: var(--brand); }
.btn-mark {
  background: var(--paper); border-color: var(--line);
  min-width: 2.6em; font-weight: 600;
}
.btn-mark:hover { border-color: var(--brand); background: var(--brand); color: #fff; }

:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }

/* ── sign in ─────────────────────────────────────────────────────────── */
.login-wrap { display: flex; justify-content: center; padding: 3em 1em; }
.login-card {
  background: var(--paper); border: 1px solid var(--line); border-radius: .6em;
  padding: 2em; width: 100%; max-width: 24em;
}
.login-card h1 { margin: 0 0 .15em; font-size: 1.5em; }
.login-card .sub { margin: 0 0 1em; color: var(--brand); font-weight: 600; font-size: .9em; }
.login-card label { display: block; margin: .9em 0 .3em; font-weight: 600; font-size: .88em; }
.login-card input {
  width: 100%; font: inherit; padding: .55em .7em;
  border: 1px solid var(--line); border-radius: .35em; background: var(--paper); color: var(--ink);
}
.login-card button { width: 100%; margin-top: 1.3em; }

/* ── tabs ────────────────────────────────────────────────────────────── */
.tabs {
  display: flex; flex-wrap: wrap; gap: .3em;
  padding: .8em 1.1em 0; background: var(--paper);
  border-bottom: 1px solid var(--line);
}
.tab {
  font: inherit; font-size: .92em; cursor: pointer;
  background: none; border: 1px solid transparent; border-bottom: none;
  padding: .55em 1em; border-radius: .4em .4em 0 0; color: var(--ink-soft);
  position: relative;
}
.tab:hover { color: var(--brand); }
.tab[aria-selected="true"] {
  background: var(--ground); border-color: var(--line);
  color: var(--brand); font-weight: 600;
  margin-bottom: -1px; border-bottom: 1px solid var(--ground);
}
.badge {
  display: inline-block; margin-left: .5em; min-width: 1.5em;
  padding: 0 .35em; border-radius: 1em;
  background: var(--bad); color: #fff; font-size: .75em; text-align: center;
}

/* ── panels ──────────────────────────────────────────────────────────── */
main { max-width: 60em; margin: 0 auto; padding: 1.5em 1.1em 4em; }
.panel-head h2 { margin: 0 0 .2em; font-size: 1.35em; }
.panel-head .muted { margin: 0 0 1.2em; }
.muted { color: var(--muted); }
.small { font-size: .85em; }
.error-text { color: var(--bad); font-weight: 600; }

/* ── filters ─────────────────────────────────────────────────────────── */
.filters { display: flex; flex-wrap: wrap; gap: .4em; margin-bottom: 1.3em; }
.chip {
  font: inherit; font-size: .82em; cursor: pointer;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: 1.2em; padding: .3em .9em; color: var(--ink-soft);
}
.chip:hover { border-color: var(--brand); color: var(--brand); }
.chip-on { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600; }

/* ── question cards ──────────────────────────────────────────────────── */
.q-list { display: flex; flex-direction: column; gap: 1.1em; }
.q-card {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: .55em; padding: 1.2em;
}
.q-head {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5em;
  margin-bottom: .8em; font-size: .78em;
}
.q-num { font-weight: 700; color: var(--brand); font-size: 1.15em; }
.q-marks, .q-spec, .q-level, .q-tag {
  padding: .15em .6em; border-radius: 1em; border: 1px solid var(--line-soft);
  background: var(--ground); color: var(--ink-soft);
}
.q-spec { font-variant-numeric: tabular-nums; }
.level-1 { background: var(--good-bg); color: var(--good); border-color: var(--good); }
.level-2 { background: var(--part-bg); color: var(--part); border-color: var(--part); }
.level-3 { background: var(--bad-bg); color: var(--bad); border-color: var(--bad); }
/* A genuine past-paper question and an adaptation of one must never look the
   same: a pupil who thinks they have seen the real thing when they have not
   is being misled about what the exam looks like. */
.tag-genuine { background: var(--tint-brand); color: var(--brand-dark); border-color: var(--brand); font-weight: 600; }
.tag-adapted { background: var(--prov-bg); color: var(--prov); border-color: var(--prov); font-style: italic; }
.q-status { margin-left: auto; font-weight: 600; }
.q-status.solved { color: var(--good); }
.q-status.trying { color: var(--part); }

.q-stem { margin-bottom: 1em; white-space: normal; }

/* Binary and hex in a stem must line up in columns. */
.q-stem { font-variant-numeric: tabular-nums; }

/* ── answer inputs ───────────────────────────────────────────────────── */
.answer { margin-bottom: 1em; }
.opt {
  display: flex; align-items: flex-start; gap: .6em;
  padding: .45em .6em; border: 1px solid var(--line-soft);
  border-radius: .35em; margin-bottom: .35em; cursor: pointer;
}
.opt:hover { border-color: var(--brand); background: var(--ground); }
.opt input { margin-top: .25em; flex: none; }

.single-input, .cell-input, .prose-input {
  font: inherit; padding: .5em .65em;
  border: 1px solid var(--line); border-radius: .35em;
  background: var(--paper); color: var(--ink); width: 100%;
}
.single-input { max-width: 18em; font-variant-numeric: tabular-nums; }
.single-row { display: flex; align-items: center; gap: .6em; flex-wrap: wrap; }
.unit { color: var(--muted); font-size: .9em; }
.prose-input { resize: vertical; }

/* Program answers. Monospace with a visible tab stop, because OCR Reference
   Language is read on indentation and a proportional font hides it. */
.code-input {
  width: 100%;
  box-sizing: border-box;
  font-family: ui-monospace, "Cascadia Mono", "Consolas", "Courier New", monospace;
  font-size: 0.95em;
  line-height: 1.5;
  tab-size: 2;
  resize: vertical;
  padding: 0.6em 0.7em;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--ground);
  color: var(--ink);
  white-space: pre;
  overflow-wrap: normal;
  overflow-x: auto;
}
.code-input:focus { outline: 2px solid #2f6fd0; outline-offset: 1px; }
.field { margin-bottom: .7em; }
.field label { display: block; font-weight: 600; font-size: .85em; margin-bottom: .25em; }

.answer-grid { border-collapse: collapse; width: 100%; font-size: .9em; }
.answer-grid th, .answer-grid td {
  border: 1px solid var(--line); padding: .45em .6em; text-align: left;
}
.answer-grid thead th { background: var(--ground); font-size: .88em; }
.answer-grid .row-label { font-weight: 400; background: var(--ground); }
.answer-grid td.given { background: var(--ground); font-variant-numeric: tabular-nums; }
.cell-input { max-width: 12em; font-variant-numeric: tabular-nums; }
/* A choice cell holds whole statements, not a short value, so it must
   not be squeezed into the 12em meant for numbers and single words. */
select.cell-input { max-width: none; min-width: 14em; }

.gap-body { line-height: 2.4; }
.gap-select {
  font: inherit; font-size: .92em; padding: .25em .4em;
  border: 1px solid var(--brand); border-radius: .3em;
  background: var(--paper); color: var(--ink); margin: 0 .15em;
}

/* ── click-to-connect diagram ─────────────────────────────────────────── */
.net-stage {
  position: relative; width: 100%; max-width: 34em;
  aspect-ratio: 400 / 260; margin: .6em 0 1em;
  background: var(--ground); border: 1px solid var(--line); border-radius: .5em;
}
.net-links { position: absolute; inset: 0; width: 100%; height: 100%; }
.net-link { stroke: var(--brand); stroke-width: 2.5; }
.net-nodes { position: absolute; inset: 0; }
.net-node {
  position: absolute; transform: translate(-50%, -50%);
  font: inherit; font-size: .75em; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: .1em;
  background: var(--paper); border: 2px solid var(--line);
  border-radius: .45em; padding: .35em .5em; min-width: 4.6em;
  color: var(--ink); line-height: 1.2;
}
.net-node:hover { border-color: var(--brand); }
.net-node-on { border-color: var(--brand); background: var(--tint-brand); box-shadow: 0 0 0 3px var(--brand); }
.net-icon { font-size: 1.5em; line-height: 1; }
.net-label { white-space: nowrap; }

.net-palette { display: flex; flex-wrap: wrap; gap: .4em; margin-bottom: .6em; }
.net-chip {
  font: inherit; font-size: .8em; cursor: pointer;
  background: var(--paper); border: 1px dashed var(--line);
  border-radius: 1.2em; padding: .3em .85em; color: var(--ink-soft);
}
.net-chip:hover { border-color: var(--brand); color: var(--brand); }
.net-chip-on {
  border-style: solid; border-color: var(--brand);
  background: var(--brand); color: #fff; font-weight: 600;
}
.net-status { margin: 0 0 .5em; font-size: .82em; color: var(--muted); }

.cell-prose {
  font: inherit; padding: .45em .6em; width: 100%; min-width: 12em;
  border: 1px solid var(--line); border-radius: .35em;
  background: var(--paper); color: var(--ink); resize: vertical;
}

@media (max-width: 560px) {
  .net-node { font-size: .68em; min-width: 4em; padding: .25em .35em; }
  .net-icon { font-size: 1.25em; }
}

/* ── wireframe builder ────────────────────────────────────────────────── */
.wf-page {
  border: 1px solid var(--line); border-radius: .5em; background: var(--ground);
  padding: .4em; margin: .6em 0 1em; max-width: 26em;
}
.wf-row { display: flex; gap: .3em; min-height: 2.1em; margin-bottom: .25em; }
.wf-block, .wf-slot {
  flex: 1; font: inherit; font-size: .8em; cursor: pointer;
  border-radius: .3em; padding: .4em .6em; text-align: center;
}
.wf-block { background: var(--tint-brand); border: 2px solid var(--brand); color: var(--brand-dark); font-weight: 600; }
.wf-block:hover { background: var(--tint-brand); filter: brightness(.95); }
.wf-slot { background: transparent; border: 1px dashed var(--line); color: var(--muted); }
.wf-slot:disabled { cursor: default; color: var(--muted); }
.wf-slot:not(:disabled):hover { border-color: var(--brand); color: var(--brand); background: var(--tint-brand); }
.wf-palette { display: flex; flex-wrap: wrap; gap: .4em; margin-bottom: .5em; }
.wf-chip {
  font: inherit; font-size: .8em; cursor: pointer;
  background: var(--paper); border: 1px dashed var(--line);
  border-radius: 1.2em; padding: .3em .85em; color: var(--ink-soft);
}
.wf-chip:hover { border-color: var(--brand); color: var(--brand); }
.wf-chip-on { border-style: solid; border-color: var(--brand); background: var(--brand); color: #fff; font-weight: 600; }
.wf-chip-used { opacity: .4; cursor: default; text-decoration: line-through; }

/* ── mock exam ────────────────────────────────────────────────────────── */
.exam-warning {
  background: var(--warn-bg); border: 1px solid var(--warn-line); border-radius: .5em;
  padding: 1em 1.2em; margin-bottom: 1.4em; font-size: .92em; line-height: 1.6;
}
.paper-list { display: flex; flex-direction: column; gap: .9em; margin-bottom: 2em; }
.paper-card {
  background: var(--paper); border: 1px solid var(--line); border-radius: .55em;
  padding: 1.1em 1.2em; display: flex; flex-wrap: wrap; align-items: center; gap: .8em;
}
.paper-head { flex: 1; display: flex; flex-direction: column; gap: .2em; min-width: 14em; }

.exam-bar {
  position: sticky; top: 0; z-index: 20;
  display: flex; flex-wrap: wrap; align-items: center; gap: 1em;
  background: var(--paper); border-bottom: 2px solid var(--line);
  padding: .8em 1.1em; margin: -1.5em -1.1em 1.4em;
}
.exam-bar-title { flex: 1; display: flex; flex-direction: column; min-width: 12em; }
.exam-bar-actions { display: flex; align-items: center; gap: .8em; }
.exam-timer {
  display: flex; flex-direction: column; align-items: center;
  padding: .3em 1em; border-radius: .45em; background: var(--ground);
  border: 2px solid var(--line);
}
.timer-label { font-size: .68em; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
.timer-value { font-size: 1.5em; font-weight: 700; font-variant-numeric: tabular-nums; }
.timer-warn { border-color: var(--part); background: var(--part-bg); }
.timer-warn .timer-value { color: var(--part); }
.timer-critical { border-color: var(--bad); background: var(--bad-bg); }
.timer-critical .timer-value { color: var(--bad); }

.exam-section {
  margin: 2em 0 .8em; font-size: .8em; font-weight: 700;
  text-transform: uppercase; letter-spacing: .12em; color: var(--muted);
  border-bottom: 1px solid var(--line); padding-bottom: .4em;
}
.exam-card { margin-bottom: 1em; }
/* A question the pupil tried to submit without answering. */
.exam-card.missing { border-color: var(--bad); box-shadow: 0 0 0 3px var(--bad-bg); }
.exam-answered.solved { color: var(--good); }
.submit-warning {
  background: var(--bad-bg); border-left: 4px solid var(--bad);
  padding: .9em 1.1em; border-radius: .4em; font-weight: 600; margin-bottom: 1.2em;
}
.exam-foot { margin: 2em 0 4em; text-align: center; }

.result-summary { display: flex; flex-wrap: wrap; gap: 1em; margin-bottom: 1em; }
.score-block {
  flex: 1; min-width: 12em; background: var(--paper); border: 1px solid var(--line);
  border-radius: .5em; padding: 1em 1.2em; display: flex; flex-direction: column; gap: .2em;
}
.score-self { border-style: dashed; }
.score-label { font-size: .78em; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
.score-value { font-size: 1.8em; font-weight: 700; font-variant-numeric: tabular-nums; }
.result-card { border-left-width: 4px; margin-bottom: 1em; }
.result-right { border-left-color: var(--good); }
.result-part  { border-left-color: var(--part); }
.result-wrong { border-left-color: var(--bad); }
.result-blank { border-left-color: var(--muted); }
.result-prov  { border-left-color: var(--prov); }
.your-answer { margin: .6em 0; }
.exam-feedback {
  background: var(--ground); border-radius: .4em; padding: .7em .9em;
  font-size: .9em; margin: .6em 0;
}

@media (max-width: 700px) {
  /* The bar STAYS sticky on a phone. It used to go static here, which meant
     the timer scrolled off the top and a pupil sitting a timed paper on a
     phone could not see the clock without scrolling back up. Compacted
     instead: title dropped, timer on one line, submit still reachable. */
  .exam-bar {
    margin: 0 0 1.2em;
    padding: .45em .6em;
    gap: .5em;
    align-items: center;
  }
  .exam-bar-title { display: none; }
  .exam-timer {
    flex-direction: row; align-items: baseline; gap: .35em;
    padding: .15em .5em; white-space: nowrap;
  }
  /* The timer and the submit button have to share one row on a 375px phone,
     or the sticky bar grows to three rows and eats a quarter of the screen
     for the whole paper. Measured: they miss fitting by a few pixels at the
     default sizes. */
  .exam-timer .timer-label { font-size: .6em; }
  .exam-timer .timer-value { font-size: 1.15em; }
  #time-call, #pace { font-size: .82em; }
  .exam-bar-actions { margin-left: auto; gap: .4em; }
  #save-state { display: none; }
  #time-call, #pace { flex-basis: 100%; margin: .25em 0 0; }
}

/* ── actions and feedback ────────────────────────────────────────────── */
.q-actions { display: flex; gap: .6em; flex-wrap: wrap; }
.hint {
  margin: .8em 0 0; padding: .7em .9em;
  background: var(--warn-bg); border-left: 3px solid var(--warn-line); border-radius: .3em;
  font-size: .9em;
}

.feedback {
  margin-top: 1em; padding: .9em 1.1em;
  border-radius: .4em; border-left: 4px solid var(--line);
}
.feedback.good { background: var(--good-bg); border-left-color: var(--good); }
.feedback.part { background: var(--part-bg); border-left-color: var(--part); }
.feedback.bad  { background: var(--bad-bg);  border-left-color: var(--bad); }
.feedback.provisional { background: var(--prov-bg); border-left-color: var(--prov); }
.score { margin: 0 0 .4em; font-weight: 700; font-size: 1.05em; }
.note { margin: .3em 0; font-size: .9em; }
.provisional-warning {
  margin: .5em 0; font-size: .88em; color: var(--prov); font-weight: 600;
}

.ms-block, .working-block { margin-top: .7em; }
.ms-block summary, .working-block summary {
  cursor: pointer; font-weight: 600; font-size: .9em; color: var(--brand);
}
.ms-text, .working-text, .prose-answer {
  white-space: pre-wrap; overflow-wrap: break-word;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .85em; background: var(--paper);
  border: 1px solid var(--line-soft); border-radius: .35em;
  padding: .7em .85em; margin: .5em 0 0;
}

.self-assess { margin-top: .9em; padding-top: .8em; border-top: 1px dashed var(--line); }
.self-assess p { margin: 0 0 .5em; font-size: .9em; }
.self-row { display: flex; gap: .4em; flex-wrap: wrap; }
.self-done { color: var(--good); font-weight: 600; }

.topic-heading {
  margin: 0 0 1.1em; font-size: 1.5em; color: var(--brand-dark);
  border-bottom: 2px solid var(--line); padding-bottom: .4em;
}
.topic-heading:empty { display: none; }

/* ── certificates ────────────────────────────────────────────────────── */
.certificate-banner {
  background: linear-gradient(180deg, #fffdf2, #fff8e0);
  border: 1px solid var(--warn-line); border-radius: .55em;
  padding: 1.1em 1.3em; margin-bottom: 1.5em;
}
.certificate-banner p { margin: 0 0 .7em; font-weight: 600; }
#certificate-links { display: flex; gap: .6em; flex-wrap: wrap; }
.certificate-btn {
  background: var(--brand); color: #fff; text-decoration: none;
  font-weight: 600; font-size: .9em; display: inline-block;
}
.certificate-btn:hover { background: var(--brand-dark); }

/* ── progress ────────────────────────────────────────────────────────── */
.prog-block {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: .55em; padding: 1.2em; margin-bottom: 1.2em;
}
.prog-block h3 { margin: 0 0 .6em; font-size: 1.05em; }
.bar { height: .7em; background: var(--line-soft); border-radius: 1em; overflow: hidden; }
.bar-fill { height: 100%; background: var(--good); border-radius: 1em; }
.topic-table { width: 100%; margin-top: .9em; border-collapse: collapse; font-size: .9em; }
.topic-table td { padding: .3em .2em; border-bottom: 1px solid var(--line-soft); }
.topic-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.topic-done td { color: var(--good); font-weight: 600; }

/* ── teacher ─────────────────────────────────────────────────────────── */
.admin-block {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: .55em; padding: 1.2em; margin-bottom: 1.3em;
}
.admin-block h3 { margin: 0 0 .5em; font-size: 1.05em; }
.cert-count { font-size: .8em; font-weight: 400; margin-left: .5em; }
.cert-count-new { color: var(--bad); font-weight: 700; }

.data-table { width: 100%; border-collapse: collapse; font-size: .88em; margin-top: .7em; }
.data-table th, .data-table td {
  text-align: left; padding: .45em .6em; border-bottom: 1px solid var(--line-soft);
}
.data-table th { background: var(--ground); font-size: .9em; }
.row-new td { background: var(--warn-bg); font-weight: 600; }

.prose-item { border-bottom: 1px solid var(--line-soft); padding: .5em 0; }
.prose-item summary { cursor: pointer; display: flex; gap: .8em; flex-wrap: wrap; font-size: .9em; }
.prose-who { font-weight: 600; }
.prose-q { color: var(--muted); font-family: ui-monospace, monospace; font-size: .9em; }
.prose-score { margin-left: auto; color: var(--prov); font-size: .88em; }
.prose-stem { font-size: .9em; color: var(--ink-soft); margin: .5em 0; }

/* The class grid is 50 columns wide — it has to scroll inside its own box
   rather than pushing the page sideways. */
.grid-wrap { overflow-x: auto; }
.prog-grid { border-collapse: collapse; font-size: .8em; }
.prog-grid th, .prog-grid td { border: 1px solid var(--line-soft); padding: .2em .35em; }
.prog-grid .sticky {
  position: sticky; left: 0; background: var(--paper);
  text-align: left; white-space: nowrap; font-weight: 600; z-index: 1;
}
.prog-grid .tiny { font-size: .85em; color: var(--muted); font-weight: 400; min-width: 1.5em; }
.prog-grid .num { text-align: center; font-variant-numeric: tabular-nums; font-weight: 600; }
.cell { width: 1.2em; height: 1.2em; padding: 0; }
.cell-yes { background: var(--good); }
.cell-no { background: var(--line-soft); }

/* ── footer ──────────────────────────────────────────────────────────── */
.foot {
  max-width: 60em; margin: 0 auto; padding: 2em 1.1em 3em;
  border-top: 1px solid var(--line); text-align: center; font-size: .88em;
}
.foot a { color: var(--brand); }

.bug-report-btn {
  position: fixed; right: 1em; bottom: 1em;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: 1.5em; padding: .45em .9em;
  font-size: .82em; text-decoration: none; color: var(--ink-soft);
  box-shadow: 0 1px 4px rgba(0,0,0,.1);
}
.bug-report-btn:hover { border-color: var(--brand); color: var(--brand); }

/* ── narrow screens ──────────────────────────────────────────────────── */
@media (max-width: 700px) {
  .q-head { font-size: .74em; }
  .q-status { margin-left: 0; width: 100%; }
  .answer-grid { font-size: .82em; }
  .answer-grid th, .answer-grid td { padding: .35em .4em; }
  .cell-input { max-width: 100%; }
  .prose-score { margin-left: 0; width: 100%; }
  .bug-report-btn { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  * { scroll-behavior: auto !important; }
}

/* The teacher's add-a-question form. One column, because it is filled in
   from top to bottom and a two-column form would only invite tabbing into
   the wrong box. */
.authored-form { display: grid; gap: 0.45em; max-width: 46em; margin: 0.8em 0; }
.authored-form label { font-weight: 600; font-size: 0.95em; }
.authored-form label .muted { font-weight: 400; }
.authored-form input,
.authored-form select,
.authored-form textarea {
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  padding: 0.45em 0.55em;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
}
.authored-form textarea { resize: vertical; }
.authored-form button { justify-self: start; margin-top: 0.4em; }

/* Result page: the indicative grade and what to do next. The grade is
   deliberately the largest thing on the page, because it is the number a
   pupil actually acts on — but it carries its basis underneath it, because
   a mock is not the paper the boundaries came from. */
.score-grade { background: var(--tint-brand); border-color: var(--brand); color: var(--ink); }
.grade-value { font-size: 2.2em; line-height: 1.1; }
.score-sub { display: block; font-size: 0.9em; font-weight: 600; color: #2f6fd0; }
.score-basis { display: block; font-size: 0.78em; color: #5b6875; margin-top: 0.3em; }

.result-next { margin: 1.6em 0; }
.next-steps { margin: 0.6em 0 0; padding-left: 1.3em; }
.next-step { margin: 0 0 1em; }
.next-head { display: flex; flex-wrap: wrap; gap: 0.6em; align-items: baseline; }
.next-lost { color: #a4331f; font-weight: 600; font-size: 0.92em; }
.next-topics { margin: 0.25em 0 0.5em; color: #46525f; font-size: 0.95em; }
.next-link { display: inline-block; margin-top: 0.2em; }

/* Question navigator. Sticky, because its whole purpose is to be reachable
   from anywhere in a thirty-question scroll. */
.q-nav {
  /* Sits BELOW the exam bar, which is also sticky. Both were at top:0, so the
     navigator slid up underneath the bar and the pupil lost the one control
     meant to be reachable from anywhere. --exam-bar-h is measured by
     exam-app.js because the bar wraps at some widths and text sizes; the
     fallback covers the moment before the script has measured it. */
  position: sticky; top: var(--exam-bar-h, 3.6em); z-index: 5;
  background: var(--paper); border: 1px solid var(--line); border-radius: 8px;
  padding: 0.6em 0.75em; margin: 0 0 1em;
}
.q-nav-head { display: flex; justify-content: space-between; align-items: center; gap: 1em; }
.q-nav-grid { display: flex; flex-wrap: wrap; gap: 0.3em; margin: 0.5em 0; }
.q-nav-cell {
  min-width: 2.1em; padding: 0.28em 0.4em;
  font: inherit; font-size: 0.88em; font-weight: 600;
  border-radius: 5px; border: 1px solid var(--line); cursor: pointer;
}
.nav-todo { background: var(--paper); color: var(--ink-soft); }
.nav-done { background: var(--good-bg); border-color: var(--good); color: var(--good); }
.nav-flag { box-shadow: inset 0 -3px 0 #e0a32e; }
.q-nav-cell:hover { border-color: #2f6fd0; }

.q-flag {
  margin-left: auto; background: none; border: none; cursor: pointer;
  font-size: 1.1em; line-height: 1; color: #b9c2cc; padding: 0 0.2em;
}
.q-flag-on { color: #e0a32e; }
.card-flagged { border-left: 3px solid #e0a32e; }

.timer-final { color: #a4331f; font-weight: 700; }
.time-call { background: var(--warn-bg); border-color: var(--warn-line); color: var(--part); }

.extra-time-note {
  /* Was a hardcoded pale blue with the browser's default text colour on top —
     which is dark, so the whole notice disappeared in dark mode. */
  background: var(--tint-brand); border: 1px solid var(--brand);
  color: var(--ink); border-radius: var(--r-sm);
  padding: 0.55em 0.75em; margin: 0 0 0.8em; font-size: 0.95em;
}

.extra-time-input { width: 5em; font: inherit; padding: 0.25em 0.4em;
  border: 1px solid var(--line); border-radius: 5px; }
.facility { font-weight: 700; text-align: right; }
.fac-low  { color: #a4331f; }
.fac-mid  { color: #8a6100; }
.fac-high { color: #1d6b38; }

.section-advice {
  margin: -0.4em 0 0.9em; padding: 0.4em 0.7em;
  background: var(--paper-2); border-left: 3px solid var(--brand); color: var(--ink);
  font-size: 0.92em; color: var(--ink-soft);
}

/* ── exam bar extras ──────────────────────────────────────────────────── */
/* Time calls and the pace line each get their own row, and their own element:
   sharing #submit-warning meant one could wipe the other off the screen. */
#time-call, #pace { flex-basis: 100%; margin: .4em 0 0; font-size: .9em; }
#time-call {
  padding: .4em .7em; border-radius: .4em; font-weight: 600;
  background: var(--warn-bg); border: 1px solid var(--warn-line); color: var(--part);
}
.pace { padding: .2em 0; color: var(--muted); }
.pace-ahead  { color: var(--good); font-weight: 600; }
.pace-on     { color: var(--ink-soft); }
.pace-behind { color: var(--part); font-weight: 600; }

/* What used to be alert(). */
.app-notice {
  margin: 0 0 1em; padding: .7em 1em; border-radius: .5em;
  background: var(--bad-bg); border: 1px solid var(--bad); color: var(--bad);
  font-weight: 600;
}

/* How much to write. Sits above the box, quiet enough not to compete with
   the question itself. */
.answer-guide {
  margin: 0 0 .4em; font-size: .85em; color: var(--muted); font-style: italic;
}

/* ── results ──────────────────────────────────────────────────────────── */
.score-compare .cmp-up    { color: var(--good); }
.score-compare .cmp-down  { color: var(--bad); }
.score-compare .cmp-level { color: var(--muted); }

.self-queue {
  margin: 0 0 1.2em; padding: .9em 1.1em; border-radius: .5em;
  background: var(--prov-bg); border: 1px solid var(--prov);
}
.self-queue p { margin: .35em 0 .7em; }

.result-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6em;
  margin: 1.2em 0 .8em; padding-top: .8em; border-top: 1px solid var(--line);
}
.result-filter { display: flex; flex-wrap: wrap; gap: .4em; flex: 1; }
.filter-btn { font-size: .88em; }
.filter-btn[disabled] { opacity: .45; cursor: default; }
.filter-on {
  background: var(--brand); border-color: var(--brand); color: #fff;
}

/* ── teacher ──────────────────────────────────────────────────────────── */
.teacher-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6em;
  margin: 1.4em 0 .8em; padding: .6em .9em;
  background: var(--ground); border: 1px solid var(--line); border-radius: .5em;
}
.teacher-bar label { font-weight: 600; }
.teacher-bar select { font: inherit; padding: .25em .4em; }

.block-actions { display: flex; flex-wrap: wrap; gap: .4em; margin: .5em 0 .8em; }

.pill {
  display: inline-block; margin-left: .5em; padding: .05em .55em;
  border-radius: 1em; font-size: .72em; font-weight: 700; vertical-align: middle;
}
.pill-todo { background: var(--part-bg); color: var(--part); }
.pill-done { background: var(--good-bg); color: var(--good); }

.marking-controls {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6em; margin: .6em 0;
}
.marking-toggle { display: flex; align-items: center; gap: .35em; font-size: .9em; }
.mark-card { border-left: 4px solid var(--prov); }
.mark-note { margin: .4em 0 0; }
/* The mark the PUPIL gave themselves, so a teacher can see at a glance what
   they are being asked to agree with. */
.btn-mark-self { outline: 2px solid var(--prov); outline-offset: 1px; }
.btn-mark-on { background: var(--brand); border-color: var(--brand); color: #fff; }
.teacher-marked { color: var(--prov); }

.to-mark { color: var(--part); font-weight: 700; }
.unmarked-key { color: var(--part); font-weight: 600; }

.access-controls, .bulk-group {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6em; margin: .6em 0;
}
.access-controls input[type="search"], .bulk-group input[type="text"],
.bulk-group input:not([type]) {
  font: inherit; padding: .3em .5em;
  border: 1px solid var(--line); border-radius: .35em;
}
.bulk-group {
  padding: .6em .8em; background: var(--ground);
  border: 1px solid var(--line); border-radius: .5em;
}
.bulk-group button[disabled] { opacity: .45; cursor: default; }

.idle { color: var(--part); font-weight: 600; }
.prose-todo > summary { border-left: 3px solid var(--part); padding-left: .5em; }

#pupil-block { position: relative; }
#pupil-close { position: absolute; top: 1em; right: 1em; }
#pupil-detail h4 { margin: 1.2em 0 .4em; }

.analysis-row td { vertical-align: top; }
.analysis-detail {
  position: relative; margin-top: 1em; padding: 1em;
  background: var(--ground); border: 1px solid var(--line); border-radius: .5em;
}
.analysis-detail h4 { margin: 0 0 .4em; }
.detail-close { position: absolute; top: .6em; right: .6em; }
.prose-answer-small { font-size: .85em; margin: 0; max-width: 32em; }

/* ── reading settings ─────────────────────────────────────────────────── */
/* Theme, tint, typeface and line spacing are data attributes on <html>, set
   by exam-app.js. Everything below reads them. Doing it this way rather than
   with inline styles is not a preference: the CSP for these hosts is
   style-src 'self' with no unsafe-inline, so an inline style simply would not
   apply. */

:root[data-theme="dark"] {
  --ink: #e8edf2;
  --ink-soft: #c2cbd4;
  --muted: #9aa7b4;
  --line: #3a444f;
  --line-soft: #2c343d;
  --paper: #1b2128;
  --ground: #12171c;
  --brand: #6aa9e9;
  --brand-dark: #8cbdf0;
  --good: #6fd39b;   --good-bg: #16301f;
  --part: #e0b064;   --part-bg: #33260f;
  --bad: #f08a8a;    --bad-bg: #3a1b1b;
  --prov: #b9a6e8;   --prov-bg: #241c33;
  --warn-bg: #332a12; --warn-line: #7a6323; --tint-brand: #16293c;
}

/* Not merely "dark": maximum separation, for a pupil who needs it rather than
   prefers it. */
:root[data-theme="contrast"] {
  --ink: #ffffff;
  --ink-soft: #ffffff;
  --muted: #d8d8d8;
  --line: #ffffff;
  --line-soft: #999999;
  --paper: #000000;
  --ground: #000000;
  --brand: #6fd3ff;
  --brand-dark: #a8e5ff;
  --good: #5cff9d;   --good-bg: #00230f;
  --part: #ffd166;   --part-bg: #241a00;
  --bad: #ff8f8f;    --bad-bg: #2a0000;
  --prov: #d3b8ff;   --prov-bg: #1a0f2b;
  --warn-bg: #241a00; --warn-line: #ffd166; --tint-brand: #001a26;
}
:root[data-theme="contrast"] body { background: #000; }
:root[data-theme="contrast"] .q-card,
:root[data-theme="contrast"] .paper-card { border-width: 2px; }

/* Tints sit UNDER the theme: a pupil who needs a coloured overlay usually
   needs it on a light ground, so a tint quietly returns the page to light. */
:root[data-tint="cream"] { --paper: #fdf6e3; --ground: #f5ecd6; --ink: #1a1a1a; }
:root[data-tint="blue"]  { --paper: #e8f2fb; --ground: #dbe9f6; --ink: #10222f; }
:root[data-tint="rose"]  { --paper: #fdeef1; --ground: #f7e0e6; --ink: #2b1218; }
:root[data-tint="green"] { --paper: #ecf7ec; --ground: #ddeedd; --ink: #12250f; }

:root[data-font="readable"] body {
  /* No web font: the CSP blocks external ones and a missing font is worse
     than a plain one. These are the most legible faces already on a school
     machine, with generous tracking. */
  font-family: "Atkinson Hyperlegible", "Verdana", "Trebuchet MS", system-ui, sans-serif;
  letter-spacing: .012em;
  word-spacing: .06em;
}
:root[data-font="mono"] body {
  font-family: ui-monospace, "Cascadia Mono", "Consolas", monospace;
}

body { line-height: var(--leading, 1.55); }

.reading-panel {
  padding: 1em 1.1em;
  background: var(--paper);
  border-bottom: 2px solid var(--line);
}
.reading-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6em; margin: 0 0 .6em;
}
.reading-label { min-width: 7.5em; font-weight: 600; }
.seg { display: flex; flex-wrap: wrap; gap: .3em; }
.seg-btn {
  font: inherit; font-size: .88em; padding: .3em .7em; cursor: pointer;
  background: var(--ground); color: var(--ink);
  border: 1px solid var(--line); border-radius: .35em;
}
.seg-on { background: var(--brand); border-color: var(--brand); color: #fff; }

/* ── offline ──────────────────────────────────────────────────────────── */
.offline-note {
  margin: 0 0 1em; padding: .7em 1em; border-radius: .5em; font-weight: 600;
}
.offline-warn { background: var(--part-bg); border: 1px solid var(--part); color: var(--part); }
.offline-bad  { background: var(--bad-bg);  border: 1px solid var(--bad);  color: var(--bad); }

/* ── paper cards: windows and shorter goes ────────────────────────────── */
.paper-note {
  margin: .3em 0; padding: .4em .7em; border-radius: .4em;
  background: var(--prov-bg); border: 1px solid var(--prov); color: var(--prov);
  font-size: .9em;
}
.section-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: .4em; margin-top: .6em;
}

/* ── review before submitting ─────────────────────────────────────────── */
.review-panel {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(0, 0, 0, .45);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 4vh 1em; overflow-y: auto;
}
.review-inner {
  position: relative; width: 100%; max-width: 40em;
  padding: 1.4em 1.5em; border-radius: .6em;
  background: var(--paper); border: 1px solid var(--line);
}
.review-close { position: absolute; top: .8em; right: .8em; }
.review-inner h2 { margin: 0 0 .6em; }
.review-inner h3 { margin: 1.1em 0 .4em; font-size: 1em; }
.review-summary { margin: 0 0 .4em; }
.review-chips { display: flex; flex-wrap: wrap; gap: .3em; }
.review-inner .btn-primary { margin-top: 1.2em; }

/* ── results ──────────────────────────────────────────────────────────── */
.q-time { margin: .4em 0 0; font-size: .85em; color: var(--muted); }
.q-time-slow { color: var(--part); font-weight: 600; }

.teacher-comment {
  margin: .6em 0; padding: .6em .9em; border-radius: .45em;
  background: var(--prov-bg); border-left: 4px solid var(--prov);
}
.teacher-comment p { margin: .2em 0 0; }

.result-certs {
  margin: 0 0 1.2em; padding: .9em 1.1em; border-radius: .5em;
  background: var(--good-bg); border: 1px solid var(--good);
}
.cert-row { display: flex; flex-wrap: wrap; gap: .4em; margin-top: .6em; }
.cert-new { border-color: var(--good); font-weight: 700; }

/* ── revision mode ────────────────────────────────────────────────────── */
.revise-card { border-left: 4px solid var(--brand); }

@media (max-width: 700px) {
  .reading-label { min-width: 100%; }
  .review-inner { padding: 1.1em; }
}

/* ── teacher: scheduling, marking by question, boundaries ─────────────── */
.assign-form {
  display: grid; grid-template-columns: auto 1fr; gap: .5em .8em;
  align-items: center; max-width: 42em; margin: .8em 0;
}
.assign-form label { font-weight: 600; }
.assign-form input, .assign-form select {
  font: inherit; padding: .3em .5em;
  border: 1px solid var(--line); border-radius: .35em;
  background: var(--paper); color: var(--ink);
}
.assign-form button, .assign-form p { grid-column: 1 / -1; justify-self: start; }

.mark-done { border-left-color: var(--good); opacity: .75; }
.mark-comment {
  font: inherit; font-size: .9em; padding: .3em .5em; min-width: 16em; flex: 1;
  border: 1px solid var(--line); border-radius: .35em;
  background: var(--paper); color: var(--ink);
}
.bound-input {
  font: inherit; padding: .25em .4em; width: 6em;
  border: 1px solid var(--line); border-radius: .3em;
  background: var(--paper); color: var(--ink);
}
.voided-row td { text-decoration: line-through; }
.voided-row td:last-child { text-decoration: none; }

/* Printing a paper. Everything that only makes sense on screen goes away;
   a question must not be split across a page break mid-stem. */
@media print {
  .top, .q-nav, .exam-bar, .exam-foot, .exam-warning,
  #submit-warning, #time-call, #pace, #app-notice,
  #extra-time-note, .q-flag, .scale-control,
  .result-toolbar, .landing-back, .self-row,
  .btn-quiet, .btn-primary, .foot { display: none !important; }
  /* A printed result is a record — for a parents' evening, or a folder. The
     mark scheme and the worked answer are the useful half of it, so the
     details blocks are opened by the print handler and must not collapse
     back to a summary line on paper. */
  .ms-block, .working-block { break-inside: avoid; page-break-inside: avoid; }
  .result-summary { break-after: avoid; page-break-after: avoid; }
  .self-queue { border: 1px solid #999; }
  body { background: #fff; }
  .q-card, .exam-card { break-inside: avoid; page-break-inside: avoid;
    border: 1px solid #999; margin: 0 0 0.6em; }
  .exam-section { break-before: page; page-break-before: always; }
  .exam-section:first-of-type { break-before: auto; page-break-before: auto; }
  textarea, input, select { border: 1px solid #999 !important; background: #fff !important; }
  .code-input { min-height: 8em; }
}

/* ════════════════════════════════════════════════════════════════════════
   ASCENDERE — visual refresh, 2026-09-13
   ════════════════════════════════════════════════════════════════════════

   ONE CONTIGUOUS BLOCK, ON PURPOSE. Everything below overrides the original
   rules rather than editing them in place, so the whole refresh can be lifted
   out again by deleting from this banner to the one at the end — and the tools
   go back to exactly how they looked before. That is the revert.

   WHAT IT CHANGES
     * A softer palette. The old one was navy-on-cold-grey at full strength;
       this is the same information at lower contrast between surfaces, with
       contrast kept where it carries meaning (text, marks, right and wrong).
     * Depth instead of borders. Cards sit on the page rather than being boxed
       in by 1px lines.
     * Rounder corners, more air, and motion that is felt rather than seen.
     * A per-tool accent, set from the topic code by the page itself, so the
       nine topic tools and the mocks are recognisably different rooms in the
       same building.

   WHAT IT DOES NOT CHANGE
     * Any layout a pupil has learned. Nothing moves; things are shaped and
       coloured differently.
     * Contrast where it means something. The high-contrast theme is untouched
       by the softening — see the guard on the surface rules.
   ════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── surfaces ── */
  --ground: #f5f6fa;
  --paper: #ffffff;
  --paper-2: #fbfcfe;          /* a step in, for nested panels */
  --line: #e6e9f0;
  --line-soft: #f0f2f7;

  /* ── ink ── */
  --ink: #1e2531;
  --ink-soft: #4c5768;
  --muted: #71809a;

  /* ── accents ── */
  --brand: #5566dd;
  --brand-dark: #3f4dc0;
  --brand-soft: #eef0fd;

  --good: #0f7a5f;  --good-bg: #e7f6f1;
  --part: #a76a10;  --part-bg: #fdf3e2;
  --bad:  #c23a4b;  --bad-bg:  #fdecee;
  --prov: #6f57a3;  --prov-bg: #f1ecfa;

  --warn-bg: #fdf6e6;
  --warn-line: #e7c877;
  --tint-brand: var(--brand-soft);

  /* Each tool sets its own hue from its topic code; this is the fallback. */
  --tool-accent: var(--brand);
  --tool-accent-soft: var(--brand-soft);

  /* ── shape and depth ── */
  --r-sm: .45rem;
  --r: .8rem;
  --r-lg: 1.2rem;
  --shadow-1: 0 1px 2px rgba(24, 33, 56, .06);
  --shadow-2: 0 2px 6px rgba(24, 33, 56, .06), 0 8px 22px -12px rgba(24, 33, 56, .18);
  --shadow-3: 0 4px 10px rgba(24, 33, 56, .08), 0 18px 40px -18px rgba(24, 33, 56, .28);
  --ring: 0 0 0 3px var(--tool-accent-soft);
  --ease: cubic-bezier(.2, .7, .3, 1);
}

/* ── theme: follow the device unless told otherwise ───────────────────────
   data-theme="auto" is the default the page sets when nobody has chosen. The
   explicit light / dark / contrast values still win, and are unaffected by
   what the operating system thinks. */
@media (prefers-color-scheme: dark) {
  :root[data-theme="auto"] {
    --ground: #0f1218;
    --paper: #171b23;
    --paper-2: #1c212b;
    --line: #29303c;
    --line-soft: #212733;
    --ink: #e8ecf3;
    --ink-soft: #c0c8d6;
    --muted: #93a0b4;
    --brand: #8e9bf5;
    --brand-dark: #a9b3f8;
    --brand-soft: #1d2340;
    --good: #4fcfa4;  --good-bg: #10291f;
    --part: #e0ad63;  --part-bg: #2d2310;
    --bad:  #f08b93;  --bad-bg:  #33191d;
    --prov: #b6a4e8;  --prov-bg: #221c33;
    --warn-bg: #2b2310; --warn-line: #6f5b25;
    --shadow-1: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-2: 0 2px 6px rgba(0, 0, 0, .35), 0 8px 22px -12px rgba(0, 0, 0, .6);
    --shadow-3: 0 4px 10px rgba(0, 0, 0, .4), 0 18px 40px -18px rgba(0, 0, 0, .7);
  }
}

/* The chosen-dark palette matches the automatic one, so switching between
   "auto" and "dark" on a dark laptop changes nothing visible. */
:root[data-theme="dark"] {
  --ground: #0f1218;
  --paper: #171b23;
  --paper-2: #1c212b;
  --line: #29303c;
  --line-soft: #212733;
  --ink: #e8ecf3;
  --ink-soft: #c0c8d6;
  --muted: #93a0b4;
  --brand: #8e9bf5;
  --brand-dark: #a9b3f8;
  --brand-soft: #1d2340;
  --good: #4fcfa4;  --good-bg: #10291f;
  --part: #e0ad63;  --part-bg: #2d2310;
  --bad:  #f08b93;  --bad-bg:  #33191d;
  --prov: #b6a4e8;  --prov-bg: #221c33;
  --warn-bg: #2b2310; --warn-line: #6f5b25;
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow-2: 0 2px 6px rgba(0, 0, 0, .35), 0 8px 22px -12px rgba(0, 0, 0, .6);
  --shadow-3: 0 4px 10px rgba(0, 0, 0, .4), 0 18px 40px -18px rgba(0, 0, 0, .7);
}

/* High contrast opts OUT of the soft treatment entirely: no shadows, hard
   borders, maximum separation. Softness is the opposite of what it is for. */
:root[data-theme="contrast"] {
  --r-sm: .2rem; --r: .3rem; --r-lg: .3rem;
  --shadow-1: none; --shadow-2: none; --shadow-3: none;
  --brand-soft: #001a26;
  --tool-accent: var(--brand);
  --tool-accent-soft: #001a26;
}
:root[data-theme="contrast"] .q-card,
:root[data-theme="contrast"] .paper-card,
:root[data-theme="contrast"] .admin-block { border-width: 2px; }

body { background: var(--ground); }

/* ── page furniture ───────────────────────────────────────────────────── */
.top {
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-1);
}
.brand {
  font-weight: 700; letter-spacing: .02em;
  border-radius: var(--r-sm);
  transition: color .18s var(--ease);
}
.brand:hover { color: var(--tool-accent); }

/* ── the hero each tool now opens with ────────────────────────────────── */
.tool-hero {
  display: flex; align-items: center; gap: 1.1em;
  margin: 1.4em 0 1.6em;
  padding: 1.3em 1.5em;
  border-radius: var(--r-lg);
  background:
    linear-gradient(135deg, var(--tool-accent-soft), transparent 62%),
    var(--paper);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-2);
}
/* The monogram. A topic code in a tile, rather than twelve illustrations
   nobody has drawn — it scales to a thirteenth tool for free. */
.tool-badge {
  flex: none;
  display: grid; place-items: center;
  min-width: 3.4em; height: 3.4em; padding: 0 .5em;
  border-radius: var(--r);
  background: linear-gradient(150deg, var(--tool-accent), var(--brand-dark));
  color: #fff;
  font-weight: 800; font-size: 1.05em; letter-spacing: .02em;
  box-shadow: var(--shadow-2);
}
.tool-hero-text { min-width: 0; }
.tool-hero h1 {
  margin: 0; font-size: clamp(1.3em, 3.4vw, 1.7em);
  line-height: 1.2; letter-spacing: -.01em;
}
.tool-hero .tool-sub { margin: .25em 0 0; color: var(--muted); font-size: .92em; }
.tool-hero-stats {
  margin-left: auto; display: flex; gap: 1.4em; flex-wrap: wrap; text-align: right;
}
.tool-stat { display: flex; flex-direction: column; }
.tool-stat b { font-size: 1.3em; line-height: 1.1; color: var(--tool-accent); }
.tool-stat span { font-size: .76em; color: var(--muted); text-transform: uppercase;
                  letter-spacing: .06em; }

/* ── tabs ─────────────────────────────────────────────────────────────── */
.tabs {
  gap: .25em;
  border-bottom: 1px solid var(--line);
}
.tab {
  border-radius: var(--r-sm) var(--r-sm) 0 0;
  padding: .6em 1em;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.tab:hover { background: var(--tool-accent-soft); color: var(--tool-accent); }
.tab[aria-selected="true"] {
  color: var(--tool-accent);
  border-bottom-color: var(--tool-accent);
  background: var(--tool-accent-soft);
}

/* ── cards ────────────────────────────────────────────────────────────── */
.q-card, .paper-card, .admin-block, .login-card {
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--paper);
  box-shadow: var(--shadow-2);
  transition: box-shadow .22s var(--ease), transform .22s var(--ease);
}
.q-card { padding: 1.4em 1.5em; }
.paper-card:hover { box-shadow: var(--shadow-3); transform: translateY(-2px); }

/* A quiet accent rail, so a card has a left edge that means something. */
.q-card { border-left: 3px solid transparent; }
.q-card:focus-within { border-left-color: var(--tool-accent); }
.result-right { border-left-color: var(--good); }
.result-part  { border-left-color: var(--part); }
.result-wrong { border-left-color: var(--bad); }
.result-blank { border-left-color: var(--muted); }
.result-prov  { border-left-color: var(--prov); }

.q-num {
  display: inline-grid; place-items: center;
  min-width: 1.9em; height: 1.9em; padding: 0 .35em;
  border-radius: 50em;
  background: var(--tool-accent-soft); color: var(--tool-accent);
  font-weight: 700;
}
.q-marks {
  border-radius: 50em; padding: .12em .7em;
  background: var(--line-soft); color: var(--ink-soft); font-weight: 600;
}

/* ── paper chooser ────────────────────────────────────────────────────── */
.paper-card { padding: 1.3em 1.4em; }
.paper-head strong { font-size: 1.12em; letter-spacing: -.005em; }
.paper-chips { display: flex; flex-wrap: wrap; gap: .4em; margin: .5em 0 .2em; }
.paper-chip {
  border-radius: 50em; padding: .2em .75em;
  background: var(--line-soft); color: var(--ink-soft);
  font-size: .82em; font-weight: 600;
}
.paper-chip-accent { background: var(--tool-accent-soft); color: var(--tool-accent); }

/* ── controls ─────────────────────────────────────────────────────────── */
.btn-primary, .btn-quiet, .btn-mark, .certificate-btn, .seg-btn, .tab {
  transition: background .18s var(--ease), color .18s var(--ease),
              border-color .18s var(--ease), box-shadow .18s var(--ease),
              transform .12s var(--ease);
}
.btn-primary, .btn-quiet, .btn-mark, .certificate-btn {
  border-radius: var(--r-sm);
}
.btn-primary {
  background: linear-gradient(160deg, var(--tool-accent), var(--brand-dark));
  border-color: transparent;
  box-shadow: var(--shadow-1);
}
.btn-primary:hover:not([disabled]) { box-shadow: var(--shadow-2); transform: translateY(-1px); }
.btn-primary:active:not([disabled]) { transform: translateY(0); }
.btn-primary[disabled] { opacity: .5; filter: saturate(.4); transform: none; }
.btn-quiet:hover:not([disabled]) {
  background: var(--tool-accent-soft); border-color: var(--tool-accent);
  color: var(--tool-accent);
}
.btn-mark:hover { background: var(--tool-accent); border-color: var(--tool-accent); }

/* One visible focus ring everywhere, for the keyboard and for anyone who
   needs to know where they are. */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, summary:focus-visible {
  outline: 2px solid var(--tool-accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

.single-input, .cell-input, .prose-input, .code-input, .cell-prose,
.gap-select, .mark-comment, .bound-input, .extra-time-input {
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.single-input:focus, .cell-input:focus, .prose-input:focus, .code-input:focus,
.cell-prose:focus, .gap-select:focus, .mark-comment:focus {
  border-color: var(--tool-accent);
  box-shadow: var(--ring);
  outline: none;
}

/* ── tables ───────────────────────────────────────────────────────────── */
.data-table, .topic-table {
  border-radius: var(--r); overflow: hidden;
  box-shadow: var(--shadow-1);
}
.data-table th, .topic-table th {
  background: var(--paper-2); color: var(--ink-soft);
  font-size: .84em; text-transform: uppercase; letter-spacing: .05em;
}
.data-table tr:hover td { background: var(--tool-accent-soft); }

/* ── the exam bar and navigator ───────────────────────────────────────── */
.exam-bar {
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-1);
  background: var(--paper);
}
.exam-timer { border-radius: var(--r); background: var(--line-soft); }
.timer-warn  { background: var(--part-bg); color: var(--part); }
.timer-final, .timer-critical { background: var(--bad-bg); color: var(--bad); }
.q-nav { border-radius: var(--r); box-shadow: var(--shadow-1); }
.q-nav-cell {
  border-radius: var(--r-sm);
  transition: transform .12s var(--ease), background .18s var(--ease),
              border-color .18s var(--ease);
}
.q-nav-cell:hover { transform: translateY(-1px); border-color: var(--tool-accent); }
.nav-done { background: var(--good-bg); color: var(--good); border-color: transparent; }
.nav-flag { box-shadow: inset 0 -3px 0 var(--part); }

/* ── motion, for those who want it ────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
  }
  .paper-card:hover, .btn-primary:hover, .q-nav-cell:hover { transform: none; }
}

@media (max-width: 700px) {
  .tool-hero { flex-wrap: wrap; padding: 1.1em 1.2em; }
  .tool-hero-stats { margin-left: 0; width: 100%; text-align: left; gap: 1.1em; }
}

/* ════════════ end of the Ascendere refresh — delete to here to revert ═══ */

/* ── dashboard ────────────────────────────────────────────────────────── */
/* Copied from the tools rather than linked, so the dashboard cannot be
   restyled by a change made for a pupil page. Everything above this line is
   the shared sheet; everything below belongs to this site only. */

.tomark-grid {
  display: flex; flex-wrap: wrap; gap: .8em; margin-top: .6em;
}
.tomark-card {
  display: flex; flex-direction: column; align-items: flex-start; gap: .25em;
  padding: .8em 1em; min-width: 13em;
  background: var(--paper); border: 1px solid var(--line);
  border-left: 4px solid var(--part); border-radius: .5em;
}
.tomark-n { font-size: 1.6em; font-weight: 700; color: var(--part); line-height: 1; }
.all-clear {
  padding: .8em 1em; border-radius: .5em;
  background: var(--good-bg); border: 1px solid var(--good); color: var(--good);
  font-weight: 600;
}

.tool-grid { display: flex; flex-wrap: wrap; gap: .8em; margin-top: .6em; }
.tool-card {
  display: flex; flex-direction: column; align-items: flex-start; gap: .25em;
  padding: .7em .9em; min-width: 15em;
  background: var(--paper); border: 1px solid var(--line); border-radius: .5em;
}

/* One row per pupil, one column per tool. It is a wide table on purpose —
   the whole point is seeing a pupil's whole picture on one line — so the
   pupil name column stays put while the rest scrolls. */
.over-table th.sticky, .over-table td.sticky,
.over-table tr > th:first-child {
  position: sticky; left: 0; background: var(--paper); text-align: left;
}
.over-table th.tiny { font-size: .75em; writing-mode: horizontal-tb; }
.over-table td.num { text-align: center; }
.cell-count { font-variant-numeric: tabular-nums; }
.cell-strong { background: var(--good-bg); color: var(--good); font-weight: 600; }
.cell-mid    { background: var(--part-bg); color: var(--part); }
.cell-weak   { background: var(--bad-bg);  color: var(--bad); }

#pupil-block { position: relative; }
#pupil-close { position: absolute; top: 1em; right: 1em; }
#pupil-detail h3 { margin: 1.2em 0 .4em; }
/* A button in a table cell must not wrap: "Open tool" broke across two
   lines and spilled out of its column. */
.data-table td .btn-quiet, .data-table td a.btn-quiet { white-space: nowrap; }
