/* =========================================================
   TRUE NORTH MATHEMATICS — shared stylesheet
   Design tokens:
     --navy       #0F2A44   primary dark / hero / header
     --navy-deep  #0A1D30   darkest, footer
     --cream      #F7F3EA   page background
     --cream-soft #FBF9F4   card background
     --gold       #C99A3E   accent, CTAs
     --gold-bright#E0B563   hover state
     --ink        #22303F   body text
     --rust       #A23B2E   sparing highlight / required marks
   Type:
     Display: Space Grotesk
     Body:    Literata
     Utility: JetBrains Mono (labels, bearings, stats)
   ========================================================= */

:root {
  --navy: #0F2A44;
  --navy-deep: #0A1D30;
  --cream: #F7F3EA;
  --cream-soft: #FBF9F4;
  --gold: #C99A3E;
  --gold-bright: #E0B563;
  --ink: #22303F;
  --rust: #A23B2E;
  --teal: #0E7C7B;
  --orange: #E8871E;
  --line: rgba(15, 42, 68, 0.14);

  --font-display: 'Space Grotesk', sans-serif;
  --font-body: 'Literata', serif;
  --font-mono: 'JetBrains Mono', monospace;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
}

img { max-width: 100%; display: block; }
a { color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.05;
  margin: 0;
  color: var(--navy);
  letter-spacing: -0.01em;
}

.container {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 28px;
}

.bearing {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold);
  display: block;
  margin-bottom: 14px;
}
.bearing::before { content: "\2014  "; opacity: 0.6; }

a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

.skip-link {
  position: absolute; left: -999px; top: 0;
  background: var(--gold); color: var(--navy-deep);
  padding: 10px 16px; z-index: 999; font-family: var(--font-mono);
}
.skip-link:focus { left: 12px; top: 12px; }

/* ---------- Header ---------- */
header.site {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--navy);
  border-bottom: 1px solid rgba(247,243,234,0.12);
}
.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 28px;
  max-width: 1120px;
  margin: 0 auto;
}
.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
}
.brand img { width: 100px; height: 100px; }
.brand-word {
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--cream);
  letter-spacing: 0.01em;
  line-height: 1.1;
  white-space: nowrap;
}
.brand-word span {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  color: var(--gold);
  font-weight: 400;
  margin-top: 2px;
}
nav.primary { display: flex; align-items: center; gap: 20px; }
nav.primary a, .nav-cta, .region-switcher-toggle, .region-switcher-label, .curriculum-switcher-group { white-space: nowrap; }
nav.primary a {
  color: rgba(247,243,234,0.85);
  text-decoration: none;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 6px 2px;
  border-bottom: 2px solid transparent;
  transition: border-color 0.2s ease, color 0.2s ease;
}
nav.primary a:hover { border-color: var(--gold); color: var(--gold-bright); }
.nav-cta {
  background: var(--gold);
  color: var(--navy-deep) !important;
  padding: 10px 18px !important;
  border-radius: 2px;
  border-bottom: none !important;
}
.nav-cta:hover { background: var(--gold-bright) !important; }
.nav-toggle {
  display: none;
  background: none;
  border: 1px solid rgba(247,243,234,0.5);
  color: var(--cream);
  font-family: var(--font-mono);
  padding: 8px 12px;
}

/* ---------- Country flag + curriculum switcher (quiet, persistent header controls) ---------- */
.curriculum-switcher-group {
  display: flex;
  align-items: center;
  gap: 8px;
}
.country-flag {
  display: inline-flex;
  align-items: center;
}
.country-flag svg {
  /* All sourced flags share a 4:3 viewBox (640x480) with no
     width/height attribute of their own, so without this they'd
     render at that intrinsic size -- constrain explicitly. */
  width: 22px;
  height: 16.5px;
  border-radius: 2px;
  /* A thin border anchors flags with large white/light areas (GB,
     US) against the navy header, which they'd otherwise bleed into
     at this small a size. */
  outline: 1px solid rgba(247,243,234,0.25);
  outline-offset: 0;
}
.region-switcher { position: relative; }
.region-switcher-label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: rgba(247,243,234,0.5);
}
.region-switcher-toggle {
  background: none;
  border: none;
  color: rgba(247,243,234,0.65);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  padding: 6px 2px;
  display: flex;
  align-items: center;
  gap: 4px;
}
.region-switcher-toggle:hover { color: var(--gold-bright); }
.region-switcher-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--navy);
  border: 1px solid rgba(247,243,234,0.15);
  min-width: 160px;
  z-index: 50;
  box-shadow: 0 12px 30px rgba(0,0,0,0.35);
}
.region-switcher-option {
  display: block;
  padding: 10px 14px;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: rgba(247,243,234,0.85);
  text-decoration: none;
  border-bottom: 1px solid rgba(247,243,234,0.08);
  text-transform: none;
  letter-spacing: normal;
}
.region-switcher-option:last-child { border-bottom: none; }
.region-switcher-option:hover { background: rgba(247,243,234,0.06); color: var(--gold-bright); }
.region-switcher-option.is-current { color: var(--gold); }
@media (max-width: 1100px) {
  /* The padding/width that used to sit directly on .region-switcher
     now sits on its wrapper, so the flag shares the same full-width
     row and left-aligned padding as every other mobile menu item,
     instead of the flag sitting outside that padded area. */
  .curriculum-switcher-group { padding: 14px 28px; width: 100%; }
  .region-switcher-menu { position: static; box-shadow: none; margin-top: 8px; }
}
@media (max-width: 1100px) {
  nav.primary {
    display: none;
    position: absolute;
    top: 100%; left: 0; right: 0;
    background: var(--navy);
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    border-bottom: 1px solid rgba(247,243,234,0.12);
  }
  nav.primary.open { display: flex; }
  nav.primary a { padding: 14px 28px; width: 100%; border-bottom: 1px solid rgba(247,243,234,0.08); }
  .nav-cta { margin: 14px 28px; width: calc(100% - 56px); text-align: center; }
  .nav-toggle { display: block; }
}

