/* ==========================================================================
   AstroQuiz portal — Aryabhat design-system port
   Look, feel and tokens follow aryabhat.org / design.md:
   cosmic dark sky, gold-on-dark interactive accents, the renfrew brand
   display face for big moments, Space Grotesk for UI, Outfit for prose.

   Class names are preserved from the legacy stylesheet so the existing
   Django templates restyle without markup changes. The starfield itself
   is painted by js/cosmos-bg.js behind everything (z-index:-1).
   ========================================================================== */

@font-face {
  font-family: 'renfrewregular';
  src: url('../fonts/renfrew-webfont.woff2') format('woff2'),
       url('../fonts/renfrew-webfont.woff') format('woff');
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ---- Design-system tokens (design.md §1.1 / §1.2) ---- */

  /* The accent, as bare RGB TRIPLES. Everything gold below — the three named
     colours and every rgba() tint of them in this file — is derived from
     these, so a portal built from this same stylesheet can take on its own
     identity by overriding three lines and nothing else. The camp portal does
     exactly that (camp/static/camp/camp.css), which is why no rule below may
     go back to writing `rgba(var(--accent-rgb), …)` literally: a hardcoded tint is
     a gold ghost that survives the override and looks like a bug.
     The quiz portal's own values are unchanged — rgb(255, 204, 51) IS #ffcc33. */
  --accent-rgb: 255, 204, 51;
  --accent-soft-rgb: 255, 229, 138;
  --accent-deep-rgb: 255, 164, 27;

  --gold: rgb(var(--accent-rgb));        /* primary brand accent, active states, headline <em> */
  --gold-soft: rgb(var(--accent-soft-rgb)); /* hover text, pull-quote, light gold moments */
  --gold-deep: rgb(var(--accent-deep-rgb)); /* bottom of primary-button gradient */
  --ink: #e6eef7;           /* default body / link text */
  --ink-dim: #9fb3c8;       /* captions, footer, muted copy */
  --accent-cyan: #1EAEDB;   /* secondary cosmic accent (sparingly) */
  --panel: #16223388;       /* translucent card backgrounds */
  --panel-solid: #1a2636;   /* opaque panel surface */
  --border: #2a3d55;        /* default 1px borders on panels */

  --font-brand: 'renfrewregular', 'Space Grotesk', Arial, sans-serif;
  --font-display: 'Space Grotesk', 'Outfit', system-ui, sans-serif;
  --font-body: 'Outfit', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --brand-shape: 14px 4px 14px 4px;
  --brand-shape-tight: 10px 3px 10px 3px;

  /* Deep-space sky; mirrors SKY_BG in cosmos-bg.js so JS-off / pre-paint
     still shows a calm night sky rather than a flat colour. */
  --sky-bg: radial-gradient(ellipse at 50% 120%, #1a2a40 0%, #0a1018 55%, #04060a 100%);

  /* ---- Legacy aliases kept so existing templates keep resolving ---- */
  --text-primary: var(--ink);
  --text-secondary: var(--ink-dim);
  --text-highlight: var(--gold);
  --text-on-dark-button: var(--gold);
  --text-error: #ff7b72;

  --bg-content: var(--panel);
  --bg-question: var(--panel-solid);
  --bg-card: var(--panel-solid);
  --bg-answer: #15212f;
  --bg-progress-div: #0d1722cc;

  --link-color: var(--ink);
  --link-hover-decoration: none;

  --border-color-table: var(--border);
  --border-color-hr: var(--border);
  --border-color-input: var(--border);
  --border-color-input-focus: var(--gold);
  --border-color-input-focus-shadow: rgba(var(--accent-rgb), 0.30);
  --input-focus-bg: #15212f;
  --input-padding: 12px;

  --font-family-base: var(--font-body);
  --font-size-base: 1em;
  --line-height-base: 1.65em;
  --line-height-condensed: 1.4em;

  --border-radius-small: 4px;
  --border-radius-medium: 10px;
  --border-radius-large: 16px;

  /* Buttons: gold text on a slate-blue fill (lighter than the body panels)
     with a gold-tinted border — distinct from the ink body text and navy
     background, but calm: no comet shape, no glow. Tune here. */
  --button-radius: 10px 0 10px 10px;   /* rounded on every corner except top-right */
  --button-bg: linear-gradient(180deg, #2c405c 0%, #1e3045 100%);
  --button-bg-hover: linear-gradient(180deg, #364c6e 0%, #273b54 100%);
  --button-border: rgba(var(--accent-rgb), 0.45);
  --button-border-hover: var(--gold);
  --button-text: var(--gold);
  --button-text-hover: var(--gold-soft);

  --max-width-container: 860px;

  /* Progress bar */
  --progress-bar-bg: #1d2c3e;
  --progress-bar-height: 12px;
  --progress-fill-default: #57A957;
  --progress-fill-blue: var(--accent-cyan);
  --progress-fill-error: #e0533d;
  --progress-fill-warning: var(--gold);
  --progress-label-color: rgba(255, 255, 255, 0.9);

  /* Pagination */
  --pagination-border: var(--border);
  --pagination-attempted-bg: #103d5d;
  --pagination-active-bg: var(--gold);

  /* Quiz specific */
  --zone-of-selection: #005500;
  --second-attempt: #555500;
  --failed-attempt: #330000;
  --ongoing-attempt: #333333;
  --correct: lightgreen;
  --wrong: lightcoral;
}

/* --------------------------------------------------------------------------
   Base / sky
   -------------------------------------------------------------------------- */
html, body {
  overflow-x: hidden;   /* non-negotiable on mobile (design.md §5) */
}

/* Kills Android Chrome's pull-to-refresh and the horizontal swipe-to-navigate
   ON THE QUIZ PAGE ONLY (questions.html sets html_class): a reload mid-quiz
   used to end the attempt, and even with resume it costs the student their
   selections and their nerve. Scoped because the first site-wide version
   broke mouse-wheel scrolling on the admin dashboard (reported 2026-08-20) —
   no other page needs it, so no other page carries it. */
html.quiz-page,
html.quiz-page body {
  overscroll-behavior: contain;
}

/* The quiz page's vertical budget (2026-08-20). A lab monitor is 1366x768,
   ~640px of viewport after browser chrome, and a student who must SCROLL to
   see option 5 or the Next button mid-quiz loses seconds per question. The
   default paragraph/panel spacing is generous by design everywhere else;
   here every pixel between the timer and the Next button is quiz time. */
html.quiz-page .content {
  padding: 10px 22px 8px;
}
html.quiz-page #question_form p {
  /* The option gap is the label's own margin-bottom; the wrapping <p>'s
     default margins doubled it. */
  margin: 0;
}
html.quiz-page .column > p.center {
  margin: 6px 0 2px;    /* the Next / END QUIZ button row */
}
#progress_div .quiz-timer-line {
  margin: 2px 0;
  font-size: 1.05em;
}

html {
  /* Fallback sky behind the canvas; cosmos-bg.js paints over this. */
  background: #04060a var(--sky-bg) fixed;
  background-attachment: fixed;
}

body {
  margin: 0;
  font: normal var(--font-size-base)/var(--line-height-base) var(--font-body);
  background: transparent;      /* let the starfield show through */
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* Big display moments use the renfrew brand heritage face (design.md §1.2):
   drop the negative tracking and add a little line-height so the strokes
   don't mash. Renfrew is the only place the brand face appears. */
h1, h2 {
  font-family: var(--font-brand);
  font-weight: 400;
  letter-spacing: 0;
}
h1 { font-size: clamp(2rem, 4.4vw, 2.9rem); line-height: 1.2; }
h2 {
  text-align: center;
  color: var(--gold);
  font-size: clamp(1.7rem, 3.6vw, 2.3rem);
  line-height: 1.18;
}
h3 { font-size: 1.2rem; line-height: 1.35; }

/* Shared page title (base.html). Uses the default h2 size; its top margin
   is zeroed so it doesn't gap away from the content panel's top edge. The
   year breaks onto its own line and reads white against the gold title. */
.page-title { margin-top: 0; }
.page-title .year { display: block; color: var(--ink); font-size: 0.78em; }
h4 {
  color: var(--gold);
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* Utility: opt any element into the renfrew brand face (large numbers,
   pull-quotes, the odd hero word). */
.renfrew { font-family: var(--font-brand); font-weight: 400; letter-spacing: 0; }

p { text-align: left; margin: 12px; line-height: var(--line-height-base); color: inherit; hyphens: auto; -webkit-hyphens: auto; }
li { text-align: left; line-height: var(--line-height-base); }

img.fit { max-width: 100%; height: auto; border-radius: var(--border-radius-large); }

.center { text-align: center; }
.left { text-align: left; }
.text-justify { text-align: justify; }
.m-10 { margin: 10px; }

.highlight { color: var(--gold); font-weight: 600; }

/* The debar notice on /home. A solid red panel and nothing else on the page,
   which is what the DOS terminal this replaced showed — the students and the
   schools already know that screen, and it is the one message on the portal
   that must not be mistaken for ordinary chrome. Not a --wrong tint: this is a
   statement, not a validation error. */
.debarred {
  background: #b00000;
  color: #ffffff;
  padding: 26px 22px;
  margin: 18px auto;
  max-width: 46ch;
  border-radius: var(--border-radius-medium);
  font-size: 1.05em;
  text-align: left;
}
.large { font-size: 1.2em; }
.larger { font-size: 1.5em; }
.text-important-date { color: var(--gold); }

/* --------------------------------------------------------------------------
   Layout shell
   -------------------------------------------------------------------------- */
#wrapper {
  margin: 0 auto;
  max-width: var(--max-width-container);
  padding: 0 14px 1px;
}

.content {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 22px 22px 18px;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
}

/* --------------------------------------------------------------------------
   Header (logo + wordmark) — design.md §1.6 white drop-shadow treatment
   -------------------------------------------------------------------------- */
#header {
  padding: 1.6rem 0 1.2rem;
}

/* Logo lockup: emblem + wordmark side by side, sized to a shared height
   so the two (differently-proportioned) marks sit on a clean baseline.
   Wraps/stacks on narrow screens (see the mobile block below). */
.header-logos {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(18px, 4vw, 44px);
}

.brand-logo {
  height: clamp(70px, 12vw, 120px);
  width: auto;
  filter:
    drop-shadow(0 0 2px rgba(255, 255, 255, 0.95))
    drop-shadow(0 0 6px rgba(255, 255, 255, 0.2))
    drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.5));
  animation: logo-float 6s ease-in-out infinite;
}

