* { box-sizing: border-box; }

:root {
  --ink: #1c2733;
  --muted: #5b6b7b;
  --line: #cfd8e0;
  /* WCAG 1.4.11 wants 3:1 for the edge of anything you can type in or press.
     --line is 1.44:1 on white — fine for a card edge, which is decoration, but
     it made every input and button boundary guesswork on a phone screen in
     daylight. Interactive controls take this instead: 3.49:1 on white, 3.23:1
     on --paper. Kept as a separate token so the cards stay light. */
  --line-strong: #7c8b99;
  --paper: #f4f6f8;
  --card: #ffffff;
  --accent: #14532d;
  --accent-soft: #e7f3ec;
  --danger: #b42318;

  /* Sampled from styling of objectives.pdf; kept in step with PROSE_PALETTE
     in server/cover-templates.js, which the two exporters read. */
  --prose-ink: #1b1a17;
  --prose-navy: #14202f;
  --prose-bronze: #8a6a3b;
}

body {
  margin: 0;
  font-family: "Segoe UI", Calibri, Arial, sans-serif;
  background: var(--paper);
  color: var(--ink);
  font-size: 15px;
}

.topbar {
  background: var(--accent);
  color: #fff;
  padding: 14px 24px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.topbar h1 { font-size: 19px; margin: 0; font-weight: 600; }
.topbar .spacer { flex: 1; }
.account-bar { display: flex; align-items: center; gap: 10px; font-size: 13px; min-width: 0; flex-wrap: wrap; }
.account-email { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The balance and the buttons carry facts the teacher acts on, so they hold
   their natural width; the email is the only item that can lose characters and
   still be recognisable, so it absorbs the squeeze alone. Without this, flex
   shrinks every item proportionally — on a phone that wrapped "4 credits" onto
   two lines inside its badge and made the balance look broken. */
.account-bar > :not(.account-email) { flex: 0 0 auto; white-space: nowrap; }
.topbar-btn { background: rgba(255, 255, 255, 0.12); border-color: rgba(255, 255, 255, 0.4); color: #fff; }
.topbar-btn:hover { border-color: #fff; }
/* ---------- Landing (the signed-out view) ----------
   Wider than the sign-in card beneath it, and first in the reading order, so
   the pitch is read before the password box rather than beside it. */
.landing { max-width: 720px; margin: 40px auto 0; padding: 0 4px; }
.landing-head {
  font-size: 27px;
  line-height: 1.25;
  margin: 0 0 12px;
  color: var(--accent);
  font-weight: 600;
}
.landing-sub { font-size: 16px; line-height: 1.55; margin: 0 0 24px; }

.landing-steps {
  margin: 0 0 24px;
  padding-left: 22px;
  display: grid;
  gap: 14px;
  line-height: 1.5;
}
.landing-steps strong { color: var(--accent); }

.landing-price {
  background: var(--accent-soft);
  border-left: 4px solid var(--accent);
  border-radius: 0 8px 8px 0;
  padding: 12px 16px;
  margin: 0 0 10px;
  line-height: 1.5;
}
.landing-note { margin: 0; }

/* The pitch is prose and wants room to breathe; the card below it is a form
   and wants to stay narrow. On a phone both are simply full width. */
@media (max-width: 640px) {
  .landing { margin-top: 22px; }
  .landing-head { font-size: 22px; }
  .landing-sub { font-size: 15px; }
}

.auth-card { max-width: 560px; margin: 28px auto 60px; }
.auth-actions { display: flex; gap: 10px; margin-top: 16px; }
.badge {
  background: rgba(255, 255, 255, 0.18);
  border-radius: 12px;
  padding: 2px 10px;
  font-size: 12px;
}

.view { max-width: 1100px; margin: 22px auto; padding: 0 18px; }
.hidden { display: none !important; }

/* Read by screen readers, invisible on screen. Not display:none, which would
   take it out of the accessibility tree along with the sight of it. */
.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;
}

/* Hidden until tabbed to. The form runs to 30-odd controls, so without this a
   keyboard user coming back to the page walks the whole topbar every time. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: #fff;
  color: var(--accent);
  padding: 10px 16px;
  border-radius: 0 0 8px 0;
  font-weight: 600;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 18px 22px;
  margin-bottom: 18px;
}
.card h2 { margin: 0 0 14px; font-size: 17px; color: var(--accent); }
.card h3 { margin: 20px 0 8px; font-size: 15px; }
.hint { color: var(--muted); font-size: 13px; font-weight: normal; }

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 12px 16px;
}
label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted); }
input, select {
  font: inherit;
  padding: 7px 9px;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  color: var(--ink);
  background: #fff;
}

/* ---------- Focus ----------
   One ring for everything focusable. The old rule outlined focused inputs in
   --accent-soft (#e7f3ec), which is 1.14:1 against the white field they sit
   in — it replaced the browser's own visible ring with one that could not be
   seen, so keyboard focus was effectively invisible. The accent is 9.11:1.

   :focus-visible rather than :focus so a mouse click does not leave a ring
   behind, and the offset keeps it clear of the red/green required-field
   borders below, which would otherwise swallow it. */
:where(input, select, textarea, button, a, [tabindex]):focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}
/* The topbar is --accent, so an accent ring on it would be invisible for the
   same reason the old one was. */
.topbar :where(button, a):focus-visible { outline-color: #fff; }

.textbook-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; align-items: center; }
/* min-width:0 is what stops the page scrolling sideways on a phone: a flex
   item defaults to min-width:auto, so these inputs refuse to shrink below
   their intrinsic ~20-character width and push the whole document wider than
   the screen. The 180px basis lets the pair wrap onto two lines when there
   is no room for both, instead of squeezing into unusable slivers. */
.textbook-row input { flex: 1 1 180px; min-width: 0; }

.special-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 8px;
}
.special-grid label { flex-direction: row; align-items: center; gap: 6px; white-space: nowrap; }
.special-grid select { flex: 1; min-width: 0; }

.actions { text-align: center; margin: 22px 0 40px; }

/* ---------- Recent schemes ---------- */
.recent-list { display: flex; flex-direction: column; gap: 8px; }
.recent-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 12px;
}
.recent-label { font-weight: 600; }
.recent-date { color: var(--muted); font-size: 13px; }
/* Pushed to the end of the row, and onto its own line when the label wraps. */
.recent-row .btn { margin-left: auto; }