/* ---------- Hero ---------- */
.hero {
  background: var(--navy);
  color: var(--cream);
  position: relative;
  overflow: hidden;
  border-bottom: 4px solid var(--gold);
}
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(247,243,234,0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(247,243,234,0.05) 1px, transparent 1px);
  background-size: 42px 42px;
  pointer-events: none;
}
.hero-inner {
  position: relative;
  max-width: 1120px;
  margin: 0 auto;
  padding: 90px 28px 96px;
  display: grid;
  grid-template-columns: 1.2fr 0.8fr;
  gap: 48px;
  align-items: center;
}
.hero h1 {
  font-size: clamp(2.6rem, 5.5vw, 4rem);
  color: var(--cream);
}
.hero h1 em {
  font-style: normal;
  color: var(--gold-bright);
}
.hero-desc {
  margin-top: 22px;
  max-width: 48ch;
  color: rgba(247,243,234,0.85);
  font-size: 1.08rem;
}
.hero-actions { margin-top: 32px; display: flex; gap: 16px; flex-wrap: wrap; }

/* The hidden attribute must beat any display rule.
   A class like .btn sets display:inline-block, which silently overrides
   the browser's built-in [hidden] { display: none } and leaves elements
   marked hidden fully visible -- the Assign button in both portals was
   showing before a year level had been chosen because of this. */
[hidden] { display: none !important; }

.btn {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 14px 26px;
  border: 2px solid transparent;
  display: inline-block;
  border-radius: 2px;
  cursor: pointer;
  transition: transform 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.btn:hover { transform: translateY(-2px); }
.btn-solid { background: var(--gold); color: var(--navy-deep); }
.btn-solid:hover { background: var(--gold-bright); }
.btn-outline { border-color: rgba(247,243,234,0.5); color: var(--cream); }
.btn-outline:hover { border-color: var(--gold); color: var(--gold-bright); }
.btn-navy { background: var(--navy); color: var(--cream); }
.btn-navy:hover { background: var(--navy-deep); }

/* Hero illustration */
.compass-wrap { display: flex; align-items: center; justify-content: center; }
.hero-illustration {
  width: 100%;
  max-width: 420px;
}
@media (max-width: 820px) {
  .hero-inner { grid-template-columns: 1fr; text-align: left; }
  .compass-wrap { order: -1; }
  .hero-illustration { max-width: 280px; margin: 0 0 8px; }
}

/* ---------- Sections ---------- */
section { padding: 88px 0; }
.section-head { max-width: 62ch; margin-bottom: 46px; }
.section-head h2 { font-size: clamp(2rem, 4.5vw, 2.7rem); }
.section-dark { background: var(--navy); color: var(--cream); }
.section-dark h2 { color: var(--cream); }
.section-dark .bearing { color: var(--gold-bright); }

/* ---------- Pathway cards (year levels) ---------- */
.pathways {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 22px;
}
.pathway-card {
  background: var(--cream-soft);
  border: 1px solid var(--line);
  padding: 30px 26px;
  position: relative;
}
.pathway-card .level {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold);
  display: block;
  margin-bottom: 10px;
}
.pathway-card h3 { font-size: 1.35rem; margin-bottom: 10px; }
.pathway-card p { margin: 0; font-size: 0.98rem; color: var(--ink); opacity: 0.85; }

/* ---------- Method / pillars ---------- */
.pillars {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 34px;
}
.pillar .num {
  font-family: var(--font-mono);
  color: var(--gold-bright);
  font-size: 0.85rem;
  letter-spacing: 0.1em;
  display: block;
  margin-bottom: 10px;
}
.pillar h3 { font-size: 1.25rem; color: var(--cream); margin-bottom: 8px; }
.pillar p { color: rgba(247,243,234,0.78); margin: 0; font-size: 0.96rem; }

/* ---------- Audience benefits (For Students / Parents / Teachers) ---------- */
.audience-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 34px;
}
.audience-photo {
  /* Same 3:2 source photos and same 300x200 display size used in
     the testimonials section on the Institute page, for visual
     consistency between the two. */
  width: 300px;
  max-width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: center 22%;
  display: block;
  margin: 0 auto 18px;
  border-radius: 10px;
  border: 2px solid var(--gold);
  box-shadow: 0 8px 20px rgba(0,0,0,0.28);
}
.audience-card h3 {
  font-size: 1.15rem;
  color: var(--gold-bright);
  margin: 0 0 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(247,243,234,0.15);
}
.audience-list { list-style: none; margin: 0; padding: 0; }
.audience-list li {
  position: relative;
  padding-left: 22px;
  margin-bottom: 13px;
  color: rgba(247,243,234,0.85);
  font-size: 0.94rem;
  line-height: 1.5;
}
.audience-list li:last-child { margin-bottom: 0; }
.audience-list li::before {
  content: "—";
  position: absolute;
  left: 0;
  color: var(--gold);
}

/* ---------- Access & control (Student / Parent / Teacher access levels) ---------- */
.access-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 26px;
}
.access-card {
  background: rgba(247,243,234,0.05);
  border: 1px solid rgba(247,243,234,0.14);
  border-radius: 4px;
  padding: 28px 26px;
}
.access-role {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold-bright);
  display: block;
  margin-bottom: 12px;
}
.access-card h3 {
  font-size: 1.2rem;
  color: var(--cream);
  margin: 0 0 16px;
  padding-bottom: 14px;
  border-bottom: 1px solid rgba(247,243,234,0.15);
}
.access-list { list-style: none; margin: 0; padding: 0; }
.access-list li {
  position: relative;
  padding-left: 24px;
  margin-bottom: 13px;
  color: rgba(247,243,234,0.85);
  font-size: 0.94rem;
  line-height: 1.5;
}
.access-list li:last-child { margin-bottom: 0; }
.access-list li::before {
  content: "\2713";
  position: absolute;
  left: 0;
  color: var(--gold);
  font-weight: 700;
}

/* ---------- Tutorial video ---------- */
.video-wrap {
  max-width: 900px;
  margin: 0 auto;
}
.video-wrap video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 6px;
  box-shadow: 0 20px 44px rgba(15,42,68,0.18);
  border: 1px solid var(--line);
  background: var(--navy-deep);
}

/* ---------- Stats ---------- */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 30px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 36px 0;
}
.stat .figure {
  font-family: var(--font-mono);
  font-size: 2.2rem;
  color: var(--navy);
  font-weight: 700;
}
.stat .label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--rust);
  margin-top: 6px;
  display: block;
}