.site-logo {
  height: clamp(64px, 11vw, 110px);
  width: auto;
}

@keyframes logo-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-6px); }
}

@media (prefers-reduced-motion: reduce) {
  .brand-logo { animation: none; }
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */
#footer {
  margin: 2.4rem 0 2.8rem;
  text-align: center;
}
#footer p {
  text-align: center;
  color: var(--ink-dim);
  font-size: 0.82rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   Tables
   -------------------------------------------------------------------------- */
table {
  margin: 1.2rem auto;
  max-width: 100%;            /* never wider than the container (.content) */
  border-collapse: separate;
  border-spacing: 0;
  background: linear-gradient(160deg, rgba(30, 45, 66, 0.55), rgba(15, 26, 38, 0.55));
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
}
td {
  border-top: 1px solid rgba(var(--accent-rgb), 0.08);
  padding: 10px 14px;
  color: var(--ink);
  overflow-wrap: break-word;   /* break-word (not anywhere) so hyphenation can apply */
  hyphens: auto;
  -webkit-hyphens: auto;
}
/* Long links (emails / URLs) hard-break without a hyphen — keeps tables
   contained and avoids a confusing hyphen inside an address. */
td a {
  overflow-wrap: anywhere;
  hyphens: manual;
  -webkit-hyphens: manual;
}
table tr:first-child td { border-top: none; }
th {
  font-weight: 600;
  color: var(--gold);
  background-color: rgba(42, 61, 85, 0.6);
  border-bottom: 1px solid var(--border);
  padding: 10px 14px;
  letter-spacing: 0.04em;
}
.padded td { padding: 10px 14px; }