.btn {
  font: inherit;
  padding: 9px 16px;
  border-radius: 7px;
  border: 1px solid var(--line-strong);
  background: #fff;
  color: var(--ink);
  cursor: pointer;
}
.btn:hover { border-color: var(--accent); }
.btn.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
}
.btn.primary:hover { background: #0f3f22; }
/* #9db3a6 put white text at 2.23:1. This is the app's main call to action and
   it ships disabled, so it is the first thing a teacher reads. 4.32:1. */
.btn.primary:disabled { background: #64806f; border-color: #64806f; cursor: not-allowed; }
.btn.small { padding: 5px 10px; font-size: 13px; }
.btn.danger { color: var(--danger); }

.status { margin-top: 10px; font-size: 13px; color: var(--muted); min-height: 18px; }
.status.ok { color: var(--accent); }
.status.warn { color: #a15c07; }
.status.err { color: var(--danger); }

.steps { list-style: none; padding: 0; margin: 14px 0; }
.steps li {
  padding: 9px 12px;
  border-left: 3px solid var(--line);
  margin-bottom: 6px;
  color: var(--muted);
  background: #fafbfc;
}
.steps li.active { border-color: #a15c07; color: var(--ink); }
.steps li.active::after { content: " …"; animation: pulse 1.2s infinite; }
.steps li.done { border-color: var(--accent); color: var(--accent); }
.steps li.done::before { content: "✓ "; }
.steps li.error { border-color: var(--danger); color: var(--danger); }
@keyframes pulse { 50% { opacity: 0.4; } }

.error {
  border: 1px solid var(--danger);
  background: #fef3f2;
  color: var(--danger);
  border-radius: 8px;
  padding: 12px 16px;
  margin-top: 12px;
}

.toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--ink);
  color: #fff;
  padding: 11px 20px;
  border-radius: 8px;
  font-size: 14px;
  max-width: 620px;
  z-index: 50;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
}
.toast.err { background: var(--danger); }

/* ---------- Buy a credit ---------- */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(28, 39, 51, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px;
  z-index: 60;
}
.buy-card {
  width: 100%;
  max-width: 460px;
  margin: 0;
  max-height: 92vh;
  overflow-y: auto;
}
.buy-price { font-size: 15px; margin: 0 0 14px; }
.buy-price strong { font-size: 21px; color: var(--accent); }
.buy-card label { display: block; }
.buy-card input { width: 100%; }
.linklike {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--accent);
  text-decoration: underline;
  cursor: pointer;
}
.dots { display: flex; gap: 6px; margin: 14px 0 16px; }
.dots span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.3;
  animation: dot 1.2s infinite ease-in-out;
}
.dots span:nth-child(2) { animation-delay: 0.2s; }
.dots span:nth-child(3) { animation-delay: 0.4s; }
@keyframes dot {
  0%, 80%, 100% { opacity: 0.25; }
  40% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .dots span { animation: none; opacity: 0.6; }
}

/* ---------- Required fields ----------
   Red means empty, green means filled. Deliberately shown from the moment the
   form loads rather than after a failed submit: the form is longer than a
   phone screen, and its job here is to be a checklist the teacher can scroll
   once. A box that is still empty stays red while it has the cursor — and
   turns green on the first keystroke, because refreshRequired() runs on input.

   Dashed vs solid carries the same message as red vs green, because red and
   green are the one pair that roughly 8% of men cannot tell apart, and half
   this app's users are men. Nothing here may depend on hue alone (WCAG 1.4.1);
   refreshRequired() also sets aria-invalid, which is how a screen reader gets
   it. The border style is why the summary no longer says "outlined in red". */
#scheme-form .field-missing {
  border-color: var(--danger);
  border-style: dashed;
  background: #fffbfa;
}
#scheme-form .field-filled { border-color: var(--accent); border-style: solid; }

#required-summary { margin: 0 0 12px; }

/* ---------- Topic picker ---------- */
/* The input and its Browse button share the row the label gives them. */
.topic-field { display: flex; gap: 6px; align-items: stretch; }
.topic-field input { flex: 1 1 auto; min-width: 0; }
.topic-field .btn { flex: 0 0 auto; }

.topics-card {
  width: 100%;
  max-width: 520px;
  margin: 0;
  max-height: 92vh;
  display: flex;
  flex-direction: column;
}
.topics-card h2 { margin-bottom: 4px; }
#topics-filter { width: 100%; margin: 12px 0 10px; }

/* The list is the only part that scrolls, so the heading, the filter and the
   Close button stay put while a 24-topic syllabus is scrolled through. */
