/* CBE Hub - base styles */

:root {
  --bg: #f6f7f9;
  --surface: #ffffff;
  --border: #e3e6ea;
  --text: #16191d;
  --muted: #5f6772;
  --brand: #1d4ed8;
  --brand-dark: #1740ad;
  --ok: #0f7b3d;
  --ok-bg: #e7f5ec;
  --err: #b3261e;
  --err-bg: #fdeceb;
  --warn: #8a5a00;
  --warn-bg: #fdf3e2;
  --radius: 10px;
  --shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 1px 3px rgba(16, 24, 40, .1);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.55 system-ui, "Segoe UI", Roboto, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--brand); }
a:hover { color: var(--brand-dark); }

.wrap { max-width: 1080px; margin: 0 auto; padding: 0 20px; }
.narrow { max-width: 460px; }


/* ---------------------------------------------------------------- header */

.site-header {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 20;
}
.site-header .wrap {
  display: flex;
  align-items: center;
  gap: 20px;
  height: 60px;
}
.brand {
  font-weight: 700;
  font-size: 18px;
  color: var(--text);
  text-decoration: none;
  letter-spacing: -.2px;
}
.brand span { color: var(--brand); }
.nav { display: flex; gap: 18px; margin-left: auto; align-items: center; }
/* :not(.btn) so the "Create account" button in the header keeps its own white
   text - `.nav a` is more specific than `.btn`, and without this it paints the
   label muted grey on the brand blue. */
.nav a:not(.btn) { color: var(--muted); text-decoration: none; font-size: 15px; font-weight: 500; }
.nav a:not(.btn):hover, .nav a:not(.btn).active { color: var(--text); }

.badge-tokens {
  background: var(--ok-bg);
  color: var(--ok);
  border-radius: 999px;
  padding: 4px 11px;
  font-size: 13px;
  font-weight: 600;
}

/* The menu button. Hidden on a wide screen, where the links have room to sit
   across the header; the panel it opens is styled in the responsive section. */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 5px;
  flex-direction: column;
  margin-left: auto;
  width: 44px; height: 44px;      /* a comfortable target on its own */
  padding: 0;
  background: none;
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
}
.nav-toggle span {
  display: block;
  width: 19px; height: 2px;
  background: var(--text);
  border-radius: 2px;
  transition: transform .18s ease, opacity .18s ease;
}
/* Open: the bars become a cross, so the button says what it will do next. */
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ------------------------------------------------------------------ main */

main { padding: 32px 0 64px; }
h1 { font-size: 28px; margin: 0 0 6px; letter-spacing: -.4px; }
h2 { font-size: 20px; margin: 32px 0 12px; }
.lede { color: var(--muted); margin: 0 0 24px; }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
  box-shadow: var(--shadow);
}
.card + .card { margin-top: 16px; }

.grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
/* Cards in a grid are sized by the grid, not by the margin they would take as
   stacked siblings, and stretch to the tallest in the row. This keeps plan
   cards - which differ in how much they say - the same size as each other. */
.grid > .card { display: flex; flex-direction: column; }
.grid > .card + .card { margin-top: 0; }
.grid > .card .plan-actions { margin-top: auto; padding-top: 14px; }

.subject-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  text-decoration: none;
  color: inherit;
  display: block;
  transition: border-color .15s, transform .15s;
}
.subject-card:hover { border-color: var(--brand); transform: translateY(-2px); }
.subject-card h3 { margin: 0 0 4px; font-size: 16px; }
.subject-card .meta { color: var(--muted); font-size: 13px; }
.pill {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .4px;
  color: var(--muted);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 9px;
  margin-bottom: 8px;
}

/* ----------------------------------------------------------------- forms */

label { display: block; font-weight: 600; font-size: 14px; margin: 0 0 6px; }
.field { margin-bottom: 18px; }
.hint { color: var(--muted); font-size: 13px; margin-top: 6px; }

input[type=text], input[type=email], input[type=password], input[type=number], select, textarea {
  width: 100%;
  padding: 11px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font: inherit;
  background: #fff;
  color: inherit;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(29, 78, 216, .13);
}
.field.has-error input, .field.has-error select { border-color: var(--err); }
.error-text { color: var(--err); font-size: 13px; margin-top: 6px; }