/* --------------------------------------------------------------------------
   Links
   -------------------------------------------------------------------------- */
a { outline: 0; text-decoration: none; color: var(--link-color); }
a:hover { text-decoration: var(--link-hover-decoration); color: var(--gold-soft); }

/* --------------------------------------------------------------------------
   Buttons — design.md §2.2.  .link == primary, .smalllink == ghost.
   -------------------------------------------------------------------------- */
/* On touch, a plain element waits ~300ms for a possible double-tap-to-zoom
   before delivering the tap; on a 180-second paper that is 20 questions of
   lag, and a genuine double-tap zooms the layout mid-quiz. `manipulation`
   keeps pinch-zoom (accessibility) and drops only double-tap. */
a, button, label, input, select { touch-action: manipulation; }

.link,
input[type=submit],
button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 1.12em;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-align: center;
  line-height: 1.1;
  min-height: 44px;
  padding: 12px 26px;
  border: 1px solid var(--button-border);
  border-radius: var(--button-radius);
  background: var(--button-bg);
  color: var(--button-text);
  cursor: pointer;
  text-decoration: none;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
  transition: background .2s ease, color .2s ease, border-color .2s ease,
              box-shadow .25s ease, transform .12s ease;
}

.link:hover,
input[type=submit]:hover,
button:hover {
  color: var(--button-text-hover);
  background: var(--button-bg-hover);
  border-color: var(--button-border-hover);
  text-decoration: none;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.08);
  transform: translateY(-1px);
}