.topic-list {
  flex: 1 1 auto;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 6px;
  min-height: 120px;
}
.topic-group {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 12px 8px 4px;
}
.topic-group:first-child { padding-top: 4px; }
.topic-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  font: inherit;
  text-align: left;
  background: none;
  border: none;
  border-radius: 6px;
  /* Gives the row a 44px height at the base font size — the touch target a
     phone-first list needs. */
  padding: 12px 8px;
  cursor: pointer;
  color: var(--ink);
}
.topic-row:hover, .topic-row:focus-visible { background: var(--accent-soft); }
.topic-num { flex: 0 0 auto; color: var(--muted); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.topic-name { flex: 1 1 auto; }
.topic-tag {
  flex: 0 0 auto;
  background: var(--accent);
  color: #fff;
  border-radius: 10px;
  padding: 1px 8px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* ---------- Support footer ---------- */
.site-footer {
  max-width: 1100px;
  margin: 0 auto;
  padding: 18px;
  color: var(--muted);
  font-size: 13px;
  text-align: center;
}
.site-footer a { color: var(--accent); }

/* ---------- Preview ---------- */
.export-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  position: sticky;
  top: 10px;
  z-index: 10;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.08);
}
.export-bar .spacer { flex: 1; }
.export-bar .status { margin: 0; width: 100%; }

#view-preview { max-width: 1500px; }