/* ---------- Testimonials ---------- */
.testimonials {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 26px;
  /* Top-align: as more testimonials are added under one photo that
     card grows, and without this the short cards would stretch to
     match it, leaving large empty gaps under their text. */
  align-items: start;
}
.testimonial {
  background: var(--cream-soft);
  border: 1px solid var(--line);
  border-top: 3px solid var(--gold);
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.testimonial-photo {
  /* Fixed display size (300x200, 3:2) rather than filling the card
     width -- capped with max-width so it still shrinks rather than
     overflowing on narrow screens. */
  width: 300px;
  max-width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: center;
  display: block;
  margin: 26px auto 0;
}
.testimonial figcaption { padding: 24px 26px 26px; }
.testimonial-heading {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--navy);
  margin: 0 0 18px;
  padding-bottom: 12px;
  border-bottom: 2px solid var(--gold);
}
.testimonial-scroll {
  /* Caps each card's height so one long testimonial (or a growing
     list of them) can't stretch the card indefinitely. The scrollbar
     only appears when the content actually exceeds this. */
  max-height: 320px;
  overflow-y: auto;
  /* Room so text never sits under the scrollbar */
  padding-right: 10px;
  scrollbar-width: thin;
  scrollbar-color: var(--gold) transparent;
}
/* WebKit/Blink equivalents of the two scrollbar-* properties above. */
.testimonial-scroll::-webkit-scrollbar { width: 8px; }
.testimonial-scroll::-webkit-scrollbar-track { background: transparent; }
.testimonial-scroll::-webkit-scrollbar-thumb {
  background: var(--gold);
  border-radius: 4px;
}
.testimonial-entry + .testimonial-entry {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}
.testimonial p.quote { margin: 0 0 16px; font-size: 1.02rem; font-style: italic; }
.testimonial .who {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  color: var(--navy);
  opacity: 0.75;
}

/* ---------- CTA banner ---------- */
.cta-banner {
  background: var(--gold);
  color: var(--navy-deep);
  text-align: left;
}
.cta-banner-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}
.cta-banner h2 { color: var(--navy-deep); font-size: clamp(1.8rem, 4vw, 2.4rem); }
.cta-banner p { margin: 8px 0 0; max-width: 50ch; }

/* ---------- Footer ---------- */
footer.site {
  background: var(--navy-deep);
  color: rgba(247,243,234,0.7);
  padding: 48px 0 30px;
  font-family: var(--font-mono);
  font-size: 0.82rem;
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 30px;
  padding-bottom: 30px;
  border-bottom: 1px solid rgba(247,243,234,0.12);
}
.footer-brand { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.footer-brand img { width: 64px; height: 64px; }
.footer-brand span { font-family: var(--font-display); color: var(--cream); font-size: 1.05rem; }
footer.site h4 {
  color: var(--gold-bright);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: 14px;
}
footer.site ul { list-style: none; margin: 0; padding: 0; }
footer.site li { margin-bottom: 8px; }
footer.site a { text-decoration: none; }
footer.site a:hover { color: var(--gold-bright); }
.footer-bottom { padding-top: 22px; opacity: 0.6; font-size: 0.75rem; }

@media (max-width: 760px) {
  .footer-grid { grid-template-columns: 1fr; }
}

/* ---------- Enquiry page ---------- */
.page-hero {
  background: var(--navy);
  color: var(--cream);
  padding: 64px 0 56px;
  border-bottom: 4px solid var(--gold);
}
.page-hero h1 { color: var(--cream); font-size: clamp(2.2rem, 5vw, 3rem); }
.page-hero p { color: rgba(247,243,234,0.8); max-width: 56ch; margin-top: 14px; }

.enquiry-grid {
  display: grid;
  grid-template-columns: 1fr 1.3fr;
  gap: 50px;
  align-items: start;
}
.enquiry-info h3 { font-size: 1.2rem; margin-bottom: 12px; }
.enquiry-info p { font-size: 0.98rem; color: var(--ink); opacity: 0.85; }
.enquiry-list { list-style: none; padding: 0; margin: 22px 0 0; font-family: var(--font-mono); font-size: 0.88rem; }
.enquiry-list li { padding: 10px 0; border-bottom: 1px solid var(--line); }
.enquiry-list a { text-decoration: none; }
.enquiry-list a:hover { color: var(--rust); }

form.enquiry-form {
  background: var(--cream-soft);
  border: 1px solid var(--line);
  padding: 34px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
/* minmax(0, 1fr) rather than plain 1fr: grid columns default to
   min-width:auto, which lets a wide control (e.g. a select sized to a
   long option label) push its column past its share and overflow the
   container. minmax(0, ...) lets the column shrink as intended. */
.form-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px; }
form.enquiry-form label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--navy);
  margin-bottom: 6px;
  display: block;
}
form.enquiry-form label .req { color: var(--rust); }
form.enquiry-form input,
form.enquiry-form select,
form.enquiry-form textarea {
  font-family: var(--font-body);
  font-size: 1rem;
  padding: 12px 14px;
  background: var(--cream);
  border: 1px solid var(--line);
  color: var(--ink);
  width: 100%;
}
form.enquiry-form textarea { resize: vertical; min-height: 120px; }
form.enquiry-form button {
  align-self: flex-start;
  background: var(--gold);
  color: var(--navy-deep);
  border: none;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.85rem;
  padding: 15px 30px;
  cursor: pointer;
  border-radius: 2px;
  transition: background 0.15s ease, transform 0.15s ease;
}
form.enquiry-form button:hover { background: var(--gold-bright); transform: translateY(-2px); }
#formStatus { font-family: var(--font-mono); font-size: 0.85rem; }

@media (max-width: 820px) {
  .enquiry-grid { grid-template-columns: 1fr; }
  .form-row { grid-template-columns: 1fr; }
}