.link:active,
input[type=submit]:active,
button:active {
  transform: translateY(0);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.3);
}

/* Ghost / secondary action */
.smalllink {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: .95rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 4px;
  padding: 8px 16px;
  min-height: 38px;
  border: 1px solid var(--button-border);
  border-radius: var(--button-radius);
  background: transparent;
  color: var(--button-text);
  text-align: center;
  box-shadow: none;
  transition: background .2s ease, color .2s ease, border-color .2s ease,
              box-shadow .25s ease, transform .12s ease;
}
.smalllink:hover {
  background: rgba(255, 255, 255, 0.05);
  color: var(--button-text-hover);
  border-color: var(--button-border-hover);
  text-decoration: none;
  box-shadow: none;
  transform: translateY(-1px);
}

/* --------------------------------------------------------------------------
   Misc text bits
   -------------------------------------------------------------------------- */
.errorlist {
  color: var(--text-error);
  font-size: 0.9em;
  padding: 2px 2px 2px 10px;
  list-style-type: none;
  margin-left: 0;
}

hr {
  border: 0;
  border-top: 1px solid rgba(var(--accent-rgb), 0.2);
  border-radius: var(--border-radius-small);
  margin: 24px 0;
}

/* --------------------------------------------------------------------------
   Inputs & form surfaces
   -------------------------------------------------------------------------- */
input[type=text],
input[type=date],
input[type=email],
input[type=password],
input[type="datetime-local"],
/* textarea was missing here, so every multi-line box on the site — the notice
   body, the debar list — rendered as the browser's default white-on-white
   rectangle in the middle of a dark panel. */
textarea,
select {
  padding: var(--input-padding);
  border-radius: var(--border-radius-medium);
  border: 1px solid var(--border-color-input);
  background-color: var(--panel-solid);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
}

/* The quiz-submission overlay (questions.html). Covers the viewport while the
   answers are POSTed — and re-POSTed: it exists for the end-of-slot spike,
   when a whole lab submits at once and some POSTs die in flight. While it
   shows, the answers live only in the page, so it both reassures ("keep this
   page open") and blocks stray clicks on the paper underneath. */
.submit-overlay {
  display: none;
  position: fixed;
  /* Longhand, not `inset: 0` — inset is Chrome 87+/Safari 14.1+, and an old
     lab machine ignoring it would leave this "fixed" box at its static spot
     in the footer instead of covering the paper. */
  top: 0; right: 0; bottom: 0; left: 0;
  z-index: 1000;
  background: rgba(4, 6, 10, 0.82);
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.submit-overlay.active { display: flex; }
.submit-overlay-card {
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: var(--border-radius-medium);
  padding: 26px 30px;
  max-width: 30em;
  text-align: center;
}
.submit-overlay-title {
  color: var(--gold);
  font-size: 1.25rem;
  margin: 0 0 10px;
  animation: submit-overlay-pulse 1.6s ease-in-out infinite;
}
.submit-overlay-detail {
  color: var(--ink);
  margin: 0;
}
@keyframes submit-overlay-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}
@media (prefers-reduced-motion: reduce) {
  .submit-overlay-title { animation: none; }
}

/* The school password box. It is `type="text"` so that no browser recognises it
   as a password field and offers to save a date-of-birth password onto a shared
   lab PC (see the login forms in forms.py) — this rule is what still shows it as
   dots. Chrome, Edge, Safari and Firefox 118+ honour it; anywhere else the
   digits are visible, which is the accepted trade. */
input.masked-input {
  -webkit-text-security: disc;
  text-security: disc;
  /* The bullets are drawn from the body face, which has no glyph for them in
     some weights; the system stack always does. */
  font-family: system-ui, -apple-system, sans-serif;
  letter-spacing: 0.12em;
}

input[type=text]:focus,
input[type=date]:focus,
input[type=email]:focus,
input[type=password]:focus,
input[type="checkbox"]:focus,
input[type="datetime-local"]:focus,
textarea:focus,
select:focus {
  outline: none;
  border-color: var(--border-color-input-focus);
  background-color: var(--input-focus-bg);
  box-shadow: 0 0 0 2px var(--border-color-input-focus-shadow);
}

input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--gold);
}

/* datetime-local kept in the gold-accent style used by the admin slot UI */
input[type="datetime-local"] {
  padding: 12px 16px;
  border: none;
  border-radius: var(--border-radius-large);
  background-color: var(--gold);
  color: #0d1722;
}
input[type="datetime-local"]:focus,
input[type="datetime-local"]:hover {
  background-color: var(--gold-soft);
}