.page {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  margin: 0 auto 22px;
  padding: 26px 30px;
  overflow-x: auto;
}
.page-label {
  max-width: 1500px;
  margin: 0 auto 4px;
  color: var(--muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* ---------- Cover templates ----------
   The ten designs in covers/. Every length below is in cqw (1% of the
   sheet's own width), so the identical rules render the full-size preview
   and the picker thumbnail at true scale — there is no second, drifting
   set of thumbnail sizes to maintain.

   Kept in step with server/cover-templates.js (palette, wording) and the
   cover builders in export-docx.js and export-pdf.js. */

:root {
  --cover-rust: #7c2d12;
  --cover-rust-light: #9c4a2f;
  --cover-ink: #111;
  --cover-grey: #8a8079;
  --cover-paper: #fdfcfa;
  --cover-tint: #f3ece7;
  --cover-tint-deep: #f7f4ef;
  --cover-serif: "EB Garamond", Garamond, Georgia, "Times New Roman", serif;
  --cover-sans: "Segoe UI", Helvetica, Arial, sans-serif;
  /* The `masthead` details table. Courier in the PDF and Consolas in Word,
     so the stack leads with the faces closest to those. */
  --cover-mono: Consolas, "Courier New", ui-monospace, monospace;
}

.cover-page { padding: 0; overflow: hidden; }

.cover-sheet {
  container-type: inline-size;
  position: relative;
  aspect-ratio: 297 / 210;
  overflow: hidden;
  background: var(--cover-paper);
  color: var(--cover-ink);
  font-family: var(--cover-serif);
  line-height: 1.25;
}
.cover-sheet [contenteditable] { display: inline-block; }
/* Only an EMPTY editable needs a minimum hit target; on a filled one the
   reserved width opens a gap mid-line ("3   rd TERM"). */
.cover-sheet [contenteditable]:empty { min-width: 3cqw; }

/* The intrinsic size of crest.png. Declaring it keeps the layout stable
   before the image loads — without it every design below the crest jumps. */
.cover-crest { display: block; width: 100%; height: auto; aspect-ratio: 557 / 484; }
.cover-school { font-weight: 700; text-transform: uppercase; }
/* Block, not the default inline-block: an inline-block editable adds the
   line box's strut below it, which inflates the school block by a whole
   descender and pushes everything under it down the page. */
.cover-school [contenteditable] { display: block; min-width: 0; }
/* A fixed string, and the layouts allow exactly one line for it. */
.cover-title { color: var(--cover-rust); font-weight: 700; letter-spacing: 0.18em; white-space: nowrap; }
/* The centred designs set the school name on one line; fitCoverSchools() in
   app.js shrinks it to fit its box, mirroring fitSchoolSize() on the server. */
.cover-tpl-classic .cover-school,
.cover-tpl-banded .cover-school,
.cover-tpl-watermark .cover-school,
.cover-tpl-brackets .cover-school,
.cover-tpl-split .cover-school { white-space: nowrap; }
.cover-eyebrow {
  font-family: var(--cover-sans);
  color: var(--cover-rust);
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
.cover-motto {
  font-family: var(--cover-sans);
  color: var(--cover-rust);
  letter-spacing: 0.22em;
  text-align: center;
}
.cover-row { font-weight: 700; text-transform: uppercase; }
/* The derived ordinal suffix stays lowercase ("3rd TERM"), matching the
   exports, even inside the uppercased rows. */
.cover-ord { text-transform: none; }
.cover-ec { font-weight: 400; }
.cover-row-term { color: var(--cover-rust); }
.cover-label {
  font-family: var(--cover-sans);
  color: var(--cover-grey);
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* --- Classic Double Rule ---
   Frame hairlines measured at 2.36cqw and 3.34cqw from the page edge. */
.cover-tpl-classic .cover-frame {
  position: absolute;
  inset: 2.36cqw;
  border: 0.09cqw solid var(--cover-rust-light);
  box-shadow: inset 0 0 0 0.89cqw var(--cover-paper), inset 0 0 0 0.98cqw var(--cover-rust-light);
}
.cover-tpl-classic .cover-stack {
  position: absolute;
  inset: 14.7cqw 8cqw auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.cover-tpl-classic .cover-crest { width: 16.8cqw; margin-bottom: 2.4cqw; }
.cover-tpl-classic .cover-school { font-size: 4.5cqw; letter-spacing: 0.005em; }
.cover-tpl-classic .cover-rule {
  width: 26cqw;
  border-top: 0.09cqw solid var(--cover-rust-light);
  margin: 1.4cqw 0 1.5cqw;
}
.cover-tpl-classic .cover-title { font-size: 2.76cqw; margin-bottom: 2.2cqw; }
.cover-tpl-classic .cover-row { font-size: 1.86cqw; margin-bottom: 1.35cqw; }
.cover-tpl-classic .cover-row-term { margin-top: 1.5cqw; }

/* --- Crest Panel ---
   Panel/divider measured at 42.5% of the page width. */
.cover-tpl-panel .cover-aside {
  position: absolute;
  inset: 0 auto 0 0;
  width: 42.5%;
  background: var(--cover-tint);
  border-right: 0.11cqw solid var(--cover-rust-light);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 11cqw;
}
.cover-tpl-panel .cover-crest { margin-bottom: 3.2cqw; }
/* One line, as the reference sets it: the tracked motto is wider than the
   padded column, so it bleeds evenly into the padding instead of wrapping. */
.cover-tpl-panel .cover-motto { font-size: 1.45cqw; white-space: nowrap; margin: 0 -9cqw; }
/* Anchored from the top rather than centred: the reference sets a specific
   vertical rhythm, and centring drifts as soon as a school name wraps. */
.cover-tpl-panel .cover-main {
  position: absolute;
  top: 17.5cqw;
  left: 42.5%;
  right: 0;
  /* Text column measured at 0.491–0.927 of the page width */
  padding: 0 7.3cqw 0 6.6cqw;
}
.cover-tpl-panel .cover-eyebrow {
  font-size: 1.2cqw;
  letter-spacing: 0.28em;
  line-height: 1;
  margin-bottom: 0.5cqw;
  white-space: nowrap;
}
/* Left to wrap at the column, since a real school name is rarely two words */
.cover-tpl-panel .cover-school { font-size: 5.6cqw; text-transform: none; line-height: 1.0; }
.cover-tpl-panel .cover-rule {
  width: 10.6cqw;
  border-top: 0.18cqw solid var(--cover-rust);
  margin: 3.1cqw 0 2.9cqw;
}
.cover-tpl-panel .cover-title { font-size: 3.7cqw; font-weight: 400; margin-bottom: 3.1cqw; }
.cover-tpl-panel .cover-row {
  display: grid;
  grid-template-columns: 7.5cqw 1fr;
  align-items: baseline;
  gap: 1.8cqw;
  font-size: 1.86cqw;
  margin-bottom: 1.6cqw;
}
.cover-tpl-panel .cover-label { font-size: 1.2cqw; }

/* --- Banded Header ---
   Header band measured at 30.7% of page height; footer band at 91.9%. */
.cover-tpl-banded .cover-band {
  position: absolute;
  inset: 0 0 auto 0;
  height: 30.7%;
  background: var(--cover-rust);
  display: flex;
  justify-content: center;
  padding-top: 2.8cqw;
}
.cover-tpl-banded .cover-eyebrow { color: #fff; font-size: 1.45cqw; }
.cover-tpl-banded .cover-medallion {
  position: absolute;
  left: 50%;
  top: 9.8cqw;
  width: 21.2cqw;
  height: 21.2cqw;
  transform: translateX(-50%);
  border-radius: 50%;
  background: var(--cover-paper);
  border: 0.36cqw solid var(--cover-rust);
  display: flex;
  align-items: center;
  justify-content: center;
}
.cover-tpl-banded .cover-crest { width: 14.5cqw; }
.cover-tpl-banded .cover-stack {
  position: absolute;
  inset: 38.6cqw 8cqw auto;
  text-align: center;
}
.cover-tpl-banded .cover-school { font-size: 4.3cqw; margin-bottom: 3.1cqw; }
/* Rules flanking the title, drawn as flex siblings so they always meet it */
.cover-tpl-banded .cover-title-flanked {
  display: flex;
  align-items: center;
  gap: 2.4cqw;
  justify-content: center;
  margin-bottom: 2.5cqw;
}
.cover-tpl-banded .cover-title-flanked::before,
.cover-tpl-banded .cover-title-flanked::after {
  content: "";
  width: 8cqw;
  border-top: 0.09cqw solid var(--cover-rust-light);
}
.cover-tpl-banded .cover-title { font-size: 2.55cqw; }
.cover-tpl-banded .cover-row { font-size: 1.86cqw; margin-bottom: 1.35cqw; }
.cover-tpl-banded .cover-foot-band {
  position: absolute;
  inset: auto 0 0 0;
  height: 8.1%;
  background: var(--cover-tint);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--cover-sans);
  font-weight: 600;
  font-size: 1.45cqw;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

/* --- Watermark Crest ---
   Two crests: a faint oversized wash behind everything, and a small solid
   one at the optical centre. Rules measured at 5.7cqw from top and bottom. */
.cover-tpl-watermark .cover-rule {
  position: absolute;
  left: 2cqw;
  right: 2cqw;
  border-top: 0.18cqw solid var(--cover-rust);
}
.cover-tpl-watermark .cover-rule-top { top: 5.7cqw; }
.cover-tpl-watermark .cover-rule-bottom { bottom: 5.7cqw; }
.cover-tpl-watermark .cover-wash {
  position: absolute;
  left: 50%;
  top: 47%;
  width: 62cqw;
  transform: translate(-50%, -50%);
  opacity: 0.07;
}
.cover-tpl-watermark .cover-corners {
  position: absolute;
  inset: 10.7cqw 5.7cqw auto;
  display: flex;
  justify-content: space-between;
  font-family: var(--cover-sans);
  color: var(--cover-grey);
  font-size: 1.3cqw;
  letter-spacing: 0.22em;
}
.cover-tpl-watermark .cover-school { font-weight: 400; }
.cover-tpl-watermark .cover-eyebrow { color: inherit; font-size: inherit; letter-spacing: inherit; }
/* The solid centre crest sits above the wash but behind the title. */
.cover-tpl-watermark .cover-badge {
  position: absolute;
  left: 50%;
  top: 23.4cqw;
  width: 9.8cqw;
  transform: translateX(-50%);
}
.cover-tpl-watermark .cover-stack {
  position: absolute;
  inset: 33cqw 5cqw auto;
  text-align: center;
}
.cover-tpl-watermark .cover-title {
  color: var(--cover-ink);
  font-weight: 400;
  font-size: 7.4cqw;
  letter-spacing: 0.01em;
}
.cover-tpl-watermark .cover-subtitle {
  color: var(--cover-rust);
  font-weight: 700;
  font-size: 2.0cqw;
  margin-top: 2.8cqw;
}
.cover-tpl-watermark .cover-foot {
  position: absolute;
  inset: auto 5.7cqw 10.5cqw;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.cover-tpl-watermark .cover-foot-l { font-weight: 700; font-size: 1.86cqw; text-transform: uppercase; }
.cover-tpl-watermark .cover-foot-r {
  font-family: var(--cover-sans);
  color: var(--cover-grey);
  font-size: 1.4cqw;
  letter-spacing: 0.14em;
}

/* --- Certificate Frame ---
   Outer margin 2.67cqw, then a 0.89cqw rust border over paper. */
.cover-tpl-certificate { background: var(--cover-tint-deep); }
.cover-tpl-certificate .cover-frame {
  position: absolute;
  inset: 2.67cqw;
  background: var(--cover-paper);
  border: 0.89cqw solid var(--cover-rust);
  box-shadow: inset 0 0 0 0.7cqw var(--cover-tint-deep), inset 0 0 0 0.79cqw var(--cover-rust-light);
}
/* Both columns anchored from the top, to the reference's own rhythm. The
   divider hairline runs between them at 47% of the page width. */
.cover-tpl-certificate .cover-main {
  position: absolute;
  top: 21.5cqw;
  left: 0;
  width: 47%;
  padding: 0 2.2cqw 0 12cqw;
  text-align: right;
  border-right: 0.09cqw solid #ddd2c8;
}
.cover-tpl-certificate .cover-school { font-size: 3.9cqw; line-height: 1.2; }
.cover-tpl-certificate .cover-rule { border-top: 0.09cqw solid #ddd2c8; margin: 1.9cqw 0; }
.cover-tpl-certificate .cover-title { font-size: 2.46cqw; }
.cover-tpl-certificate .cover-meta { margin-top: 2.4cqw; }
.cover-tpl-certificate .cover-row { font-size: 1.73cqw; margin-bottom: 1.3cqw; }
/* Crest measured spanning 0.521–0.829 of the page width */
.cover-tpl-certificate .cover-aside {
  position: absolute;
  top: 23.1cqw;
  left: 47%;
  right: 0;
  padding: 0 17.1cqw 0 5.1cqw;
}
.cover-tpl-certificate .cover-crest { margin-bottom: 1.2cqw; }
.cover-tpl-certificate .cover-motto { font-size: 1.35cqw; color: var(--cover-grey); }

/* ---------- The sans-serif five ----------
   These carry no crest, are set in the neutral sans, and each brings its own
   colours — so each block below restates the four palette variables the
   shared rules read (--cover-rust is the accent, --cover-grey the muted
   type) and adds --c-panel and --c-deep for the two colours those rules have
   no name for.

   Unlike the crested five, these place every element absolutely, because the
   references position by cap top rather than by a vertical rhythm. `top` is
   therefore the measured cap position less 0.08em — with line-height 1 the
   cap of a sans sits about that far below its line box. The same allowance is
   what capLift does in export-pdf.js. */

.cover-tpl-sidebar,
.cover-tpl-brackets,
.cover-tpl-split,
.cover-tpl-masthead,
.cover-tpl-plaque {
  font-family: var(--cover-sans);
  background: var(--cover-paper);
  color: var(--cover-ink);
  line-height: 1;
}
.cover-tpl-sidebar .cover-title,
.cover-tpl-brackets .cover-title,
.cover-tpl-split .cover-title,
.cover-tpl-masthead .cover-title,
.cover-tpl-plaque .cover-title { letter-spacing: 0; }

/* --- Navy Sidebar --- */
.cover-tpl-sidebar {
  --cover-rust: #1b9895;
  --cover-ink: #1b1b18;
  --cover-grey: #3a3a36;
  --cover-paper: #fbf9f5;
  --c-panel: #132c50;
  --c-deep: #06656b;
}
.cover-tpl-sidebar .cover-bar {
  position: absolute;
  inset: 0 auto 0 0;
  width: 15.7cqw;
  background: var(--c-panel);
  border-right: 0.6cqw solid var(--cover-rust);
}
.cover-tpl-sidebar .cover-eyebrow {
  position: absolute;
  left: 23.5cqw;
  top: 10.56cqw;
  color: var(--c-panel);
  font-size: 1.3cqw;
  letter-spacing: 0.26em;
}
.cover-tpl-sidebar .cover-rule {
  position: absolute;
  left: 23.5cqw;
  top: 14.4cqw;
  width: 9.6cqw;
  border-top: 0.27cqw solid var(--cover-rust);
}
.cover-tpl-sidebar .cover-school {
  position: absolute;
  left: 23.5cqw;
  right: 5cqw;
  top: 21.22cqw;
  color: var(--c-panel);
  font-size: 6cqw;
  line-height: 1.105;
}
.cover-tpl-sidebar .cover-mark {
  position: absolute;
  left: 23.5cqw;
  top: 37.9cqw;
  width: 5.8cqw;
  border-top: 0.27cqw solid var(--cover-rust);
}
.cover-tpl-sidebar .cover-title {
  position: absolute;
  left: 23.5cqw;
  top: 40.66cqw;
  color: var(--c-deep);
  font-weight: 400;
  font-size: 5.5cqw;
}
.cover-tpl-sidebar .cover-divider {
  position: absolute;
  left: 33.3cqw;
  top: 49.4cqw;
  height: 10.8cqw;
  border-left: 0.2cqw solid var(--cover-rust);
}
.cover-tpl-sidebar .cover-meta {
  position: absolute;
  left: 23.5cqw;
  right: 4cqw;
  top: 50.48cqw;
  display: grid;
  grid-template-columns: 13cqw auto;
  row-gap: 2.2cqw;
  align-items: baseline;
  font-size: 1.5cqw;
}
.cover-tpl-sidebar .cover-label {
  font-family: inherit;
  color: var(--c-panel);
  font-weight: 700;
  font-size: 1.4cqw;
  letter-spacing: 0.06em;
}
.cover-tpl-sidebar .cover-value { font-weight: 700; text-transform: uppercase; }
.cover-tpl-sidebar .cover-ec {
  font-weight: 400;
  font-size: 1.3cqw;
  color: var(--cover-grey);
  margin-left: 2.5cqw;
}
.cover-tpl-sidebar .cover-row-term { color: var(--cover-ink); }

/* --- Gold Brackets ---
   A hairline frame, and two heavy corner brackets outside it. The reference
   sets the title in a tall condensed face; set in the neutral sans it is
   sized to the rule's width instead, so the block still squares up. */
.cover-tpl-brackets {
  --cover-rust: #c9932e;
  --cover-ink: #23252a;
  --cover-grey: #6b6b66;
  --cover-paper: #fcfaf7;
}
.cover-tpl-brackets .cover-frame {
  position: absolute;
  inset: 2.4cqw;
  border: 0.09cqw solid var(--cover-rust);
}
.cover-tpl-brackets .cover-bracket { position: absolute; width: 12.6cqw; height: 12.6cqw; }
.cover-tpl-brackets .cover-bracket-tl {
  top: 1.5cqw;
  left: 1.5cqw;
  border-top: 0.72cqw solid var(--cover-rust);
  border-left: 0.72cqw solid var(--cover-rust);
}
.cover-tpl-brackets .cover-bracket-br {
  bottom: 1.5cqw;
  right: 1.5cqw;
  border-bottom: 0.72cqw solid var(--cover-rust);
  border-right: 0.72cqw solid var(--cover-rust);
}
/* Centred by its own width rather than stretched across the page: the fit in
   app.js reads scrollWidth, which on a full-width block reports the block. */
.cover-tpl-brackets .cover-school {
  position: absolute;
  top: 21.86cqw;
  left: 50%;
  width: max-content;
  transform: translateX(-50%);
  text-align: center;
  font-size: 4cqw;
  letter-spacing: 0.15em;
  /* Tracking adds a step after the last letter, pulling a centred line left */
  text-indent: 0.15em;
}
.cover-tpl-brackets .cover-rule {
  position: absolute;
  left: 20.3cqw;
  top: 28.1cqw;
  width: 59.4cqw;
  border-top: 0.1cqw solid var(--cover-rust);
}
.cover-tpl-brackets .cover-rule::after {
  content: "";
  position: absolute;
  left: 50%;
  top: -0.35cqw;
  width: 0.7cqw;
  height: 0.7cqw;
  margin-left: -0.35cqw;
  background: var(--cover-rust);
}
.cover-tpl-brackets .cover-title {
  position: absolute;
  inset: 31.47cqw 6cqw auto;
  text-align: center;
  color: var(--cover-ink);
  font-weight: 300;
  font-size: 5.4cqw;
  letter-spacing: 0.05em;
  text-indent: 0.05em;
}
.cover-tpl-brackets .cover-mark {
  position: absolute;
  left: 40.55cqw;
  top: 44cqw;
  width: 18.9cqw;
  border-top: 0.13cqw solid var(--cover-rust);
}
/* Equal cells, so a long class name cannot squeeze the term out of its own */
.cover-tpl-brackets .cover-fields {
  position: absolute;
  left: 17cqw;
  top: 52.58cqw;
  width: 66.6cqw;
  display: grid;
  /* The cell shares in COVER_LAYOUT.brackets.fields.weights */
  grid-template-columns: 22fr 22fr 34fr 22fr;
  font-size: 1.35cqw;
  letter-spacing: 0.06em;
  text-align: center;
}
.cover-tpl-brackets .cover-field {
  padding: 0 0.8cqw 2.6cqw;
  font-weight: 700;
  text-transform: uppercase;
}
.cover-tpl-brackets .cover-field + .cover-field { border-left: 0.09cqw solid var(--cover-rust); }
.cover-tpl-brackets .cover-field::after {
  content: "";
  display: block;
  width: 60%;
  margin: 2.6cqw auto -2.6cqw;
  border-top: 0.13cqw solid var(--cover-rust);
}
.cover-tpl-brackets .cover-row-term { color: var(--cover-rust); }

/* --- Forest Split --- */
.cover-tpl-split {
  --cover-rust: #e06349;
  --cover-ink: #232323;
  --cover-grey: #4a4a45;
  --cover-paper: #efece5;
  --c-panel: #1d4937;
}
.cover-tpl-split .cover-panel {
  position: absolute;
  inset: 0 0 0 68cqw;
  background: var(--c-panel);
  border-left: 0.13cqw solid var(--cover-rust);
}
.cover-tpl-split .cover-school {
  position: absolute;
  left: 6.7cqw;
  top: 19.14cqw;
  color: var(--c-panel);
  font-size: 1.95cqw;
  letter-spacing: 0.24em;
}
.cover-tpl-split .cover-title {
  position: absolute;
  left: 6.7cqw;
  top: 22.73cqw;
  width: 57cqw;
  color: var(--cover-ink);
  font-weight: 800;
  font-size: 8.4cqw;
  line-height: 1.037;
  white-space: normal;
}
.cover-tpl-split .cover-rule {
  position: absolute;
  left: 6.7cqw;
  top: 41.5cqw;
  width: 42.5cqw;
  border-top: 0.27cqw solid var(--cover-rust);
}
.cover-tpl-split .cover-meta {
  position: absolute;
  left: 6.97cqw;
  top: 45cqw;
  padding-left: 2.2cqw;
  border-left: 0.3cqw solid var(--cover-rust);
}
.cover-tpl-split .cover-name {
  color: var(--c-panel);
  font-weight: 700;
  font-size: 2.15cqw;
  text-transform: uppercase;
  margin-bottom: 1.25cqw;
}
.cover-tpl-split .cover-row { font-size: 1.85cqw; margin-bottom: 1.35cqw; }
.cover-tpl-split .cover-row-term {
  display: inline-block;
  background: var(--cover-rust);
  color: #fff;
  font-weight: 700;
  font-size: 1.85cqw;
  padding: 1.25cqw 1.5cqw;
  margin-top: 0.4cqw;
}

/* --- Slate Masthead --- */
.cover-tpl-masthead {
  --cover-rust: #1e6bf0;
  --cover-ink: #232323;
  --cover-grey: #6c7480;
  --cover-paper: #fafafb;
  --c-panel: #3d556d;
  --c-hair: #c8c8c8;
}
.cover-tpl-masthead .cover-band {
  position: absolute;
  inset: 0 0 auto 0;
  height: 11cqw;
  background: var(--c-panel);
  border-bottom: 0.4cqw solid var(--cover-rust);
}
.cover-tpl-masthead .cover-eyebrow {
  position: absolute;
  left: 5.4cqw;
  top: 4.69cqw;
  color: #fff;
  font-size: 1.35cqw;
  letter-spacing: 0.28em;
}
.cover-tpl-masthead .cover-school {
  position: absolute;
  left: 5.4cqw;
  right: 5cqw;
  top: 19.54cqw;
  color: var(--c-panel);
  font-size: 8.2cqw;
  line-height: 1.038;
}
.cover-tpl-masthead .cover-mark {
  position: absolute;
  left: 5.4cqw;
  top: 38.7cqw;
  width: 8.8cqw;
  border-top: 0.34cqw solid var(--cover-rust);
}
.cover-tpl-masthead .cover-title {
  position: absolute;
  left: 5.4cqw;
  top: 41.87cqw;
  color: var(--cover-ink);
  font-weight: 400;
  font-size: 4.1cqw;
  letter-spacing: 0.1em;
}
/* Monospaced in the reference, and the face's small cap height is why this
   block is set larger than the sans elsewhere on the page. */
.cover-tpl-masthead .cover-meta {
  position: absolute;
  left: 5.3cqw;
  top: 51.35cqw;
  width: 43.8cqw;
  font-family: var(--cover-mono);
  font-size: 1.9cqw;
}
.cover-tpl-masthead .cover-row {
  display: grid;
  grid-template-columns: 12.5cqw auto;
  align-items: baseline;
  padding: 0.55cqw 0 0.85cqw 1cqw;
  font-weight: 400;
  text-transform: none;
}
.cover-tpl-masthead .cover-row + .cover-row { border-top: 0.13cqw solid var(--c-hair); }
.cover-tpl-masthead .cover-row:nth-child(2) { border-bottom: 0.13cqw solid var(--c-hair); }
.cover-tpl-masthead .cover-label {
  font-family: inherit;
  color: var(--cover-grey);
  letter-spacing: 0;
  font-size: 1.9cqw;
}
.cover-tpl-masthead .cover-value {
  padding-left: 1.7cqw;
  border-left: 0.13cqw solid var(--c-hair);
  text-transform: uppercase;
}
.cover-tpl-masthead .cover-row-term {
  position: absolute;
  right: 5.9cqw;
  top: 60.53cqw;
  color: var(--cover-rust);
  font-family: var(--cover-mono);
  font-weight: 700;
  font-size: 2.1cqw;
}

/* --- Burgundy Plaque --- */
.cover-tpl-plaque {
  --cover-rust: #841b33;
  --cover-ink: #1a1a1a;
  --cover-grey: #6b5f55;
  --cover-paper: #f2e9de;
  --c-panel: #55305c;
  --c-hair: #c8ac9a;
}
.cover-tpl-plaque .cover-frame {
  position: absolute;
  inset: 3.3cqw;
  border: 0.11cqw solid var(--cover-rust);
}
.cover-tpl-plaque .cover-bracket { position: absolute; width: 11.5cqw; height: 11.5cqw; }
.cover-tpl-plaque .cover-bracket-tr {
  top: 2.2cqw;
  right: 2.2cqw;
  border-top: 0.55cqw solid var(--cover-rust);
  border-right: 0.55cqw solid var(--cover-rust);
}
.cover-tpl-plaque .cover-bracket-bl {
  bottom: 2.2cqw;
  left: 2.2cqw;
  border-bottom: 0.55cqw solid var(--cover-rust);
  border-left: 0.55cqw solid var(--cover-rust);
}
/* The reference's face is a bold condensed slab; the bundled Garamond is the
   only serif all three renderers share, so it stands in here. */
.cover-tpl-plaque .cover-school {
  position: absolute;
  left: 9.85cqw;
  right: 28cqw;
  top: 14.53cqw;
  font-family: var(--cover-serif);
  color: var(--cover-rust);
  font-size: 8.35cqw;
  line-height: 0.867;
}
.cover-tpl-plaque .cover-rule {
  position: absolute;
  left: 9.85cqw;
  top: 30.6cqw;
  width: 9.2cqw;
  border-top: 0.27cqw solid var(--cover-rust);
}
.cover-tpl-plaque .cover-title {
  position: absolute;
  left: 10.5cqw;
  top: 37.09cqw;
  color: var(--cover-ink);
  font-weight: 300;
  font-size: 6.4cqw;
}
.cover-tpl-plaque .cover-mark {
  position: absolute;
  left: 9.85cqw;
  top: 46.7cqw;
  width: 10cqw;
  border-top: 0.8cqw solid var(--cover-rust);
}
.cover-tpl-plaque .cover-strip {
  position: absolute;
  left: 9cqw;
  top: 52.4cqw;
  width: 81.7cqw;
  display: grid;
  /* The cell shares in COVER_LAYOUT.plaque.strip.weights */
  grid-template-columns: 22fr 22fr 34fr 22fr;
  border-top: 0.09cqw solid var(--c-hair);
  border-bottom: 0.09cqw solid var(--c-hair);
  font-size: 1.5cqw;
  letter-spacing: 0.04em;
  text-align: center;
}
/* Padded rather than centred by flex: a flex cell makes every text run its
   own item, which opens a gap between the term and its ordinal ("3 rd"). */
.cover-tpl-plaque .cover-field {
  padding: 3.3cqw 0.8cqw 3.8cqw;
  font-weight: 700;
  text-transform: uppercase;
}
.cover-tpl-plaque .cover-field + .cover-field { border-left: 0.09cqw solid var(--c-hair); }
.cover-tpl-plaque .cover-row-term {
  background: var(--c-panel);
  color: #fff;
  border-left: 0;
  /* Inset from the strip's rules, as a filled block within them */
  padding: 2.6cqw 0.8cqw 3.1cqw;
  margin: 0.7cqw 0;
}

/* ---------- Template picker ---------- */
.template-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 14px;
}
.template-card {
  font: inherit;
  text-align: left;
  background: #fff;
  border: 2px solid var(--line-strong);
  border-radius: 8px;
  padding: 10px;
  cursor: pointer;
}
.template-card:hover { border-color: var(--accent); }
.template-card.selected { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.template-card .template-name { font-weight: 600; font-size: 13px; margin-top: 8px; }
.template-card.selected .template-name::after { content: " ✓"; color: var(--accent); }
.template-card .template-desc { font-size: 11.5px; color: var(--muted); margin-top: 2px; }

/* Thumbnails are the real cover sheet at thumbnail width — the cqw units in
   the template rules do the scaling, so nothing here restates a size. */
.cover-thumb {
  pointer-events: none;
  border: 1px solid var(--line);
  border-radius: 4px;
  overflow: hidden;
}

/* The aims and topics pages, matching the PDF and DOCX exports. Both bodies
   stay plain editable text — the roman numerals and rules of the finished page
   are added by the exporters, because turning them into markup here would put
   them into what the teacher types and edits. */
.section-heading {
  font-family: var(--cover-serif);
  text-align: center;
  font-size: 26px;
  font-weight: 600;
  letter-spacing: 0.12em;
  /* Tracking is added after the last letter too, which pulls a centred line
     left by half a step; the indent puts it back. */
  text-indent: 0.12em;
  color: var(--prose-navy);
  margin-bottom: 12px;
}

.section-heading::after {
  content: "";
  display: block;
  width: 46px;
  height: 1.5px;
  margin: 12px auto 0;
  background: var(--prose-bronze);
}

.aims-body,
.topics-body {
  font-family: var(--cover-serif);
  white-space: pre-wrap;
  max-width: 640px;
  margin: 0 auto;
  color: var(--prose-ink);
}

.aims-body {
  font-size: 15.5px;
  line-height: 1.53;
  text-align: justify;
}

.topics-body {
  font-size: 17px;
  line-height: 2.1;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--prose-navy);
}

[contenteditable] {
  outline: none;
  border-radius: 3px;
}
[contenteditable]:hover { background: #f6f9f7; box-shadow: inset 0 0 0 1px #d5e5da; }
[contenteditable]:focus { background: #f0f7f2; box-shadow: inset 0 0 0 2px var(--accent); }

.scheme-table {
  border-collapse: collapse;
  width: 100%;
  min-width: 1250px;
  table-layout: fixed;
  font-size: 12.5px;
}
.scheme-table th, .scheme-table td {
  border: 1px solid #333;
  padding: 6px 7px;
  vertical-align: top;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.scheme-table th { background: #d9d9d9; text-align: center; font-size: 12px; }
.scheme-table td.topic-cell { font-weight: 700; }
/* The narrowest column in the table: a date like "16 Jan 2026" only fits by
   wrapping, so it is centred to sit tidily however many lines it takes. */
.scheme-table td.week-ending-cell { text-align: center; }
.scheme-table .special-cell {
  text-align: center;
  font-weight: 800;
  font-size: 15px;
  padding: 60px 10px;
}
.week-toolbar {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-top: 8px;
  color: var(--muted);
  font-size: 13px;
}

/* ---------- Phones ----------
   Most of this product's users are on a phone, so nothing here may make the
   document wider than the screen: a page that pans sideways hides the right
   edge of every form field. The rules above already avoid fixed widths; this
   block handles the two places where a row simply has more in it than a
   375px screen can hold. */
@media (max-width: 560px) {
  .topbar { padding: 12px 16px; gap: 8px; }
  .topbar h1 { font-size: 17px; }
  /* Decorative only — the heading beside it already says what this is. */
  .topbar > .badge { display: none; }
  .topbar .spacer { display: none; }
  /* Own line, so the email can truncate instead of shoving the buttons off. */
  .account-bar { width: 100%; gap: 8px; }

  .view { margin: 16px auto; padding: 0 12px; }
  .card { padding: 14px 16px; }
  .auth-card { margin: 24px auto; }
  .auth-actions .btn { flex: 1; }

  /* A scheme table is far wider than any phone; it scrolls inside its page
     (.page has overflow-x: auto) rather than dragging the document with it. */
  .page { padding: 16px 14px; }
  /* The cover sheet sizes itself from its own width, so it needs no phone
     overrides — only the page padding that would otherwise crop it. */
}