/* ---------- Auth pages (signup / login / password reset) ---------- */
.auth-shell {
  min-height: calc(100vh - 68px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
}
.auth-card {
  width: 100%;
  max-width: 440px;
  background: var(--cream-soft);
  border: 1px solid var(--line);
  padding: 40px 36px;
}
.auth-card h1 {
  font-size: 1.7rem;
  margin-bottom: 8px;
}
.auth-card .auth-sub {
  font-size: 0.95rem;
  color: var(--ink);
  opacity: 0.75;
  margin-bottom: 26px;
}
.auth-role-toggle {
  display: flex;
  border: 1px solid var(--line);
  margin-bottom: 22px;
}
.auth-role-toggle button {
  flex: 1;
  padding: 11px;
  background: none;
  border: none;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  color: var(--navy);
  opacity: 0.55;
  transition: background 0.15s ease, opacity 0.15s ease;
}
.auth-role-toggle button.active {
  background: var(--navy);
  color: var(--cream);
  opacity: 1;
}
form.auth-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
form.auth-form label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--navy);
  margin-bottom: 6px;
  display: block;
}
form.auth-form input,
form.auth-form select {
  font-family: var(--font-body);
  font-size: 1rem;
  padding: 12px 14px;
  background: var(--cream);
  border: 1px solid var(--line);
  color: var(--ink);
  width: 100%;
  /* Without border-box the 14px horizontal padding is added ON TOP of
     the 100% width, pushing the control past its container. And
     without max-width a <select> still grows to fit its widest
     option -- some curriculum names are very long -- so both are
     needed for these to line up with the text inputs. */
  box-sizing: border-box;
  max-width: 100%;
}
form.auth-form button {
  margin-top: 4px;
  background: var(--gold);
  color: var(--navy-deep);
  border: none;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.85rem;
  padding: 14px 20px;
  cursor: pointer;
  border-radius: 2px;
  transition: background 0.15s ease, transform 0.15s ease;
}
form.auth-form button:hover { background: var(--gold-bright); transform: translateY(-2px); }
form.auth-form button:disabled { opacity: 0.6; cursor: not-allowed; transform: none; }
.auth-links {
  margin-top: 20px;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
}
.auth-links a { color: var(--rust); text-decoration: none; }
.auth-links a:hover { text-decoration: underline; }
#authMessage {
  font-family: var(--font-mono);
  font-size: 0.84rem;
  display: none;
  margin-top: 4px;
  line-height: 1.5;
}

/* ---------- Portal pages ---------- */
.portal-header {
  background: var(--navy);
  color: var(--cream);
  padding: 22px 0;
  border-bottom: 4px solid var(--gold);
}
.portal-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}
.portal-welcome { font-family: var(--font-mono); font-size: 0.85rem; color: rgba(247,243,234,0.85); }
.portal-welcome strong { color: var(--gold-bright); }
.btn-logout {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: none;
  border: 1px solid rgba(247,243,234,0.5);
  color: var(--cream);
  padding: 9px 16px;
  cursor: pointer;
  border-radius: 2px;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.btn-logout:hover { border-color: var(--gold); color: var(--gold-bright); }

.portal-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 22px;
}
.portal-card {
  background: var(--cream-soft);
  border: 1px solid var(--line);
  padding: 26px;
}
.portal-card h3 { font-size: 1.15rem; margin-bottom: 10px; }
.portal-card p { font-size: 0.95rem; opacity: 0.8; margin: 0; }
.portal-card .placeholder-note {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--rust);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  display: block;
  margin-top: 10px;
}

/* ---------- AI Practice Test ---------- */
.quiz-shell { max-width: 760px; margin: 0 auto; }
.quiz-setup-card {
  background: var(--cream-soft);
  border: 1px solid var(--line);
  padding: 34px;
}
.quiz-setup-card .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-bottom: 20px; }
.quiz-setup-card .form-row-full { margin-bottom: 20px; }
.quiz-setup-card label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--navy);
  margin-bottom: 6px;
  display: block;
}
.quiz-setup-card select {
  font-family: var(--font-body);
  font-size: 1rem;
  padding: 12px 14px;
  background: var(--cream);
  border: 1px solid var(--line);
  color: var(--ink);
  width: 100%;
}
.quiz-loading {
  text-align: center;
  padding: 60px 20px;
  font-family: var(--font-mono);
  color: var(--navy);
}
.quiz-spinner {
  width: 34px; height: 34px;
  border: 3px solid var(--line);
  border-top-color: var(--gold);
  border-radius: 50%;
  margin: 0 auto 18px;
  animation: quiz-spin 0.8s linear infinite;
}
@keyframes quiz-spin { to { transform: rotate(360deg); } }

.quiz-progress {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--gold);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 18px;
}
.quiz-question-card {
  background: var(--cream-soft);
  border: 1px solid var(--line);
  padding: 26px;
  margin-bottom: 18px;
}
.quiz-question-card .qnum {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--gold);
  display: block;
  margin-bottom: 8px;
}
.quiz-question-card .qtext { font-size: 1.05rem; margin-bottom: 16px; color: var(--ink); }
.quiz-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  margin-bottom: 8px;
  cursor: pointer;
  font-size: 0.95rem;
}
.quiz-option:hover { border-color: var(--gold); }
.quiz-option input { accent-color: var(--gold); }
.quiz-short-input {
  font-family: var(--font-body);
  font-size: 1rem;
  padding: 12px 14px;
  background: var(--cream);
  border: 1px solid var(--line);
  width: 100%;
  max-width: 320px;
}