input[type="file"]::file-selector-button {
  font-family: var(--font-display);
  background: transparent;
  color: var(--gold);
  border: 1px solid rgba(var(--accent-rgb), 0.5);
  padding: 10px 16px;
  border-radius: var(--button-radius);
  cursor: pointer;
  transition: background-color 0.2s ease-in-out, border-color .2s ease;
}
input[type="file"]::file-selector-button:hover {
  background: rgba(var(--accent-rgb), 0.08);
  border-color: var(--gold);
}

summary {
  font-family: var(--font-display);
  background-color: var(--panel-solid);
  color: var(--gold);
  border: 1px solid var(--border);
  border-radius: var(--border-radius-large);
  margin: 8px 0;
  padding: 14px 18px;
  cursor: pointer;
  font-weight: 600;
  letter-spacing: 0.04em;
}
summary:hover { border-color: rgba(var(--accent-rgb), 0.35); }

form {
  background: linear-gradient(160deg, rgba(30, 45, 66, 0.6), rgba(15, 26, 38, 0.6));
  border: 1px solid var(--border);
  border-radius: var(--border-radius-large);
  margin: 12px 0;
  padding: 18px;
}

.checkbox-large {
  transform: scale(1.5);
  margin: 15px;
  vertical-align: middle;
}
.form-prompt { font-size: 1.05rem; }
form table td p.required > label { font-weight: 600; }
form table { background: transparent; border: none; }
form table td { border: none; padding: 8px; }

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */
.card {
  background: linear-gradient(160deg, rgba(30, 45, 66, 0.9), rgba(15, 26, 38, 0.9));
  border: 1px solid var(--border);
  border-radius: var(--border-radius-large);
  padding: 18px;
  transition: border-color .25s ease, box-shadow .25s ease;
}
.card:hover { border-color: rgba(var(--accent-rgb), 0.28); }

/* A student name that opens the details popup (`[data-student]`). These were
   `.card`s, which is the wrong control for the job: the name sits in ONE
   column of a long table, and an 18px-padded panel around it made every row
   several times taller than the row's own data — a page of forty attempts
   scrolled like a page of forty cards. All the cell has to say is "this is
   clickable", which is what a link says: a dotted underline at rest, the
   accent on hover. No box, no padding, so the row height stays the table's.
   Works on a <td> and on a <span> inside one — text-decoration hugs the text
   either way, where a border-bottom would draw across the whole cell. */
.student-link {
  cursor: pointer;
  text-decoration: underline dotted rgba(var(--accent-rgb), 0.45);
  text-underline-offset: 3px;
  transition: color .2s ease, text-decoration-color .2s ease;
}
.student-link:hover {
  color: var(--gold-soft);
  text-decoration-color: rgb(var(--accent-rgb));
}

/* --------------------------------------------------------------------------
   Birthday greeting (astroquiz/birthday.py, _birthday.html)
   -------------------------------------------------------------------------- */
/* One quiet line, not a banner. On /home it sits directly above the quiz
   instructions a student is about to be timed on, so it may not shout and it
   may not push them down the page — hence a single row, no animation, and the
   accent used as a tint and a rule rather than as a fill. */
.birthday {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 14px;
  padding: 10px 16px;
  text-align: left;
  background: rgba(var(--accent-rgb), 0.08);
  border: 1px solid rgba(var(--accent-rgb), 0.28);
  border-radius: var(--border-radius-large);
  color: var(--gold-soft);
}
.birthday b { color: var(--gold); }
.birthday-cake { font-size: 1.5rem; line-height: 1; flex: 0 0 auto; }
.birthday-sub {
  display: block;
  font-size: .85rem;
  color: var(--ink-dim);
}

.user-username { color: var(--ink-dim); }
.user-logout-link {
  padding: 4px 10px;
  border-radius: var(--button-radius);
  border: 1px solid rgba(var(--accent-rgb), 0.4);
  color: var(--gold);
}
.user-logout-link:hover { background: rgba(var(--accent-rgb), 0.08); }

/* --------------------------------------------------------------------------
   Quiz — question + answer options
   -------------------------------------------------------------------------- */
/* The paper is not selectable text. A long-press on a phone otherwise pops
   "Copy / Web Search / Translate" over the question — a distraction, and a
   one-tap search of the question itself (the context menu is already blocked;
   this closes the touch route). Scoped to the paper and its controls — the
   rest of the site keeps normal selection. */