/**
 * Buttons.
 *
 * inline-flex with centred items rather than inline-block, so the box always
 * grows to whatever is inside it: a long label, a wrapped label, or text at a
 * size the reader has turned up on their phone. A fixed height, or a line
 * height inherited from the body, is what cuts the bottom off a button's text,
 * so both are stated here rather than left to chance.
 */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--brand);
  color: #fff;
  border: 1px solid var(--brand);
  padding: 10px 20px;
  min-height: 44px;                /* a finger-sized target, and room to breathe */
  border-radius: 8px;
  font: inherit;
  font-weight: 600;
  line-height: 1.25;
  text-align: center;
  white-space: normal;             /* a long label wraps instead of spilling out */
  /* break-word, NOT anywhere. Both break an unbroken word rather than let it
     escape, but `anywhere` also counts those breaks when a layout asks the
     button how narrow it can get - which in a table's auto layout let the
     action column collapse to one letter and print "Add" down the page. */
  overflow-wrap: break-word;
  cursor: pointer;
  text-decoration: none;
}
.btn:hover { background: var(--brand-dark); color: #fff; }
.btn.secondary { background: #fff; color: var(--text); border-color: var(--border); }
.btn.secondary:hover { background: var(--bg); color: var(--text); }
/* Full width. NOT called .block: that name belongs to the lesson content box
   further down this file, which sets a white background at the same specificity
   and, being later, won - painting white text on white and leaving every button
   on the sign-in, register and password pages invisible until it was hovered. */
.btn.full { width: 100%; }
.btn.small { padding: 6px 13px; min-height: 34px; font-size: 14px; }

/* Deleting. Outlined rather than a solid red block: the red is there to make
   the button read differently from the ones beside it, not to draw the eye to
   it first - it is never the thing a teacher came to the page to do. */
.btn.danger, .btn.secondary.danger {
  background: #fff;
  color: var(--err);
  border-color: var(--err);
}
.btn.danger:hover, .btn.secondary.danger:hover {
  background: var(--err);
  border-color: var(--err);
  color: #fff;
}

/* A disabled button is greyed rather than dimmed: reducing the opacity of white
   text on the brand blue is what makes a label hard to read. */
.btn:disabled, .btn[disabled] {
  background: #e6e8ec;
  border-color: #dcdfe4;
  color: var(--muted);
  cursor: not-allowed;
}

.btn:focus-visible,
.sim-btn:focus-visible,
.tabs a:focus-visible,
.nav-toggle:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* -------------------------------------------------------------- messages */

.flash { border-radius: 8px; padding: 12px 15px; margin-bottom: 18px; font-size: 15px; }
.flash.success { background: var(--ok-bg); color: var(--ok); }
.flash.error   { background: var(--err-bg); color: var(--err); }
.flash.info    { background: #e8effc; color: var(--brand-dark); }
.flash.warn    { background: var(--warn-bg); color: var(--warn); }

/* --------------------------------------------------------------- tables */

table { width: 100%; border-collapse: collapse; font-size: 15px; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border); }
th { font-size: 13px; text-transform: uppercase; letter-spacing: .3px; color: var(--muted); }
tbody tr:last-child td { border-bottom: none; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
/* A row action is a one- or two-word label. Keeping it on one line makes the
   action column ask the table for the width the button really needs, so a wide
   question stem cannot squeeze it. */
td .btn.small { white-space: nowrap; }
.pos { color: var(--ok); font-weight: 600; }
.neg { color: var(--err); font-weight: 600; }

.auth-links { margin-top: 18px; font-size: 14px; color: var(--muted); text-align: center; }
.empty { color: var(--muted); padding: 22px; text-align: center; }

.tabs { display: flex; gap: 8px; margin-bottom: 20px; flex-wrap: wrap; }
.tabs a {
  padding: 8px 15px; border-radius: 999px; text-decoration: none;
  border: 1px solid var(--border); background: var(--surface);
  color: var(--muted); font-size: 14px; font-weight: 500;
}
.tabs a.active { background: var(--brand); border-color: var(--brand); color: #fff; }
/* A grade that is listed but not open yet (GRADES_COMING_SOON). */
.tabs .tab-disabled {
  padding: 8px 15px; border-radius: 999px;
  border: 1px dashed var(--border); background: transparent;
  color: #9aa1ab; font-size: 14px; font-weight: 500; cursor: not-allowed;
}

.site-footer {
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 14px;
  padding: 22px 0;
  background: var(--surface);
}

/* --------------------------------------------------------------- the tree */

/* Curriculum tree on a subject page. Indentation is a class rather than an
   inline style so it can be tightened on a phone, where four levels of 22px
   would push the titles off the screen. */
.tree { list-style: none; margin: 0; padding: 0; }
.tree ul {
  list-style: none;
  margin: 0;
  padding-left: 22px;
  border-left: 1px solid var(--border);
}
.tree-row { display: flex; gap: 10px; align-items: baseline; padding: 7px 0; }
.tree-num { color: var(--muted); font-variant-numeric: tabular-nums; min-width: 3.2em; }
.tree-title { min-width: 0; }
.tree-strand { font-weight: 600; }
.tree-row .pill { margin: 0; }
.pill-ready { background: var(--ok-bg); color: var(--ok); border-color: transparent; }
.pill-planned { background: transparent; border-style: dashed; color: var(--muted); }

/* Column-width rather than column-count, so a narrow screen collapses to one
   column on its own instead of needing a breakpoint. */
.cols { columns: 22em; column-gap: 32px; }
.cols li { break-inside: avoid; }

/* ------------------------------------------------------------- responsive */

@media screen and (max-width: 860px) {
  .wrap { padding: 0 16px; }
  .cols { columns: auto; }
}

@media screen and (max-width: 680px) {

  /* Header: brand and a menu button on one line. There are up to seven links
     once a token balance and the knowledge card are in play, and wrapping them
     cost two rows of a small screen before the page even started. */
  /* The collapse is scoped to .js, which a one-line script in the head adds.
     Without scripting there is no button to open the panel, so the links stay
     where they are and simply wrap - usable rather than unreachable. */
  .js .site-header .wrap { height: 56px; padding: 0 16px; flex-wrap: nowrap; gap: 12px; }
  .js .nav-toggle { display: inline-flex; }

  .js .nav {
    position: absolute;
    left: 0; right: 0; top: 100%;
    display: none;
    flex-direction: column;
    align-items: stretch;
    margin: 0;
    gap: 0;
    padding: 4px 16px 12px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    box-shadow: 0 10px 20px rgba(16, 24, 40, .10);
    max-height: calc(100vh - 56px);
    overflow-y: auto;
  }
  /* Visibility belongs to CSS, not to a `hidden` attribute JavaScript has to
     remember to clear: above this breakpoint the rules below simply stop
     applying and the navigation is a row again, whatever state it was left in. */
  .js .nav.is-open { display: flex; }

  /* Plain links become full-width rows with a divider. Buttons and the token
     badge keep their own shape - a row divider drawn across a filled button
     just looks like a mistake. */
  .nav a:not(.btn):not(.badge-tokens) {
    font-size: 16px;
    padding: 13px 2px;
    border-top: 1px solid var(--border);
  }
  .nav > a:first-child { border-top: 0; }
  .nav a.btn { margin: 12px 0 4px; }
  .nav .badge-tokens { align-self: flex-start; margin: 10px 0 4px; }
  .badge-tokens { padding: 3px 9px; font-size: 12px; }

  main { padding: 20px 0 44px; }
  h1 { font-size: 23px; }
  h2 { font-size: 18px; margin: 26px 0 10px; }
  .lede { margin-bottom: 18px; }

  .card { padding: 16px; }
  .card + .card { margin-top: 12px; }
  .grid { grid-template-columns: 1fr; gap: 12px; }

  /* A wide table scrolls inside its own card rather than stretching the page
     and giving the whole document a sideways scroll. */
  .card { overflow-x: auto; }
  table { min-width: 520px; font-size: 14px; }
  th, td { padding: 8px 10px; }

  /* Full-width tap targets read better than a row of small ones. */
  .btn { padding: 11px 18px; }
  .field { margin-bottom: 14px; }

  /* The number and title keep the first line to themselves; the lesson counts
     wrap underneath rather than squeezing the title into a two-word column. */
  .tree ul { padding-left: 13px; }
  .tree-row { flex-wrap: wrap; gap: 4px 8px; padding: 9px 0; }
  .tree-num { min-width: 2.6em; }
  .tree-title { flex: 1 1 calc(100% - 3.6em); }

  .block { padding: 14px; }
  figure.figure { padding: 10px 0; }

  .know-card { padding: 24px 20px 18px; max-width: none; }
  .know-title { font-size: 18px; }
  .know-actions { gap: 8px; }
  .know-left { margin-left: 0; width: 100%; }

  .opt { padding: 11px 12px; }
  .tabs { gap: 6px; }
  .tabs a { padding: 7px 12px; font-size: 14px; }
}

@media screen and (max-width: 420px) {
  h1 { font-size: 21px; }
  .card { padding: 14px; }
  /* Buttons keep their content width here. Stretching every .btn to 100% made
     the same action look different depending on whether it happened to sit in
     its own <form>; .btn.full is the way to ask for a full-width button. */
}

/* ------------------------------------------------------------ lesson body */

/* No max-width here on purpose. The lesson body takes the same full page width
   as its cards, its practice tasks and every other page in the app; capping it
   narrower is what made the prose sit in a column while the cards beside it ran
   the full width, and the page read as two different layouts. */
.lesson p { margin: 0 0 15px; }
.lesson h4, .lesson h5 { margin: 26px 0 8px; font-size: 17px; }
.lesson ul, .lesson ol { margin: 0 0 15px; padding-left: 22px; }
.lesson li { margin-bottom: 6px; }
.lesson code {
  background: #eef1f5; padding: 1px 5px; border-radius: 4px;
  font-size: .92em; font-family: ui-monospace, Consolas, monospace;
}
.lesson blockquote {
  margin: 0 0 15px; padding: 2px 0 2px 16px;
  border-left: 3px solid var(--border); color: var(--muted);
}

.block {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--brand);
  border-radius: 8px;
  padding: 16px 18px;
  margin: 0 0 18px;
}
.block > :last-child { margin-bottom: 0; }
.block-label {
  display: block; font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .6px; color: var(--brand); margin-bottom: 7px;
}
.block.definition     { border-left-color: #6d28d9; }
.block.definition .block-label { color: #6d28d9; }
.block.example,
.block.worked_example { border-left-color: var(--ok); background: #fbfefc; }
.block.example .block-label,
.block.worked_example .block-label { color: var(--ok); }
.block.callout        { border-left-color: var(--warn); background: var(--warn-bg); }
.block.callout .block-label { color: var(--warn); }
.block.summary        { border-left-color: #0891b2; }
.block.summary .block-label { color: #0891b2; }
.block.check          { border-left-color: #be185d; }
.block.check .block-label { color: #be185d; }
.block.formula { text-align: center; }
.formula-body {
  font-size: 19px; font-family: ui-monospace, Consolas, monospace; padding: 4px 0;
}

/* ---------------------------------------------------------------- figures */

figure.figure { margin: 0 0 22px; padding: 14px; text-align: center; border-left-width: 1px; }
.figure-svg svg { max-width: 100%; height: auto; }
.figure-3d { position: relative; }
.figure-3d canvas {
  width: 100%; display: block; border-radius: 6px; background: #fbfcfd; touch-action: none;
}
.figure-3d-hint {
  position: absolute; right: 10px; bottom: 10px;
  background: rgba(22, 25, 29, .68); color: #fff;
  font-size: 11px; padding: 3px 9px; border-radius: 999px; pointer-events: none;
}
figure.figure figcaption {
  color: var(--muted); font-size: 14px; margin-top: 10px; text-align: center;
}
.figure-spec {
  text-align: left; overflow-x: auto; background: #f4f6f8;
  padding: 12px; border-radius: 6px; font-size: 13px;
}

/* ------------------------------------------------------- quiz and test UI */

.opt {
  display: flex; gap: 11px; align-items: flex-start;
  border: 1px solid var(--border); border-radius: 8px;
  padding: 12px 14px; margin-bottom: 9px; cursor: pointer; font-weight: 400;
}
.opt:hover { border-color: var(--brand); background: #fafbff; }
.opt input { width: auto; margin: 3px 0 0; flex: none; }
.opt.opt-correct { border-color: var(--ok); background: var(--ok-bg); }
.opt.opt-wrong   { border-color: var(--err); background: var(--err-bg); }

.diy-form textarea { font-size: 15px; }

@media (max-width: 640px) {
  #timer-bar { position: static; }
}

mark { background: #fff3bf; color: inherit; padding: 0 2px; border-radius: 2px; }

/* -------------------------------------------------- "Do you know.." card */

.know-backdrop {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(16, 20, 27, .55);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  animation: know-fade .18s ease-out;
}
.know-backdrop[hidden] { display: none; }
@keyframes know-fade { from { opacity: 0; } to { opacity: 1; } }

body.know-open { overflow: hidden; }

.know-card {
  position: relative;
  background: var(--surface);
  border-radius: 14px;
  box-shadow: 0 18px 48px rgba(16, 24, 40, .28);
  padding: 30px 32px 24px;
  width: 100%; max-width: 520px;
  max-height: calc(100vh - 40px); overflow-y: auto;
  animation: know-rise .22s cubic-bezier(.2, .8, .3, 1);
}
@keyframes know-rise {
  from { opacity: 0; transform: translateY(14px) scale(.98); }
  to   { opacity: 1; transform: none; }
}

.know-close {
  position: absolute; top: 10px; right: 12px;
  background: none; border: 0; width: auto; padding: 4px 8px;
  font-size: 24px; line-height: 1; color: var(--muted); cursor: pointer;
}
.know-close:hover { color: var(--text); }

.know-eyebrow {
  margin: 0 0 14px; font-size: 13px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 1.2px; color: var(--brand);
}
.know-cat { margin-bottom: 10px; }
.know-title { margin: 0 0 10px; font-size: 20px; line-height: 1.3; letter-spacing: -.2px; }
.know-body { margin: 0 0 14px; color: var(--text); }
.know-takeaway {
  margin: 0; padding: 11px 14px;
  background: var(--ok-bg); border-left: 3px solid var(--ok); border-radius: 0 6px 6px 0;
  color: var(--ok); font-weight: 600; font-size: 15px;
}
.know-takeaway[hidden] { display: none; }

.know-actions {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  margin: 22px 0 0;
}
.know-left { color: var(--muted); font-size: 13px; margin-left: auto; }
.know-foot {
  margin: 18px 0 0; padding-top: 14px; border-top: 1px solid var(--border);
  font-size: 13px; color: var(--muted);
}
.linkish {
  background: none; border: 0; padding: 0; width: auto;
  color: var(--brand); font: inherit; cursor: pointer; text-decoration: underline;
}

/* ------------------------------------------------------- exam full screen */

/* The paper is blurred out until the browser is actually in full screen, so a
   student cannot read the questions with other windows beside them. */
.exam-locked #exam-body { filter: blur(9px); pointer-events: none; user-select: none; }

.exam-gate {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(246, 247, 249, .96);
  display: flex; align-items: center; justify-content: center; padding: 24px;
}
.exam-gate[hidden] { display: none; }
.exam-gate .card { max-width: 460px; text-align: center; }
.exam-gate h2 { margin: 0 0 10px; font-size: 21px; }

.exam-warn {
  background: var(--warn-bg); border: 1px solid #f0d9a8; color: var(--warn);
  border-radius: 8px; padding: 10px 14px; font-size: 14px; margin: 0 0 16px;
}

/* Full screen strips the browser chrome, so the page supplies its own edges. */
:fullscreen .site-header, :fullscreen .site-footer { display: none; }
:fullscreen main { padding-top: 20px; }
:fullscreen #timer-bar { top: 10px; }

.schedule-line { color: var(--muted); font-size: 13px; }
.conflict-row { background: var(--err-bg); }

.pkg-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
.pkg {
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 18px; background: var(--surface); text-align: center;
}
.pkg:hover { border-color: var(--brand); }
.pkg-tokens { font-size: 28px; font-weight: 700; line-height: 1.1; }
.pkg-bonus { color: var(--ok); font-size: 13px; font-weight: 600; }
.pkg-price { color: var(--muted); margin: 6px 0 14px; }

/* ----------------------------------------------------------------- print */

/* Utility pair: .no-print is dropped on paper, .print-only exists only there. */
.print-only { display: none; }

@media print {

  /* Nothing interactive or navigational belongs on paper: the site header and
     footer, in-page navigation, buttons, forms, flash notices, and the
     "Do you know.." card. What is left is the document itself. */
  .site-header,
  .site-footer,
  .nav,
  .btn,
  button,
  form,
  .flash,
  .know-backdrop,
  .exam-gate,
  .tabs,
  .no-print { display: none !important; }

  .print-only { display: block; }

  @page { margin: 16mm 14mm; }

  html, body {
    background: #fff;
    color: #000;
    font-size: 11.5pt;
    line-height: 1.45;
  }
  main { padding: 0; }
  .wrap, .wrap.narrow { max-width: none; margin: 0; padding: 0; }

  /* A card is a screen affordance. On paper it is just a block of text, so the
     border, shadow and padding come off and the sections read continuously. */
  .card {
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 0;
    margin: 0 0 14px;
    background: none;
  }
  .card + .card { margin-top: 0; }

  /* Links are stripped back to plain text. A printed plan is read, not
     clicked, and blue underlines only add noise; URLs are deliberately not
     expanded after the text for the same reason. */
  a, a:hover { color: #000 !important; text-decoration: none !important; }

  h1 { font-size: 19pt; margin: 0 0 4px; }
  h2 {
    font-size: 13pt;
    margin: 16px 0 6px;
    padding-bottom: 3px;
    border-bottom: 1px solid #999;
    /* keep a heading with the section it introduces */
    break-after: avoid;
    page-break-after: avoid;
  }
  h3 { font-size: 12pt; margin: 12px 0 4px; break-after: avoid; page-break-after: avoid; }

  .lede, .hint { color: #333; }
  .pill {
    border-color: #999;
    color: #333;
    background: none;
  }

  /* Short blocks stay whole; long prose sections may flow across a page. */
  li, tr, figure.figure, .block {
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .block { border-left-width: 2px; padding: 8px 0 8px 12px; background: none !important; }

  table { font-size: 10.5pt; }
  th, td { border-bottom: 1px solid #ccc; padding: 6px 8px; }
  th { color: #000; }

  figure.figure { padding: 0; border: 0; }
  .figure-svg svg, img { max-width: 100% !important; }
  .figure-3d, .figure-spec { display: none; }   /* needs a screen to be worth anything */
}

/* --------------------------------------------------------- simulations */

/* Stage beside its controls on a wide screen; stacked on a narrow one. The
   stage keeps the 900:560 shape the simulations are drawn in, so nothing is
   ever cropped - it only gets larger or smaller. */
.sim-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 18px;
  align-items: start;
  margin-bottom: 8px;
}
.sim-stage {
  position: relative;
  background: #0e1726;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  line-height: 0;
}
.sim-stage canvas {
  width: 100%;
  height: auto;
  display: block;
  aspect-ratio: 900 / 560;   /* reserves the space before the script runs */
  background: #0e1726;
}
.sim-readout {
  position: absolute; left: 12px; bottom: 12px;
  background: rgba(8, 14, 24, .82);
  color: #cfe0f0;
  font: 13px/1.45 ui-monospace, Consolas, monospace;
  white-space: pre-line;
  padding: 8px 12px;
  border-radius: 8px;
  pointer-events: none;
  max-width: calc(100% - 24px);
}

/* Opt-in for sims whose x-axis or ground line runs along the bottom, where the
   default position would cover the scale. See S.readout(text, 'top-left'). */
.sim-readout--top { top: 12px; bottom: auto; }

.sim-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
}
.sim-panel-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-bottom: 12px;
}
.sim-panel-head h2 { margin: 0; font-size: 15px; }

.sim-panel .ctl { margin-bottom: 14px; }
.sim-panel .ctl label {
  display: flex; justify-content: space-between; align-items: baseline; gap: 8px;
  font-size: 13px; font-weight: 600; margin-bottom: 5px;
}
.sim-panel .ctl label output {
  font-weight: 700; color: var(--brand); font-variant-numeric: tabular-nums;
}
.sim-panel .ctl label.ctl-check { justify-content: flex-start; font-weight: 500; }
.sim-panel .ctl input[type=range] { width: 100%; margin: 0; accent-color: var(--brand); }
.sim-panel .ctl select,
.sim-panel .ctl input[type=text],
.sim-panel .ctl input[type=number] { padding: 8px 10px; font-size: 14px; }
.sim-panel .ctl input[type=checkbox] { width: auto; margin: 0 6px 0 0; }
.ctl-buttons { display: flex; gap: 7px; flex-wrap: wrap; }

.sim-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 8px 12px;
  min-height: 36px;
  font: inherit; font-size: 13px; font-weight: 600;
  line-height: 1.25;
  text-align: center;
  white-space: normal;
  overflow-wrap: anywhere;
  cursor: pointer;
  width: auto;
}
.sim-btn:hover { border-color: var(--brand); color: var(--brand); }
.sim-btn:disabled { color: var(--muted); border-color: var(--border); cursor: not-allowed; }

.sim-note {
  font-size: 13px; color: var(--muted); line-height: 1.5;
  border-top: 1px solid var(--border); padding-top: 11px; margin-top: 11px;
}
.sim-note-tip { display: none; }        /* only worth saying on a small screen */

.pill-3d { background: #ede9fe; color: #6d28d9; border-color: transparent; margin: 0 0 0 6px; }

.sim-lesson-list { list-style: none; margin: 0; padding: 0; }
.sim-lesson-list li { padding: 8px 0; border-top: 1px solid var(--border); }
.sim-lesson-list li:first-child { border-top: 0; }
.sim-lesson-list .schedule-line { display: block; }

.sim-card { display: block; text-decoration: none; color: inherit; }
.sim-card h3 { margin: 0 0 4px; font-size: 15px; }
.sim-card .sim-card-desc { color: var(--muted); font-size: 13px; line-height: 1.45; }
.sim-card-foot {
  margin-top: 10px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  font-size: 12px; color: var(--muted);
}

/* Full screen: the stage becomes the whole display and centres the canvas. */
.sim-stage.is-fullscreen {
  display: flex; align-items: center; justify-content: center;
  background: #0a1020; border: 0; border-radius: 0;
}
.sim-stage.is-fullscreen canvas { max-height: 100vh; width: auto; max-width: 100vw; }

@media screen and (max-width: 900px) {
  .sim-layout { grid-template-columns: 1fr; }
  .sim-note-tip { display: block; }
}

@media screen and (max-width: 680px) {
  /* Edge to edge: every pixel of width is a pixel of diagram. */
  .sim-stage {
    margin-left: -16px;
    margin-right: -16px;
    border-left: 0; border-right: 0; border-radius: 0;
    width: calc(100% + 32px);
  }
  /* The readout is HTML at a fixed size, so over a canvas shrunk to phone
     width it covers a third of the picture. Below the stage it costs
     nothing and is easier to read. */
  .sim-readout {
    position: static;
    max-width: none;
    border-radius: 0;
    font-size: 12px;
    padding: 10px 16px;
    background: #0b1220;
    border-top: 1px solid rgba(255,255,255,.12);
  }
  .sim-panel { padding: 14px; }
  /* A finger needs a bigger target than a mouse pointer does. */
  .sim-panel .ctl input[type=range] { height: 30px; }
  .sim-btn { padding: 10px 14px; font-size: 14px; }
}

/* A simulation offered inside a lesson. */
.sim-lesson-card {
  display: flex; align-items: center; gap: 14px;
  text-decoration: none; color: inherit;
  margin-bottom: 12px; padding: 16px 18px;
  transition: border-color .15s;
}
.sim-lesson-card:hover { border-color: var(--brand); color: inherit; }
.sim-lesson-card-body { flex: 1; min-width: 0; }
.sim-lesson-card h3 { margin: 0 0 3px; font-size: 16px; color: var(--brand); }
.sim-lesson-go { color: var(--brand); font-size: 20px; flex: none; }


/* ================================================================= tests */

/* ------------------------------------------------- the test editor layout

   The editor is a workbench, not a document: a teacher moves between the
   schedule, the questions, the class and the results many times over. Two
   things follow from that. The sections are tabs rather than one long scroll,
   so the question bank never stands between the teacher and the results; and
   the other tests sit in a rail beside the work, so moving to last term's
   paper is a click rather than a trip back through the list. */

.editor-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 288px;
  gap: 22px;
  align-items: start;
}
.editor-main { min-width: 0; }

/* Sticky under the site header, which is 60px tall. */
.editor-rail {
  position: sticky;
  top: 78px;
  max-height: calc(100vh - 100px);
  overflow-y: auto;
}
.editor-rail h2 { margin-top: 0; font-size: 15px; }

.rail-list { list-style: none; margin: 0; padding: 0; }
.rail-item {
  display: block;
  padding: 10px 12px;
  border-radius: 8px;
  text-decoration: none;
  color: inherit;
  border: 1px solid transparent;
}
.rail-item:hover { background: var(--bg); color: inherit; }
.rail-item.current {
  background: var(--bg);
  border-color: var(--border);
  cursor: default;
}
.rail-title { display: block; font-weight: 600; font-size: 14px; line-height: 1.35; }
.rail-meta { display: block; color: var(--muted); font-size: 12.5px; margin-top: 2px; }
.rail-meta .pos, .rail-meta .neg { font-size: 12.5px; }
.rail-more { margin: 12px 0 0; font-size: 13px; }

@media (max-width: 900px) {
  .editor-layout { grid-template-columns: minmax(0, 1fr); }
  .editor-rail { position: static; max-height: none; order: 2; }
}

/* The shared .tabs pills carry the editor sections; only the count is new. */
.tab-count {
  display: inline-block;
  margin-left: 6px;
  font-size: 12px;
  font-weight: 600;
  opacity: .75;
}

/* ------------------------------------------------------ a printed paper

   These styles are screen-first: a teacher checks the sheet on screen before
   spending toner on it, so it has to read in both places. The print block
   further down only trims what a screen adds. */

.paper { max-width: 780px; }
.paper-break { break-before: page; page-break-before: always; }

.paper-head { border-bottom: 2px solid var(--text); padding-bottom: 14px; margin-bottom: 20px; }
.paper-org {
  font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 1px; color: var(--muted);
}
.paper-title { font-size: 24px; margin: 6px 0 2px; }
.paper-meta { color: var(--muted); margin: 0 0 14px; }

/* Label/value pairs, two to a line on a wide sheet. A grid rather than a
   table: minmax(0,1fr) lets a long value wrap, where a table insists on its
   own minimum width and pushes the whole sheet sideways on a phone. */
.paper-facts {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 1fr);
  column-gap: 12px;
  row-gap: 4px;
  font-size: 14px;
  margin: 0 0 14px;
}
.paper-facts dt { font-weight: 600; color: var(--muted); }
.paper-facts dd { margin: 0; }
.paper-script-facts { margin: -6px 0 18px; }

/* Ruled boxes filled in by hand on a photocopy. */
.paper-fill { display: flex; gap: 20px; flex-wrap: wrap; margin: 14px 0 4px; }
.paper-fill div { flex: 1; min-width: 150px; display: flex; align-items: flex-end; gap: 8px; }
.paper-fill span { font-size: 13px; color: var(--muted); white-space: nowrap; }
.paper-fill i { flex: 1; border-bottom: 1px solid var(--text); height: 18px; }

.paper-instructions {
  background: var(--bg);
  border-radius: 8px;
  padding: 12px 14px;
  margin-top: 14px;
  font-size: 15px;
}
.paper-instructions-label {
  display: block; margin-bottom: 4px; font-weight: 700;
  font-size: 12px; text-transform: uppercase; letter-spacing: .6px;
}
.paper-instructions p { margin: 0 0 6px; }
.paper-instructions p:last-child { margin-bottom: 0; }

.paper-rubric { font-weight: 600; margin: 0 0 18px; }
.paper-end, .paper-total {
  margin: 22px 0 0; padding-top: 10px;
  border-top: 2px solid var(--text);
  text-align: right; font-size: 15px;
}
.paper-total { font-size: 17px; }

.paper-sign { display: flex; gap: 26px; flex-wrap: wrap; margin: 22px 0 0; }
.paper-sign div { flex: 1; min-width: 170px; display: flex; align-items: flex-end; gap: 8px; }
.paper-sign span { font-size: 13px; color: var(--muted); white-space: nowrap; }
.paper-sign i { flex: 1; border-bottom: 1px solid var(--text); height: 22px; }

.paper-note {
  margin: 10px 0 0; text-align: right;
  color: var(--muted); font-size: 13.5px;
}
.paper-foot { color: var(--muted); font-size: 12px; margin-top: 20px; }

/* --------------------------------------------------- one printed question */

.pq {
  padding: 16px 0;
  border-bottom: 1px solid var(--border);
  break-inside: avoid;
  page-break-inside: avoid;
}
.pq:last-of-type { border-bottom: none; }

.pq-head { display: flex; gap: 10px; align-items: baseline; }
.pq-no { font-weight: 700; min-width: 24px; }
.pq-stem { flex: 1; min-width: 0; font-weight: 600; }
.pq-marks {
  flex: none; color: var(--muted); font-size: 13px; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.pq-note { color: var(--muted); font-size: 13px; margin: 6px 0 0 34px; }

.pq-opts { list-style: none; margin: 10px 0 0 34px; padding: 0; }
.pq-opt { display: flex; gap: 10px; align-items: flex-start; padding: 4px 0; }
.pq-box {
  flex: none;
  width: 22px; height: 22px;
  border: 1px solid var(--text);
  border-radius: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700;
}
/* Not flex:1 - the "chosen" tag on a script belongs beside the option it
   marks, not pushed out to the far edge of a short line. */
.pq-opt-text { flex: 0 1 auto; min-width: 0; }

/* The key is drawn on the letter box, so a marker reads down one column
   rather than every line. */
.pq-opt-key .pq-box { background: var(--ok); border-color: var(--ok); color: #fff; }
.pq-opt-key .pq-opt-text { font-weight: 600; }
.pq-opt-chosen .pq-box { box-shadow: 0 0 0 3px rgba(29, 78, 216, .2); border-color: var(--brand); }
.pq-chose {
  flex: none; font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .5px; color: var(--brand); align-self: center;
}

/* Room to write on a blank paper. Real elements rather than a background
   image, because a browser will not print a background by default. */
.pq-lines { margin: 12px 0 0 34px; }
.pq-line { border-bottom: 1px solid #c9ced6; height: 26px; }
.pq-choice-space {
  display: flex; align-items: center; gap: 10px; margin: 12px 0 0 34px;
  color: var(--muted); font-size: 13px;
}
.pq-answer-box { width: 46px; height: 30px; border: 1px solid var(--text); border-radius: 4px; }

.pq-response {
  margin: 12px 0 0 34px;
  padding: 10px 12px;
  background: var(--bg);
  border-left: 3px solid var(--border);
  border-radius: 0 6px 6px 0;
}
.pq-blank { color: var(--muted); font-style: italic; }

.pq-award {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 10px 0 0 34px; font-size: 14px;
}
.pq-tick { color: var(--ok); font-weight: 700; }
.pq-cross { color: var(--err); font-weight: 700; }
.pq-hand { color: var(--warn); font-weight: 600; }
.pq-score {
  margin-left: auto; font-weight: 700; font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* A rule to write a hand-awarded mark on. */
.pq-write {
  display: inline-block; width: 34px;
  border-bottom: 1px solid var(--text); vertical-align: baseline;
}

.pq-key {
  display: flex; gap: 10px; align-items: baseline;
  margin: 12px 0 0 34px;
  padding: 10px 12px;
  border: 1px solid var(--ok);
  border-radius: 6px;
  background: var(--ok-bg);
  font-size: 15px;
}
.pq-key-label {
  flex: none; font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .5px; color: var(--ok);
}
.pq-key-body { flex: 1; min-width: 0; }
.pq-key-body p { margin: 0 0 6px; }
.pq-key-body p:last-child { margin-bottom: 0; }

.pq-why { margin: 8px 0 0 34px; color: var(--muted); font-size: 14px; }
.pq-why p { margin: 0 0 6px; }
.pq-why p:last-child { margin-bottom: 0; }

@media (max-width: 640px) {
  .pq-opts, .pq-lines, .pq-response, .pq-award, .pq-key, .pq-why,
  .pq-note, .pq-choice-space { margin-left: 0; }
  .pq-score { margin-left: 0; }

  /* Two pairs to a line do not fit a phone, so it drops to one. */
  .paper-facts {
    grid-template-columns: 76px minmax(0, 1fr);
    column-gap: 8px;
    row-gap: 6px;
  }
}

/* ------------------------------------------------- papers, on actual paper */

@media print {
  /* The paper is the document here, so it gets the page to itself, and the
     screen's soft greys become ink a photocopier will hold. */
  .editor-rail, .tab-count { display: none !important; }

  .paper { max-width: none; }
  .paper-head { border-bottom-color: #000; }
  .paper-title { font-size: 17pt; }
  .paper-org { color: #333; }
  .paper-facts { font-size: 10.5pt; row-gap: 2px; }
  /* Screen grey is too light for a photocopier to hold. */
  .paper-facts dt, .paper-meta, .pq-marks, .pq-note, .pq-why,
  .paper-fill span, .paper-sign span, .pq-choice-space { color: #333; }
  .paper-instructions { background: none; border: 1px solid #999; }

  .pq { border-bottom: 1px solid #ddd; padding: 10px 0; }
  .pq-box { border-color: #000; }
  .pq-line { height: 22px; border-bottom: 1px solid #999; }

  /* A tinted panel is a screen idea. On paper the same distinction is drawn
     with a rule and a label, which survives a black-and-white photocopier. */
  .pq-response {
    background: none;
    border-left: 2px solid #999;
    padding: 4px 0 4px 10px;
  }
  .pq-key {
    background: none;
    border: 0;
    border-top: 1px solid #999;
    border-radius: 0;
    padding: 6px 0 0;
  }
  .pq-key-label { color: #000; }
  .pq-opt-key .pq-box { background: #000; border-color: #000; color: #fff; }
  .pq-opt-chosen .pq-box { box-shadow: none; outline: 2px solid #000; outline-offset: 1px; }
  .pq-tick, .pq-cross, .pq-hand, .pq-chose { color: #000; }
  .pq-write { border-bottom-color: #000; }

  .paper-end, .paper-total { border-top-color: #000; }
  .paper-note { color: #333; }
  .paper-fill i, .paper-sign i { border-bottom-color: #000; }
  .paper-foot { color: #333; }

  /* Each script is handed to one learner, so it starts its own sheet. */
  .paper-break { break-before: page; page-break-before: always; }
}

/* ------------------------------------------------------------- analytics
   The admin dashboard. Charts are plain elements sized by a percentage, so
   they print, they survive a browser with no JavaScript, and they need no
   library to draw a bar. */

/* Two blocks side by side. Distinct from .cols, which flows TEXT into columns
   and would happily break a card in half. */
.duo {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0 24px; align-items: start;
}
.duo > div { min-width: 0; }

.range {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end;
  margin: 0 0 18px;
}
.range .chips { display: flex; flex-wrap: wrap; gap: 6px; }
.range .chip {
  display: inline-block; padding: 6px 12px; border: 1px solid var(--border);
  border-radius: 999px; background: var(--surface); color: var(--muted);
  font-size: 13px; text-decoration: none; white-space: nowrap;
}
.range .chip:hover { border-color: var(--brand); color: var(--brand); }
.range .chip.active {
  background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600;
}
.range form { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; }
.range .field { margin: 0; }
.range .field label { font-size: 12px; color: var(--muted); }
.range input[type="date"] { padding: 7px 9px; }

.stat-grid {
  display: grid; gap: 12px; margin: 0 0 6px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.stat {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow); padding: 14px 16px;
}
.stat-num { font-size: 26px; font-weight: 700; line-height: 1.15; }
.stat-label { color: var(--muted); font-size: 13px; margin-top: 2px; }
.stat-delta { font-size: 12px; margin-top: 6px; }
.stat-delta.up   { color: var(--ok); }
.stat-delta.down { color: var(--err); }
.stat-delta.flat { color: var(--muted); }

/* A row of vertical columns: traffic per day, views per hour. */
.trend {
  display: flex; align-items: flex-end; gap: 3px;
  height: 140px; margin: 6px 0 0; overflow-x: auto; padding-bottom: 2px;
}
.trend .col { flex: 1 1 0; min-width: 6px; display: flex; flex-direction: column;
              justify-content: flex-end; height: 100%; }
.trend .col i {
  display: block; background: var(--brand); border-radius: 3px 3px 0 0;
  min-height: 2px; opacity: .85;
}
.trend .col:hover i { opacity: 1; }
.trend .col.empty i { background: var(--border); }
.trend-axis {
  display: flex; justify-content: space-between; gap: 8px;
  color: var(--muted); font-size: 12px; margin-top: 6px;
}

/* A ranked list where the bar sits behind the label: popular pages, roles. */
.bars { display: flex; flex-direction: column; gap: 2px; }
.bars .row {
  position: relative; display: flex; justify-content: space-between; gap: 12px;
  padding: 8px 10px; border-radius: 6px; overflow: hidden;
}
.bars .row .fill {
  position: absolute; inset: 0 auto 0 0; background: var(--brand);
  opacity: .12; border-radius: 6px;
}
.bars .row .name, .bars .row .val { position: relative; }
.bars .row .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bars .row .val { color: var(--muted); font-variant-numeric: tabular-nums;
                  white-space: nowrap; }

.analytics-note { color: var(--muted); font-size: 13px; margin: 8px 0 0; }

@media (max-width: 860px) {
  .duo { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .range { flex-direction: column; align-items: stretch; }
  .trend { height: 110px; }
}


/* ================================================================ landing */
/* views/landing.php - the public front page. Everything is prefixed lp- so
   nothing here leaks into the signed-in pages. */

body.landing { overflow-x: clip; }
body.landing main { padding-top: 0; }

.lp-svg { display: block; width: 100%; height: auto; }
.lp-small { color: var(--muted); font-size: 14px; margin: 14px 0 0; }
.lp-eyebrow {
  color: var(--brand); font-weight: 700; font-size: 13px;
  letter-spacing: .6px; text-transform: uppercase; margin: 0 0 12px;
}
.lp-btn-lg { padding: 13px 24px; font-size: 16px; min-height: 50px; }
.lp-cta-row { display: flex; flex-wrap: wrap; gap: 12px; }

/* hero */
.lp-hero {
  display: grid; grid-template-columns: 1fr 1.05fr; gap: 40px; align-items: center;
  padding: 48px 0 32px;
}
.lp-hero h1 { font-size: 44px; line-height: 1.1; letter-spacing: -1px; margin: 0 0 16px; }
.lp-lede { font-size: 18px; color: var(--muted); margin: 0 0 26px; max-width: 34em; }
.lp-hero-art { min-width: 0; }

/* numbers */
.lp-stats {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px;
  background: var(--border); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden; margin: 8px 0 12px;
}
.lp-stats div { background: var(--surface); padding: 18px 20px; }
.lp-stats strong { display: block; font-size: 26px; letter-spacing: -.5px; }
.lp-stats span { color: var(--muted); font-size: 14px; }

/* sections */
.lp-section { padding: 44px 0 8px; scroll-margin-top: 70px; }
.lp-h2 { font-size: 28px; letter-spacing: -.5px; margin: 0 0 6px; }
.lp-sub { color: var(--muted); margin: 0 0 22px; max-width: 42em; }

/* grades */
.lp-grades { display: grid; grid-template-columns: repeat(6, 1fr); gap: 12px; }
.lp-grade {
  display: flex; flex-direction: column; gap: 4px; text-align: left;
  padding: 16px; border-radius: var(--radius); text-decoration: none;
  background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);
  color: var(--text); font: inherit;
  transition: border-color .15s ease, transform .15s ease;
}
a.lp-grade:hover { border-color: var(--brand); transform: translateY(-2px); color: var(--text); }
.lp-grade-name { font-weight: 700; font-size: 17px; }
.lp-grade-meta { color: var(--muted); font-size: 13px; }
.lp-grade:disabled {
  cursor: not-allowed; background: #f1f3f6; box-shadow: none;
  border-style: dashed; color: #8a919b;
}
.lp-grade:disabled .lp-grade-meta { color: #8a919b; font-weight: 600; }

/* features */
.lp-features { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.lp-feature {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow);
}
.lp-icon { display: block; width: 100%; height: auto; margin-bottom: 14px; }
.lp-feature h3 { font-size: 16px; margin: 0 0 6px; }
.lp-feature p { color: var(--muted); font-size: 14px; margin: 0; }

/* demo tabs */
.lp-demo-tabs {
  display: inline-flex; gap: 4px; padding: 4px; margin-bottom: 16px;
  background: #e9edf3; border-radius: 12px; flex-wrap: wrap;
}
.lp-demo-tabs button {
  font: inherit; font-weight: 600; font-size: 15px; color: var(--muted);
  background: none; border: 0; border-radius: 9px; padding: 9px 18px; cursor: pointer;
  min-height: 42px;
}
.lp-demo-tabs button[aria-selected="true"] { background: var(--surface); color: var(--text); box-shadow: var(--shadow); }
.lp-demo-tabs button:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
/* Without scripting every panel shows, one after another. */
html:not(.js) .lp-demo-tabs { display: none; }
html:not(.js) .lp-panel + .lp-panel { margin-top: 16px; }
.lp-panel[hidden] { display: none; }

.lp-panel-head { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 8px; }
.lp-tag {
  background: #dbeafe; color: #1e40af; font-size: 12px; font-weight: 700;
  border-radius: 999px; padding: 3px 10px; text-transform: uppercase; letter-spacing: .4px;
}
.lp-tag-teacher { background: #f3e8ff; color: #6b21a8; }
.lp-crumb { color: var(--muted); font-size: 14px; }
.lp-lesson-title { font-size: 24px; margin: 4px 0 14px; letter-spacing: -.3px; }
.lp-panel-foot {
  display: flex; flex-wrap: wrap; gap: 14px; align-items: center; justify-content: space-between;
  margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border);
}
.lp-panel-foot p { margin: 0; color: var(--muted); max-width: 36em; }

/* lesson blocks */
.lp-block { border-radius: 8px; padding: 14px 16px; margin: 16px 0; }
.lp-block p { margin: 0; }
.lp-block ol { margin: 0; padding-left: 22px; }
.lp-block-label { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; margin-bottom: 6px; }
.lp-def { background: #eff6ff; border-left: 4px solid var(--brand); }
.lp-def .lp-block-label { color: var(--brand); }
.lp-steps { background: #f8fafc; border: 1px solid var(--border); }
.lp-example { background: #ecfdf5; border-left: 4px solid #0f766e; }
.lp-example .lp-block-label { color: #0f766e; }
.lp-callout { background: var(--warn-bg); border-left: 4px solid #d97706; }
.lp-check { background: #faf5ff; border: 1px dashed #c084fc; }
.lp-check .lp-block-label { color: #7e22ce; }
.lp-check summary { cursor: pointer; font-weight: 600; color: #7e22ce; margin-top: 10px; }
.lp-check details p { margin-top: 8px; }
.lp-figure { margin: 18px 0; padding: 12px; border: 1px solid var(--border); border-radius: 8px; background: #fff; }
.lp-figure .lp-svg { max-width: 620px; margin: 0 auto; }
.lp-figure figcaption { text-align: center; color: var(--muted); font-size: 14px; margin-top: 6px; }

/* lesson plan */
.lp-plan { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.lp-plan section { border: 1px solid var(--border); border-radius: 8px; padding: 14px 16px; }
.lp-plan-wide { grid-column: 1 / -1; }
.lp-plan h4 { margin: 0 0 6px; font-size: 13px; text-transform: uppercase; letter-spacing: .5px; color: #6b21a8; }
.lp-plan p, .lp-plan ul { margin: 0 0 6px; }
.lp-plan ul { padding-left: 20px; }
.lp-inquiry { font-size: 17px; font-style: italic; }
.lp-timeline { list-style: none; margin: 0; padding: 0; }
.lp-timeline li { display: flex; gap: 12px; align-items: baseline; padding: 7px 0; border-top: 1px solid var(--border); }
.lp-timeline li:first-child { border-top: 0; }
.lp-timeline span {
  flex: none; min-width: 58px; text-align: center; font-size: 13px; font-weight: 700;
  background: #f3e8ff; color: #6b21a8; border-radius: 999px; padding: 2px 8px;
}

/* demo quiz */
.lp-quiz-pick { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 8px 0 18px; }
.lp-quiz-chip {
  font: inherit; text-align: left; cursor: pointer; display: flex; flex-direction: column; gap: 2px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px;
  color: var(--text);
}
.lp-quiz-chip span { color: var(--muted); font-size: 12px; }
.lp-quiz-chip strong { font-size: 14px; }
.lp-quiz-chip:hover { border-color: var(--brand); }
.lp-quiz-chip.active { border-color: var(--brand); background: #eff6ff; box-shadow: inset 0 0 0 1px var(--brand); }
.lp-quiz { max-width: 640px; }
.lp-quiz-meta { display: flex; justify-content: space-between; color: var(--muted); font-size: 14px; margin-bottom: 6px; }
.lp-quiz-bar { height: 6px; background: #e9edf3; border-radius: 3px; overflow: hidden; margin-bottom: 18px; }
.lp-quiz-bar i { display: block; height: 100%; background: var(--brand); transition: width .25s ease; }
.lp-quiz-stem { font-size: 19px; font-weight: 600; margin: 0 0 14px; }
.lp-quiz-opts { display: grid; gap: 10px; }
.lp-quiz-opt {
  font: inherit; text-align: left; cursor: pointer; display: flex; gap: 12px; align-items: center;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  padding: 12px 14px; min-height: 48px; color: var(--text);
}
.lp-quiz-opt b {
  flex: none; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center;
  background: #eef2f7; font-size: 13px; color: var(--muted);
}
.lp-quiz-opt:hover:not(:disabled) { border-color: var(--brand); background: #f8fbff; }
.lp-quiz-opt:disabled { cursor: default; }
.lp-quiz-opt.right { border-color: var(--ok); background: var(--ok-bg); }
.lp-quiz-opt.right b { background: var(--ok); color: #fff; }
.lp-quiz-opt.wrong { border-color: var(--err); background: var(--err-bg); }
.lp-quiz-opt.wrong b { background: var(--err); color: #fff; }
.lp-quiz-why { margin: 14px 0 0; padding: 12px 14px; border-radius: 8px; font-size: 15px; }
.lp-quiz-why.ok { background: var(--ok-bg); color: #0b5d2e; }
.lp-quiz-why.no { background: var(--err-bg); color: #8c1d17; }
.lp-quiz-next { margin-top: 14px; }
.lp-quiz-done { text-align: center; padding: 10px 0; }
.lp-quiz-done .lp-svg { width: 120px; margin: 0 auto 8px; }
.lp-quiz-done h4 { font-size: 22px; margin: 0 0 6px; }
.lp-quiz-done p { color: var(--muted); margin: 0 auto 16px; max-width: 30em; }
.lp-quiz-done .lp-cta-row { justify-content: center; }

/* accounts */
.lp-accounts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.lp-account {
  position: relative; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 14px; padding: 20px; box-shadow: var(--shadow);
}
.lp-account-school { border: 2px solid #0f766e; }
.lp-ribbon {
  position: absolute; top: -12px; right: 16px; background: #0f766e; color: #fff;
  font-size: 12px; font-weight: 700; border-radius: 999px; padding: 3px 12px;
}
.lp-account-art { display: block; width: 100%; height: auto; margin-bottom: 14px; }
.lp-account h3 { margin: 0; font-size: 20px; }
.lp-price { font-weight: 700; font-size: 17px; margin: 2px 0 12px; }
.lp-price span { color: var(--muted); font-weight: 500; font-size: 14px; }
.lp-ticks { list-style: none; padding: 0; margin: 0 0 18px; flex: 1; }
.lp-ticks li { position: relative; padding: 5px 0 5px 26px; font-size: 15px; }
.lp-ticks li::before {
  content: ""; position: absolute; left: 2px; top: 10px; width: 14px; height: 8px;
  border-left: 2.5px solid var(--ok); border-bottom: 2.5px solid var(--ok); transform: rotate(-45deg);
}

.lp-plans { margin-top: 26px; scroll-margin-top: 70px; }
.lp-plans h3 { font-size: 17px; margin: 0 0 10px; }
.lp-plan-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.lp-plan-card {
  display: flex; flex-direction: column; gap: 2px; padding: 14px 16px;
  background: #f0fdfa; border: 1px solid #99f6e4; border-radius: 10px;
}
.lp-plan-price { font-size: 22px; font-weight: 700; color: #0f766e; }
.lp-plan-price small { font-size: 14px; font-weight: 500; color: var(--muted); }
.lp-plan-blurb { color: var(--muted); font-size: 14px; }

/* three steps */
.lp-steps3 { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.lp-steps3 li { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px; }
.lp-steps3 span {
  display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%;
  background: var(--brand); color: #fff; font-weight: 700; margin-bottom: 10px;
}
.lp-steps3 h3 { margin: 0 0 4px; font-size: 17px; }
.lp-steps3 p { margin: 0; color: var(--muted); font-size: 15px; }

/* final call to action */
.lp-final {
  margin: 48px 0 0; padding: 40px 32px; border-radius: 18px; text-align: center; color: #fff;
  background: linear-gradient(135deg, #1d4ed8 0%, #1740ad 55%, #0f766e 100%);
}
.lp-final h2 { font-size: 30px; margin: 0 0 8px; letter-spacing: -.5px; }
.lp-final p { margin: 0 0 22px; color: #dbeafe; }
.lp-final .lp-cta-row { justify-content: center; }
.lp-final .lp-small { color: #dbeafe; margin-top: 18px; }
.lp-final .lp-small a { color: #fff; }
.lp-btn-light { background: #fff; color: var(--brand); border-color: #fff; }
.lp-btn-light:hover { background: #eff6ff; color: var(--brand-dark); }
.lp-btn-ghost { background: transparent; border-color: rgba(255,255,255,.7); color: #fff; }
.lp-btn-ghost:hover { background: rgba(255,255,255,.12); color: #fff; }

@media (max-width: 960px) {
  .lp-hero { grid-template-columns: 1fr; gap: 24px; padding-top: 28px; }
  .lp-hero h1 { font-size: 36px; }
  .lp-hero-art { max-width: 560px; }
  .lp-grades { grid-template-columns: repeat(3, 1fr); }
  .lp-features { grid-template-columns: repeat(2, 1fr); }
  .lp-quiz-pick { grid-template-columns: repeat(2, 1fr); }
  .lp-accounts { grid-template-columns: 1fr; max-width: 560px; }
}
@media (max-width: 640px) {
  .lp-hero h1 { font-size: 30px; }
  .lp-lede { font-size: 16px; }
  .lp-stats { grid-template-columns: repeat(2, 1fr); }
  .lp-grades { grid-template-columns: repeat(2, 1fr); }
  .lp-features, .lp-plan, .lp-plan-grid, .lp-steps3 { grid-template-columns: 1fr; }
  .lp-quiz-pick { grid-template-columns: 1fr; }
  .lp-h2 { font-size: 23px; }
  .lp-final { padding: 30px 18px; }
  .lp-cta-row .btn { flex: 1 1 100%; }
  .lp-demo-tabs { display: flex; }
  .lp-demo-tabs button { flex: 1; padding: 9px 8px; font-size: 14px; }
}

/* ------------------------------------------------------ lesson side menu */

/* views/lesson-nav.php. Scripted, the menu is a drawer that slides in from the
   left when its tab is pressed and sits over the margin beside the lesson.
   Unscripted, the tab is useless and hidden, and the menu is an ordinary list
   of contents at the foot of the page. */

.lnav-tab { display: none; }

.lnav {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin: 30px auto 0;
  max-width: 1040px;
}
.lnav-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  padding-bottom: 10px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
.lnav-subject { font-weight: 700; color: var(--text); text-decoration: none; }
.lnav-subject:hover { color: var(--brand); }
.lnav-level { font-size: 13px; color: var(--muted); }
.lnav-close { display: none; }

.lnav-tree, .lnav-tree ul { list-style: none; margin: 0; padding: 0; }
.lnav-tree ul { padding-left: 14px; }
.lnav summary {
  display: flex;
  gap: 8px;
  padding: 6px 4px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  line-height: 1.35;
  list-style: none;
}
.lnav summary::-webkit-details-marker { display: none; }
.lnav summary::before {
  content: "\25B8";
  flex: 0 0 auto;
  color: var(--muted);
  transition: transform .15s;
}
.lnav details[open] > summary::before { transform: rotate(90deg); }
.lnav summary:hover { background: var(--bg); }
.lnav-strand { font-weight: 700; }
.lnav-num { flex: 0 0 auto; color: var(--muted); font-variant-numeric: tabular-nums; }
.lnav-lesson {
  display: block;
  padding: 5px 8px;
  margin-left: 16px;
  border-left: 2px solid var(--border);
  font-size: 14px;
  line-height: 1.35;
  color: var(--text);
  text-decoration: none;
}
.lnav-lesson:hover { color: var(--brand); border-left-color: var(--brand); background: var(--bg); }
.lnav-lesson.is-current {
  color: var(--brand);
  font-weight: 600;
  border-left-color: var(--brand);
  background: #eef3fd;
}

.js .lnav-tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  position: fixed;
  left: 0;
  top: 96px;
  z-index: 30;
  padding: 14px 8px;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .3px;
  color: #fff;
  background: var(--brand);
  border: 0;
  border-radius: 8px 0 0 8px;
  box-shadow: var(--shadow);
  cursor: pointer;
  transition: opacity .15s;
}
.js .lnav-tab:hover { background: var(--brand-dark); }
.js .lnav-tab:focus-visible { outline: 3px solid #93b4f5; outline-offset: 2px; }
.js .lnav-tab-icon { transform: rotate(90deg); }
.js .lnav-tab[aria-expanded="true"] { opacity: 0; pointer-events: none; }

.js .lnav {
  position: fixed;
  top: 60px;
  bottom: 0;
  left: 0;
  z-index: 30;
  width: 320px;
  max-width: calc(100vw - 48px);
  margin: 0;
  border-width: 0 1px 0 0;
  border-radius: 0;
  box-shadow: 4px 0 18px rgba(16, 24, 40, .12);
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translateX(-105%);
  visibility: hidden;
  transition: transform .22s ease, visibility 0s linear .22s;
}
.js .lnav.is-open {
  transform: none;
  visibility: visible;
  transition: transform .22s ease, visibility 0s;
}
.js .lnav-head {
  position: sticky;
  top: -14px;
  margin-top: -14px;
  padding-top: 14px;
  background: var(--surface);
  z-index: 1;
}
.js .lnav-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex: 0 0 auto;
  font-size: 22px;
  line-height: 1;
  color: var(--muted);
  background: none;
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
}
.js .lnav-close:hover { color: var(--text); background: var(--bg); }

@media screen and (max-width: 680px) {
  .js .lnav { top: 56px; }
}
/* Below this the margin beside the lesson is too thin for the edge tab, which
   would sit on the text; a round button in the corner stays out of the way. */
@media screen and (max-width: 1140px) {
  .js .lnav-tab {
    top: auto;
    bottom: 18px;
    left: 14px;
    writing-mode: horizontal-tb;
    transform: none;
    padding: 10px 14px;
    border-radius: 999px;
  }
  .js .lnav-tab-icon { transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .js .lnav, .js .lnav.is-open { transition: none; }
}

@media print {
  .lnav, .lnav-tab { display: none !important; }
}