.quiz-report-summary {
  text-align: center;
  padding: 34px;
  background: var(--navy);
  color: var(--cream);
  margin-bottom: 26px;
}
.quiz-report-summary .score {
  font-family: var(--font-display);
  font-size: 3rem;
  font-weight: 700;
  color: var(--gold-bright);
}
.quiz-report-summary .label {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(247,243,234,0.75);
  margin-top: 6px;
}
.quiz-report-item {
  border: 1px solid var(--line);
  border-left: 4px solid var(--rust);
  padding: 20px 22px;
  margin-bottom: 14px;
  background: var(--cream-soft);
}
.quiz-report-item.correct { border-left-color: #3C7A4E; }
.quiz-report-item .result-tag {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--rust);
}
.quiz-report-item.correct .result-tag { color: #3C7A4E; }
.quiz-report-item .qtext { margin: 8px 0 10px; font-size: 1rem; }
.quiz-report-item .answer-line { font-family: var(--font-mono); font-size: 0.85rem; margin: 4px 0; }
.quiz-report-item .answer-line.wrong { color: var(--rust); }
.quiz-report-item .answer-line.right { color: #3C7A4E; }
.quiz-report-item .feedback-line { font-size: 0.9rem; opacity: 0.8; margin-top: 8px; font-style: italic; }

/* ---------- Manage Users (teacher admin panel) ---------- */
.manage-table-wrap {
  overflow-x: auto;
  background: var(--cream-soft);
  border: 1px solid var(--line);
}
table.manage-table { width: 100%; border-collapse: collapse; font-family: var(--font-body); font-size: 0.92rem; }
/* The Students table carries more columns than Parents/Teachers/Links
   (Year Level, Subjects, Status all in addition to Name/Email/Login/
   Actions) -- at width:100% alone, a narrow browser window forces the
   browser's table layout to squeeze every column to fit, truncating
   button text in Actions rather than wrapping or scrolling for it.
   A minimum width means it overflows horizontally instead, using the
   existing .manage-table-wrap { overflow-x: auto } to scroll rather
   than squeeze -- scoped to just this table since the other three
   have few enough columns that forcing the same width would just add
   empty space. */
table.manage-table#studentsTable { min-width: 1000px; }
table.manage-table th {
  text-align: left;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--navy);
  padding: 14px 16px;
  border-bottom: 2px solid var(--line);
  white-space: nowrap;
}
table.manage-table td { padding: 14px 16px; border-bottom: 1px solid var(--line); vertical-align: middle; }
table.manage-table tr:last-child td { border-bottom: none; }

/* Portal list tables (student/parent/teacher lists, assignment
   lists) grow without bound as the user base grows -- capped to
   exactly 10 visible rows with the rest reachable by scrolling,
   rather than the page itself growing to fit however many records
   exist. 583px = the real, measured height of a thead (47.5px) plus
   10 tbody rows (53.3px each) at this table's actual font/padding,
   PLUS 2px for this element's own top+bottom border -- box-sizing is
   border-box sitewide, so max-height constrains the border-box, and
   without adding the border back the budget is silently 2px short of
   the true target. Easy to miss: it only shows up as a visibly cut-
   off 10th row on a table whose row-height arithmetic lands within a
   couple of pixels of the cap, which is exactly how this was found
   (parent-portal.html's linked-students table, otherwise identical to
   the table this was first calibrated against). Not a guessed round
   number either way -- an estimate here would show 9 or 11 rows
   instead of exactly 10.
   This is the base calibration for a simple, single-line-per-row
   table; #studentsTableWrap below overrides it with its own
   measurement, since that table's rows are genuinely taller.
   A NEW class, not an extension of .manage-table-wrap above: this
   page's four tables all now use this class instead (including the
   Students table, previously .manage-table-wrap -- see the
   overflow-x comment just below for why both scroll axes had to
   move onto one shared class rather than staying split across two
   nested ones). .manage-table-wrap itself is left in place since
   other pages in this codebase may still reference it. */
.portal-table-scroll {
  max-height: 583px;
  overflow-y: auto;
  /* Horizontal scroll lives on this SAME element, not a nested wrapper
     inside it. A table wide enough to overflow narrow screens still
     needs to scroll sideways -- but per the CSS overflow spec, an
     inner div with overflow-x set (and overflow-y left at its default
     "visible") has its overflow-y silently forced to "auto" too,
     making it a second, separate vertical scroll container. That
     breaks position:sticky's header, since sticky only holds relative
     to its NEAREST scrolling ancestor -- which becomes that inner
     div, which never itself scrolls, rather than this outer element,
     which does. One element handling both axes avoids the conflict
     entirely. */
  overflow-x: auto;
  border: 1px solid var(--line);
}
/* manage-users.html's Students table specifically: its Actions
   column stacks 3 buttons vertically (#studentsTable .manage-actions
   below sets flex-direction:column, unlike every other table's
   actions cell, which lays buttons out side by side) -- that stack
   is taller than a single line of text/controls regardless of a
   given student's other data, making every row a measured 132px
   tall rather than the 53.3px the base .portal-table-scroll above
   is calibrated for. 1370px = 47.5px header + 10 * 132px rows + 2px
   border (see the base rule's comment for why the border has to be
   added back under border-box sizing), measured the same way,
   against this table's own real row height, not the shared one. */
#studentsTableWrap.portal-table-scroll {
  max-height: 1370px;
}
/* manage-users.html's Teachers, Parents, and Links tables: their
   Status column uses a native <select> dropdown for account status
   (admin-editable, unlike the other portal files' read-only status
   badge), which renders a few pixels taller than plain text or a
   badge span -- a measured 58.5px row rather than the base
   calibration's 53.3px. At the shared cap this showed 9 full rows
   plus a cut-off 10th, not exactly 10. 635px = 47.5px header + 10 *
   58.5px rows + 2px border (same border-box correction as the base
   rule), measured directly against these three tables' real rendered
   rows and verified to show exactly 10 full rows, not the shared
   value carried over on the assumption it would still fit. */
#teachersTableWrap.portal-table-scroll,
#parentsTableWrap.portal-table-scroll,
#linksTableWrap.portal-table-scroll {
  max-height: 635px;
}
/* The header must stay visible while rows scroll underneath it --
   otherwise column meaning is lost a few rows in. Needs its own
   background (matching the surrounding page, not transparent) since a
   sticky element still has scrolling content passing behind it. */
.portal-table-scroll table.manage-table thead th {
  position: sticky;
  top: 0;
  background: var(--cream-soft);
  z-index: 1;
}

/* Same 10-visible-then-scroll treatment for results.html's list,
   which uses .quiz-report-item card rows rather than a table -- no
   column header, so no sticky-header piece needed here, just the
   height cap. 1209px = 9 full card-plus-margin units (122px each,
   measured) plus the height of the 10th card alone (108px, no
   trailing margin needed since nothing has to be visible below it)
   plus 2px for this element's own border (see .portal-table-scroll's
   comment for the border-box reasoning) -- again measured against
   the real rendered card, not estimated. */