div.question,
label.answer_radio,
.pagination {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

div.question {
  font-size: 1.25em;
  padding: 10px 16px;
  color: var(--ink);
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: var(--border-radius-large);
  margin-bottom: 10px;
  line-height: 1.45;
}

input[type=radio].aq-radio {
  opacity: 0;
  position: fixed;
  width: 0;
  height: 0;
}

label.answer_radio {
  background: var(--bg-answer);
  border: 1px solid var(--border);
  padding: 8px 14px;    /* ~44px tall — the touch-target floor, no lower */
  font-size: 1.1em;
  display: inline-flex;
  align-items: center;
  border-radius: var(--border-radius-large);
  cursor: pointer;
  margin-bottom: 8px;
  width: 100%;
  box-sizing: border-box;
  transition: border-color .2s ease, background-color .2s ease;
}
label.answer_radio:hover { border-color: rgba(var(--accent-rgb), 0.4); }
html.quiz-page label.answer_radio { margin-bottom: 6px; }

input[type=radio].aq-radio + label.answer_radio::before {
  content: '';
  display: inline-block;
  width: 1.2em;
  height: 1.2em;
  border: 2px solid var(--ink-dim);
  border-radius: 50%;
  margin-right: 0.75em;
  background-color: transparent;
  flex-shrink: 0;
  transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out;
}
input[type=radio].aq-radio:checked + label.answer_radio::before {
  background-color: var(--gold);
  border-color: var(--gold);
}
input[type=radio].aq-radio:checked + label.answer_radio {
  color: var(--gold);
  border-color: var(--gold);
  background: rgba(var(--accent-rgb), 0.06);
}

/* --------------------------------------------------------------------------
   Quiz — progress strip + pagination
   -------------------------------------------------------------------------- */
#progress_div {
  text-align: center;
  top: 0px;
  max-width: calc(var(--max-width-container) - 20px);
  width: 96%;
  /* Vertical padding is fixed and small — the old 2% scaled with viewport
     WIDTH, so the wider the screen the taller the dead space. */
  padding: 8px 2%;
  background: var(--bg-progress-div);
  border: 1px solid var(--border);
  color: var(--ink);
  border-radius: var(--border-radius-large);
  margin: 0 auto 6px auto;
  box-sizing: border-box;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

/* One compact line instead of two display-size h2s: the old header put the
   quiz title and the student's name at heading scale, which on a phone spent
   ~40% of the viewport before the first question. The paper's chrome must
   never compete with the paper. */
.quiz-header-line {
  /* Title hugs the left, the student's name and roll the right — two facts,
     two corners, nothing competing with the paper between them. */
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;          /* a long name drops to its own line on phones */
  gap: 2px 12px;
  margin: 0 0 6px;
  font-family: var(--font-display);
  /* Readable from across a lab — an invigilator checks WHO is on a machine
     from a few desks away. One line still, just a louder one. */
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--ink-dim);
  text-align: left;
}
.quiz-header-line .quiz-header-student { margin-left: auto; color: var(--ink); }
.quiz-header-line .quiz-header-roll { margin-left: 8px; color: var(--ink); }

/* Centred kicker over the number grid. Costs one short row; paid for by the
   tighter timer/strip margins below so the paper stays above the fold. */
.quiz-grid-caption {
  margin: 1px 0 2px;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-dim);
  text-align: center;
}

.ui-progress-bar {
  background-color: var(--progress-bar-bg);
  border-radius: var(--border-radius-small);
  height: var(--progress-bar-height);
  position: relative;
  overflow: hidden;
}
.ui-progress-bar .ui-progress {
  background-color: var(--progress-fill-default);
  height: 100%;
  display: block;
  border-radius: var(--border-radius-small);
  transition: width 0.3s ease-in-out, background-color 0.3s ease-in-out;
  text-align: right;
  line-height: var(--progress-bar-height);
}
.ui-progress-bar.blue .ui-progress { background-color: var(--progress-fill-blue); }
.ui-progress-bar.error .ui-progress { background-color: var(--progress-fill-error); }
.ui-progress-bar.warning .ui-progress { background-color: var(--progress-fill-warning); }
.ui-progress-bar.success .ui-progress { background-color: var(--progress-fill-default); }
.ui-progress-bar .ui-progress span.ui-label {
  font-size: 10px;
  position: absolute;
  right: 0;
  line-height: var(--progress-bar-height);
  padding-right: 8px;
  color: var(--progress-label-color);
  white-space: nowrap;
}
.ui-progress-bar .ui-progress span.ui-label b { font-weight: bold; }

.pagination table {
  width: 100%;
  table-layout: fixed;     /* all 10 columns share the width equally -> always fit */
  background: transparent;
  border: none;
  border-radius: 0;
  margin: 0;
  border-spacing: 4px;
  overflow: visible;       /* override base card-table clip that cut the first row's top border */
}
.pagination td {
  border: none;            /* box lives on the <a>; table-cell borders clip oddly */
  padding: 0;              /* override the wide default td padding */
  text-align: center;
}
.pagination a {
  display: block;
  padding: 3px 0;
  border: 1px solid var(--pagination-border);
  border-radius: var(--border-radius-small);
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: .95rem;
  text-align: center;
  white-space: nowrap;     /* keep "11"-"20" on a single line */
  overflow-wrap: normal;
}
.pagination a.attempted {
  text-decoration: line-through;
  background-color: var(--pagination-attempted-bg);
  color: var(--ink-dim);
}
.pagination a.active {
  background-color: var(--pagination-active-bg);
  color: #0d1722;
  font-weight: 700;
}
.pagination a:hover:not(.active) {
  background-color: rgba(var(--accent-rgb), 0.12);
  color: var(--gold);
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   Quiz slot window (home.html)
   --------------------------------------------------------------------------
   The slot used to render as one gold string — "07:00 PM 30 Jul 2026" — with
   the date in the same size and colour as the time, so a student read a run of
   digits and had to pick their start time out of it. The time is what they act
   on, so it carries the weight; the date sits under it in body colour, and a
   window that begins and ends on one day (which is every real slot — they are
   30 minutes) states that day ONCE instead of printing it twice.
   -------------------------------------------------------------------------- */
.quiz-slot {
  display: flex;
  flex-wrap: wrap;
  /* Centred, not flex-end: when both ends carry a date the arrow has to sit
     against the times it joins, not down on the date line. */
  align-items: center;
  justify-content: center;
  gap: 6px 26px;
  max-width: 520px;
  margin: 14px auto 4px;
  padding: 16px 18px 14px;
  border: 1px solid var(--border);
  border-radius: var(--border-radius-large);
  background: var(--panel-solid);
}
/* The shared day, on its own line above the two times. Sized up and ruled off:
   it is the second thing a student needs (after "what time"), so it should read
   as a heading for the two times rather than as a caption under them. */
.quiz-slot-day {
  flex-basis: 100%;
  margin: 0 0 10px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--border);
  text-align: center;
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--ink);
}
.quiz-slot-part { text-align: center; }
.quiz-slot-kicker {
  margin: 0;
  text-align: center;
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.quiz-slot-time {
  display: block;
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: 600;
  line-height: 1.15;
  color: var(--gold);
  /* Tabular figures so 7:00 and 11:30 do not shift the layout between them. */
  font-variant-numeric: tabular-nums;
}
/* The date under each time, when the two ends fall on different days. White
   against the gold time and a step down in size: two attributes differ, so
   neither has to shout, and the pair still reads as one fact rather than as one
   long number the way the old single gold string did. */
.quiz-slot-date {
  display: block;
  margin-top: 3px;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--ink);
}
.quiz-slot-arrow {
  color: var(--ink-dim);
  font-size: 1.2rem;
  line-height: 1;
}
@media (max-width: 420px) {
  /* Stacked: the arrow has to point down the page, not across it. */
  .quiz-slot { gap: 2px; }
  .quiz-slot-part { flex-basis: 100%; }
  .quiz-slot-arrow { flex-basis: 100%; text-align: center; padding: 2px 0; transform: rotate(90deg); }
}

/* --------------------------------------------------------------------------
   Result page
   -------------------------------------------------------------------------- */
/* The result page is a stack of three or four headings sitting directly above
   the score table, so the display h2 (renfrew, clamp up to 2.3rem) turned the
   whole top half of the page into a banner and pushed the numbers — the only
   thing the student came for — below the fold on a phone. Before the 2026 theme
   these were plain body-font h2s at the browser default, which is the
   proportion this restores: readable UI font, one step above body text. Same
   reasoning as the h2 override in admin/admin_base.html.
   No colour here on purpose: the gold from the `h1, h2` rule still applies, and
   score_message brings its own .selected / .not_selected colour. */
/* Final score hero (result.html). The .result tables are the breakdown; this
   card is the verdict, and it leads the page because the school flow logs the
   student out ~20 seconds after it renders — whatever the eye lands on first
   is most of what they take away.

   A negative score gets its own treatment because students reliably read
   "-2" as "2": the glyph cannot carry the sign, so the card turns red, wears
   a NEGATIVE SCORE flag, and says it in a sentence (messages.py). */