.results-list-scroll {
  max-height: 1209px;
  overflow-y: auto;
  border: 1px solid var(--line);
}
.role-badge {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--gold);
}
.status-badge {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  padding: 4px 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.status-badge.active { background: #EAF4EC; color: #3C7A4E; }
.status-badge.disabled { background: #F7E7E4; color: var(--rust); }
/* Fixed width (not shrink-to-fit like .status-badge) is deliberate --
   it's what makes a column of these actually line up like a table
   column would, in lists that are label+checkbox rows rather than a
   real <table>. Sized for "VIC/NSW", the longest value it ever shows
   (a topic worded identically in both curricula). */
.curriculum-badge {
  display: inline-block;
  width: 52px;
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  padding: 2px 6px;
  text-align: center;
  background: var(--cream-soft);
  border: 1px solid var(--line);
  color: var(--ink);
  opacity: 0.75;
  letter-spacing: 0.02em;
}
.manage-actions { display: flex; gap: 8px; flex-wrap: wrap; }
/* Students table specifically: stacking vertically (rather than the
   default wrap, which can fit 2 buttons on one line and 1 on the
   next depending on exact column width) makes the Actions column's
   footprint just the width of its single widest button, consistently,
   regardless of viewport width -- freeing up the horizontal room the
   wider Subjects checkboxes need instead of competing for it. */
#studentsTable .manage-actions { flex-direction: column; align-items: flex-start; }
.btn-small {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  padding: 7px 12px;
  border: 1px solid var(--line);
  background: var(--cream);
  color: var(--navy);
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.btn-small:hover { border-color: var(--gold); }
.btn-small:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-small.danger { border-color: var(--rust); color: var(--rust); }
.btn-small.danger:hover { background: var(--rust); color: #fff; }
.manage-empty {
  padding: 40px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.9rem;
  color: var(--ink);
  opacity: 0.7;
}

/* ---------- Resources / Paywall ---------- */
.resource-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 22px;
}
.resource-card {
  background: var(--cream-soft);
  border: 1px solid var(--line);
  padding: 26px;
  display: flex;
  flex-direction: column;
}
.resource-card .type-badge {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gold);
  margin-bottom: 10px;
}
.resource-card h3 { font-size: 1.15rem; margin-bottom: 8px; }
.resource-card p { font-size: 0.92rem; opacity: 0.8; margin: 0 0 18px; flex-grow: 1; }
.resource-card .btn { align-self: flex-start; }

.paywall-banner {
  background: var(--navy);
  color: var(--cream);
  padding: 30px 34px;
  margin-bottom: 40px;
}
.paywall-banner h3 { color: var(--cream); font-size: 1.3rem; margin-bottom: 10px; }
.paywall-banner p { color: rgba(247,243,234,0.8); margin: 0 0 20px; max-width: 60ch; }
.plan-options { display: flex; gap: 16px; flex-wrap: wrap; }
.plan-card {
  background: rgba(247,243,234,0.06);
  border: 1px solid rgba(247,243,234,0.2);
  padding: 18px 22px;
  min-width: 220px;
}
.plan-card .price { font-family: var(--font-display); font-size: 1.6rem; color: var(--gold-bright); }
.plan-card .desc { font-size: 0.85rem; opacity: 0.75; margin: 6px 0 14px; }

.access-badge {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 6px 12px;
  background: #EAF4EC;
  color: #3C7A4E;
  margin-bottom: 20px;
}

/* ---------- Resources / Paywall ---------- */
.resource-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 22px;
}
.resource-card {
  background: var(--cream-soft);
  border: 1px solid var(--line);
  padding: 26px;
  display: flex;
  flex-direction: column;
}
.resource-card .type-badge {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gold);
  margin-bottom: 10px;
}
.resource-card h3 { font-size: 1.15rem; margin-bottom: 8px; }
.resource-card p { font-size: 0.92rem; opacity: 0.8; margin: 0 0 18px; flex-grow: 1; }
.resource-card .btn { align-self: flex-start; }

.paywall-banner {
  background: var(--navy);
  color: var(--cream);
  padding: 30px 34px;
  margin-bottom: 40px;
}
.paywall-banner h3 { color: var(--cream); font-size: 1.3rem; margin-bottom: 10px; }
.paywall-banner p { color: rgba(247,243,234,0.8); margin: 0 0 20px; max-width: 60ch; }
.plan-options { display: flex; gap: 16px; flex-wrap: wrap; }
.plan-card {
  background: rgba(247,243,234,0.06);
  border: 1px solid rgba(247,243,234,0.2);
  padding: 18px 22px;
  min-width: 220px;
}
.plan-card .price { font-family: var(--font-display); font-size: 1.6rem; color: var(--gold-bright); }
.plan-card .desc { font-size: 0.85rem; opacity: 0.75; margin: 6px 0 14px; }

.access-badge {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 6px 12px;
  background: #EAF4EC;
  color: #3C7A4E;
  margin-bottom: 20px;
}

/* ---------- Resource sections (Worksheets / Practice Exams) ---------- */
.resource-section {
  padding: 34px 30px;
  margin-bottom: 40px;
  border: 1px solid var(--line);
}
.worksheets-section {
  background: var(--cream-soft);
}
.exams-section {
  background: var(--navy);
  color: var(--cream);
}
.resource-section-title {
  font-family: var(--font-display);
  font-size: 1.6rem;
  color: var(--navy);
  margin: 0 0 24px;
  padding-bottom: 12px;
  border-bottom: 2px solid var(--gold);
}
.exams-section .resource-section-title {
  color: var(--cream);
}
.resource-subsection-title {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gold-bright);
  margin: 30px 0 4px;
}
.resource-subsection-title:first-of-type { margin-top: 0; }
.resource-subsection-note {
  font-size: 0.88rem;
  color: rgba(247,243,234,0.7);
  margin: 0 0 18px;
}
.year-group-heading {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 22px 0 12px;
}
.exams-section .year-group-heading {
  color: var(--gold-bright);
}
.worksheets-section .resource-grid,
.exams-section .resource-grid {
  margin-bottom: 6px;
}
.exams-section .resource-card {
  background: rgba(247,243,234,0.06);
  border-color: rgba(247,243,234,0.18);
}
.exams-section .resource-card h3 {
  color: var(--cream);
}
.exams-section .resource-card p {
  color: rgba(247,243,234,0.75);
}