/* The card wears the TIER's colour (the same bands score_tier() answers, and
   the same hues as the .selected/.second_attempt message spans): bright green
   for selected, gold for second-attempt, red for negative — and deliberately
   NEUTRAL below the second-attempt line, so gold reads as "still in it"
   rather than being the wallpaper every score gets. */
.final-score-card {
  margin: 8px auto 6px;
  padding: 14px 22px 13px;
  max-width: 360px;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: var(--border-radius-large);
  text-align: center;
  animation: final-score-pop .45s ease-out;
}
/* One row, echoing the breakdown tables below: label on the left, number on
   the right. */
.final-score-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
}
.final-score-label {
  margin: 0;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.final-score-value {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 2.7rem;
  line-height: 1.1;
  color: var(--ink);
  text-align: right;
}
.final-score-card.tier-second { border-color: var(--gold); }
.final-score-card.tier-second .final-score-value { color: var(--gold); }
.final-score-card.tier-selected { border-color: #5df076; background: #10251a; }
.final-score-card.tier-selected .final-score-value { color: #5df076; }
.final-score-outof {
  margin-left: 8px;
  font-size: 1.05rem;
  font-weight: 500;
  color: var(--ink-dim);
}
.final-score-card.negative { border-color: #e05252; background: #2b1111; }
.final-score-card.negative .final-score-value { color: #ff6b6b; }
.final-score-flag {
  display: inline-block;
  margin: 7px 0 0;
  padding: 3px 13px;
  border: 1px solid #ff6b6b;
  border-radius: 999px;
  color: #ff6b6b;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.final-score-note {
  margin: 8px 0 0;
  font-size: .9rem;
  line-height: 1.45;
  color: var(--ink);
}
@keyframes final-score-pop {
  from { transform: scale(.93); opacity: .3; }
  to   { transform: scale(1);   opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .final-score-card { animation: none; } }

.result-heading {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.3rem;
  letter-spacing: -0.01em;
  line-height: 1.35;
  margin: 14px 0 10px;
}

table.result {
  width: 100%;
  max-width: 420px;
  text-align: center;
  margin: 15px auto;
}
table.result td { padding: 10px 8px; }
table.result td:nth-child(1) { text-align: left; padding-left: 8%; }
.not_selected { color: #fc8c88; }
.selected { color: #5df076; }
.second_attempt { color: var(--gold-soft); }

/* --------------------------------------------------------------------------
   Notices — organiser-written messages on the student's home/result page.
   The left rule carries the level, so the three variants stay one component.
   -------------------------------------------------------------------------- */
.notices { margin: 0 auto 18px; max-width: 640px; }
.notices-heading {
  margin: 0 0 8px;
  font-size: .82rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-dim);
  text-align: center;
}
.notice {
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-left: 4px solid var(--ink-dim);
  border-radius: var(--border-radius-large);
  padding: 12px 16px;
  margin-bottom: 10px;
  text-align: left;
}
.notice-title { margin: 0 0 4px; font-weight: 600; color: var(--ink); }
.notice-body { margin: 0; color: var(--ink-dim); line-height: 1.5; }
.notice-actions { margin: 10px 0 0; }
/* Its own class, not .link/.smalllink: on the public pages those are the big
   gold call-to-action buttons, and a notice must not out-shout the Start Quiz
   button sitting right under it. */
.notice-link {
  display: inline-block;
  padding: 6px 12px;
  font-size: .88rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--gold);
}
.notice-link:hover { border-color: var(--button-border-hover); background: rgba(var(--accent-rgb), 0.08); }
.notice-important { border-left-color: var(--gold); }
.notice-important .notice-title { color: var(--gold); }
.notice-urgent { border-left-color: var(--text-error); }
.notice-urgent .notice-title { color: var(--text-error); }

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */
@media screen and (max-width: 600px) {
  #wrapper { padding: 0 8px 1px; }
  .content { padding: 18px 16px 14px; border-radius: 14px; }
  #header { padding: 1.1rem 0 0.9rem; }
  .link, input[type=submit], button {
    font-size: 1.02rem;
    min-height: 40px;
    padding: 11px 18px;
  }
  div.question { font-size: 1.15em; padding: 14px; }
  label.answer_radio { font-size: 1.02em; }
}

/* Narrow screens: side-by-side gets cramped, so stack and let the emblem
   run full width as the hero mark, with the wordmark beneath it. */
@media screen and (max-width: 480px) {
  .header-logos { flex-direction: column; gap: 12px; }
  .brand-logo { height: auto; width: 100%; max-width: 380px; }
  .site-logo { height: auto; width: 88%; max-width: 320px; }
}