/* ---------- Comprehensive test-review options (MCQ) ---------- */
.review-options {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 6px;
}
.review-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--line);
  font-size: 0.92rem;
  background: var(--cream);
}
.review-option .opt-marker {
  width: 16px;
  font-weight: 700;
  text-align: center;
  flex-shrink: 0;
}
.review-option .opt-text { flex: 1; }
.review-option .opt-tag {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.85;
  white-space: nowrap;
}
.review-option.chosen-correct {
  background: #EAF4EC;
  border-color: #3C7A4E;
  color: #2E5F3C;
}
.review-option.chosen-correct .opt-marker { color: #3C7A4E; }
.review-option.chosen-wrong {
  background: #F7E7E4;
  border-color: var(--rust);
  color: var(--rust);
}
.review-option.chosen-wrong .opt-marker { color: var(--rust); }
.review-option.correct-missed {
  background: #EAF4EC;
  border-color: #3C7A4E;
  color: #2E5F3C;
  border-style: dashed;
}
.review-option.correct-missed .opt-marker { color: #3C7A4E; }

/* ---------- Secondary button variant for light backgrounds ---------- */
.btn-outline-navy {
  border: 2px solid var(--navy);
  color: var(--navy);
  background: transparent;
}
.btn-outline-navy:hover {
  background: var(--navy);
  color: var(--cream);
}
.btn-outline-navy:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}
/* Practice Exams (and any other dark-background section) needs a
   light-colored version of this button -- navy-on-navy is invisible,
   same root cause as the earlier card-title contrast fix. */
.exams-section .btn-outline-navy {
  border-color: var(--cream);
  color: var(--cream);
}
.exams-section .btn-outline-navy:hover {
  background: var(--cream);
  color: var(--navy-deep);
}

/* ---------- Manage Accounts: per-account status dropdown ---------- */
.status-select {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  padding: 5px 8px;
  border: 1px solid var(--line);
  background: var(--cream-soft);
  color: var(--ink);
  cursor: pointer;
}
.status-select:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* ---------- Locked year-level selector (students) ---------- */
.quiz-setup-card select:disabled {
  background: var(--line);
  opacity: 0.75;
  cursor: not-allowed;
}

/* ---------- Diagnostic test difficulty tiers (teacher portal) ----------
   Each row: an enable/disable checkbox for that tier, a question-count
   dropdown (0-5), and a short hint. The dropdown greys out (matching
   the locked-select style just above) when its tier's checkbox is
   unchecked, but keeps its chosen value, so re-checking the tier
   restores the teacher's preferred count rather than resetting it. */
.diag-difficulty-row {
  display: flex; align-items: center; gap: 14px;
  margin-bottom: 12px;
}
.diag-difficulty-check {
  display: flex; align-items: center; gap: 8px;
  font-weight: 600; min-width: 130px;
}
.diag-difficulty-check input[type="checkbox"] { width: auto; }
.diag-tier-count {
  width: auto; min-width: 70px; padding: 8px 10px !important;
}
.diag-tier-count:disabled {
  background: var(--line);
  opacity: 0.6;
  cursor: not-allowed;
}
.diag-tier-hint {
  font-family: var(--font-mono); font-size: 0.72rem; opacity: 0.65;
}

/* ---------- mathtext (shared) ----------
   Used by take-test, vce-exam, and results via js/mathtext.js, which
   renders the AI's plain-text maths (x^2, a_n, sqrt(...)) as real
   superscripts/subscripts (native <sup>/<sub>, no CSS needed) and a
   real radical -- this is the CSS for that last part. A radical glyph
   next to a plain span would just look like "√16" in a row; the
   vinculum (the horizontal bar over the radicand) is what actually
   makes it read as a root rather than the letter-like glyph sitting
   beside a number. Nesting (sqrt(sqrt(16))) works automatically,
   since each .mathtext-sqrt independently draws its own bar over its
   own contents, whatever those are. */
.mathtext-sqrt {
  display: inline-flex;
  align-items: flex-start;
  white-space: nowrap;
}
.mathtext-radical {
  position: relative;
  top: 0.05em;
  margin-right: 1px;
}
.mathtext-radicand {
  border-top: 1.3px solid currentColor;
  padding: 0 2px;
}

/* ---------- special character palette (shared) ----------
   Used by ask-teacher, take-test and vce-exam. Lived only in
   ask-teacher.html originally; moved here so all three pages get the
   same appearance from one place. */
.char-picker {
  display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; margin-bottom: 8px;
}
.char-picker button {
  font-family: var(--font-mono); font-size: 0.95rem; min-width: 34px; height: 34px;
  border: 1px solid var(--line); background: var(--cream); color: var(--navy-deep);
  border-radius: 4px; cursor: pointer; transition: background 0.15s, border-color 0.15s;
}
.char-picker button:hover { background: #FBF3DE; border-color: var(--gold); }

/* ---------- idle examiner avatar (practice tests / VCE exams) ----------
   A calmer, static counterpart to the Teach Me tutor: gentle bob, no
   talking frame, and pointer-events:none so it can never intercept a
   click on the answer box or an option beneath it. Hidden on small
   screens, where it would crowd the question.

   Width is 120px rather than the Teach Me avatar's 150px because this
   artwork is a portrait crop: at 150px it would stand ~235px tall and
   loom over the question area. 120px lands it at ~188px, closer to the
   visual weight of the landscape tutor image. Only take-test.html and
   vce-exam.html use this rule -- Teach Me has its own #tutorAvatarWrap. */
#idleAvatarWrap {
  position: fixed; bottom: 18px; right: 18px; z-index: 20;
  width: 120px; pointer-events: none; user-select: none;
  filter: drop-shadow(0 6px 14px rgba(15,42,68,0.25));
  animation: idle-avatar-bob 3.2s ease-in-out infinite;
}

/* Two frames share the wrap: the examiner waits while the student works,
   then holds up the certificate once the paper has been handed in. Only
   one is in the layout at a time, so the wrap simply takes the height of
   whichever is showing -- the two artworks are different heights and
   both are pinned to the bottom of the viewport, which keeps the feet in
   the same place either way. */
#idleAvatarWrap img { display: block; width: 100%; height: auto; }
#idleAvatarWrap .result-frame,
#idleAvatarWrap .sad-frame { display: none; }
#idleAvatarWrap.is-complete .idle-frame { display: none; }
/* Which "handed in" expression shows depends on the score, decided once
   grading returns -- see setExaminerComplete(). Below 50% shows the sad
   frame instead of the default celebratory one. */
#idleAvatarWrap.is-complete:not(.is-low-score) .result-frame { display: block; }
#idleAvatarWrap.is-complete.is-low-score .sad-frame { display: block; }
#idleAvatarWrap img { width: 100%; height: auto; display: block; }
@keyframes idle-avatar-bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}
@media (max-width: 900px) { #idleAvatarWrap { display: none; } }
@media (prefers-reduced-motion: reduce) { #idleAvatarWrap { animation: none; } }

/* ---------- optional test timer (practice tests / VCE exams) ----------
   The countdown bar is sticky so it stays visible while a student
   scrolls a 25-question paper. Colour shifts at five minutes and again
   at one minute; the change is paired with a text announcement so it
   does not rely on colour alone. */
.timer-setup {
  margin: 16px 0 4px;
  padding: 14px 16px;
  border: 1px solid var(--rule, #D6DEE8);
  border-radius: 6px;
  background: #FAFBFD;
}
.timer-setup-label {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--font-mono); font-size: 0.85rem;
  color: var(--navy-deep); margin: 0; cursor: pointer;
}
.timer-setup-label input { width: auto; margin: 0; }
.timer-setup-controls {
  display: none; align-items: center; gap: 10px; margin-top: 12px;
  flex-wrap: wrap;
}
.timer-setup-controls select { min-width: 190px; max-width: 100%; }
.timer-custom { width: 90px; }
.timer-custom-unit {
  font-family: var(--font-mono); font-size: 0.8rem; opacity: 0.75;
}
.timer-setup-hint {
  display: none; margin: 10px 0 0;
  font-family: var(--font-mono); font-size: 0.75rem; opacity: 0.7;
}

.timer-bar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; margin-bottom: 18px; padding: 10px 16px;
  border: 1px solid var(--navy-deep, #0F2A44);
  border-radius: 6px;
  background: var(--navy-deep, #0F2A44);
  color: #fff;
}
.timer-bar-label {
  font-family: var(--font-mono); font-size: 0.75rem;
  letter-spacing: 0.06em; text-transform: uppercase; opacity: 0.8;
}
.timer-bar-value {
  font-family: var(--font-mono); font-size: 1.35rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* Covered by the global [hidden] rule near the top of this file; kept
   for clarity about why the timer bar needs it. */
.timer-bar[hidden] { display: none; }

.timer-bar.is-warning { background: #8A5B00; border-color: #8A5B00; }
.timer-bar.is-critical { background: #A23B2E; border-color: #A23B2E; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (max-width: 520px) {
  .timer-bar { flex-direction: column; align-items: flex-start; gap: 2px; }
}

.timer-setup-note {
  margin: 10px 0 0; padding: 8px 10px;
  background: #FBF3DE; border: 1px solid var(--gold, #C99A3E);
  border-radius: 4px;
  font-family: var(--font-mono); font-size: 0.75rem;
  color: var(--navy-deep, #0F2A44);
}

/* ---------- busy state while an action is in flight ----------
   cursor: progress (not wait) -- the page is working but still usable.
   Applied to the document because a disabled button receives no pointer
   events and therefore cannot show a cursor of its own. */
html.is-busy, html.is-busy * { cursor: progress !important; }
button[aria-busy="true"] { opacity: 0.85; }

/* ---------------------------------------------------------------------
   Embedded PDF viewer -- shared by any page that lets a student open a
   PDF inline instead of just downloading it (Past Exam Papers,
   Resources). Moved here from being duplicated per-page so both stay
   in sync automatically.
--------------------------------------------------------------------- */
.pdf-viewer-overlay {
  position: fixed; inset: 0; background: rgba(18, 41, 77, 0.55);
  display: flex; align-items: center; justify-content: center; z-index: 200; padding: 24px;
}
.pdf-viewer-panel {
  background: #fff; width: 100%; max-width: 1000px; height: 100%; max-height: 90vh;
  display: flex; flex-direction: column; box-shadow: 0 20px 60px rgba(0,0,0,0.3);
}
.pdf-viewer-header {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 20px; border-bottom: 1px solid var(--line); background: var(--navy); color: #fff;
}
.pdf-viewer-title { font-family: var(--font-mono); font-size: 0.85rem; }
.pdf-viewer-actions { display: flex; gap: 10px; }
.pdf-viewer-actions a, .pdf-viewer-actions button {
  font-family: var(--font-mono); font-size: 0.78rem; padding: 7px 14px;
  background: var(--gold); color: var(--navy-deep); border: none; cursor: pointer; text-decoration: none;
}
.pdf-viewer-actions .close-btn { background: transparent; color: #fff; border: 1px solid rgba(255,255,255,0.4); }
.pdf-viewer-body { flex: 1; background: #525659; }
.pdf-viewer-body iframe { width: 100%; height: 100%; border: none; }
.pdf-viewer-no-preview {
  height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center;
  color: #fff; font-family: var(--font-mono); font-size: 0.9rem; gap: 16px; text-align: center; padding: 24px;
}
.pdf-viewer-no-preview a { color: var(--gold); }

/* ---------------------------------------------------------------------
   Enquiry modal -- the "get in touch" prompt under the homepage CTA
   button, and the footer's "Enquiry" link, both open this. Reuses
   .pdf-viewer-overlay's exact backdrop/centering (same fixed, inset:0,
   semi-transparent navy scrim, same z-index) so the two modals this
   site has feel like one consistent system rather than two different
   ones -- only the panel itself is new, sized for a short form instead
   of a full-height document.
--------------------------------------------------------------------- */
.enquiry-modal-panel {
  background: var(--cream-soft); width: 100%; max-width: 460px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.3);
}
.enquiry-modal-body { padding: 26px 28px; }
.enquiry-modal-body form.auth-form textarea {
  font-family: var(--font-body); font-size: 1rem; padding: 12px 14px;
  background: var(--cream); border: 1px solid var(--line); color: var(--ink);
  width: 100%; box-sizing: border-box; max-width: 100%; resize: vertical;
  min-height: 110px;
}
/* Honeypot: visually hidden from a sighted human (unlike `hidden` or
   display:none, which some spam bots specifically detect and skip
   filling in), and unreachable by keyboard/AT via tabindex + aria-hidden. */
.enquiry-honeypot { position: absolute; left: -9999px; top: -9999px; }
