/* ============================================================
   revision.css — Revision-notes-specific styles
   Loads after page.css on /resources pages.
============================================================ */

/* ============================================================
   META BADGES — for hero (AQA, Paper 1 etc)
============================================================ */
.rn-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}
.rn-meta-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 5px 10px;
  border: 1px solid var(--hairline);
  background: var(--paper);
  border-radius: 999px;
  font-weight: 500;
  color: var(--ink-soft);
}
.rn-meta-badge.aqa {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}
.rn-meta-badge.paper1,
.rn-meta-badge.paper2 {
  color: var(--ink);
}
/* A-level-only topic badge (7405 content not examined at AS) — green reads
   as "Year 13"; pairs with .tag-alevel. */
.rn-meta-badge.alevel {
  color: oklch(0.40 0.08 165);
  border-color: oklch(0.78 0.07 165);
  background: oklch(0.96 0.02 165);
}
/* Muted "coming soon" variant of a meta badge (e.g. Paper 2 on the
   GCSE hub hero, where those notes are still in progress). */
.rn-meta-badge.is-coming {
  color: var(--muted);
  border-style: dashed;
}
/* Required-practical badge — sits on a section heading next to the RP that
   AQA names for that topic (RP1–RP8). Teal reads as "lab work". */
.rn-meta-badge.rp {
  color: oklch(0.42 0.09 195);
  border-color: oklch(0.78 0.06 195);
  background: oklch(0.96 0.025 195);
  font-size: 9.5px;
  vertical-align: middle;
}

/* Topic pager styles live in the TOPIC PAGER section lower in this file. */

/* ============================================================
   HERO MOTIF — chapter line art beside the heading
   Mirrors the OG card art (see assets/og/build-og.mjs). Turns the
   hero into two columns: text on the left, motif on the right.
============================================================ */
.rn-hero-inner {
  max-width: none;            /* span the full wrap, not the 880px article cap */
  display: flex;
  align-items: flex-end;      /* sit the art on the same baseline as the last text line (byline) */
  gap: clamp(28px, 5vw, 72px);
}
.rn-hero-main {
  flex: 1 1 0;
  min-width: 0;              /* let the text column shrink instead of overflowing */
  max-width: 820px;
}
.rn-hero-figure {
  flex: 0 0 auto;
  width: clamp(300px, 37vw, 500px);   /* large hero art — fills the right-hand space */
  display: flex;
  justify-content: center;
}
/* C4's motif is landscape (beaker + electrolysis cell) — give it more room */
.rn-hero-figure.is-wide {
  width: clamp(340px, 47vw, 620px);
}
.rn-hero-svg {
  width: 100%;
  height: auto;
  overflow: visible;
}

@media (max-width: 900px) {
  .rn-hero-inner { display: block; }
  .rn-hero-figure { display: none; }   /* decorative — drop it on narrow screens */
}

/* GCSE Chemistry hub — the page-hero reuses the two-column motif layout.
   page.css makes .page-hero-inner a flex column with a 12px gap, so restore
   the row here and move the column stacking into the text side. */
.page-hero-inner.rn-hero-inner {
  flex-direction: row;
  /* rn-hero-inner removes the article cap with max-width:none, but here the
     class sits on the .wrap element itself — restore the page cap. */
  max-width: var(--maxw);
}
.page-hero-inner.rn-hero-inner .rn-hero-main {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
@media (max-width: 900px) {
  /* keep the stacked text rhythm once the figure is dropped.
     align-items must reset too: the base rule's flex-end baseline trick
     turns into a right-shifted text block once the axis is vertical. */
  .page-hero-inner.rn-hero-inner { display: flex; flex-direction: column; align-items: flex-start; }
}

/* Sub-hub masthead topline — the revision hub's grammar (breadcrumb left,
   mono proof line right) carried onto the section hubs. Sits full-width
   above the two-column hero, so it reuses .rn-hub-topline/.rn-hub-proof. */
.rn-hero-topline { margin-bottom: clamp(14px, 2vw, 22px); }
/* The board-code eyebrow directly above the hub h1 (e.g. "AQA 8462 · Notes");
   the flex column's own 12px gap provides the spacing on page-hero hubs. */
.page-hero-inner.rn-hero-inner .rn-hero-main .section-eyebrow { margin-bottom: 0; }

/* ============================================================
   LEGEND — explains badge meanings on topic index
============================================================ */
.rn-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 24px;
  align-items: center;
  margin: 24px 0 40px;
  padding: 16px 20px;
  border: 1px solid var(--hairline);
  background: var(--paper-2);
  border-radius: 4px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--muted);
}
/* Badge stays fixed on the first line; the explanation text flexes and
   wraps beside it instead of dropping underneath the badge. */
.rn-legend-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.rn-legend-item .tag { flex: 0 0 auto; }
.rn-legend-item > :not(.tag) { flex: 1 1 0; min-width: 0; }
.rn-legend .tag {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.08em;
  font-weight: 500;
  padding: 3px 8px;
  border-radius: 999px;
  text-transform: uppercase;
  border: 1px solid currentColor;
}

/* ============================================================
   TIER & SPEC TAGS — inline (Triple, Higher, Coming soon)
============================================================ */
.tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 500;
  padding: 3px 8px;
  border-radius: 999px;
  border: 1px solid currentColor;
  vertical-align: middle;
  margin-left: 6px;
  white-space: nowrap;
}
.tag-triple { color: oklch(0.42 0.10 290); }
.tag-higher { color: oklch(0.45 0.13 50); }
.tag-alevel { color: oklch(0.40 0.08 165); } /* A-level only (AS/A2 split, 7404/7405) */
.tag-coming { color: var(--muted); }

/* Compact single-letter tier badge (used in the TOC so long entries
   don't push the full-word pill onto its own line). */
.tag-dot,
.rn-legend .tag-dot {
  box-sizing: border-box;
  width: 17px;
  height: 17px;
  padding: 0;
  line-height: 15px;
  text-align: center;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0;
}

/* ============================================================
   TOPIC INDEX (paper sections + grid)
============================================================ */
.rn-papers {
  padding: clamp(56px, 8vw, 100px) 0;
}
.rn-paper-heading {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(28px, 3vw, 40px);
  line-height: 1.05;
  letter-spacing: -0.018em;
  color: var(--ink);
  margin: 48px 0 6px;
}
.rn-paper-heading:first-of-type { margin-top: 0; }
/* Full-sentence section subtitles — sentence-case muted sans (the old
   uppercase mono treatment set 3–5 heavy caps lines at 375px). */
.rn-paper-sub {
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--muted);
  max-width: 68ch;
  margin: 0 0 24px;
}
.rn-topic-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  /* Hairlines are drawn per-card (border-right/bottom) over a transparent
     grid with a top/left frame — NOT via a hairline grid background showing
     through 1px gaps. The background technique painted every unfilled track
     as a large slate slab whenever a section's card count didn't divide by
     the column count (16 organic cards in 3 columns, 8 bridging modules in
     3, …), reading as a broken card at tablet/laptop widths. */
  gap: 0;
  border-top: 1px solid var(--hairline);
  border-left: 1px solid var(--hairline);
  margin-bottom: 48px;
}
.rn-topic-card {
  background: var(--paper);
  border-right: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  padding: 24px 24px 22px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  text-decoration: none;
  color: inherit;
  transition: background .15s;
  position: relative;
  min-height: 180px;
}
.rn-topic-card:hover {
  background: var(--paper-2);
}
.rn-topic-card:hover .rn-topic-link { color: var(--accent); }
.rn-topic-num {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 500;
}
/* Card head row — topic number left, small chapter motif right.
   Motifs are injected by assets/og/inject-hero-motifs.mjs. */
.rn-topic-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.rn-topic-motif {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  opacity: 0.85;
  transition: opacity .15s;
}
.rn-topic-motif svg {
  width: 100%;
  height: 100%;
}
.rn-topic-card:hover .rn-topic-motif { opacity: 1; }
.rn-topic-card h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 22px;
  line-height: 1.1;
  letter-spacing: -0.012em;
  margin: 0;
  color: var(--ink);
}
.rn-topic-card p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-soft);
  flex-grow: 1;
}
.rn-topic-link {
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid var(--hairline);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  transition: color .15s;
}
/* "Coming soon" cards read as de-emphasised via a recessed background + muted
   heading, NOT a blanket opacity — opacity dropped the body text below WCAG AA
   (was ~2.5:1). Text now stays legible (ink-soft ≥ 11:1). */
.rn-topic-card-coming {
  background: var(--paper-2);
  cursor: default;
  pointer-events: none;
}
.rn-topic-card-coming h3 { color: var(--ink-soft); }
.rn-topic-card-coming .rn-topic-num { color: var(--muted); }
.rn-topic-card-coming::after {
  content: "Coming soon";
  position: absolute;
  top: 18px;
  right: 18px;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 3px 8px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
}

/* Cross-sell card in a topic grid — links out (e.g. GCSE hub → bridging course).
   A faint accent wash + accent top rule mark it as a next step, visually distinct
   from the ink topic cards around it. */
.rn-topic-card-crosslink {
  background: color-mix(in srgb, var(--accent) 6%, var(--paper));
  box-shadow: inset 0 3px 0 0 var(--accent);
}
.rn-topic-card-crosslink:hover {
  background: color-mix(in srgb, var(--accent) 11%, var(--paper));
}
.rn-topic-card-crosslink .rn-topic-num { color: var(--accent); }
.rn-topic-card-crosslink .rn-topic-link {
  color: var(--accent);
  border-top-color: color-mix(in srgb, var(--accent) 30%, transparent);
}

/* Single-card sections: the auto-fill grid would leave its lone card
   beside empty hairline tracks that read as broken slate slabs. --solo
   collapses the grid to one full-width feature strip in the crosslink /
   summit language (3px accent top rule + faint accent wash). Reuse for
   any future one-card section. */
.rn-topic-grid--solo { grid-template-columns: minmax(0, 1fr); }
.rn-topic-grid--solo .rn-topic-card {
  min-height: 0;
  background: color-mix(in srgb, var(--accent) 4%, var(--paper));
  box-shadow: inset 0 3px 0 0 var(--accent);
}
.rn-topic-grid--solo .rn-topic-card:hover {
  background: color-mix(in srgb, var(--accent) 8%, var(--paper));
}
.rn-topic-grid--solo .rn-topic-card p { max-width: 68ch; }

/* ============================================================
   BRIDGING BANNER (revision landing page)
   The GCSE→A-Level bridging course sits below the course grid as a
   full-width strip rather than inside it — it's a transition resource,
   not a specification. Shares the crosslink accent language (faint
   accent wash + accent top rule) so "next step" links read as one family.
============================================================ */
.rn-bridge-banner { margin-top: -32px; }
.rn-bridge-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(20px, 4vw, 56px);
  padding: clamp(22px, 3vw, 30px) clamp(22px, 3vw, 34px);
  background: color-mix(in srgb, var(--accent) 6%, var(--paper));
  border: 1px solid var(--hairline);
  box-shadow: inset 0 3px 0 0 var(--accent);
  text-decoration: none;
  color: inherit;
  transition: background .15s;
}
.rn-bridge-banner:hover {
  background: color-mix(in srgb, var(--accent) 10%, var(--paper));
}
.rn-bridge-banner .rn-topic-num { color: var(--accent); }
.rn-bridge-banner h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(22px, 2.2vw, 26px);
  line-height: 1.1;
  letter-spacing: -0.012em;
  margin: 8px 0;
  color: var(--ink);
}
.rn-bridge-banner p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 62ch;
}
.rn-bridge-banner-btn { flex: 0 0 auto; }
.rn-bridge-banner:hover .rn-bridge-banner-btn { background: var(--accent); }
@media (max-width: 720px) {
  .rn-bridge-banner {
    flex-direction: column;
    align-items: flex-start;
    gap: 18px;
  }
  .rn-bridge-banner-btn { align-self: stretch; }
}

/* Bridge hub standfirst — use the sans .page-lede treatment shared by the other
   revision hubs instead of the italic-serif article standfirst, so the section's
   hero intros read consistently. (Insights articles keep the italic style.) */
.rn-standfirst {
  font-family: var(--font-body);
  font-style: normal;
  font-size: clamp(17px, 1.25vw, 20px);
  line-height: 1.5;
}

/* ============================================================
   REVISION NOTE ARTICLE — 2-col layout
============================================================ */
.rn-wrap {
  padding: clamp(48px, 7vw, 80px) 0 clamp(28px, 4vw, 48px);
}
.rn-grid {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: clamp(32px, 5vw, 64px);
  align-items: start;
}

/* ── Sticky TOC ────────────────────────────────────────── */
.rn-toc {
  position: sticky;
  top: 100px;
  /* Cap to the viewport so a long contents list scrolls within itself
     instead of being clipped at the bottom while reading the notes. */
  max-height: calc(100vh - 120px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--paper-2);
  border: 1px solid var(--hairline);
  border-radius: 4px;
  padding: 22px 22px 20px;
}
/* Slim, unobtrusive scrollbar for the contents panel */
.rn-toc {
  scrollbar-width: thin;
  scrollbar-color: var(--hairline) transparent;
}
.rn-toc::-webkit-scrollbar {
  width: 8px;
}
.rn-toc::-webkit-scrollbar-thumb {
  background: var(--hairline);
  border-radius: 999px;
  border: 2px solid var(--paper-2);
}
.rn-toc::-webkit-scrollbar-track {
  background: transparent;
}
.rn-toc-title {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 500;
  margin: 0 0 14px;
}
.rn-toc-list {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: rn-toc;
}
.rn-toc-list li {
  counter-increment: rn-toc;
  position: relative;
  padding-left: 28px;
  margin-bottom: 8px;
}
.rn-toc-list li::before {
  content: counter(rn-toc, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 1px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  color: var(--accent);
}
.rn-toc-list a {
  font-size: 13px;
  line-height: 1.4;
  color: var(--ink-soft);
  text-decoration: none;
  transition: color .15s;
}
.rn-toc-list a:hover,
.rn-toc-list a.is-active { color: var(--ink); }
.rn-toc-divider {
  border: 0;
  border-top: 1px solid var(--hairline);
  margin: 16px 0;
}
.rn-toc-meta {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.02em;
  color: var(--muted);
  line-height: 1.5;
}
.rn-toc-meta .tag {
  font-size: 9px;
  margin-left: 0;
}
.rn-toc-meta .tag-dot {
  font-size: 10px;
  margin-right: 7px;
}
/* Keep a pair of tier badges together so they wrap as one unit
   rather than splitting across two lines. */
.rn-toc-tags { white-space: nowrap; }

.rn-print-btn {
  margin-top: 12px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--hairline);
  padding: 10px 12px;
  border-radius: 999px;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.rn-print-btn:hover {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

/* ── Main content ──────────────────────────────────────── */
.rn-content { min-width: 0; }
.rn-content > h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(28px, 3vw, 38px);
  line-height: 1.08;
  letter-spacing: -0.018em;
  color: var(--ink);
  margin: 56px 0 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--hairline);
  display: flex;
  align-items: center;
  gap: 14px;
  scroll-margin-top: 100px;
}
.rn-content > h2:first-child { margin-top: 0; }
.section-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px; height: 36px;
  background: var(--ink);
  color: var(--paper);
  border-radius: 50%;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
.rn-content > h3 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 17px;
  letter-spacing: -0.005em;
  color: var(--ink);
  margin: 32px 0 10px;
}
.rn-content > p {
  margin: 0 0 18px;
  font-size: 16.5px;
  line-height: 1.7;
  color: var(--ink-soft);
}
.rn-content > p strong { color: var(--ink); font-weight: 600; }
.rn-content > p em { color: var(--ink); font-style: italic; }
.rn-content > ul,
.rn-content > ol {
  padding-left: 0;
  list-style: none;
  display: grid;
  gap: 10px;
  margin: 0 0 22px;
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--ink-soft);
}
.rn-content > ul li,
.rn-content > ol li {
  position: relative;
  padding-left: 24px;
}
.rn-content > ul li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.7em;
  width: 12px; height: 1px;
  background: var(--accent);
}
.rn-content > ol {
  counter-reset: rn-ol;
}
.rn-content > ol > li {
  counter-increment: rn-ol;
}
.rn-content > ol > li::before {
  content: counter(rn-ol, decimal-leading-zero) ".";
  position: absolute;
  left: 0; top: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--accent);
  font-weight: 500;
  line-height: 1.9;
}
.rn-content li strong { color: var(--ink); font-weight: 600; }
.rn-content a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--accent) 50%, transparent);
  transition: color .15s, text-decoration-color .15s;
}
.rn-content a:hover {
  color: var(--accent);
  text-decoration-color: var(--accent);
}
.rn-content sub, .rn-content sup {
  font-size: 0.72em;
  line-height: 0;
}
/* Subscripts/superscripts in the display-serif headings (Kc, Kp, Mr…): the
   browser-default vertical-align sits them too large and gappy in Instrument
   Serif, so position them explicitly and a touch smaller. */
.article-title sub, .rn-content h2 sub, .rn-content h3 sub {
  font-size: 0.58em; line-height: 0; position: relative; vertical-align: baseline; bottom: -0.14em;
}
.article-title sup, .rn-content h2 sup, .rn-content h3 sup {
  font-size: 0.58em; line-height: 0; position: relative; vertical-align: baseline; top: -0.42em;
}

/* Equation / formula highlight (e.g. <p style="background...") */
.rn-eq {
  background: var(--paper-2);
  border-left: 3px solid var(--accent);
  padding: 12px 18px;
  font-weight: 500;
  font-family: var(--font-mono);
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--ink);
  margin: 0 0 18px;
}
/* Verbal-fraction equations (percentage by mass / yield / atom economy) have a
   long worded numerator. .rn-eq-fracmul keeps the fraction and its trailing
   "× 100" together as one unit — "× 100" sits to the RIGHT of the fraction,
   vertically centred, and never drops onto its own line (.rn-eq-mul is nowrap).
   On narrow screens the whole equation centres and the label wraps above the
   fraction; the numerator wraps to stay narrow so "× 100" always has room to its
   right. Desktop keeps the normal inline .rn-eq flow. */
.rn-eq-fracmul { display: inline-flex; align-items: center; gap: 6px; }
.rn-eq-fracmul .rn-eq-mul { white-space: nowrap; }
@media (max-width: 560px) {
  /* Centre equations on mobile. NB: do NOT make this a flex container —
     that turns each <sub>/<sup> into a flex item, which ignores
     vertical-align and breaks subscripts (e.g. C2H5OH). text-align keeps
     normal inline flow so subscripts render, and the inline-flex fraction
     unit (.rn-eq-fracmul) still centres and wraps correctly. */
  .rn-eq--center {
    text-align: center;
  }
  .rn-eq--center .rn-frac-num,
  .rn-eq--center .rn-frac-den { padding-left: 3px; padding-right: 3px; }
}

/* ============================================================
   CALLOUTS — definition / key / tip / warning
============================================================ */
.callout {
  border: 1px solid var(--hairline);
  border-left-width: 4px;
  border-radius: 0 4px 4px 0;
  padding: 18px 22px;
  margin: 24px 0;
  background: var(--paper-2);
  font-size: 15.5px;
}
.callout-title {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 500;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.callout p {
  margin: 0 0 8px;
  line-height: 1.65;
  color: var(--ink-soft);
}
.callout p:last-child { margin-bottom: 0; }
.callout p strong { color: var(--ink); font-weight: 600; }
.callout p em { color: var(--ink); }
.callout ul,
.callout ol {
  padding-left: 0;
  list-style: none;
  margin: 8px 0 0;
  display: grid;
  gap: 6px;
}
.callout ul li,
.callout ol li {
  position: relative;
  padding-left: 20px;
  line-height: 1.6;
  color: var(--ink-soft);
}
.callout ul li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.7em;
  width: 10px; height: 1px;
  background: currentColor;
  opacity: 0.5;
}
.callout ol {
  counter-reset: cl-ol;
}
.callout ol > li {
  counter-increment: cl-ol;
}
.callout ol > li::before {
  content: counter(cl-ol) ".";
  position: absolute;
  left: 0; top: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  color: currentColor;
  opacity: 0.7;
  line-height: 1.7;
}
.callout li strong { color: var(--ink); font-weight: 600; }

/* Variant colours: just the left border + title color */
.callout-def       { border-left-color: var(--ink); }
.callout-def .callout-title { color: var(--ink); }
.callout-key       { border-left-color: var(--accent); }
.callout-key .callout-title { color: var(--accent); }
.callout-tip       { border-left-color: oklch(0.55 0.11 75); }
.callout-tip .callout-title { color: oklch(0.45 0.11 75); }
.callout-warn      { border-left-color: oklch(0.55 0.15 25); }
.callout-warn .callout-title { color: oklch(0.45 0.15 25); }

/* ============================================================
   TABLES — editorial restyle
============================================================ */
.rn-table {
  width: 100%;
  border-collapse: collapse;
  margin: 16px 0 28px;
  font-size: 14.5px;
  border: 1px solid var(--hairline);
}
.rn-table th {
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 10px 14px;
  text-align: left;
  vertical-align: top;
}
/* AQA-verbatim tables inside exam questions keep their source case — the
   uppercase transform corrupts chemistry (Fe → FE, (g) → (G)), so the exam
   engine and print worksheet opt out. */
.rn-exam-q .rn-table th,
/* .wcqg-print covers both halves of the worksheet: the questions AND the mark
   schemes at the back, which is the half a student marks from. Naming only
   .wcqg-print-q left AsF5/KrF2 printing as ASF5/KRF2 on the answer pages. */
.wcqg-print .rn-table th {
  text-transform: none;
  letter-spacing: normal;
  font-size: 12.5px;
}
.rn-table td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--hairline);
  vertical-align: top;
  line-height: 1.55;
  color: var(--ink-soft);
}
.rn-table tr:last-child td { border-bottom: 0; }
.rn-table tr:nth-child(even) td { background: var(--paper-2); }
.rn-table .highlight-col {
  font-weight: 500;
  color: var(--ink);
  font-family: var(--font-body);
}
.rn-table td strong { color: var(--ink); font-weight: 600; }

/* Wide tables (4+ dense columns) stay fully legible on narrow screens by
   scrolling sideways inside their own box rather than clipping or wrapping
   words mid-letter. No forced min-width: tables that fit the screen show no
   scrollbar; only genuinely wide ones scroll. An edge fade hints at the
   off-screen columns on touch devices, where scrollbars are hidden. */
.rn-table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 16px 0 28px;
}
.rn-table-scroll > .rn-table {
  margin: 0;
}
/* Edge-fade cue: site.js toggles .has-more-left / .has-more-right on
   .rn-table-scroll whenever columns sit off-screen in that direction.
   The mask fades that edge so it is obvious the table scrolls. */
.rn-table-scroll { --fade-l: 0px; --fade-r: 0px; }
.rn-table-scroll.has-more-left  { --fade-l: 32px; }
.rn-table-scroll.has-more-right { --fade-r: 32px; }
.rn-table-scroll.has-more-left,
.rn-table-scroll.has-more-right {
  -webkit-mask-image: linear-gradient(to right,
    transparent, black var(--fade-l),
    black calc(100% - var(--fade-r)), transparent);
  mask-image: linear-gradient(to right,
    transparent, black var(--fade-l),
    black calc(100% - var(--fade-r)), transparent);
}

/* ============================================================
   TIMELINE — history of the atom
============================================================ */
.rn-timeline {
  list-style: none;
  padding: 0;
  margin: 16px 0 28px;
  border-left: 1px solid var(--hairline);
  position: relative;
}
.rn-timeline-item {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 24px;
  padding: 24px 0 24px 24px;
  position: relative;
  border-bottom: 1px solid var(--hairline);
}
.rn-timeline-item:last-child { border-bottom: 0; }
.rn-timeline-item::before {
  content: "";
  position: absolute;
  left: -5px; top: 30px;
  width: 9px; height: 9px;
  background: var(--accent);
  border-radius: 50%;
  border: 2px solid var(--paper);
  box-shadow: 0 0 0 1px var(--accent);
}
.rn-timeline-date {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  font-weight: 500;
  color: var(--accent);
  padding-top: 2px;
}
.rn-timeline-scientist {
  font-family: var(--font-display);
  font-size: 22px;
  line-height: 1.1;
  letter-spacing: -0.012em;
  font-weight: 400;
  margin: 0 0 8px;
  color: var(--ink);
}
.rn-timeline-body p {
  margin: 0 0 10px;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-soft);
}
.rn-timeline-body p:last-child { margin-bottom: 0; }
.rn-timeline-body strong { color: var(--ink); font-weight: 600; }
.rn-timeline-body em { color: var(--ink); }
.rn-timeline-body ul {
  list-style: none;
  padding: 0;
  margin: 10px 0 0;
  display: grid;
  gap: 6px;
}
.rn-timeline-body ul li {
  position: relative;
  padding-left: 20px;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink-soft);
}
.rn-timeline-body ul li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.7em;
  width: 10px; height: 1px;
  background: var(--accent);
}

.rn-portrait {
  float: right;
  margin: 0 0 12px 20px;
  text-align: center;
  width: 88px;
}
.rn-portrait img {
  width: 100%;
  height: 88px;
  object-fit: cover;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  background: var(--paper-2);
  display: block;
}
.rn-portrait figcaption {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-top: 6px;
  text-transform: uppercase;
}

/* ============================================================
   FIGURES & IMAGES
============================================================ */
.rn-img-figure {
  margin: 18px 0 22px;
}
.rn-img-figure.center { text-align: center; }
.rn-img-figure img {
  max-width: 100%;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  background: var(--paper-2);
  display: block;
}
.rn-img-figure.center img { margin: 0 auto; }
.rn-img-caption {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin: 8px 0 0;
  line-height: 1.5;
  text-transform: uppercase;
}
/* Chemical formulae keep their correct case (e.g. SiO₂, NaCl, HCl) even inside
   uppercase editorial labels like .rn-img-caption, .callout-title and mono labels. */
.rn-chem { text-transform: none; letter-spacing: normal; }

/* Stacked nuclide notation — mass number over atomic number, both left of the
   symbol. Full markup, so the numbers can NEVER wrap apart from the symbol:
   <span class="rn-nuclide"><span class="rn-nuc"><sup>23</sup><sub>11</sub></span>Na</span>
   (any charge sup goes inside .rn-nuclide too). The .rn-nuc flex column stacks
   the sup/sub (as flex items their super/sub alignment is ignored, so they sit
   flush) and right-aligns them against the symbol; .rn-nuclide pins the whole
   unit to one line — an inline-flex box is otherwise a legal break point. */
.rn-nuclide { white-space: nowrap; }
.rn-nuc { display: inline-flex; flex-direction: column; align-items: flex-end; justify-content: center; vertical-align: 0.32em; line-height: 1; margin-right: 1.5px; }
.rn-nuc sup, .rn-nuc sub { font-size: 0.68em; line-height: 1.12; position: static; vertical-align: baseline; }
/* Narrow figures (e.g. the ΔH⦵ symbol anatomy) — cap the drawing at a readable
   size on desktop instead of stretching to the full column; the 640px mobile
   full-bleed rule below still wins on small screens. */
.rn-img-figure--narrow > svg {
  max-width: 520px;
  display: block;
  margin-inline: auto;
}
/* Scrollable figures (e.g. full periodic table SVG) — scroll rather than shrink on mobile */
.rn-img-figure--scrollable {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.rn-img-figure--scrollable svg {
  min-width: 560px;
}
/* Mobile: figure SVGs bleed into the page gutter (~12% larger drawings, and
   SVG label text with them); the VSEPR matrix scroller bleeds the same amount
   but keeps the gutter as internal padding, so it aligns with the column at
   rest and pans edge-to-edge. Raster <img> figures keep their border and stay
   inside the column. */
@media (max-width: 640px) {
  .rn-content .rn-img-figure > svg {
    width: calc(100% + 2 * var(--gutter));
    margin-inline: calc(-1 * var(--gutter));
    display: block;
  }
  .rn-content .am-matrix-scroll {
    margin-inline: calc(-1 * var(--gutter));
    padding-inline: var(--gutter);
  }
}

/* Two-panel figure duo — a pair of sibling SVG panels (exo vs endo profiles,
   side-by-side definitions) drawn as two narrow SVGs in one figure: 2-up on
   desktop, stacked full-width on mobile, so panel text keeps its authored
   size instead of halving with one wide viewBox. */
.rn-figduo { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 18px; align-items: end; }
.rn-figduo svg { display: block; width: 100%; height: auto; }
@media (max-width: 640px) {
  .rn-figduo { grid-template-columns: 1fr; gap: 16px; }
  .rn-content .rn-img-figure > .rn-figduo {
    width: calc(100% + 2 * var(--gutter));
    margin-inline: calc(-1 * var(--gutter));
  }
}

/* Displayed-formula molecule grid — the CONVENTION for a series of displayed
   formulae (alkanes, alkenes, alcohols …): one panel per molecule, each its own
   SVG + label, that reflow from a row into stacked boxes on mobile. Build each
   panel SVG in the straight gapped-bond style (vertical C–H bonds, lines stopping
   short of every atom). The 1px grid gap over a hairline background draws the
   dividers, so reflow needs no per-cell border bookkeeping. Default 4-up; override
   grid-template-columns inline for a different molecule count. */
.rn-mgrid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  border-radius: 2px;
  overflow: hidden;
}
.rn-mgrid-cell {
  background: var(--paper);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.rn-mgrid-cell svg { display: block; width: 100%; height: auto; }
.rn-mgrid-lbl {
  text-align: center;
  padding: 8px 4px 11px;
  background: var(--paper-2);
  border-top: 1px solid var(--hairline);
}
.rn-mgrid-lbl b { display: block; font-family: var(--font-body); font-size: 13px; font-weight: 600; color: var(--ink); }
.rn-mgrid-lbl span { display: block; font-family: var(--font-mono); font-size: 11.5px; color: var(--muted); margin-top: 2px; }
@media (max-width: 720px) { .rn-mgrid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 460px) { .rn-mgrid { grid-template-columns: 1fr; } }
/* Flame-tests variant: 5 cells on one desktop row (default 4-up orphans the 5th),
   reflowing 5→3→2 columns. Shared: used on C8 Part 3 + required-practicals
   (hoisted from inline copies the page-split had left stranded). */
.rn-mgrid.rn-mgrid-flames { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 700px){
  .rn-mgrid.rn-mgrid-flames { grid-template-columns: repeat(3, 1fr); }
  /* the 5th cell would orphan a column — let it span so there is never an empty box */
  .rn-mgrid.rn-mgrid-flames .rn-mgrid-cell:last-child { grid-column: span 2; }
}
@media (max-width: 440px){ .rn-mgrid.rn-mgrid-flames { grid-template-columns: repeat(2, 1fr); } }

/* ============================================================
   ATOM DIAGRAM
============================================================ */
.atom-diagram {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 28px 0 32px;
  padding: 28px;
  background: var(--paper-2);
  border: 1px solid var(--hairline);
  border-radius: 4px;
}
.atom-outer {
  width: 220px;
  height: 220px;
  border-radius: 50%;
  border: 1px dashed color-mix(in srgb, var(--ink) 25%, transparent);
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}
.atom-nucleus {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  text-align: center;
  line-height: 1.2;
  letter-spacing: 0.02em;
}
.atom-shell {
  position: absolute;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--ink) 18%, transparent);
}
.atom-shell-1 { width: 100px; height: 100px; }
.atom-shell-2 { width: 170px; height: 170px; }
.atom-electron {
  position: absolute;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--paper);
}
.atom-caption {
  margin-top: 16px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--muted);
  text-align: center;
  text-transform: uppercase;
}

/* ============================================================
   ELECTRONIC CONFIG GRID
============================================================ */
.econfig-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  margin: 18px 0 28px;
}
.econfig-card {
  background: var(--paper);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 13.5px;
  color: var(--ink-soft);
}
.econfig-symbol {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--ink);
  line-height: 1.1;
}
.econfig-config {
  font-family: var(--font-mono);
  font-size: 13.5px;
  font-weight: 500;
  color: var(--accent);
  letter-spacing: 0.02em;
}
.econfig-note {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.02em;
  color: var(--muted);
  margin-top: 2px;
  line-height: 1.4;
  text-transform: uppercase;
}

/* ── Periodic table layout ──────────────────────────────────── */
.econfig-ptable {
  display: grid;
  grid-template-columns: auto repeat(2, 1fr) 28px repeat(6, 1fr);
  gap: 4px;
  margin: 16px 0 24px;
  overflow-x: auto;
}
.econfig-period-label {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-right: 6px;
  font-size: 0.68rem;
  font-weight: 600;
  color: #6a7e88;
  white-space: nowrap;
  letter-spacing: 0.02em;
}
.econfig-gh {
  background: #e8f0f5;
  border: 1px solid #c8d8e4;
  border-radius: 6px;
  font-size: 0.65rem;
  font-weight: 700;
  color: #3a5a6a;
  text-align: center;
  padding: 4px 2px;
  white-space: nowrap;
}
.econfig-ptable .econfig-card {
  padding: 6px 5px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  min-width: 0;
  text-align: center;
}
.econfig-ptable .econfig-symbol {
  font-size: 1.05rem;
  font-weight: 700;
  color: #0a2d4a;
  line-height: 1;
  text-transform: none;
  letter-spacing: 0;
}
.econfig-name {
  font-size: 0.6rem;
  color: #4a6070;
  line-height: 1.2;
  text-transform: none;
  font-family: var(--font-body);
}
.econfig-ptable .econfig-config {
  font-size: 0.72rem;
  margin-top: 3px;
}
.econfig-ptable .econfig-note { display: none; }
.econfig-ptable-gap {
  border: 1px dashed #b8ccd4;
  border-radius: 6px;
  background: repeating-linear-gradient(45deg, transparent, transparent 3px, rgba(0,0,0,0.035) 3px, rgba(0,0,0,0.035) 6px);
  display: flex;
  align-items: center;
  justify-content: center;
}
.econfig-ptable-gap span {
  writing-mode: vertical-rl;
  font-size: 0.58rem;
  color: #7a9aaa;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-family: var(--font-mono);
}
.econfig-noble { background: #eef5f0; border-color: #afd0b8; }
.econfig-noble .econfig-symbol { color: #1c6040; }

.econfig-ptable .econfig-card { cursor: pointer; }

.econfig-popup {
  position: fixed;
  width: 140px;
  height: 140px;
  background: #f8f5ef;
  border: 1px solid #d4ccc4;
  border-radius: 10px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.13);
  padding: 6px;
  box-sizing: border-box;
  opacity: 0;
  pointer-events: none;
  z-index: 50;
  transform: translateY(4px);
  transition: opacity 0.12s ease, transform 0.12s ease;
}
.econfig-popup.is-visible {
  opacity: 1;
  transform: translateY(0);
}
.econfig-popup svg { width: 100%; height: 100%; display: block; }

/* ============================================================
   ZOOMABLE FIGURE LIGHTBOX
   Tap a periodic-table figure to open a full-screen, pinch / drag /
   button zoom view. Reusable + opt-in via .rn-img-figure--zoom; the
   behaviour lives in site.js (mirrors the .rn-feedback shared pattern).
============================================================ */
.rn-img-figure--zoom { position: relative; }
/* Inline preview fits the column width (the whole table, scaled down) */
.rn-img-figure--zoom svg,
.rn-img-figure--zoom img { width: 100%; height: auto; display: block; }
.rn-zoom-trigger {
  position: absolute;
  top: 12px; right: 12px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
  background: color-mix(in srgb, var(--paper) 86%, transparent);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  padding: 5px 11px;
  cursor: pointer;
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  transition: background .12s, color .12s, border-color .12s;
}
.rn-zoom-trigger:hover { background: var(--paper); color: var(--ink); border-color: var(--accent); }
/* Graph-figure variant: reserve a strip above the plot so the tap-to-enlarge
   button never covers the drawing or labels. Shared: used on C5 Part 2, C6
   Parts 1/3/4/5, required-practicals (hoisted from C5 Part 1's inline copy
   the page-split had left stranded). */
.rn-graphzoom { padding-top: 28px; }
.rn-graphzoom .rn-zoom-trigger { top: 2px; right: 8px; }

.rn-lightbox {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: flex;
  flex-direction: column;
}
.rn-lightbox[hidden] { display: none; }
.rn-lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: oklch(0.18 0.02 250 / 0.86);
}
.rn-lightbox-stage {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  touch-action: none;            /* drive pan/zoom from JS, not native gestures */
  cursor: grab;
}
.rn-lightbox-stage:active { cursor: grabbing; }
.rn-lightbox-stage svg,
.rn-lightbox-stage img {
  max-width: 96vw;
  max-height: 100%;
  width: auto;
  height: auto;
  background: var(--paper);
  border-radius: 4px;
  transform-origin: center center;
  will-change: transform;
  -webkit-user-select: none;
  user-select: none;
}
.rn-lightbox-controls {
  position: relative;
  display: flex;
  justify-content: center;
  gap: 8px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
}
.rn-lightbox-controls button {
  font-family: var(--font-mono);
  font-size: 13px;
  min-width: 44px;
  height: 40px;
  padding: 0 14px;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  cursor: pointer;
  transition: background .12s, border-color .12s;
}
.rn-lightbox-controls button:hover { border-color: var(--accent); }

/* ============================================================
   RESPONSIVE
============================================================ */
@media (max-width: 960px) {
  .rn-grid { grid-template-columns: 1fr; gap: 32px; }
  /* Single column: let the contents list flow naturally rather than
     becoming a cramped internal scroll box. */
  .rn-toc { position: static; max-height: none; overflow-y: visible; }
  /* Single-column timeline. minmax(0,1fr) + min-width:0 remove the implicit
     min-content floor so a wide child (e.g. a scrollable periodic-table figure
     nested in a timeline item) scrolls inside its frame instead of stretching
     the whole notes column and overflowing the page. */
  .rn-timeline-item { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .rn-timeline-body { min-width: 0; }
}
@media (max-width: 720px) {
  /* Tables fill the width and wrap to fit rather than scrolling sideways
     (with the cell content on these pages this fits without a horizontal bar). */
  .rn-table { font-size: 13.5px; }
  .rn-table th, .rn-table td { padding: 8px 9px; }
}
@media (max-width: 600px) {
  .rn-portrait { float: none; margin: 0 0 12px; width: 100%; max-width: 200px; }
  .rn-portrait img { height: auto; aspect-ratio: 1 / 1; }
  .rn-content > h2 { gap: 10px; font-size: 24px; }
  .section-num { width: 30px; height: 30px; font-size: 11px; }
  /* Clear inline floats on timeline figures (Thomson, Rutherford diagrams) */
  .rn-timeline-body .rn-img-figure {
    float: none !important;
    width: 100% !important;
    margin: 0 0 16px 0 !important;
  }
}

/* Make the small data widgets FIT on mobile instead of scrolling sideways.
   Scoped to these two widgets so the general .rn-table scroll fallback above
   (used by other, genuinely wide tables) is untouched. */
@media (max-width: 560px) {
  /* Protons / Neutrons / Electrons practice table — compact to fit the screen */
  .rn-subatomic-practice th,
  .rn-subatomic-practice td { padding: 6px 4px; font-size: 11.5px; }
  .rn-subatomic-practice .rn-particle-input {
    width: 40px; padding: 4px 2px; font-size: 12px;
  }
}
@media (max-width: 520px) {
  /* First-20-elements electronic-structure table — shrink cells so every group
     fits; hide the always-on "2,8,1" text and read it via the tap shell-diagram
     popup instead (the popup JS still reads .econfig-config, which stays in the
     DOM — only display is suppressed). */
  .econfig-ptable { gap: 2px; }
  .econfig-ptable .econfig-card { padding: 4px 1px; }
  .econfig-ptable .econfig-symbol { font-size: 0.85rem; }
  .econfig-ptable .econfig-name { font-size: 0.46rem; line-height: 1.1; }
  .econfig-ptable .econfig-config { display: none; }
  .econfig-period-label { font-size: 0.5rem; padding-right: 3px; white-space: normal; }
  /* Let "Group 1" headers wrap so they stop flooring the column width */
  .econfig-gh { font-size: 0.5rem; padding: 3px 1px; white-space: normal; }
  .econfig-ptable-gap span { font-size: 0.5rem; }
}

/* ============================================================
   TABLE UTILITY WIDTH CLASSES
============================================================ */
.rn-table--narrow { max-width: 420px; }
.rn-table--med    { max-width: 620px; }

/* ============================================================
   PRACTICE QUESTIONS — <details>/<summary> reveal component
============================================================ */
.rn-practice {
  border: 1px solid var(--hairline);
  border-left: 4px solid oklch(0.52 0.13 200);
  border-radius: 0 4px 4px 0;
  margin: 28px 0;
  background: var(--paper-2);
  overflow: hidden;
}
.rn-practice-header {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 500;
  color: oklch(0.40 0.12 200);
  padding: 14px 22px 6px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.rn-practice-q {
  padding: 0 22px 14px;
  font-size: 15.5px;
  line-height: 1.65;
  color: var(--ink-soft);
  margin: 0;
}
.rn-practice-q strong { color: var(--ink); font-weight: 600; }
/* Descendant combinator so reveals nested inside .rn-exam-q (e.g. C4's
   per-question answers) get the same styling as direct children. */
.rn-practice details {
  border-top: 1px solid var(--hairline);
}
.rn-practice details > summary {
  padding: 10px 22px;
  cursor: pointer;
  font-family: var(--font-mono);
  /* font-size:0 hides the literal "Show answer" text node so it doesn't
     duplicate the ::after label; ::after restores its own size below. */
  font-size: 0;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 500;
  color: oklch(0.40 0.12 200);
  list-style: none;
  display: flex;
  align-items: center;
  gap: 8px;
  user-select: none;
  transition: background .15s;
}
.rn-practice details > summary::-webkit-details-marker { display: none; }
.rn-practice details > summary::after {
  content: "Show answer →";
  font-size: 11px;
  margin-left: auto;
}
.rn-practice details[open] > summary::after { content: "Hide ↑"; }
.rn-practice details > summary:hover {
  background: color-mix(in srgb, oklch(0.52 0.13 200) 8%, transparent);
}
.rn-practice-answer {
  padding: 14px 22px;
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink-soft);
  border-top: 1px solid var(--hairline);
}
.rn-practice-answer p { margin: 0 0 8px; }
.rn-practice-answer p:last-child { margin-bottom: 0; }
.rn-practice-answer strong { color: var(--ink); font-weight: 600; }
.rn-practice-answer ul {
  list-style: none;
  padding: 0;
  margin: 6px 0 0;
  display: grid;
  gap: 4px;
}
.rn-practice-answer ul li {
  position: relative;
  padding-left: 18px;
  line-height: 1.55;
}
.rn-practice-answer ul li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.7em;
  width: 10px; height: 1px;
  background: oklch(0.52 0.13 200);
}

/* ============================================================
   COLLAPSIBLE EXAM SECTIONS — testing practice tucked behind a bar
   (.rn-practice container upgraded from <div> to <details>; the
   header becomes a full-width clickable summary. Closed by default
   so teaching content isn't crowded by question banks.)
============================================================ */
details.rn-practice--collapsible > summary.rn-practice-summary {
  cursor: pointer;
  list-style: none;
  user-select: none;
  padding: 13px 22px;          /* balanced bar when closed */
  align-items: center;
  transition: background .15s;
}
details.rn-practice--collapsible > summary.rn-practice-summary::-webkit-details-marker { display: none; }
details.rn-practice--collapsible > summary.rn-practice-summary::after {
  content: "Show questions ↓";
  margin-left: auto;
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--muted);
  flex: none;
}
details.rn-practice--collapsible[open] > summary.rn-practice-summary::after { content: "Hide ↑"; }
/* non-question collapsibles (e.g. a model answer) override the affordance
   label via data-reveal="Show … ↓" ON THE SUMMARY (attr() in a ::after can
   only read the summary's own attributes) — include the arrow in the value */
details.rn-practice--collapsible:not([open]) > summary.rn-practice-summary[data-reveal]::after { content: attr(data-reveal); }
details.rn-practice--collapsible > summary.rn-practice-summary:hover {
  background: color-mix(in srgb, oklch(0.52 0.13 200) 8%, transparent);
}
details.rn-practice--collapsible[open] > summary.rn-practice-summary {
  border-bottom: 1px solid var(--hairline);
}

/* ============================================================
   EXAM-STYLE QUESTIONS — builds on .rn-practice
   (interactive MCQ tick-boxes, type-in numeric, equation balancing)
============================================================ */
.rn-exam-q { padding: 15px 22px 17px; border-top: 1px solid var(--hairline); }
.rn-exam-qhead { display: flex; align-items: baseline; gap: 12px; margin-bottom: 10px; }
.rn-exam-num {
  font-family: var(--font-mono); font-size: 11px; font-weight: 500; letter-spacing: 0.05em;
  color: var(--paper); background: oklch(0.40 0.12 200);
  padding: 2px 8px; border-radius: 3px; flex: none;
}
.rn-exam-marks { font-family: var(--font-mono); font-size: 11px; color: var(--muted); margin-left: auto; flex: none; }
.rn-exam-stem { font-size: 15.5px; line-height: 1.6; color: var(--ink-soft); margin: 0; }
/* a stem set as paragraphs and bullet points, the way the paper prints it */
.rn-exam-stem .wcqg-line { margin: 0 0 8px; }
.rn-exam-stem .wcqg-ul { margin: 0 0 8px; padding-left: 22px; }
.rn-exam-stem .wcqg-ul li { margin: 0 0 4px; }
.rn-exam-stem + .rn-exam-stem { margin-top: 9px; }
.rn-exam-stem strong { color: var(--ink); font-weight: 600; }
.rn-exam-instr { display: block; margin-top: 5px; font-size: 13px; color: var(--muted); font-style: italic; }
.rn-exam-given {
  margin: 13px 0 0; padding: 9px 13px; border-left: 2px solid oklch(0.52 0.13 200);
  background: var(--paper); font-size: 13.5px; line-height: 1.55; color: var(--ink-soft);
  border-radius: 0 3px 3px 0;
}
.rn-exam-given strong { color: var(--ink); font-weight: 600; }
.rn-exam-eq, .rn-exam-work { font-family: var(--font-mono); font-size: 13px; color: var(--ink); }
.rn-exam-mk { font-family: var(--font-mono); font-size: 10px; font-weight: 500; letter-spacing: 0.04em; text-transform: uppercase; color: oklch(0.40 0.12 200); background: oklch(0.95 0.025 200); border: 1px solid oklch(0.82 0.04 200); border-radius: 3px; padding: 1px 5px; white-space: nowrap; }
.rn-exam-note { color: var(--muted); font-size: 13px; }
.rn-exam-src { margin: 14px 0 0; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
/* Interactive tick-the-box options — feedback colours mirror .rn-classify */
.rn-exam-options { padding: 0; margin: 13px 0 0; display: grid; gap: 8px; }
.rn-exam-option {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  font-family: inherit; font-size: 15px; color: var(--ink-soft);
  min-height: 44px;                 /* comfortable touch target on phones */
  padding: 8px 11px; border: 1px solid var(--hairline); border-radius: 4px;
  background: var(--paper); cursor: pointer; transition: background .12s, border-color .12s;
}
.rn-exam-option:hover:not(:disabled) { background: var(--paper-2); border-color: var(--ink-soft); }
.rn-exam-option:disabled { cursor: default; }
.rn-exam-option:focus-visible { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 2px; }
.rn-exam-box {
  flex: none; width: 17px; height: 17px; border: 1.5px solid var(--muted); border-radius: 3px;
  background: var(--paper); display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; line-height: 1; color: var(--paper); font-weight: 700;
}
.rn-exam-option.opt-ok  { background: oklch(0.95 0.04 155); border-color: oklch(0.50 0.15 155); color: oklch(0.30 0.12 155); }
.rn-exam-option.opt-err { background: oklch(0.96 0.04 25);  border-color: oklch(0.55 0.15 25);  color: oklch(0.35 0.15 25); }
/* Dimmed, not unreadable: at 0.4 the options you did not pick fell to about
   2.2:1 against the paper, well under the 4.5:1 body text needs — and they are
   still the wrong answers a student has to read to learn anything from the
   question. */
.rn-exam-option.opt-dim { opacity: 0.68; }
.rn-exam-option.opt-ok  .rn-exam-box { border-color: oklch(0.45 0.15 155); background: oklch(0.52 0.15 155); }
.rn-exam-option.opt-ok  .rn-exam-box::after { content: "✓"; }
.rn-exam-option.opt-err .rn-exam-box { border-color: oklch(0.55 0.15 25);  background: oklch(0.60 0.17 25); }
.rn-exam-option.opt-err .rn-exam-box::after { content: "✗"; }
/* select-two: in-progress "selected" state for a tick-two MCQ before grading */
.rn-exam-option.opt-sel { background: oklch(0.95 0.03 230); border-color: oklch(0.52 0.13 230); color: oklch(0.30 0.10 230); }
.rn-exam-option.opt-sel .rn-exam-box { border-color: oklch(0.48 0.13 230); background: oklch(0.52 0.13 230); }
.rn-exam-option.opt-sel .rn-exam-box::after { content: "\2713"; }
.rn-exam-feedback { margin: 12px 0 0; font-family: var(--font-mono); font-size: 12px; font-weight: 500; letter-spacing: 0.02em; }
.rn-exam-feedback:empty { display: none; }
.rn-exam-feedback.fc-ok  { color: oklch(0.38 0.13 155); }
.rn-exam-feedback.fc-err { color: oklch(0.45 0.15 25); }
.rn-exam-explanation {
  margin: 9px 0 0; padding: 11px 14px; border-radius: 3px; font-size: 14.5px; line-height: 1.6;
  border: 1px solid var(--hairline); background: var(--paper-2); color: var(--ink-soft);
}
.rn-exam-explanation.fc-ok  { background: oklch(0.95 0.04 155); color: oklch(0.30 0.12 155); border-color: oklch(0.50 0.15 155); }
.rn-exam-explanation.fc-err { background: oklch(0.96 0.04 25);  color: oklch(0.35 0.15 25);  border-color: oklch(0.55 0.15 25); }
.rn-exam-explanation strong { color: inherit; font-weight: 700; }
/* Type-in numeric answers */
.rn-exam-numeric { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 9px; margin: 13px 0 0; }
.rn-exam-numeric + .rn-exam-numeric { margin-top: 9px; }
.rn-exam-ilabel { font-family: var(--font-mono); font-size: 12.5px; color: var(--muted); }
.rn-exam-field {
  font-family: var(--font-mono); font-size: 15px; color: var(--ink);
  width: 130px; max-width: 46vw; padding: 8px 11px;
  border: 1px solid var(--hairline); border-radius: 4px; background: var(--paper);
}
.rn-exam-field::placeholder { color: var(--muted); opacity: 0.55; }
.rn-exam-field:focus-visible { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 1px; border-color: oklch(0.52 0.13 200); }
.rn-exam-unit { font-family: var(--font-mono); font-size: 14px; color: var(--ink-soft); }
.rn-exam-field.is-ok  { border-color: oklch(0.50 0.15 155); background: oklch(0.96 0.035 155); color: oklch(0.30 0.12 155); font-weight: 600; }
.rn-exam-field.is-err { border-color: oklch(0.58 0.16 25);  background: oklch(0.96 0.035 25);  color: oklch(0.38 0.16 25); }
.rn-exam-check {
  display: inline-block; margin-top: 11px;
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--paper); background: oklch(0.40 0.12 200); border: 1px solid oklch(0.40 0.12 200);
  padding: 9px 17px; border-radius: 4px; cursor: pointer; transition: background .12s;
}
.rn-exam-check:hover { background: oklch(0.34 0.12 200); }
.rn-exam-check:focus-visible { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 2px; }
/* When .rn-exam-check is an <a> inside article prose, `.article-body-inner a`
   (page.css) would otherwise force the dark --ink text onto the teal fill,
   making the button look muddy. Keep the white --paper label so an anchor CTA
   matches the <button> version (e.g. the diagnostic "Start" button). */
.article-body-inner a.rn-exam-check,
a.rn-exam-check { color: var(--paper); text-decoration: none; }
.article-body-inner a.rn-exam-check:hover,
a.rn-exam-check:hover { color: var(--paper); }
/* Interactive balancing. No column-gap: a bare formula like N<sub>2</sub>
   splits into separate anonymous flex items, so a gap would push the
   subscript away from its letter — horizontal spacing lives on the
   inputs/operators instead. */
.rn-exam-eqline {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 0; margin: 14px 0 2px;
  font-family: var(--font-mono); font-size: 15.5px; color: var(--ink); line-height: 2;
}
.rn-exam-eqline .rn-exam-coef { margin-right: 7px; }
.rn-exam-eqline > span[aria-hidden="true"] { margin: 0 7px; }
.rn-exam-eqline .rn-exam-check { margin-top: 0; margin-left: 13px; }
.rn-exam-coef {
  font-family: var(--font-mono); font-size: 15px; font-weight: 600; color: var(--accent);
  width: 40px; text-align: center; padding: 6px 2px;
  border: 1px solid var(--hairline); border-radius: 4px; background: var(--paper);
}
.rn-exam-coef::placeholder { color: var(--muted); opacity: 0.5; font-weight: 400; }
.rn-exam-coef:focus-visible { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 1px; border-color: oklch(0.52 0.13 200); }
.rn-exam-coef.is-ok  { border-color: oklch(0.50 0.15 155); background: oklch(0.96 0.035 155); color: oklch(0.30 0.12 155); }
.rn-exam-coef.is-err { border-color: oklch(0.58 0.16 25);  background: oklch(0.96 0.035 25);  color: oklch(0.38 0.16 25); }

/* ============================================================
   ASIDE — beyond-spec / interesting note
============================================================ */
.rn-aside {
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted);
  border-left: 2px solid var(--hairline);
  padding: 4px 14px;
  margin: 10px 0 12px;
  font-style: italic;
}
.rn-aside strong { color: var(--ink-soft); font-weight: 600; font-style: normal; }

/* ============================================================
   FORWARD LINK — "covered later" signposting banner
============================================================ */
.rn-forward-link {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 18px;
  background: var(--paper-2);
  border: 1px solid var(--hairline);
  border-radius: 4px;
  margin: 16px 0 24px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-soft);
}
.rn-forward-link-icon {
  font-size: 16px;
  flex-shrink: 0;
  margin-top: 1px;
}
.rn-forward-link a {
  color: var(--accent);
  font-weight: 500;
  text-decoration: none;
}
.rn-forward-link a:hover { text-decoration: underline; }
/* Backward "recap" variant — same component, signalled as looking back to a
   prerequisite topic (icon 🔗 in markup) rather than forward (📌). Cooler,
   slightly recessed so forward vs back reads at a glance. */
.rn-forward-link--recap {
  background: oklch(0.97 0.012 220);
  border-color: oklch(0.86 0.03 220);
}
.rn-forward-link--recap .rn-forward-link a { color: oklch(0.46 0.10 220); }

/* ============================================================
   RUTHERFORD DIAGRAM
============================================================ */
.rn-rutherford-svg {
  display: block;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  background: var(--paper-2);
}

/* ============================================================
   INLINE FRACTION — for equation display
============================================================ */
.rn-frac {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  vertical-align: middle;
  line-height: 1.3;
  margin: 0 2px;
}
.rn-frac-num {
  border-bottom: 1.5px solid currentColor;
  padding: 0 6px 3px;
  text-align: center;
}
.rn-frac-den {
  padding: 3px 6px 0;
  text-align: center;
}

/* ============================================================
   PARTICLE INPUT TABLE — interactive practice
============================================================ */
.rn-practice-hint {
  font-size: 14.5px;
  color: var(--ink-soft);
  margin: -8px 0 14px;
  line-height: 1.55;
}
.rn-particle-input {
  width: 68px;
  padding: 5px 8px;
  font-family: var(--font-mono);
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink);
  background: var(--paper);
  border: 1.5px solid var(--hairline);
  border-radius: 3px;
  text-align: center;
  outline: none;
  transition: border-color .15s, background .15s;
  -moz-appearance: textfield;
}
.rn-particle-input::-webkit-inner-spin-button,
.rn-particle-input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.rn-particle-input:focus {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 6%, var(--paper));
}
.rn-particle-input.is-correct {
  border-color: oklch(0.50 0.15 155);
  background: oklch(0.95 0.04 155);
  color: oklch(0.30 0.12 155);
}
.rn-particle-input.is-incorrect {
  border-color: oklch(0.55 0.15 25);
  background: oklch(0.96 0.04 25);
  color: oklch(0.35 0.15 25);
}
.rn-practice-controls {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: -12px 0 28px;
  flex-wrap: wrap;
}
.rn-check-btn,
.rn-reset-btn {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 500;
  padding: 9px 18px;
  border-radius: 999px;
  border: 1.5px solid;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.rn-check-btn {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
.rn-check-btn:hover {
  background: oklch(0.45 0.12 200);
  border-color: oklch(0.45 0.12 200);
}
.rn-reset-btn {
  background: transparent;
  color: var(--ink-soft);
  border-color: var(--hairline);
}
.rn-reset-btn:hover {
  background: var(--paper-2);
  border-color: var(--ink-soft);
  color: var(--ink);
}
.rn-score {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}
.rn-score.is-perfect { color: oklch(0.38 0.13 155); }
.rn-score.is-partial  { color: oklch(0.45 0.11 75); }
.rn-score.is-zero     { color: oklch(0.45 0.15 25); }

/* ============================================================
   TOC GROUP HEADINGS — subheadings between content-group lists
============================================================ */
.rn-toc-subheading {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--muted);
  margin: 14px 0 6px;
  padding-bottom: 5px;
  border-bottom: 1px solid var(--hairline);
}
.rn-toc-subheading:first-of-type { margin-top: 0; }
.rn-toc-list + .rn-toc-subheading { margin-top: 14px; }
/* Capstone TOC entry: a standalone link styled as a subheading but WITHOUT the
   group-label underline, so it doesn't double up with the rn-toc-divider below it. */
.rn-toc-subheading--link { border-bottom: none; padding-bottom: 0; }

/* ============================================================
   DIAGRAM PLACEHOLDER — temporary marker for future diagrams
============================================================ */
.rn-diagram-placeholder {
  border: 1.5px dashed var(--hairline);
  border-radius: 4px;
  background: var(--paper-2);
  padding: 28px 20px;
  text-align: center;
  margin: 18px 0 24px;
}
.rn-diagram-placeholder p {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.03em;
  color: var(--muted);
  margin: 0;
  line-height: 1.6;
}

/* ============================================================
   FEEDBACK — report an error / suggestion (Formspree)
============================================================ */
.rn-feedback {
  padding: clamp(36px, 5vw, 60px) 0;
  border-top: 1px solid var(--hairline);
}
.rn-feedback-inner {
  max-width: 680px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 18px 24px;
}
.rn-feedback-copy { max-width: 44ch; }
.rn-feedback-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(21px, 2.4vw, 27px);
  line-height: 1.12;
  letter-spacing: -0.015em;
  margin: 0 0 6px;
  color: var(--ink);
}
.rn-feedback-sub {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-soft);
}
.rn-feedback-toggle { flex: none; }
.rn-feedback-toggle[hidden] { display: none; }

/* Form — revealed when the toggle is pressed */
.rn-feedback-form {
  flex-basis: 100%;
  margin-top: 4px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  animation: rn-feedback-in .25s ease;
}
.rn-feedback-form[hidden] { display: none; }
@keyframes rn-feedback-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
.rn-feedback-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.rn-feedback-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
}
.rn-feedback-opt { font-weight: 400; color: var(--muted); }
.rn-feedback-form textarea,
.rn-feedback-form input[type="email"] {
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 10px 12px;
  width: 100%;
}
.rn-feedback-form textarea { resize: vertical; min-height: 92px; }
.rn-feedback-form textarea:focus,
.rn-feedback-form input[type="email"]:focus {
  outline: none;
  border-color: var(--accent);
}
.rn-feedback-form textarea::placeholder,
.rn-feedback-form input::placeholder { color: var(--muted); }
.rn-feedback-actions {
  display: flex;
  align-items: center;
  gap: 8px 18px;
  flex-wrap: wrap;
}
.rn-feedback-status {
  margin: 0;
  font-size: 14px;
  color: var(--ink-soft);
}
.rn-feedback-status.is-err { color: var(--accent); }
.rn-feedback-thanks {
  margin: 0;
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink);
}
@media (prefers-reduced-motion: reduce) {
  .rn-feedback-form { animation: none; }
}
@media (max-width: 560px) {
  .rn-feedback-inner { flex-direction: column; align-items: stretch; }
  .rn-feedback-toggle { width: 100%; }
}

/* ============================================================
   TOPIC PAGER — previous / next in the Paper 1 sequence
============================================================ */
.rn-pager-section { padding: 0; }
.rn-pager {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
}
.rn-pager-link {
  background: var(--paper);
  padding: 24px 28px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  text-decoration: none;
  color: inherit;
  transition: background .15s;
}
.rn-pager-link:hover { background: var(--paper-2); }
.rn-pager-next { align-items: flex-end; text-align: right; }
.rn-pager-dir {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.rn-pager-link:hover .rn-pager-dir { color: var(--ink-soft); }
.rn-pager-topic {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 19px;
  line-height: 1.2;
  letter-spacing: -0.012em;
  color: var(--ink);
}
.rn-pager-link:hover .rn-pager-topic { color: var(--accent); }
@media (max-width: 600px) {
  .rn-pager { grid-template-columns: 1fr; }
  .rn-pager-next { align-items: flex-start; text-align: left; }
}

/* ============================================================
   PRINT
============================================================ */
@media print {
  .header, .footer, .rn-toc, .article-cta, .final-cta, .nav-cta, .rn-feedback, .rn-pager-section, .sticky-cta, .article-related { display: none !important; }
  .rn-grid { grid-template-columns: 1fr; }
  .rn-content > h2 { page-break-after: avoid; }
  .callout, .rn-table, .rn-timeline-item, .atom-diagram, .econfig-grid { break-inside: avoid; }
  body { background: white; color: black; }
}

/* ============================================================
   SKIP LINK — first focusable element in <body>; visually hidden
   until focused so keyboard users can jump past the header nav.
============================================================ */
/* .skip-link is defined once in styles.css (loaded by every page) — the
   duplicate that used to live here fought it in the cascade on revision
   pages, producing a hybrid of two designs. */

/* ============================================================
   CAPSTONE — shared drag-or-tap "sort the chips into bins" activity
   used by the ★ capstone on every topic page. Behaviour is in
   site.js (driven by .rn-cap-wrap / data-cat / data-bin). Was
   previously duplicated inline per page (cl-/cap-).
============================================================ */
.rn-cap-wrap { margin: 18px 0 28px; padding: 16px 16px 14px; background: var(--paper-2); border: 1px solid var(--hairline); border-radius: 6px; }
.rn-cap-lead { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); margin: 0 0 8px; }
.rn-cap-tray { display: flex; flex-wrap: wrap; gap: 8px; padding: 10px; border: 1px dashed var(--hairline); border-radius: 6px; background: var(--paper); margin-bottom: 14px; align-content: flex-start; min-height: 40px; }
.rn-cap-chip { font-family: var(--font-sans); font-size: 13px; font-weight: 600; padding: 8px 13px; border-radius: 999px; border: 1.5px solid var(--ink-soft); background: var(--paper); color: var(--ink); cursor: grab; line-height: 1; min-height: 38px; display: inline-flex; align-items: center; touch-action: none; user-select: none; -webkit-user-select: none; }
/* Subscripts/superscripts that read correctly inside the tight (line-height:1) pill:
   line-height:0 + relative offset, so the glyph lowers without inflating the chip. */
.rn-cap-chip sub, .rn-cap-chip sup { font-size: 0.72em; line-height: 0; position: relative; vertical-align: baseline; }
.rn-cap-chip sub { bottom: -0.22em; }
.rn-cap-chip sup { top: -0.45em; }
.rn-cap-chip:hover { border-color: var(--accent); }
.rn-cap-chip:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.rn-cap-chip.rn-cap-dragging { position: fixed; z-index: 9999; pointer-events: none; cursor: grabbing; box-shadow: 0 6px 18px oklch(0.2 0.02 250 / 0.25); opacity: 0.97; margin: 0; }
.rn-cap-chip.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.95 0.045 150); color: oklch(0.32 0.08 150); }
.rn-cap-chip.is-err { border-color: var(--accent); background: oklch(0.95 0.05 30); color: var(--accent); }
.rn-cap-tray.rn-cap-over, .rn-cap-bin.rn-cap-over { border-color: var(--accent); background: oklch(0.96 0.03 30); }
.rn-cap-bins { display: flex; gap: 10px; flex-wrap: wrap; }
.rn-cap-bin { flex: 1 1 150px; min-width: 138px; border: 1.5px solid var(--hairline); border-radius: 6px; overflow: hidden; background: var(--paper); cursor: pointer; }
.rn-cap-bin-h { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; font-weight: 600; padding: 8px; text-align: center; color: oklch(0.975 0.005 80); line-height: 1.3; background: oklch(0.45 0.03 250); }
/* Up to four bins get distinct heading colours by position. */
.rn-cap-bin:nth-of-type(1) .rn-cap-bin-h { background: oklch(0.52 0.13 38); }
.rn-cap-bin:nth-of-type(2) .rn-cap-bin-h { background: oklch(0.40 0.025 250); }
.rn-cap-bin:nth-of-type(3) .rn-cap-bin-h { background: oklch(0.48 0.07 200); }
.rn-cap-bin:nth-of-type(4) .rn-cap-bin-h { background: oklch(0.46 0.10 150); }
.rn-cap-bin-h span { display: block; font-weight: 400; text-transform: none; letter-spacing: 0; font-size: 9.5px; opacity: 0.85; margin-top: 1px; }
.rn-cap-bin-body { display: flex; flex-wrap: wrap; gap: 7px; padding: 10px; min-height: 58px; align-content: flex-start; }
.rn-cap-controls { display: flex; align-items: center; gap: 12px; margin-top: 14px; flex-wrap: wrap; }
.rn-cap-btn { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.07em; text-transform: uppercase; font-weight: 500; padding: 8px 16px; border-radius: 999px; border: 1.5px solid var(--hairline); cursor: pointer; background: var(--paper); color: var(--ink-soft); min-height: 38px; }
.rn-cap-btn:hover { border-color: var(--ink-soft); color: var(--ink); }
.rn-cap-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.rn-cap-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.rn-cap-btn:disabled:hover { border-color: var(--hairline); color: var(--ink-soft); }
.rn-cap-score { font-family: var(--font-mono); font-size: 12.5px; font-weight: 600; color: var(--ink); }
.rn-cap-msg { font-size: 13px; color: var(--ink-soft); font-style: italic; margin: 10px 0 0; min-height: 1.4em; }


/* ============================================================
   GCSE topic-split components: cross-page sidebar nav (.rn-nav*),
   hub accordion (.rn-acc*) + hub pager, cluster pager (.rn-cluster-pager).
   Folded in from the C1 split prototype.
   ============================================================ */

/* The cross-page navigation sidebar (replaces the single-page .rn-toc).
   Mirrors .rn-toc so it looks native, but lists every sub-topic across
   all cluster pages, with the current page highlighted. */
.rn-nav {
  position: sticky;
  top: 100px;
  max-height: calc(100vh - 120px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--paper-2);
  border: 1px solid var(--hairline);
  border-radius: 4px;
  padding: 18px 18px 18px;
  scrollbar-width: thin;
  scrollbar-color: var(--hairline) transparent;
}
.rn-nav::-webkit-scrollbar { width: 8px; }
.rn-nav::-webkit-scrollbar-thumb { background: var(--hairline); border-radius: 8px; }

.rn-nav-title {
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3, #69605a);
  margin: 0 0 12px;
}

/* Each cluster (= one page) is a group in the nav */
.rn-nav-group { margin: 0 0 6px; }
.rn-nav-grouphead {
  display: block;
  font-weight: 600;
  font-size: 0.92rem;
  line-height: 1.35;
  color: var(--ink);
  text-decoration: none;
  padding: 7px 10px;
  border-radius: 4px;
  border: 1px solid transparent;
}
.rn-nav-grouphead:hover { background: var(--paper, #fff); }
.rn-nav-group.is-current > .rn-nav-grouphead {
  background: var(--paper, #fff);
  border-color: var(--hairline);
  color: var(--accent, #b5462f);
}

/* Sub-topic links inside a cluster */
.rn-nav-list {
  list-style: none;
  margin: 2px 0 8px;
  padding: 0 0 0 2px;
  border-left: 2px solid var(--hairline);
  /* Collapsed by default for non-current groups to keep the list short */
}
.rn-nav-group:not(.is-current) .rn-nav-list { display: none; }
/* Single-page contents (.rn-nav--index, e.g. required practicals): there is no
   "current page" to collapse to, so keep every group's sub-list open. */
.rn-nav--index .rn-nav-group .rn-nav-list { display: block; }
/* Flex row so an A2 / tier dot appended after the link sits on the SAME line
   (aligned to the first line of the link text), not wrapped onto its own line. */
.rn-nav-list li { margin: 0; display: flex; align-items: baseline; gap: 4px; }
.rn-nav-list li > a { flex: 1 1 auto; min-width: 0; }
.rn-nav-list li > .rn-toc-tags { flex: none; padding-right: 8px; }
.rn-nav-list a {
  display: block;
  font-size: 0.86rem;
  line-height: 1.3;
  color: var(--ink-2, #4a443e);
  text-decoration: none;
  padding: 6px 10px;
  border-radius: 4px;
}
.rn-nav-list a:hover { color: var(--ink); background: var(--paper, #fff); }
.rn-nav-list a.is-active {
  color: var(--accent, #b5462f);
  font-weight: 600;
}

.rn-nav-divider { border: 0; border-top: 1px solid var(--hairline); margin: 14px 0 10px; }
.rn-nav-meta { display: flex; flex-direction: column; gap: 6px; font-size: 0.74rem; color: var(--ink-3, #69605a); }
.rn-nav-meta .tag { margin-right: 4px; }

/* Mobile toggle button — hidden on desktop */
.rn-nav-toggle { display: none; }

/* Cross-page pager between cluster pages */
.rn-cluster-pager .rn-pager-topic { display: block; }
.rn-cluster-pager .rn-pager-allbtn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0 auto;
  font-size: 0.85rem;
  color: var(--ink-2, #4a443e);
  text-decoration: none;
}
.rn-cluster-pager .rn-pager-allbtn:hover { color: var(--accent, #b5462f); }

/* ---------- Hub: SaveMyExams-style accordion ---------- */
.rn-acc-list { display: flex; flex-direction: column; gap: 12px; margin: 10px 0 32px; }

.rn-acc, .rn-acc-link {
  border: 1px solid var(--hairline);
  border-radius: 12px;
  background: var(--paper-2);
  transition: border-color .15s ease, background .15s ease;
}
.rn-acc[open] { background: var(--paper, #fff); }
.rn-acc:hover, .rn-acc-link:hover { border-color: var(--ink-3, #b8b1a8); }

.rn-acc-head, .rn-acc-link {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 20px 24px;
  cursor: pointer;
  list-style: none;
  text-decoration: none;
}
.rn-acc-head::-webkit-details-marker { display: none; }
.rn-acc-head::marker { content: ""; }

.rn-acc-title { flex: 1 1 auto; font-weight: 600; font-size: 1.05rem; color: var(--ink); }
.rn-acc-link:hover .rn-acc-title,
.rn-acc-head:hover .rn-acc-title { color: var(--accent, #b5462f); }

.rn-acc-chev { flex: 0 0 auto; color: var(--ink-3, #69605a); font-size: 0.9rem; transition: transform .18s ease; }
.rn-acc[open] .rn-acc-chev { transform: rotate(180deg); }
.rn-acc-arrow { flex: 0 0 auto; color: var(--accent, #b5462f); font-weight: 600; }
.rn-acc-flag {
  flex: 0 0 auto;
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: var(--ink-3, #69605a);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  padding: 3px 9px;
}
.rn-acc-capstone { border-left: 3px solid var(--accent, #b5462f); }

.rn-acc-body { list-style: none; margin: 0; padding: 4px 24px 14px; }
.rn-acc-body li { border-top: 1px solid var(--hairline); }
.rn-acc-body a {
  display: block;
  padding: 12px 6px;
  color: var(--ink-2, #4a443e);
  text-decoration: none;
  font-size: 0.96rem;
}
.rn-acc-body a:hover { color: var(--accent, #b5462f); }

/* Tier note as a compact, muted collapsible above the parts list */
.rn-acc-tier { margin-bottom: 18px; border-style: dashed; background: transparent; }
.rn-acc-tier .rn-acc-title { font-weight: 600; font-size: 0.95rem; color: var(--ink-2, #4a443e); }
.rn-acc-tierbody { padding: 2px 24px 18px; color: var(--ink-2, #4a443e); font-size: 0.92rem; line-height: 1.55; }
.rn-acc-tierbody p { margin: 0 0 8px; }
.rn-acc-tierbody ul { margin: 8px 0 0; padding-left: 20px; }
.rn-acc-tierbody li { margin: 5px 0; }

/* Hub: trim the generous article padding so the short page isn't full of gaps */
.hub-page .rn-wrap { padding-top: clamp(28px, 4vw, 40px); padding-bottom: clamp(12px, 2vw, 20px); }
.hub-page .article-related { padding-top: clamp(36px, 5vw, 56px); }
/* Hub has no sidebar grid: let the contents column span the full wrap width
   so the accordion lines up with the hero/header (no lopsided right-hand gap).
   Keep the intro paragraph at a readable measure. */
.hub-page .rn-content { max-width: none; }

/* Beat the global `.rn-content a { text-decoration: underline; color: ink }` rule */
.rn-content a.rn-acc-link,
.rn-content .rn-acc-body a,
.rn-content a.rn-pager-link,
.rn-content a.btn { text-decoration: none; }
.rn-content a.rn-acc-link .rn-acc-title { color: var(--ink); }
.rn-content a.btn-primary { color: var(--paper); }   /* keep button label legible on dark fill */

/* ---------- Capstone row: same bar family, marked with a red box ---------- */
.rn-acc-capstone { border: 1.5px solid var(--accent, #b5462f); }
.rn-acc-capstone-text { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; }
.rn-acc-capstone-eyebrow {
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent, #b5462f);
}

/* Topic pager on the hub */
.rn-hub-pager { margin-top: 30px; }

/* ---------- Mobile: collapse the nav into a sticky toggle ---------- */
@media (max-width: 960px) {
  .rn-nav {
    position: sticky;
    /* Sit flush against the mobile header, no gap. The header is 82-83px tall
       (46px hamburger/CTA + 18px top & bottom padding + 1px border), so 82px
       keeps the bar tight to its underside without clipping the toggle text. */
    top: 82px;
    z-index: 20;
    max-height: none;
    overflow: visible;
    padding: 10px 12px;
    margin-bottom: 8px;
  }
  .rn-nav-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    background: none;
    border: 0;
    padding: 6px 4px;
    font: inherit;
    font-weight: 600;
    color: var(--ink);
    cursor: pointer;
  }
  .rn-nav-toggle .rn-nav-toggle-caret { transition: transform 0.18s ease; }
  .rn-nav[aria-expanded="true"] .rn-nav-toggle-caret { transform: rotate(180deg); }

  /* Hide the title + nav body until expanded */
  .rn-nav-title { display: none; }
  .rn-nav-body {
    display: none;
    margin-top: 8px;
    max-height: 65vh;
    overflow-y: auto;
  }
  .rn-nav.is-open .rn-nav-body { display: block; }

  /* When open on mobile, expand every group's list so all pages are reachable */
  .rn-nav.is-open .rn-nav-group .rn-nav-list { display: block; }
}

/* Split-page polish: let the breadcrumb wrap instead of clipping the
   last crumb on narrow screens (audit item). */
.breadcrumb { flex-wrap: wrap; row-gap: 4px; }

/* ============================================================
   TOF RACE — A-Level atomic structure §3: two isotope ions race
   down a flight tube at the same KE. Behaviour in site.js
   (driven by [data-tr] / .tr-*); chrome shared with .rn-cap-*.
============================================================ */
.tr-pairs { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; }
.tr-pair { text-transform: none; letter-spacing: 0.02em; font-size: 12.5px; }
.tr-pair sup { font-size: 0.72em; line-height: 0; position: relative; vertical-align: baseline; top: -0.45em; }
.tr-svg { display: block; width: 100%; height: auto; margin: 0 0 4px; }
.tr-spec { display: block; width: 100%; height: auto; }
.tr-caption sup { font-size: 0.78em; }

/* ============================================================
   SPECTRUM → Ar TRAINER — A-Level atomic structure §4: draggable
   mass-spectrum peaks with a live weighted-mean working line +
   guess-the-element mode. Behaviour in site.js ([data-sa] / .sa-*).
============================================================ */
.sa-blurb { font-size: 14px; color: var(--ink-soft); margin: 0 0 12px; }
.sa-modes, .sa-presets { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 10px; }
.sa-preset { text-transform: none; font-size: 12.5px; letter-spacing: 0.02em; }
.rn-cap-btn.is-on { border-color: var(--accent); color: var(--accent); background: oklch(0.96 0.03 30); }
.sa-svg { display: block; width: 100%; height: auto; }
.sa-hit { touch-action: none; }
.sa-steppers { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 6px 0 0; }
.sa-step { display: inline-flex; align-items: center; gap: 7px; }
.sa-step-mz { font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-soft); }
.sa-bump { min-width: 38px; padding: 6px 0; font-size: 14px; line-height: 1; }
.sa-eq { margin-top: 18px; }
.sa-eq-ar { font: inherit; font-weight: 700; color: inherit; background: none; border: none; padding: 0; cursor: pointer; text-decoration: underline dotted var(--muted) 1.5px; text-underline-offset: 3px; }
.sa-eq-ar:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.sa-guess-q { font-size: 14.5px; margin: 12px 0 8px; }
.sa-guess-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 12px; }
.sa-arlab { font-family: var(--font-mono); font-size: 13.5px; }
.sa-ar-in { width: 110px; }
.sa-el-q { font-size: 14.5px; font-weight: 600; margin: 4px 0 8px; }
.sa-el-opts { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.sa-el-opts .rn-cap-btn.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.95 0.045 150); color: oklch(0.32 0.08 150); }
.sa-el-opts .rn-cap-btn.is-err { border-color: var(--accent); background: oklch(0.95 0.05 30); color: var(--accent); }

/* ============================================================
   ELECTRONS-IN-BOXES BUILDER — A-Level atomic structure §5:
   place electrons one tap at a time with aufbau / Pauli / Hund
   enforced and named. Behaviour in site.js ([data-eb] / .eb-*).
============================================================ */
.eb-top { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 0 0 12px; }
.eb-el-lab { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); display: inline-flex; align-items: center; gap: 8px; }
.eb-el { font-family: var(--font-sans); font-size: 14px; padding: 8px 10px; border: 1.5px solid var(--hairline); border-radius: 6px; background: var(--paper); color: var(--ink); min-height: 38px; max-width: 230px; }
.eb-progress { font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-soft); margin: 0 0 12px; min-height: 1.4em; }
.eb-ladder { display: flex; flex-direction: column; gap: 13px; }
.eb-row { display: flex; align-items: center; gap: 12px; }
.eb-lab { font-family: var(--font-mono); font-size: 14px; width: 26px; flex: none; color: var(--ink); }
.eb-boxes { display: flex; }
.eb-box { width: 52px; height: 52px; flex: none; padding: 0; border: 3px solid oklch(0.20 0.018 250); border-radius: 0; background: var(--paper); cursor: pointer; display: block; }
.eb-box + .eb-box { margin-left: -3px; }
.eb-box:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; position: relative; z-index: 1; }
.eb-box svg { display: block; width: 100%; height: 100%; }
.eb-box path { fill: none; stroke: oklch(0.20 0.018 250); stroke-width: 2.8; stroke-linecap: round; opacity: 0; }
.eb-box.has1 .eb-up { opacity: 1; }
.eb-box.has2 .eb-up, .eb-box.has2 .eb-dn { opacity: 1; }
.eb-box path.is-new { stroke: oklch(0.52 0.165 30); }
.eb-box.is-err { border-color: var(--accent); background: oklch(0.95 0.05 30); z-index: 1; position: relative; }
.eb-out { margin-top: 18px; }
.eb-ion-q { font-size: 14.5px; font-weight: 600; margin: 14px 0 0; }
@media (max-width: 420px) {
  .eb-box { width: 44px; height: 44px; }
}

/* ============================================================
   PERIOD 3 IE GRAPH — A-Level atomic structure §6: progressive
   enhancement of the static first-IE graph (tappable points,
   config strip + reason panel, Group 2 view). site.js ([data-p3]).
============================================================ */
.p3-views { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
[data-p3] .p3-pt { cursor: pointer; outline: none; }
.p3-panel { margin: 12px 0 0; padding: 12px 14px; border: 1px solid var(--hairline); border-radius: 6px; background: var(--paper-2); text-align: left; }
.p3-hint { font-size: 13px; font-style: italic; color: var(--muted); margin: 0; }
.p3-meta { font-family: var(--font-mono); font-size: 13px; margin: 0 0 10px; color: var(--ink); }
.p3-strip { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
.p3-sub { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.p3-sublab { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
.p3-orbs { display: flex; }
.p3-box { width: 26px; height: 26px; border: 2px solid oklch(0.20 0.018 250); background: var(--paper); display: flex; align-items: center; justify-content: center; font-size: 14px; letter-spacing: -1px; color: oklch(0.20 0.018 250); }
.p3-box + .p3-box { margin-left: -2px; }
.p3-out { color: oklch(0.52 0.165 30); font-weight: 700; }
.p3-why { font-size: 13.5px; color: var(--ink-soft); margin: 10px 0 0; }

/* ============================================================
   SAME-KE SPEED TOGGLE — A-Level atomic structure §3 stage 2:
   two ions at fixed kinetic energy; picking ion B's mass rescales
   its speed (and its CSS run animation). Behaviour in site.js
   ([data-ke] / .ke-*); the dots animate with pure CSS so the
   no-JS fallback still moves.
============================================================ */
.ke-blurb { font-size: 14px; color: var(--ink-soft); margin: 0 0 12px; }
.ke-masses { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0 0 16px; }
.ke-mlab { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); margin-right: 4px; }
.ke-lanes { display: flex; flex-direction: column; gap: 14px; margin: 0 0 14px; }
.ke-lane { display: grid; grid-template-columns: 108px 1fr minmax(150px, auto); align-items: center; gap: 12px; }
.ke-ion-lab { font-family: var(--font-mono); font-size: 12.5px; color: var(--ink); }
.ke-track { position: relative; height: 16px; border-bottom: 2px solid var(--hairline); }
.ke-dot { position: absolute; top: 50%; left: 0; width: 13px; height: 13px; margin-top: -6.5px; border-radius: 50%; animation: ke-run var(--ke-dur, 1.8s) linear infinite; }
.ke-dot-a { background: oklch(0.52 0.165 30); }
.ke-dot-b { background: oklch(0.20 0.018 250); opacity: 0.85; }
.ke-v { font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-soft); text-align: right; }
@keyframes ke-run { from { left: 0; } to { left: calc(100% - 13px); } }
@media (prefers-reduced-motion: reduce) {
  .ke-dot { animation: none; left: calc(60% - 13px); }
  .ke-dot-a { left: calc(100% - 13px); }
}
@media (max-width: 560px) {
  .ke-lane { grid-template-columns: 90px 1fr; }
  .ke-v { grid-column: 1 / -1; text-align: left; margin-top: -6px; }
}

/* ============================================================
   GUIDED TOF CALCULATION — A-Level atomic structure §3: three
   gated steps (mass → speed → time), each answered as
   number × 10^power. Behaviour in site.js ([data-tc] / .tc-*).
============================================================ */
.tc-q { font-size: 14.5px; margin: 0 0 16px; }
.tc-q sup { font-size: 0.72em; }
.tc-steps { list-style: none; margin: 0 0 4px; padding: 0; }
.tc-step { margin: 0 0 12px; }
.tc-step[hidden] { display: none; }
.tc-step-lab { margin: 0 0 6px; font-size: 14px; }
.tc-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 6px; }
.tc-eq { font-family: var(--font-mono); font-size: 13.5px; color: var(--ink); }
.tc-in { width: 84px; }
.tc-x10 { font-family: var(--font-mono); font-size: 13.5px; color: var(--ink); margin-right: -2px; }
.tc-in-exp { width: 56px; font-size: 12.5px; padding: 5px 7px; transform: translateY(-7px); }
.tc-unit { font-family: var(--font-mono); font-size: 13.5px; color: var(--ink-soft); }
.tc-hint { font-size: 12.5px; line-height: 1.6; color: var(--ink-soft); margin: 0; }
.tc-hint:empty { display: none; }
.tc-done { font-size: 14px; font-weight: 500; margin: 10px 0 0; }

/* ============================================================
   ORBITAL SHAPES — A-Level atomic structure §5: static 3-panel
   figure (s sphere, p dumbbell, three p orbitals). No JS.
============================================================ */
.orb-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.orb-panel svg { display: block; width: 100%; height: auto; }

/* ============================================================
   ATOM-MODEL TIMELINE — A-Level atomic structure §1: five mini
   models (Dalton → today) in a strip. No JS.
============================================================ */
/* Shape gallery grid (.am-grid, used on atomic-structure) + the VSEPR chart
   (.am-matrix on bonding: rows = charge clouds, columns = lone pairs; scrolls
   horizontally inside its own box on narrow screens). */
.am-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; }
.am-matrix-scroll { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; margin: 4px 0; }
.am-matrix { display: grid; grid-template-columns: max-content repeat(4, 1fr); gap: 4px 10px; align-items: start; min-width: 560px; }
.am-colhead { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); text-align: center; align-self: end; padding-bottom: 4px; }
.am-rowhead { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.02em; color: var(--ink-soft); align-self: center; white-space: nowrap; padding-right: 6px; }
.am-panel svg { display: block; width: 100%; height: auto; }
.am-name { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink); text-align: center; margin: 2px 0 2px; }
.am-idea { font-size: 12px; line-height: 1.45; color: var(--muted); text-align: center; margin: 0; }
.am-legend { display: flex; flex-wrap: wrap; gap: 16px; justify-content: center; align-items: center; font-size: 11.5px; color: var(--muted); margin: 14px 0 2px; }
.am-legend span { display: inline-flex; align-items: center; gap: 6px; }
@media (max-width: 560px) {
  .am-grid { grid-template-columns: repeat(3, 1fr); row-gap: 18px; }
}

/* ============================================================
   SHIELDING COMPARISONS — A-Level atomic structure §6: static
   side-by-side atom panels (Na vs Ar, Be vs Ca). No JS.
============================================================ */
.sh-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; max-width: 560px; margin: 0 auto; }
.sh-panel svg { display: block; width: 100%; height: auto; }

/* ============================================================
   PERIODIC TABLE IN BLOCKS — A-Level atomic structure §5:
   block-coloured table; elements to Z = 36 are buttons that fill
   the panel with the configuration. site.js ([data-pt] / .pt-*).
============================================================ */
.pt-blurb { font-size: 14px; color: var(--ink-soft); margin: 0 0 12px; }
.pt-legend { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.pt-key { font-family: var(--font-mono); font-size: 11.5px; padding: 3px 10px; border-radius: 4px; border: 1px solid oklch(0.86 0.008 250); color: var(--ink); }
/* No scrollbar chrome — the shared .rn-table-scroll edge fade (also on this
   div) is the "more off-screen" cue, so mobile gets a clean swipeable table. */
.pt-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 0 12px; scrollbar-width: none; }
.pt-scroll::-webkit-scrollbar { display: none; }
.pt-grid { display: grid; grid-template-columns: repeat(18, minmax(26px, 1fr)); grid-template-rows: repeat(7, auto) 10px repeat(2, auto); gap: 2px; min-width: 540px; }
.pt-el { display: flex; align-items: center; justify-content: center; aspect-ratio: 1 / 1; font-family: var(--font-mono); font-size: 11px; line-height: 1; border: 1px solid oklch(0.86 0.008 250); border-radius: 3px; color: var(--ink); background: var(--paper); padding: 0; }
button.pt-el { cursor: pointer; font-weight: 600; }
button.pt-el:hover { border-color: var(--ink-soft); }
button.pt-el:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; position: relative; z-index: 1; }
button.pt-el.is-on { border-color: var(--ink); box-shadow: inset 0 0 0 1.5px var(--ink); }
.pt-far { color: var(--muted); font-size: 10px; font-weight: 400; }
.pt-mark { font-size: 8.5px; color: var(--muted); border-style: dashed; letter-spacing: -0.02em; }
.pt-s { background: oklch(0.94 0.035 165); }
.pt-p { background: oklch(0.95 0.035 30); }
.pt-d { background: oklch(0.94 0.028 250); }
.pt-f { background: oklch(0.95 0.03 310); }
.pt-panel { margin: 0; padding: 12px 14px; border: 1px solid var(--hairline); border-radius: 6px; background: var(--paper-2); }
.pt-hint { font-size: 13px; font-style: italic; color: var(--muted); margin: 0; }
.pt-meta { font-family: var(--font-mono); font-size: 13px; margin: 0 0 8px; color: var(--ink); }
.pt-cfg { font-size: 15px; margin: 0 0 8px; }
.pt-why { font-size: 13.5px; color: var(--ink-soft); margin: 0; }

/* ============================================================
   SUCCESSIVE-IE CAPSTONE — A-Level atomic structure §6: mystery
   element, log-scale successive-IE bars, pick the group.
   Behaviour in site.js ([data-ij] / .ij-*).
============================================================ */
.ij-blurb { font-size: 14px; color: var(--ink-soft); margin: 0 0 12px; }
.ij-svg { display: block; width: 100%; height: auto; margin: 0 0 12px; }
.ij-groups { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.ij-g { text-transform: none; letter-spacing: 0.02em; font-size: 12.5px; }
.ij-g.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.95 0.045 150); color: oklch(0.32 0.08 150); }
.ij-g.is-err { border-color: oklch(0.55 0.15 25); background: oklch(0.96 0.04 25); color: oklch(0.35 0.15 25); }

/* ============================================================
   A-Level 3.1.2 widgets: SI-units drill (si-) + titre trainer (tt-)
   Chrome shared with .rn-cap-*; palette matches the sa-/tr- widgets.
   ============================================================ */
.si-given { font-family: var(--font-mono); font-size: 13.5px; color: var(--ink); margin: 0 0 12px; padding: 8px 10px; background: var(--paper); border: 1px solid var(--hairline); border-radius: 4px; }
.si-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 10px; }
.si-lab { font-family: var(--font-mono); font-size: 12px; color: var(--muted); min-width: 62px; }
.si-opt { text-transform: none; letter-spacing: 0.02em; font-size: 12.5px; }
.si-opt.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.95 0.045 150); color: oklch(0.32 0.08 150); }
.si-opt.is-err { border-color: oklch(0.55 0.15 25); background: oklch(0.96 0.04 25); color: oklch(0.35 0.15 25); }
.si-opt:disabled:not(.is-ok) { opacity: 0.45; cursor: default; }
.si-hint { font-size: 12px; color: oklch(0.45 0.12 25); flex-basis: 100%; min-height: 1em; }
.si-hint:empty { display: none; }
.si-result { font-family: var(--font-mono); font-size: 13px; line-height: 1.7; color: var(--ink); margin: 12px 0 0; }
.si-result:empty { display: none; }
/* Shared widget button row (was .si-foot; now used by si-, tt-, sg-, be-) */
.rn-cap-foot { margin-top: 12px; display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

/* Equation-line helpers: a small muted label prefix, and struck-out spectator
   ions in worked ionic-equation lines */
.rn-eqlab { display: inline-block; min-width: 172px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }
.rn-strike { text-decoration: line-through; text-decoration-color: oklch(0.52 0.165 30); text-decoration-thickness: 1.5px; color: var(--muted); }
@media (max-width: 560px) { .rn-eqlab { display: block; min-width: 0; margin-bottom: 2px; } }

.tt-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin: 0 0 12px; }
@media (max-width: 560px) { .tt-cards { grid-template-columns: repeat(2, 1fr); } }
.tt-card { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 10px 6px; border: 1.5px solid var(--hairline); border-radius: 6px; background: var(--paper); cursor: pointer; font-family: var(--font-mono); }
.tt-card:hover { border-color: var(--ink-soft); }
.tt-card:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.tt-lab { font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }
.tt-val { font-size: 16px; font-weight: 500; color: var(--ink); }
.tt-box { width: 15px; height: 15px; border: 1.5px solid var(--muted); border-radius: 3px; background: var(--paper); display: inline-flex; align-items: center; justify-content: center; font-size: 11px; line-height: 1; color: var(--paper); }
.tt-card[aria-pressed="true"] { border-color: oklch(0.52 0.13 230); background: oklch(0.96 0.02 230); }
.tt-card[aria-pressed="true"] .tt-box { border-color: oklch(0.48 0.13 230); background: oklch(0.52 0.13 230); }
.tt-card[aria-pressed="true"] .tt-box::after { content: "\2713"; }
.tt-card.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.95 0.045 150); }
.tt-card.is-err { border-color: oklch(0.55 0.15 25); background: oklch(0.96 0.04 25); }
.tt-feedback { font-size: 13px; line-height: 1.6; color: var(--ink-soft); margin: 0 0 10px; min-height: 1em; }
.tt-feedback:empty { display: none; }
.tt-mean { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 12px; font-size: 14px; }
.tt-mean[hidden] { display: none; }
.tt-mean label { display: flex; align-items: center; gap: 8px; }
.tt-in { font-family: var(--font-mono); font-size: 14px; padding: 6px 8px; width: 84px; border: 1.5px solid var(--hairline); border-radius: 4px; background: var(--paper); color: var(--ink); }
.tt-in:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }

/* Virtual titration (A-Level 3.1.2) — .vt-* driven by [data-vt] in site.js.
   The burette level + phenolphthalein opacity are decorative; the reading is
   the truth. Static fallback = the apparatus/meniscus figures + tt- trainer. */
.vt-stage { display: flex; justify-content: center; margin: 4px 0 8px; }
.vt-svg { display: block; width: 100%; max-width: 340px; height: auto; touch-action: manipulation; }
.vt-read { font-family: var(--font-mono); font-size: 13px; color: var(--ink); text-align: center; margin: 0 0 4px; min-height: 1.3em; }
.vt-table { margin-top: 6px; }
.vt-table td, .vt-table th { text-align: center; }
.vt-table td:first-child, .vt-table th:first-child { text-align: left; }
.vt-table tr.is-rough td { color: var(--muted); }
.vt-table tr.is-over td { color: oklch(0.5 0.15 25); }
.vt-concord { font-size: 13.5px; line-height: 1.6; color: var(--ink); background: var(--paper); border: 1px solid var(--hairline); border-left: 3px solid var(--accent); border-radius: 4px; padding: 10px 12px; margin: 12px 0 0; }
.vt-concord[hidden] { display: none; }

/* Auto-marked gated-step calculators (A-Level 3.1.2) — .tg-* titration grid
   [data-tg] and its sibling .gv-* gas-volumes drill [data-gv] in site.js.
   Gated step boxes; each unlocks the next; hint on a wrong value. */
.tg-q, .gv-q, .sg-q, .rt-q { font-size: 14px; line-height: 1.6; margin: 0 0 6px; }
.tg-steps, .gv-steps { margin: 8px 0 4px; }
.tg-step, .gv-step { display: flex; align-items: center; gap: 8px 10px; flex-wrap: wrap; margin: 0 0 8px; padding: 9px 11px; border: 1px solid var(--hairline); border-radius: 6px; background: var(--paper); }
.tg-step[hidden], .gv-step[hidden] { display: none; }
.tg-step.is-done, .gv-step.is-done { border-color: oklch(0.55 0.11 150); background: oklch(0.97 0.03 150); }
.tg-lab, .gv-lab { font-size: 13px; flex: 1 1 210px; color: var(--ink); }
.tg-lab .tg-n, .gv-lab .gv-n { font-family: var(--font-mono); font-size: 11px; color: var(--muted); margin-right: 4px; }
.tg-in, .gv-in, .sg-in, .be-in, .rt-in, .hs-in, .me-in, .gq-in, .ec-in { font-family: var(--font-mono); font-size: 14px; padding: 6px 8px; width: 130px; border: 1.5px solid var(--hairline); border-radius: 4px; background: var(--paper); color: var(--ink); }
.tg-in:focus-visible, .gv-in:focus-visible, .sg-in:focus-visible, .be-in:focus-visible, .rt-in:focus-visible, .hs-in:focus-visible, .me-in:focus-visible, .me-cin:focus-visible, .gq-in:focus-visible, .ec-in:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.tg-in.is-ok, .gv-in.is-ok, .sg-in.is-ok, .be-in.is-ok, .rt-in.is-ok, .hs-in.is-ok, .me-in.is-ok, .me-cin.is-ok, .gq-in.is-ok, .ec-in.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.96 0.045 150); }
.tg-in.is-err, .gv-in.is-err, .sg-in.is-err, .be-in.is-err, .rt-in.is-err, .hs-in.is-err, .me-in.is-err, .me-cin.is-err, .gq-in.is-err, .ec-in.is-err { border-color: oklch(0.55 0.15 25); background: oklch(0.97 0.04 25); }
.tg-unit, .gv-unit { font-size: 12px; color: var(--muted); }
.tg-check, .gv-check { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; padding: 7px 12px; border-radius: 999px; border: 1.5px solid var(--hairline); cursor: pointer; background: var(--paper); color: var(--ink-soft); min-height: 34px; }
.tg-check:hover, .gv-check:hover { border-color: var(--ink-soft); color: var(--ink); }
.tg-check:focus-visible, .gv-check:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.tg-hint, .gv-hint { font-size: 12px; color: oklch(0.5 0.12 25); flex-basis: 100%; min-height: 1em; }
.tg-hint:empty, .gv-hint:empty { display: none; }
.tg-done-note, .gv-done-note { flex-basis: 100%; font-size: 12.5px; color: oklch(0.4 0.09 150); font-weight: 500; }

/* Sig-figs & standard-form drill (A-Level 3.1.2) — .sg-* driven by [data-sg] */
.sg-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sg-in { width: 150px; }
.sg-score { font-family: var(--font-mono); font-size: 12px; color: var(--muted); }
.sg-score:empty { display: none; }

/* Balance-the-equation drill (A-Level 3.1.2) — .be-* driven by [data-be] */
.be-eq { line-height: 2.1; }
.be-sp { white-space: nowrap; }
.be-in { width: 46px; text-align: center; margin-right: 3px; }
.be-tally { max-width: 360px; }
.be-tally td, .be-tally th { text-align: center; }
.be-tally td:first-child, .be-tally th:first-child { text-align: left; }
.be-tally td.be-ok { color: oklch(0.45 0.11 150); font-weight: 700; }
.be-tally td.be-err { color: oklch(0.5 0.15 25); font-weight: 700; }

/* Three-step-method capstone (A-Level 3.1.2) — .rt-* driven by [data-rt].
   Tap step tiles into an ordered route, then a numeric answer + revealed
   working. Route chips reuse .rn-cap-chip; inputs share the .tg-in family. */
.rt-eqline { margin: 2px 0 14px; }
.rt-eqline[hidden] { display: none; }
.rt-route { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; min-height: 50px; padding: 8px 10px; border: 1px dashed var(--hairline); border-radius: 6px; background: var(--paper); margin: 0 0 12px; }
.rt-route .rn-cap-chip { cursor: pointer; }
.rt-route .rn-cap-chip[disabled] { cursor: default; }
.rt-route-num { font-family: var(--font-mono); font-size: 10px; color: var(--muted); margin-right: 7px; }
.rt-placeholder { font-size: 12.5px; font-style: italic; color: var(--muted); }
.rt-bank { display: flex; flex-direction: column; gap: 10px; }
.rt-bankgroup { display: flex; align-items: flex-start; gap: 10px; flex-wrap: wrap; }
.rt-banklab { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); flex: 0 0 88px; padding-top: 10px; }
.rt-tiles { display: flex; flex-wrap: wrap; gap: 8px; flex: 1 1 240px; }
.rt-tile { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 7px 11px; border: 1.5px solid var(--ink-soft); border-radius: 6px; background: var(--paper); cursor: pointer; font-family: var(--font-sans); text-align: left; }
.rt-tile:hover { border-color: var(--accent); }
.rt-tile:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.rt-tile[disabled] { opacity: 0.38; cursor: default; border-color: var(--hairline); }
.rt-tile-f { font-size: 13.5px; font-weight: 600; color: var(--ink); line-height: 1.25; }
.rt-tile-f sub, .rt-tile-f sup { font-size: 0.72em; line-height: 0; }
.rt-tile-cap { font-size: 10.5px; color: var(--muted); }
.rt-run { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.rt-run[hidden] { display: none; }
.rt-runlab { font-size: 13px; color: var(--ink); font-weight: 600; }
.rt-unit { font-size: 13px; color: var(--ink-soft); }
.rt-working { margin-top: 14px; padding: 12px 14px 6px; border-left: 3px solid oklch(0.55 0.11 150); background: var(--paper); border-radius: 0 6px 6px 0; }
.rt-working[hidden] { display: none; }
.rt-worklab { font-size: 13px; margin: 0 0 2px; }
.rt-worklab strong { font-weight: 600; }
.rt-coda { font-size: 13px; font-style: italic; color: var(--ink-soft); margin: 2px 0 8px; }
.rt-score { font-family: var(--font-mono); font-size: 12px; color: var(--muted); }
.rt-score:empty { display: none; }
/* no-JS gating: without .rt-live the bank stays as a static map of the moves;
   the inert route/answer/controls stay hidden (same pattern as .vt-wrap) */
.rt-wrap:not(.rt-live) .rt-route,
.rt-wrap:not(.rt-live) .rt-run,
.rt-wrap:not(.rt-live) .rt-planlead,
.rt-wrap:not(.rt-live) .rn-cap-foot { display: none; }
@media (max-width: 560px) {
  .rt-banklab { flex-basis: 100%; padding-top: 0; }
}

/* Virtual titration no-JS gating: until site.js adds .vt-live, only the
   labelled apparatus figure + noscript note show (no inert controls). */
.vt-wrap:not(.vt-live) .rn-cap-controls,
.vt-wrap:not(.vt-live) .vt-read,
.vt-wrap:not(.vt-live) .rn-table-scroll { display: none; }

/* ============================================================
   BRIDGE THE GAP — GCSE → A-Level bridging course styles
   (.rn-bridge-* chrome · .rn-fml-* formula input · .rn-drill-*
    drill runner · .rn-diag-* diagnostic — engines in site.js)
============================================================ */

/* Worked-example stepper — a <details> chain inside prose */
.rn-bridge-steps {
  margin: 14px 0 2px; border: 1px solid var(--hairline); border-radius: 6px;
  background: var(--paper-2); padding: 0 14px;
}
.rn-bridge-steps > summary {
  cursor: pointer; padding: 10px 0;
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 500;
  letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-soft);
}
.rn-bridge-steps > summary:focus-visible { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 2px; }
.rn-bridge-steps[open] { padding-bottom: 10px; }
.rn-bridge-steps ol { margin: 4px 0 6px; padding-left: 22px; }
.rn-bridge-steps li { margin: 7px 0; }
.rn-bridge-steps li strong { font-weight: 600; }

/* Formula-input question */
.rn-fml-q { margin: 18px 0; }
.rn-fml-prompt { margin: 0 0 8px; font-weight: 600; }
.rn-fml-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.rn-fml-in {
  font-family: var(--font-mono); font-size: 15px; letter-spacing: 0.02em;
  width: 150px; padding: 8px 10px; border: 1.5px solid var(--hairline);
  border-radius: 4px; background: var(--paper); color: var(--ink);
}
.rn-fml-in:focus-visible { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 1px; border-color: oklch(0.52 0.13 200); }
.rn-fml-in.is-ok  { border-color: oklch(0.50 0.15 155); background: oklch(0.96 0.035 155); color: oklch(0.30 0.12 155); font-weight: 600; }
.rn-fml-in.is-err { border-color: oklch(0.58 0.16 25);  background: oklch(0.96 0.035 25);  color: oklch(0.38 0.16 25); }
.rn-fml-preview {
  min-width: 74px; font-size: 17px; color: var(--ink-soft);
  border-bottom: 1px dashed var(--hairline); padding: 2px 4px;
}
.rn-fml-preview:empty::before { content: "· · ·"; color: var(--muted); opacity: 0.5; }
.rn-fml-row .rn-fml-check { margin-top: 0; }
.rn-fml-check {
  display: inline-block;
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--paper); background: oklch(0.40 0.12 200); border: 1px solid oklch(0.40 0.12 200);
  padding: 9px 17px; border-radius: 4px; cursor: pointer; transition: background .12s;
}
.rn-fml-check:hover:not(:disabled) { background: oklch(0.34 0.12 200); }
.rn-fml-check:focus-visible { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 2px; }
.rn-fml-check:disabled { opacity: 0.5; cursor: default; }
.rn-fml-feedback { margin: 10px 0 0; font-family: var(--font-mono); font-size: 12px; font-weight: 500; letter-spacing: 0.02em; }
.rn-fml-feedback:empty { display: none; }
.rn-fml-feedback.fc-ok  { color: oklch(0.38 0.13 155); }
.rn-fml-feedback.fc-err { color: oklch(0.45 0.15 25); }
.rn-fml-feedback sub, .rn-drill-misses sub { font-size: 0.72em; }

/* Drill runner chrome */
[data-drill] {
  border: 1px solid var(--hairline); border-radius: 8px;
  padding: 16px 18px 18px; margin: 22px 0; background: var(--paper);
}
[data-drill] .rn-fml-q, [data-drill] .rn-exam-q { margin: 14px 0 4px; }
.rn-drill-hud {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px;
  padding-bottom: 10px; border-bottom: 1px solid var(--hairline);
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: 0.05em; text-transform: uppercase;
}
.rn-drill-title { font-weight: 600; color: var(--ink); }
.rn-drill-count { color: var(--ink-soft); }
.rn-drill-streak { color: var(--accent); font-weight: 600; margin-left: auto; }
.rn-drill-next {
  display: inline-block; margin-top: 14px;
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--ink); background: var(--paper-2); border: 1.5px solid var(--ink-soft);
  padding: 9px 17px; border-radius: 4px; cursor: pointer; transition: background .12s;
}
.rn-drill-next:hover { background: var(--paper-3); }
.rn-drill-next:focus-visible { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 2px; }
.rn-drill-end { margin-top: 12px; }
.rn-drill-end-score { font-size: 17px; }
.rn-drill-misses { margin: 6px 0 12px; padding-left: 22px; }
.rn-drill-misses li { margin: 5px 0; }
.rn-drill-retry {
  display: inline-block;
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--paper); background: oklch(0.40 0.12 200); border: 1px solid oklch(0.40 0.12 200);
  padding: 9px 17px; border-radius: 4px; cursor: pointer; transition: background .12s;
}
.rn-drill-retry:hover { background: oklch(0.34 0.12 200); }
.rn-drill-retry:focus-visible { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 2px; }

/* Diagnostic — two columns: the one-at-a-time quiz (left) + a slim "what it
   checks" panel (right), so the runner isn't a narrow column with a big empty
   right. Mirrors the two-column hero above. Stacks/drops the panel on mobile. */
.rn-diag-layout { display: flex; align-items: flex-start; gap: clamp(32px, 4vw, 56px); }
.rn-diag-layout > .article-body-inner[data-diag] { flex: 0 1 680px; min-width: 0; }
/* margin-left:auto sits the panel's right edge flush with the hero gauge above */
.rn-diag-aside { flex: 0 0 clamp(258px, 27vw, 336px); margin-left: auto; position: sticky; top: 96px; }
.rn-diag-aside-card {
  border: 1px solid var(--hairline); border-radius: 8px;
  background: var(--paper-2); padding: 20px 22px 18px;
}
.rn-diag-aside-eyebrow {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--accent); margin: 0 0 9px;
}
.rn-diag-aside-lead { font-size: 14px; line-height: 1.5; color: var(--ink-soft); margin: 0 0 12px; }
.rn-diag-aside-skills { margin: 0 0 14px; padding: 0; list-style: none; counter-reset: dsk; }
.rn-diag-aside-skills li {
  counter-increment: dsk; display: flex; gap: 11px; align-items: baseline;
  font-size: 14.5px; color: var(--ink); padding: 8px 0; border-top: 1px solid var(--hairline);
}
.rn-diag-aside-skills li:first-child { border-top: 0; padding-top: 0; }
.rn-diag-aside-skills li::before {
  content: counter(dsk); font-family: var(--font-mono); font-size: 11px;
  font-weight: 500; color: var(--accent); flex: none;
}
.rn-diag-aside-foot {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.02em;
  color: var(--muted); margin: 0; line-height: 1.55;
}
@media (max-width: 820px) {
  .rn-diag-layout { display: block; }
  .rn-diag-aside { display: none; }   /* the intro prose already lists the skills */
}

/* Diagnostic runner */
.rn-diag-bar { display: flex; align-items: center; gap: 12px; margin: 18px 0; }
.rn-diag-bar-txt {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--ink-soft); white-space: nowrap;
}
.rn-diag-bar-track {
  flex: 1; height: 6px; border-radius: 3px; background: var(--paper-3); overflow: hidden;
}
.rn-diag-bar-fill {
  display: block; height: 100%; width: 0; border-radius: 3px;
  background: var(--accent); transition: width .3s;
}
@media (prefers-reduced-motion: reduce) { .rn-diag-bar-fill { transition: none; } }
.rn-diag-skills { margin: 14px 0 18px; display: grid; gap: 8px; }
.rn-diag-skill {
  display: grid; grid-template-columns: minmax(150px, 1.4fr) 1fr auto;
  gap: 4px 12px; align-items: center;
  padding: 9px 12px; border: 1px solid var(--hairline); border-radius: 6px; background: var(--paper);
}
.rn-diag-skill-name { font-weight: 600; font-size: 14.5px; }
.rn-diag-skill-name em { font-weight: 400; color: var(--muted); font-size: 12.5px; }
.rn-diag-skill-bar { display: flex; gap: 3px; }
.rn-diag-skill-bar i {
  width: 14px; height: 8px; border-radius: 2px; background: var(--paper-3);
  border: 1px solid var(--hairline);
}
.rn-diag-skill-bar i.is-hit { background: oklch(0.52 0.15 155); border-color: oklch(0.50 0.15 155); }
.rn-diag-skill-verdict { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.03em; text-transform: uppercase; white-space: nowrap; }
.rn-diag-skill.is-solid .rn-diag-skill-verdict { color: oklch(0.38 0.13 155); }
.rn-diag-skill.is-shaky .rn-diag-skill-verdict { color: oklch(0.55 0.12 75); }
.rn-diag-skill.is-start .rn-diag-skill-verdict { color: oklch(0.45 0.15 25); }
@media (max-width: 560px) {
  .rn-diag-skill { grid-template-columns: 1fr auto; }
  .rn-diag-skill-bar { grid-column: 1 / -1; }
}

/* Hub: progress rings + module cards + reset */
.rn-bridge-ring { width: 44px; height: 44px; flex: none; transform: rotate(-90deg); }
.rn-bridge-ring circle { fill: none; stroke-width: 3.4; }
.rn-bridge-ring-track { stroke: var(--paper-3); }
.rn-bridge-ring-fill { stroke: var(--accent); stroke-linecap: round; stroke-dasharray: 0 100; transition: stroke-dasharray .4s; }
@media (prefers-reduced-motion: reduce) { .rn-bridge-ring-fill { transition: none; } }
.rn-bridge-card .rn-bridge-ring-wrap {
  display: flex; align-items: center; gap: 8px; margin-top: 10px;
}
.rn-bridge-ring-txt { font-family: var(--font-mono); font-size: 11px; color: var(--ink-soft); }
.rn-bridge-card.is-done .rn-bridge-ring-fill { stroke: oklch(0.52 0.15 155); }
.rn-bridge-card.is-done .rn-bridge-ring-txt { color: oklch(0.38 0.13 155); font-weight: 700; }
.rn-bridge-meta {
  display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 8px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--muted);
}
.rn-bridge-reset {
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: 0.03em;
  color: var(--muted); text-decoration: underline; text-underline-offset: 2px;
}
.rn-bridge-reset:hover { color: var(--ink-soft); }
.rn-bridge-reset:focus-visible { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 2px; }
.rn-bridge-score { min-height: 1.4em; }
.rn-bridge-score .fc-ok { color: oklch(0.38 0.13 155); }

/* Mole Maze — the answers sit ON the tiles; picking an answer picks a direction */
[data-maze] { margin: 22px 0; }
.rn-maze-qbox { font-weight: 600; font-size: 16.5px; margin: 0 0 12px; }
.rn-maze-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(4, 1fr);
  gap: 7px; width: min(430px, 94vw); aspect-ratio: 1; margin: 4px auto 14px;
}
.rn-maze-tile {
  border: 1.5px solid var(--hairline); border-radius: 7px; background: var(--paper-2);
  position: relative; transition: background .2s, border-color .2s;
}
@media (prefers-reduced-motion: reduce) { .rn-maze-tile { transition: none; } }
.rn-maze-tile.is-visited { background: oklch(0.91 0.055 80); border-color: oklch(0.72 0.1 70); }
.rn-maze-tile.is-here {
  outline: 3px solid var(--accent); outline-offset: 1.5px;
  background: oklch(0.87 0.08 75);
}
.rn-maze-tile.is-dead { background: oklch(0.96 0.035 25); border-color: oklch(0.58 0.16 25); }
/* blank wall squares — fill the 4×4 grid but carry no answer and aren't playable */
.rn-maze-tile.rn-maze-wall {
  background: repeating-linear-gradient(45deg, var(--paper-2), var(--paper-2) 6px, var(--paper-3) 6px, var(--paper-3) 12px);
  border-style: dashed; border-color: var(--hairline); opacity: 0.6;
}
.rn-maze-tile[data-start]::after, .rn-maze-tile[data-finish]::after {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-size: 9.5px; font-weight: 600; letter-spacing: 0.08em;
  color: var(--ink-soft);
}
.rn-maze-tile[data-start]::after { content: "START"; }
.rn-maze-tile[data-finish]::after { content: "EXIT"; align-items: flex-start; padding-top: 5px; }
/* the START/EXIT label must never intercept a tap meant for an answer chip
   placed on that tile, nor draw over it — ignore pointer events, and hide it
   entirely once the engine flags a chip is present (.has-chip) */
.rn-maze-tile[data-start]::after, .rn-maze-tile[data-finish]::after { pointer-events: none; }
.rn-maze-tile.has-chip::after { display: none; }
/* answers placed on tiles by the engine */
.rn-maze-chips {
  position: absolute; inset: 5px; display: flex; flex-direction: column;
  gap: 4px; justify-content: center;
}
.rn-maze-chips .rn-maze-opt {
  min-height: 0; width: 100%; padding: 5px 4px; border-radius: 5px;
  font-size: clamp(10.5px, 2.9vw, 12.5px); line-height: 1.3; text-align: center;
  flex: 1 1 auto; display: flex; align-items: center; justify-content: center;
}
.rn-maze-q { margin: 14px 0 4px; }
.rn-maze-stem { font-weight: 600; margin: 0 0 10px; }
.rn-maze-opts { display: grid; gap: 8px; }
.rn-maze-opt {
  display: block; width: 100%; text-align: left; cursor: pointer;
  font: inherit; font-size: 15px; color: var(--ink);
  background: var(--paper); border: 1.5px solid var(--hairline); border-radius: 6px;
  padding: 11px 14px; min-height: 44px; transition: background .12s, border-color .12s;
}
.rn-maze-opt:hover:not(:disabled) { background: var(--paper-2); border-color: var(--ink-soft); }
.rn-maze-opt:focus-visible { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 2px; }
.rn-maze-opt:disabled { opacity: 0.45; cursor: default; text-decoration: line-through; }
.rn-maze-dead {
  border: 1.5px solid oklch(0.58 0.16 25); border-radius: 8px;
  background: oklch(0.96 0.035 25); padding: 14px 16px; margin: 14px 0;
}
.rn-maze-dead-fb { margin: 0; color: oklch(0.38 0.16 25); font-weight: 500; }
.rn-maze-status { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-soft); }
.rn-maze-end {
  border: 1.5px solid oklch(0.50 0.15 155); border-radius: 8px;
  background: oklch(0.95 0.04 155); padding: 16px 18px; margin: 14px 0;
}
.rn-maze-end-line { font-size: 16.5px; margin: 0 0 10px; }

/* Retrieval cards */
[data-cards] {
  border: 1px solid var(--hairline); border-radius: 8px;
  padding: 16px 18px 18px; margin: 22px 0; background: var(--paper);
}
.rn-card { margin: 16px 0 6px; }
.rn-card-front { font-weight: 600; font-size: 16.5px; margin: 0 0 10px; }
.rn-card-back {
  display: inline-block; margin: 0 0 4px; padding: 8px 16px;
  font-size: 18px; font-weight: 600; color: oklch(0.30 0.12 155);
  background: oklch(0.95 0.04 155); border: 1.5px solid oklch(0.50 0.15 155);
  border-radius: 6px;
}
/* The deck JS hides the answer with the `hidden` attribute; the author
   `display: inline-block` above out-specifies the UA `[hidden]` rule, so
   without this guard the answer would always show. */
.rn-card-back[hidden] { display: none; }

/* Dilution simulator — bridging concentration.html (data-dilution). Fixed
   solute, slider adds water: level rises, colour fades, c = n ÷ V falls. */
.dil-wrap {
  display: grid; grid-template-columns: minmax(0, 190px) 1fr; gap: 26px; align-items: center;
  margin: 24px 0; padding: 22px; border: 1px solid var(--hairline); border-radius: 10px; background: var(--paper-2);
}
.dil-stage { display: flex; justify-content: center; }
.dil-stage svg { width: 100%; max-width: 180px; height: auto; }
.dil-liquid { transition: y .28s ease, height .28s ease, fill .28s ease; }
.dil-controls label { display: block; font-family: var(--font-mono); font-size: 11.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 10px; }
.dil-slider { width: 100%; accent-color: oklch(0.52 0.18 330); }
.dil-readout { font-family: var(--font-mono); font-size: 15px; margin: 16px 0 6px; color: var(--ink); }
.dil-readout strong { font-size: 17px; }
.dil-note { font-size: 13.5px; color: var(--muted); margin: 0 0 16px; }
.dil-word { font-weight: 600; color: var(--ink); }
.dil-meter { position: relative; height: 9px; border-radius: 5px; background: linear-gradient(90deg, oklch(0.93 0.05 330), oklch(0.50 0.18 330)); }
.dil-band-marker { position: absolute; top: -3.5px; left: 100%; width: 4px; height: 16px; border-radius: 2px; background: var(--ink); transform: translateX(-50%); transition: left .28s ease; }
.dil-meter-labels { display: flex; justify-content: space-between; margin-top: 7px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
@media (max-width: 560px) { .dil-wrap { grid-template-columns: 1fr; gap: 16px; } .dil-stage svg { max-width: 150px; } }
.rn-cards-controls { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; }
.rn-cards-controls .rn-drill-next { margin-top: 0; }

/* Electron-config guided sequence (bridging M7) */
.eb-seq-strip { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 4px; }
.eb-seq-chip {
  padding: 6px 14px; border: 1.5px solid var(--hairline); border-radius: 999px;
  font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.04em; color: var(--muted);
}
.eb-seq-chip.is-current { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.eb-seq-chip.is-done { border-color: oklch(0.50 0.15 155); color: oklch(0.38 0.13 155); }
.eb-seq-chip.is-done::after { content: " ✓"; }
.eb-seq-next { margin-top: 10px; }

/* ============================================================
   A-LEVEL 3.1.2 PORTED WIDGETS
   fb- ionic-formula builder (A-Level port of the GCSE C4 .sf- salt
   builder, fresh namespace) · lm- limiting-reagent simulator (port of
   the GCSE C3 .lr- sim) · .rn-rmt table-method grids (promoted from the
   GCSE per-page copies — those pages still carry their own inline CSS,
   which wins the cascade there; keep the two in step).
============================================================ */
.fb-wrap { margin: 24px 0 28px; padding: 16px 18px; background: var(--paper-2); border: 1px solid var(--hairline); border-radius: 4px; }
.fb-title { font-family: var(--font-body); font-size: 13px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink); text-align: center; margin: 0 0 4px; }
.fb-intro { font-size: 12.5px; color: var(--ink-soft); text-align: center; margin: 0 auto 16px; max-width: 560px; line-height: 1.45; }
.fb-step { margin-bottom: 14px; }
.fb-step-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); margin: 0 0 7px; }
.fb-btns { display: flex; flex-wrap: wrap; gap: 7px; }
.fb-btn { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.02em; font-weight: 500; padding: 6px 11px; border-radius: 999px; border: 1.5px solid var(--hairline); cursor: pointer; background: var(--paper); color: var(--ink-soft); transition: background .15s, border-color .15s, color .15s; }
.fb-btn:hover { background: var(--paper-2); border-color: var(--ink-soft); }
.fb-btn.is-on-pos { background: oklch(0.46 0.10 165); border-color: oklch(0.46 0.10 165); color: var(--paper); }
.fb-btn.is-on-neg { background: oklch(0.44 0.11 265); border-color: oklch(0.44 0.11 265); color: var(--paper); }
.fb-placeholder { font-size: 12.5px; color: var(--muted); font-style: italic; text-align: center; padding: 16px 0 4px; }
.fb-eqbox { background: var(--paper); border: 1.5px solid var(--hairline); border-radius: 4px; padding: 14px 12px 12px; }
.fb-formula { font-family: var(--font-mono); font-size: 22px; font-weight: 600; letter-spacing: 0.01em; color: var(--ink); text-align: center; margin: 0 0 14px; }
.fb-cols { display: flex; align-items: stretch; justify-content: center; gap: 10px; }
.fb-col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 11px 8px; border: 1.5px dashed var(--hairline); border-radius: 4px; background: var(--paper-2); }
.fb-colhead { font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.fb-ionrow { display: inline-flex; align-items: center; gap: 6px; }
.fb-count { font-family: var(--font-mono); font-size: 15px; font-weight: 600; color: var(--ink); min-width: 12px; text-align: right; }
.fb-times { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
.fb-ionchip { font-family: var(--font-mono); font-size: 15px; font-weight: 600; padding: 4px 9px; border-radius: 4px; white-space: nowrap; }
.fb-ionchip--pos { background: oklch(0.93 0.05 165); border: 1.5px solid oklch(0.62 0.10 165); color: oklch(0.34 0.10 165); }
.fb-ionchip--neg { background: oklch(0.93 0.05 265); border: 1.5px solid oklch(0.62 0.11 265); color: oklch(0.36 0.12 265); }
.fb-stepper { display: inline-flex; align-items: center; gap: 9px; }
.fb-pm { width: 25px; height: 25px; border-radius: 50%; border: 1.5px solid var(--hairline); background: var(--paper); color: var(--ink); font-size: 15px; line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.fb-pm:hover { border-color: var(--ink-soft); background: var(--paper-2); }
.fb-pm:disabled { opacity: 0.4; cursor: not-allowed; }
.fb-coltot { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
.fb-coltot b { color: var(--ink); font-size: 12.5px; }
.fb-readout { margin-top: 12px; text-align: center; font-family: var(--font-mono); font-size: 12px; color: var(--ink-soft); }
.fb-readout.is-balanced { color: oklch(0.46 0.13 155); font-weight: 600; }
.fb-check { margin-top: 14px; display: flex; flex-direction: column; gap: 7px; }
.fb-ci { display: flex; align-items: flex-start; gap: 9px; font-size: 12.5px; color: var(--ink-soft); line-height: 1.4; }
.fb-cbox { flex: 0 0 auto; width: 18px; height: 18px; border-radius: 4px; border: 1.5px solid var(--hairline); display: inline-flex; align-items: center; justify-content: center; font-size: 12px; color: transparent; margin-top: 1px; }
.fb-ci.is-done { color: var(--ink); }
.fb-ci.is-done .fb-cbox { background: oklch(0.52 0.15 155); border-color: oklch(0.52 0.15 155); color: var(--paper); }
.fb-ci .lab { font-weight: 600; }
.fb-ci .det { color: var(--muted); font-family: var(--font-mono); font-size: 10.5px; }
.fb-reveal { margin-top: 14px; padding: 13px 15px; border-radius: 4px; border: 1.5px solid oklch(0.60 0.13 155); background: oklch(0.96 0.035 155); }
.fb-reveal-title { font-family: var(--font-body); font-weight: 700; font-size: 15px; margin-bottom: 5px; color: oklch(0.42 0.13 155); }
.fb-reveal-title .fb-final { font-family: var(--font-mono); }
.fb-reveal p { margin: 6px 0 0; font-size: 13px; line-height: 1.5; color: var(--ink-soft); }
.fb-status { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; margin: 0; }
.fb-foot { margin-top: 14px; text-align: center; }
.fb-reset { border-style: dashed; }
@media (max-width: 480px) {
  .fb-formula { font-size: 19px; }
  .fb-ionchip { font-size: 13px; }
}

/* lm- limiting-reagent simulator */
.lm-wrap { margin: 18px 0 26px; padding: 20px 16px 16px; background: var(--paper-2); border: 1px solid var(--hairline); border-radius: 4px; text-align: center; }
.lm-wrap svg.lm-stage { display: block; width: 100%; max-width: 600px; margin: 0 auto; overflow: visible; }
.lm-legend { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 18px; margin: 12px auto 2px; max-width: 540px; font-size: 12px; color: var(--ink-soft); line-height: 1.45; }
.lm-leg-item { display: inline-flex; align-items: center; gap: 7px; }
.lm-controls { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px 26px; margin: 15px auto 6px; }
.lm-step { display: inline-flex; align-items: center; gap: 8px; }
.lm-step-label { font-family: var(--font-mono); font-weight: 700; font-size: 15px; letter-spacing: 0.02em; }
.lm-step-btn { font-family: var(--font-mono); font-size: 17px; line-height: 1; font-weight: 500; width: 28px; height: 28px; border-radius: 999px; border: 1.5px solid var(--hairline); background: var(--paper); color: var(--ink-soft); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.lm-step-btn:hover:not(:disabled) { background: var(--paper-2); border-color: var(--ink-soft); }
.lm-step-btn:disabled { opacity: 0.35; cursor: default; }
.lm-count { min-width: 1.3em; text-align: center; font-family: var(--font-mono); font-weight: 700; font-size: 17px; color: var(--ink); }
.lm-caption { font-size: 13px; color: var(--ink-soft); margin: 10px 0 8px; font-style: italic; min-height: 3.0em; }
.lm-btn { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.07em; text-transform: uppercase; font-weight: 500; padding: 7px 20px; border-radius: 999px; border: 1.5px solid var(--hairline); cursor: pointer; background: var(--paper); color: var(--ink-soft); }
.lm-btn:hover:not(:disabled) { background: var(--paper-2); border-color: var(--ink-soft); }
.lm-btn:disabled { opacity: 0.5; cursor: default; }
.lm-result { max-width: 520px; margin: 10px auto 2px; padding: 11px 14px 12px; border-radius: 6px; border: 1.5px solid var(--hairline); background: var(--paper); text-align: left; }
.lm-result-title { display: block; font-family: "IBM Plex Sans", sans-serif; font-weight: 700; font-size: 14.5px; margin-bottom: 3px; }
.lm-result-body { display: block; font-size: 13px; color: var(--ink-soft); line-height: 1.5; }
.lm-result--lim { border-color: oklch(0.55 0.165 30 / 0.55); background: oklch(0.965 0.03 40); }
.lm-result--lim .lm-result-title { color: oklch(0.50 0.17 30); }
.lm-result--bal { border-color: oklch(0.52 0.10 165 / 0.6); background: oklch(0.965 0.03 165); }
.lm-result--bal .lm-result-title { color: oklch(0.42 0.11 165); }
.lm-quotient { display: block; margin-top: 7px; padding-top: 7px; border-top: 1px dashed var(--hairline); font-size: 12.5px; color: var(--ink-soft); }
.lm-quotient code { font-family: var(--font-mono); font-size: 12px; color: var(--ink); background: none; }

/* rn-rmt table-method grids (worked + one-box-at-a-time live variant) */
.rn-rmt-figure { margin: 16px 0 10px; }
.rn-rmt-figure .rn-rmt-eq { margin: 0; border-radius: 4px 4px 0 0; display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 8px; }
.rn-rmt-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.rn-rmt { width: 100%; border-collapse: collapse; table-layout: fixed; margin: 0; font-size: 14.5px; min-width: 340px; border: 1px solid var(--hairline); border-top: 0; }
.rn-rmt th, .rn-rmt td { border: 1px solid var(--hairline); padding: 8px 10px; text-align: center; vertical-align: middle; }
.rn-rmt thead th { background: var(--ink); color: var(--paper); font-family: var(--font-mono); font-weight: 500; font-size: 14px; letter-spacing: 0; text-transform: none; line-height: 1.25; }
.rn-rmt thead .rn-rmt-corner { background: var(--ink-soft); }
.rn-rmt-role { display: block; margin-top: 2px; font-size: 9.5px; font-weight: 400; letter-spacing: 0.06em; text-transform: uppercase; color: oklch(0.82 0.02 250); }
.rn-rmt tbody th[scope="row"] { width: 74px; background: var(--paper-3); color: var(--ink); text-align: left; font-family: var(--font-mono); font-weight: 600; font-size: 12.5px; }
.rn-rmt tbody td { position: relative; background: var(--paper); color: var(--ink); font-family: var(--font-mono); }
.rn-rmt-num  { display: block; font-size: 15px; font-weight: 600; line-height: 1.2; }
.rn-rmt-work { display: block; margin-top: 2px; font-size: 11px; font-weight: 400; color: var(--muted); white-space: nowrap; }
.rn-rmt-step { position: absolute; top: 3px; left: 4px; width: 15px; height: 15px; line-height: 15px; text-align: center; font-family: var(--font-mono); font-size: 9px; font-weight: 600; color: var(--paper); background: var(--muted); border-radius: 50%; }
.rn-rmt td.is-given  { background: oklch(0.96 0.022 200); }
.rn-rmt td.is-given .rn-rmt-work { color: oklch(0.50 0.05 200); }
.rn-rmt td.is-answer { background: oklch(0.95 0.045 30); }
.rn-rmt td.is-answer .rn-rmt-num  { color: var(--accent); }
.rn-rmt td.is-answer .rn-rmt-step { background: var(--accent); }
.rn-rmt-legend { margin: 8px 0 4px; font-weight: 600; color: var(--ink-soft); font-size: 14.5px; }
ol.rn-rmt-steps { margin: 0 0 4px; padding-left: 22px; }
ol.rn-rmt-steps li { margin: 3px 0; line-height: 1.55; }
.rn-rmt--live td { padding: 6px 7px; }
.rn-rmt td.is-answer-live { box-shadow: inset 0 0 0 2px oklch(0.85 0.06 30); }
.rn-rmt-input { font-family: var(--font-mono); font-size: 15px; font-weight: 600; color: var(--accent); width: 100%; max-width: 78px; text-align: center; padding: 7px 4px; border: 1px solid var(--hairline); border-radius: 4px; background: var(--paper); }
.rn-rmt-input:disabled { background: var(--paper-3); color: var(--muted); opacity: 0.55; cursor: not-allowed; }
.rn-rmt-input.is-active { border-color: oklch(0.52 0.13 200); box-shadow: 0 0 0 3px oklch(0.52 0.13 200 / 0.18); }
.rn-rmt-input.is-err { border-color: oklch(0.58 0.16 25); background: oklch(0.96 0.035 25); color: oklch(0.38 0.16 25); }
.rn-rmt-input.is-ok  { border-color: oklch(0.50 0.15 155); background: oklch(0.96 0.035 155); color: oklch(0.30 0.12 155); opacity: 1; cursor: default; }
.rn-rmt-unit { margin-left: 4px; font-family: var(--font-mono); font-size: 13px; color: var(--ink-soft); }
.rn-rmt-prompt { margin: 11px 0 0; min-height: 1.4em; padding: 9px 13px; border-left: 2px solid oklch(0.52 0.13 200); background: var(--paper-2); border-radius: 0 3px 3px 0; font-size: 14px; line-height: 1.55; color: var(--ink-soft); }
.rn-rmt-prompt.is-done { border-left-color: oklch(0.50 0.15 155); background: oklch(0.96 0.035 155); color: oklch(0.30 0.12 155); font-weight: 600; }
.rn-rmt-prompt .rn-rmt-err { color: oklch(0.48 0.16 25); font-weight: 600; }
.rn-rmt-reset { margin-top: 10px; font-family: var(--font-mono); font-size: 11px; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-soft); background: var(--paper); border: 1px solid var(--hairline); border-radius: 4px; padding: 7px 13px; cursor: pointer; }
.rn-rmt-reset:hover { background: var(--paper-2); border-color: var(--ink-soft); }
@media (max-width: 560px) {
  .rn-rmt-scroll { overflow-x: visible; }
  .rn-rmt { min-width: 0; font-size: 12.5px; }
  .rn-rmt th, .rn-rmt td { padding: 6px 4px; }
  .rn-rmt thead th { font-size: 11.5px; }
  .rn-rmt-role { font-size: 8px; }
  .rn-rmt tbody th[scope="row"] { width: 50px; font-size: 10.5px; padding: 6px 3px; }
  .rn-rmt-num { font-size: 12.5px; }
  .rn-rmt-work { font-size: 9px; white-space: normal; }
  .rn-rmt-step { width: 13px; height: 13px; line-height: 13px; font-size: 8px; top: 2px; left: 2px; }
  .rn-rmt--live td { padding: 5px 3px; }
  .rn-rmt-input { font-size: 12.5px; max-width: 100%; padding: 6px 2px; }
  .rn-rmt-unit { font-size: 10px; margin-left: 2px; }
}

/* ============================================================
   COMMON-IONS REFERENCE CARD (.ion-*)
   Three-box ion-charges grid: metals / non-metals / molecular-
   or-polyatomic ions (emphasised memorise box), with a variable-
   metals sub-box. Used on GCSE C2 Part 2 (#ionic-formulae) and
   A-Level amount-of-substance (#formulae-first).
   ============================================================ */
.ion-charges {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  margin: 18px 0 22px;
}
@media (max-width: 720px) { .ion-charges { grid-template-columns: 1fr; } }

.ion-col {
  display: flex;
  flex-direction: column;
  background: var(--paper-2);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 15px 16px 17px;
}
.ion-col-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--ink);
  padding-bottom: 8px;
  margin-bottom: 11px;
  border-bottom: 1px solid var(--hairline);
}
.ion-rule {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-soft);
  margin: 0 0 13px;
}
.ion-rule strong { color: var(--ink); font-weight: 600; }

.ion-group { margin-bottom: 9px; }
.ion-group:last-child { margin-bottom: 0; }
.ion-group-label {
  display: block;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 2px;
}
.ion-f {
  font-family: var(--font-mono);
  font-size: 15px;
  font-weight: 500;
  color: var(--ink);
}
.ion-sep { color: oklch(0.72 0.01 250); margin: 0 3px; }

/* Variable/transition-metals sub-box — charge comes from the Roman numeral */
.ion-tmetals {
  margin-top: 13px;
  padding: 10px 12px 11px;
  background: var(--paper);
  border: 1.5px solid oklch(0.72 0.015 250);
  border-radius: 5px;
}
.ion-tmetals-head {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 5px;
}
.ion-tmetals-note {
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--ink-soft);
  margin: 0 0 8px;
}
.ion-tmetals-note strong { color: var(--ink); font-weight: 600; }
.ion-tmetals-row {
  font-size: 13px;
  color: var(--ink-soft);
  margin-bottom: 4px;
}
.ion-tmetals-row:last-child { margin-bottom: 0; }
.ion-tmetals-row .ion-f { font-size: 14px; }

/* Molecular/polyatomic ions — the box to MEMORISE (emphasised) */
.ion-col-memorise {
  border: 2px solid oklch(0.74 0.11 80);
  background: oklch(0.965 0.035 88);
  box-shadow: 0 0 0 4px oklch(0.74 0.11 80 / 0.12);
}
.ion-col-memorise .ion-col-head {
  color: oklch(0.43 0.10 62);
  border-bottom-color: oklch(0.82 0.07 82);
}
.ion-memorise-flag {
  flex: none;
  font-family: var(--font-mono);
  font-size: 8.5px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  font-weight: 600;
  color: oklch(0.40 0.12 52);
  background: oklch(0.91 0.075 86);
  border: 1px solid oklch(0.76 0.10 76);
  border-radius: 999px;
  padding: 2px 8px;
}
.ion-mol-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 14px;
}
.ion-mol-name {
  display: block;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: oklch(0.45 0.08 62);
  margin-bottom: 1px;
}
.ion-mol-grid .ion-f { color: oklch(0.30 0.04 60); }

/* ============================================================
   PERIODIC-TABLE COLLAPSIBLE (.rn-pt-*)
   <details> wrapper with a zoomable periodic-table figure.
   Used on GCSE C2 Parts 1 & 2. (Hoisted from inline copies —
   the split had left Part 2 without these rules.)
   ============================================================ */
.rn-pt-details { margin: 16px 0 24px; }
.rn-pt-details > summary {
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--ink-soft);
  padding: 10px 14px;
  background: var(--paper-2);
  border: 1px solid var(--hairline);
  border-radius: 4px;
  list-style: none;
  user-select: none;
}
.rn-pt-details > summary::-webkit-details-marker { display: none; }
.rn-pt-details > summary:hover { background: var(--paper); }
.rn-pt-details[open] > summary { border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-bottom: none; }
.rn-pt-details > summary::after { content: '\25B6'; margin-left: auto; font-size: 9px; transition: transform .15s; }
.rn-pt-details[open] > summary::after { transform: rotate(90deg); }
.rn-pt-hint { font-weight: 400; text-transform: none; letter-spacing: 0; font-size: 12px; color: var(--muted); font-family: var(--font-body); }
.rn-pt-fig {
  border: 1px solid var(--hairline);
  border-top: none;
  border-radius: 0 0 4px 4px;
  padding: 12px 12px 4px;
}
.rn-pt-fig img { display: block; width: 100%; }

/* ============================================================
   CLASSIFY TASKS (.rn-classify-*, .rn-el-btn pill buttons)
   Click-to-classify cards inside .rn-practice (metal/non-metal,
   bond type, element/compound/mixture …). Used on GCSE C1 Part 1
   and C2 Parts 1 & 2. Page-specific: .rn-classify-task padding
   stays inline per page.
   ============================================================ */
.rn-classify-card {
  border: 1px solid var(--hairline);
  border-radius: 4px;
  padding: 12px 16px;
  margin-bottom: 10px;
  background: var(--paper);
}
.rn-classify-header { margin-bottom: 10px; line-height: 1.4; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.rn-classify-formula { font-family: var(--font-mono); font-size: 15px; font-weight: 700; color: var(--ink); }
.rn-classify-cname { font-size: 13px; color: var(--ink-soft); }
.rn-classify-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
  flex-wrap: wrap;
}
.rn-classify-el { min-width: 110px; font-size: 14px; line-height: 1.3; }
.rn-classify-elname { color: var(--ink-soft); font-size: 12px; display: block; }
.rn-classify-btns { display: flex; gap: 6px; flex-wrap: wrap; }
.rn-classify-feedback {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
}
.rn-classify-feedback.fc-ok  { color: oklch(0.38 0.13 155); }
.rn-classify-feedback.fc-err { color: oklch(0.45 0.15 25); }
.rn-classify-explanation {
  margin-top: 10px;
  padding: 10px 14px;
  border-radius: 3px;
  font-size: 14px;
  line-height: 1.6;
  border: 1px solid var(--hairline);
  background: var(--paper-2);
  color: var(--ink-soft);
}
.rn-classify-explanation.fc-ok  { background: oklch(0.95 0.04 155); color: oklch(0.30 0.12 155); border-color: oklch(0.50 0.15 155); }
.rn-classify-explanation.fc-err { background: oklch(0.96 0.04 25);  color: oklch(0.35 0.15 25);  border-color: oklch(0.55 0.15 25); }
.rn-el-btn {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 500;
  padding: 6px 13px;
  border-radius: 999px;
  border: 1.5px solid var(--hairline);
  cursor: pointer;
  background: var(--paper);
  color: var(--ink-soft);
  transition: background .12s, border-color .12s;
}
.rn-el-btn:hover:not(:disabled) { background: var(--paper-2); border-color: var(--ink-soft); }
.rn-el-btn:disabled { cursor: default; }
.rn-el-btn:focus-visible { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 2px; }
.rn-el-btn.b-ok  { background: oklch(0.95 0.04 155); border-color: oklch(0.50 0.15 155); color: oklch(0.30 0.12 155); }
.rn-el-btn.b-err { background: oklch(0.96 0.04 25);  border-color: oklch(0.55 0.15 25);  color: oklch(0.35 0.15 25); }
.rn-el-btn.b-dim { opacity: 0.35; }
.rn-bond-tag {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 3px;
  background: var(--paper-2);
  border: 1px solid var(--hairline);
  color: var(--ink-soft);
  white-space: nowrap;
}

/* ============================================================
   HALF-EQUATION BUILDER (.he-*)
   Shared by the C4 Part 1 displacement builder and the C4 Part 4
   molten-electrolysis builder (its markup reuses these classes).
   Hoisted from Part 1's inline copy — the split had left Part 4
   without these rules.
   ============================================================ */
.he-wrap { margin: 24px 0 28px; padding: 16px 18px; background: var(--paper-2); border: 1px solid var(--hairline); border-radius: 4px; }
.he-title { font-family: var(--font-body); font-size: 13px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink); text-align: center; margin: 0 0 4px; }
.he-intro { font-size: 12.5px; color: var(--ink-soft); text-align: center; margin: 0 auto 16px; max-width: 560px; line-height: 1.45; }
.he-step { margin-bottom: 14px; }
.he-step-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); margin: 0 0 7px; }
.he-btns { display: flex; flex-wrap: wrap; gap: 7px; }
.he-btn { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.02em; font-weight: 500; padding: 7px 12px; border-radius: 999px; border: 1.5px solid var(--hairline); cursor: pointer; background: var(--paper); color: var(--ink-soft); transition: background .15s, border-color .15s, color .15s; }
.he-btn:hover { background: var(--paper-2); border-color: var(--ink-soft); }
.he-btn.is-active { background: oklch(0.46 0.10 200); border-color: oklch(0.46 0.10 200); color: var(--paper); }
.he-rxn { font-family: var(--font-mono); font-size: 13px; color: var(--ink); background: var(--paper); border-left: 3px solid oklch(0.46 0.10 200); padding: 8px 12px; border-radius: 0 3px 3px 0; margin: 8px 0 0; }
.he-hint { font-size: 12px; color: var(--ink-soft); margin: 0 0 12px; line-height: 1.45; }
.he-placeholder { font-size: 12.5px; color: var(--muted); font-style: italic; text-align: center; padding: 16px 0 4px; }
.he-eqbox { background: var(--paper); border: 1.5px solid var(--hairline); border-radius: 4px; padding: 14px 12px 12px; }
.he-eq { display: flex; align-items: flex-start; justify-content: center; gap: 8px; }
.he-side { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.he-zone { width: 100%; min-height: 48px; display: flex; align-items: center; justify-content: center; gap: 5px; flex-wrap: wrap; padding: 7px; border: 1.5px dashed var(--hairline); border-radius: 4px; background: var(--paper-2); }
.he-zone.is-empty::before { content: "empty"; font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.he-plus { color: var(--muted); font-family: var(--font-mono); font-size: 13px; }
.he-arrow { align-self: center; font-size: 19px; color: var(--ink-soft); flex: 0 0 auto; padding-top: 12px; }
.he-chip { font-family: var(--font-mono); font-size: 14px; font-weight: 600; padding: 5px 9px; border-radius: 4px; white-space: nowrap; }
.he-chip--atom { background: oklch(0.93 0.03 250); border: 1.5px solid oklch(0.70 0.07 250); color: oklch(0.28 0.07 250); }
.he-chip--ion { background: oklch(0.93 0.05 320); border: 1.5px solid oklch(0.66 0.11 320); color: oklch(0.32 0.12 320); }
.he-chip--e { background: oklch(0.95 0.04 95); border: 1.5px solid oklch(0.72 0.11 95); color: oklch(0.40 0.10 95); }
.he-charge { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
.he-charge b { color: var(--ink); font-size: 12.5px; }
.he-ctrl { margin-top: 14px; display: flex; flex-direction: column; gap: 9px; }
.he-ctrl-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.he-ctrl-name { font-family: var(--font-mono); font-size: 12px; color: var(--ink); flex: 0 0 auto; min-width: 134px; }
.he-seg { display: inline-flex; border: 1.5px solid var(--hairline); border-radius: 999px; overflow: hidden; }
.he-seg button { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.04em; padding: 5px 13px; border: none; background: var(--paper); color: var(--ink-soft); cursor: pointer; transition: background .15s, color .15s; }
.he-seg button + button { border-left: 1.5px solid var(--hairline); }
.he-seg button.is-on { background: oklch(0.46 0.10 200); color: var(--paper); }
.he-estep { display: inline-flex; align-items: center; gap: 16px; }
.he-estep .grp { display: inline-flex; align-items: center; gap: 7px; }
.he-estep .grp > span { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.he-pm { width: 25px; height: 25px; border-radius: 50%; border: 1.5px solid var(--hairline); background: var(--paper); color: var(--ink); font-size: 15px; line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.he-pm:hover { border-color: var(--ink-soft); background: var(--paper-2); }
.he-count { font-family: var(--font-mono); font-size: 13px; min-width: 14px; text-align: center; color: var(--ink); }
.he-check { margin-top: 14px; display: flex; flex-direction: column; gap: 7px; }
.he-ci { display: flex; align-items: flex-start; gap: 9px; font-size: 12.5px; color: var(--ink-soft); line-height: 1.4; }
.he-cbox { flex: 0 0 auto; width: 18px; height: 18px; border-radius: 4px; border: 1.5px solid var(--hairline); display: inline-flex; align-items: center; justify-content: center; font-size: 12px; color: transparent; margin-top: 1px; }
.he-ci.is-done { color: var(--ink); }
.he-ci.is-done .he-cbox { background: oklch(0.52 0.15 155); border-color: oklch(0.52 0.15 155); color: var(--paper); }
.he-ci .lab { font-weight: 600; }
.he-ci .det { color: var(--muted); font-family: var(--font-mono); font-size: 10.5px; }
.he-reveal { margin-top: 14px; padding: 13px 15px; border-radius: 4px; border: 1.5px solid; }
/* correct answers (oxidation or reduction) → green; not-yet-right → amber */
.he-reveal--ox { background: oklch(0.96 0.03 155); border-color: oklch(0.64 0.12 155); }
.he-reveal--red { background: oklch(0.96 0.03 155); border-color: oklch(0.64 0.12 155); }
.he-reveal--nudge { background: oklch(0.96 0.03 85); border-color: oklch(0.74 0.10 85); }
.he-reveal-title { font-family: var(--font-body); font-weight: 700; font-size: 15px; margin-bottom: 5px; }
.he-reveal--ox .he-reveal-title { color: oklch(0.45 0.14 155); }
.he-reveal--red .he-reveal-title { color: oklch(0.45 0.14 155); }
.he-reveal--nudge .he-reveal-title { color: oklch(0.50 0.11 80); }
.he-reveal p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-soft); }
.he-final-eq { font-family: var(--font-mono); font-size: 14px; color: var(--ink) !important; margin-top: 8px !important; font-weight: 600; }
.he-foot { margin-top: 14px; text-align: center; }
.he-reset { border-style: dashed; }
@media (max-width: 480px) {
  .he-ctrl-name { min-width: 0; width: 100%; }
  .he-chip { font-size: 13px; }
  .he-estep { gap: 12px; }
}

/* Back-titration stage stepper (figure[data-bt], A-Level amount-of-substance).
   JS fades the inactive g[data-bt-stage] groups; buttons reuse .rn-cap-btn. */
[data-bt] [data-bt-stage] { transition: opacity 0.2s ease; }
[data-bt] .rn-bt-controls, [data-gs] .rn-gs-controls, [data-lp] .rn-lp-controls { justify-content: center; margin-top: 12px; }
.rn-bt-caption, .rn-lp-caption { text-align: center; font-size: 15px; line-height: 1.5; color: var(--ink-soft); margin: 10px auto 0; max-width: 560px; }
/* Lone-pair squeeze (figure[data-lp], A-Level bonding) — stage fade; the
   centre-stage clone + tweened arc/number are built by site.js. */
[data-lp] [data-lp-mol], [data-lp] [data-lp-labels] { transition: opacity 0.25s ease; }

/* Metallic bonding Na/Mg toggle (figure[data-mb], A-Level bonding). The toggle is
   hidden until site.js reveals it; the ions and electrons are persistent elements so
   changing r / opacity animates the switch between the two metals. */
.mb-toggle { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; justify-content: center; margin: 0 0 12px; }
.mb-toggle-lead { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.mb-ion { transition: r 0.4s ease; }
.mb-e { transition: opacity 0.35s ease; }
.mb-e-extra { transition: opacity 0.35s ease; }

/* Polar-or-not predict-then-reveal (figure[data-dp], A-Level bonding). The six
   molecule skeletons stay put; site.js spotlights one, hides the rest and each
   molecule's [data-dp-reveal] arrows/badge until the student commits. */
[data-dp] [data-dp-mol], [data-dp] [data-dp-reveal] { transition: opacity 0.25s ease; }
[data-dp] .rn-dp-controls { justify-content: center; margin-top: 6px; }
[data-vw] .rn-vw-controls { justify-content: center; margin-top: 12px; }
.rn-vw-caption { text-align: center; font-size: 15px; line-height: 1.5; color: var(--ink-soft); margin: 10px auto 0; max-width: 560px; min-height: 1.5em; }

/* Hydride bp predict-then-reveal (figure[data-bp], A-Level bonding). Trend
   lines stay put; site.js hides each [data-bp-anom] period-2 hydride until the
   student picks a band. The rise is an SVG-attribute tween (rAF) in site.js. */
[data-bp] [data-bp-series], [data-bp] [data-bp-anom] { transition: opacity 0.25s ease; }
[data-bp] .rn-bp-groups, [data-bp] .rn-bp-bands { justify-content: center; margin-top: 10px; }
[data-bp] .rn-bp-bands { margin-top: 8px; }
/* [hidden] must beat .rn-cap-controls' display:flex on the band row */
[data-bp] .rn-bp-bands[hidden] { display: none; }

/* Shape deducer drill (figure-less [data-sd], A-Level bonding). Step panels
   are plain blocks so [hidden] gates them; grids reuse .rn-cap-btn options. */
.sd-species { font-size: 15px; color: var(--ink); margin: 0 0 14px; }
.sd-step { padding: 12px 0; border-top: 1px dashed var(--hairline); }
.sd-step:first-child { border-top: 0; }
.sd-q { font-size: 14.5px; line-height: 1.5; color: var(--ink); margin: 0 0 10px; }
.sd-hint { color: var(--muted); font-weight: 400; }
.sd-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.sd-lab { font-size: 13px; color: var(--ink-soft); display: inline-flex; align-items: center; gap: 6px; }
.sd-in { width: 76px; font-family: var(--font-mono); font-size: 15px; padding: 9px 10px; border: 1.5px solid var(--hairline); border-radius: 6px; background: var(--paper); color: var(--ink); min-height: 40px; }
.sd-in:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.sd-in.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.97 0.03 150); }
.sd-in.is-err { border-color: var(--accent); background: oklch(0.97 0.03 30); }
.sd-grid { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 6px; }
.sd-opt { text-transform: none; letter-spacing: 0; font-family: var(--font-sans); font-size: 13px; }
.sd-opt.is-on { border-color: oklch(0.55 0.11 150); color: oklch(0.34 0.09 150); background: oklch(0.95 0.045 150); }
.sd-opt:disabled { cursor: default; opacity: 0.55; }
.sd-opt.is-on:disabled, .sd-opt.rn-dp-wrong:disabled { opacity: 1; }
.sd-fb { font-size: 13.5px; line-height: 1.5; color: var(--ink-soft); margin: 10px 0 0; min-height: 1em; }
.sd-done { margin-top: 16px; }
.sd-done .sd-model { margin: 0; }

/* Capstone name-the-attraction (figure-less [data-bs], A-Level bonding).
   Two phases: classify into 4 bins, then build the explanation from tiles. */
.bs-q { font-size: 15px; line-height: 1.5; color: var(--ink); margin: 4px 0 12px; }
.bs-chip { font-size: 1.05em; }
.bs-bins { display: flex; flex-wrap: wrap; gap: 8px; }
.bs-bin { text-transform: none; letter-spacing: 0; font-family: var(--font-sans); font-size: 13.5px; }
.bs-bin.is-on { border-color: oklch(0.55 0.11 150); color: oklch(0.34 0.09 150); background: oklch(0.95 0.045 150); }
.bs-build-lead { font-size: 13px; color: var(--muted); margin: 0 0 10px; }
.bs-answer { list-style: none; counter-reset: bs; margin: 0 0 12px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.bs-answer li { counter-increment: bs; position: relative; padding: 9px 12px 9px 34px; background: oklch(0.95 0.045 150); border: 1px solid oklch(0.72 0.09 150); border-radius: 6px; font-size: 13.5px; line-height: 1.4; color: var(--ink); }
.bs-answer li::before { content: counter(bs); position: absolute; left: 10px; top: 50%; transform: translateY(-50%); font-family: var(--font-mono); font-size: 11px; font-weight: 600; color: oklch(0.4 0.09 150); }
.bs-pool { display: flex; flex-wrap: wrap; gap: 8px; }
.bs-opts { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.bs-opt { text-transform: none; letter-spacing: 0; font-family: var(--font-sans); font-size: 13.5px; text-align: left; max-width: 100%; white-space: normal; line-height: 1.35; padding: 10px 13px; }
.bs-opt.is-on { border-color: oklch(0.55 0.11 150); color: oklch(0.34 0.09 150); background: oklch(0.95 0.045 150); }
.bs-tile { text-transform: none; letter-spacing: 0; font-family: var(--font-sans); font-size: 13px; text-align: left; max-width: 100%; white-space: normal; line-height: 1.35; padding: 10px 13px; }
.bs-tile.is-placed { display: none; }
.bs-tile.bs-nudge { border-color: var(--accent); }
.bs-fb { font-size: 13.5px; line-height: 1.5; color: var(--ink-soft); margin: 12px 0 0; min-height: 1em; }

/* Strongest-force quick-fire (figure-less [data-fi], A-Level bonding). */
.fi-species { font-size: 15px; line-height: 1.5; color: var(--ink); margin: 0 0 14px; }
.fi-opts { display: flex; flex-wrap: wrap; gap: 8px; }
.fi-opt { text-transform: none; letter-spacing: 0; font-family: var(--font-sans); font-size: 13.5px; }
.fi-opt.is-on { border-color: oklch(0.55 0.11 150); color: oklch(0.34 0.09 150); background: oklch(0.95 0.045 150); }
.fi-opt.is-on:disabled, .fi-opt.rn-dp-wrong:disabled { opacity: 1; }
.fi-fb { font-size: 13.5px; line-height: 1.5; color: var(--ink-soft); margin: 12px 0 0; min-height: 1.4em; }
.rn-bp-verdict { min-height: 1.5em; }
@media (prefers-reduced-motion: reduce) {
  [data-bp] [data-bp-series], [data-bp] [data-bp-anom] { transition: none; }
}
.rn-dp-prompt { text-align: center; font-size: 15px; color: var(--ink); margin: 12px auto 0; }
.rn-dp-prompt sub { font-size: 0.75em; }
.rn-cap-btn.rn-dp-wrong { border-color: var(--accent); color: var(--accent); background: oklch(0.95 0.05 30); }

@media (prefers-reduced-motion: reduce) {
  [data-bt] [data-bt-stage] { transition: none; }
  [data-lp] [data-lp-mol], [data-lp] [data-lp-labels] { transition: none; }
  [data-dp] [data-dp-mol], [data-dp] [data-dp-reveal] { transition: none; }
}

/* ============================================================
   A-Level ENERGETICS widgets (energetics.html) — driven by site.js:
   cal- run-the-calorimeter [data-cal], cc- cooling-curve drag [data-cc],
   hs- Hess route builder [data-hs], me- bond-enthalpy stepper [data-me],
   ec- capstone route runner [data-ec]. Mounts ship [hidden] in the page;
   each IIFE flips hidden off, so no-JS keeps the static figures and
   worked examples as the complete fallback.
   ============================================================ */
/* cal- run the calorimeter */
.cal-modes { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.cal-rx, .hs-tile, .ec-tile, .ec-m, .ec-dir { text-transform: none; letter-spacing: 0; font-family: var(--font-sans); font-size: 13px; }
.cal-desc { font-size: 13.5px; color: var(--ink-soft); margin: 0 0 12px; min-height: 1.4em; }
.cal-stage { display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-start; }
.cal-svg { display: block; flex: 1 1 220px; max-width: 300px; height: auto; }
.cal-lines { flex: 1 1 250px; font-family: var(--font-mono); font-size: 12.5px; color: var(--ink); display: flex; flex-direction: column; gap: 6px; }
.cal-lines p { margin: 0; padding: 6px 9px; background: var(--paper); border: 1px solid var(--hairline); border-radius: 4px; }
.cal-lines p.cal-final--exo { border-color: oklch(0.55 0.11 150); background: oklch(0.96 0.045 150); }
.cal-lines p.cal-final--endo { border-color: var(--accent); background: oklch(0.97 0.03 30); }
/* cc- cooling-curve extrapolation (controls live inside the F5 figure) */
.cc-controls { margin: 4px 0 8px; }
.cc-controls[hidden] { display: none; }
.cc-controls .rn-cap-controls { margin-top: 0; justify-content: center; }
.cc-controls .rn-cap-msg { text-align: center; margin-top: 8px; }
.cc-hit { touch-action: none; }
/* hs- Hess route builder + ec- capstone (rt-style tiles) */
.hs-q, .ec-q, .me-q, .gq-q { font-size: 15px; line-height: 1.55; color: var(--ink); margin: 0 0 6px; }
.hs-data, .ec-data, .me-data, .gq-data { font-size: 13px; font-family: var(--font-mono); color: var(--ink-soft); margin: 0 0 12px; }
.hs-planlead, .ec-plead { font-size: 13.5px; color: var(--ink-soft); margin: 0 0 8px; }
.hs-bank, .ec-bank, .ec-methods, .ec-dirs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.hs-tile[disabled], .ec-tile[disabled] { opacity: 0.38; }
.hs-tile sub, .hs-tile sup, .ec-tile sub, .ec-tile sup { font-size: 0.72em; line-height: 0; position: relative; vertical-align: baseline; }
.hs-tile sub, .ec-tile sub { bottom: -0.22em; }
.hs-tile sup, .ec-tile sup { top: -0.45em; }
.hs-route, .ec-route { margin-bottom: 12px; }
.hs-route .rn-cap-chip, .ec-route .rn-cap-chip { cursor: pointer; }
.hs-route-num, .ec-route-num { font-family: var(--font-mono); font-size: 10px; color: var(--muted); margin-right: 6px; }
.hs-run, .ec-run { margin: 0 0 4px; }
.hs-run[hidden], .ec-run[hidden] { display: none; }
.hs-anslab, .ec-anslab { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; flex-wrap: wrap; }
.hs-working { font-family: var(--font-mono); font-size: 12.5px; background: var(--paper); border: 1px solid var(--hairline); border-radius: 4px; padding: 10px 12px; margin-top: 12px; }
.hs-working[hidden] { display: none; }
.hs-working p { margin: 0 0 4px; }
.ec-methods .rn-cap-btn.is-ok, .ec-dirs .rn-cap-btn.is-ok { border-color: oklch(0.55 0.11 150); color: oklch(0.34 0.09 150); background: oklch(0.95 0.045 150); }
.ec-methods .rn-cap-btn.is-err, .ec-dirs .rn-cap-btn.is-err { border-color: var(--accent); color: var(--accent); background: oklch(0.95 0.05 30); }
.ec-m.is-ok:disabled, .ec-m.is-err:disabled, .ec-dir.is-ok:disabled, .ec-dir.is-err:disabled { opacity: 1; }
.ec-phase[hidden] { display: none; }
.ec-why { font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); margin: 10px 0 0; padding: 10px 12px; border: 1px solid var(--hairline); border-left: 3px solid oklch(0.55 0.11 150); background: var(--paper); }
.ec-why[hidden] { display: none; }
/* me- bond-enthalpy stepper */
.me-steps, .gq-steps { margin: 0 0 10px; padding-left: 0; list-style: none; display: flex; flex-direction: column; gap: 12px; }
.me-step, .gq-step { border-left: 3px solid var(--hairline); padding-left: 12px; }
.me-step[hidden], .gq-step[hidden] { display: none; }
.me-step.is-done, .gq-step.is-done { border-left-color: oklch(0.55 0.11 150); }
.me-step-lab, .gq-step-lab { margin: 0 0 6px; font-size: 13.5px; color: var(--ink); }
.me-row, .gq-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.me-eq, .gq-eq { font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-soft); }
.me-counts { display: inline-flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; }
.me-count { display: inline-flex; align-items: center; gap: 6px; font-size: 13.5px; color: var(--ink); }
.me-cin { font-family: var(--font-mono); font-size: 14px; padding: 6px 4px; width: 46px; text-align: center; border: 1.5px solid var(--hairline); border-radius: 4px; background: var(--paper); color: var(--ink); }
.me-hint, .gq-hint { font-size: 12px; color: oklch(0.5 0.12 25); min-height: 1em; margin: 6px 0 0; }
.me-hint.is-ok, .gq-hint.is-ok { color: oklch(0.4 0.09 150); }
.me-hint:empty, .gq-hint:empty { display: none; }
.me-done, .gq-done { font-size: 13.5px; line-height: 1.55; padding: 10px 12px; border: 1.5px solid oklch(0.55 0.11 150); background: oklch(0.96 0.045 150); border-radius: 4px; }
.me-done[hidden], .gq-done[hidden] { display: none; }
.me-red { color: oklch(0.52 0.165 30); font-weight: 600; }
.me-grn { color: oklch(0.45 0.11 150); font-weight: 600; }

/* ============================================================
   Grade-boundary calculator + reference tables
   Page: insights/chemistry-grade-boundaries.html
   The interactive calculator is built by initGradeCalc() in site.js
   (progressive enhancement); the static .gb-tables stay visible as the
   no-JS fallback and on-page reference. All styling here uses the shared
   site tokens so the widget matches the article around it.
   ============================================================ */

/* --- Calculator card ------------------------------------------------------ */
.gb-calc {
  margin: 40px 0;
  padding: clamp(22px, 4vw, 34px);
  background: var(--paper-2);
  border: 1px solid var(--hairline);
  border-radius: 10px;
}
.gb-calc > h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(26px, 3vw, 34px);
  line-height: 1.1;
  letter-spacing: -0.018em;
  color: var(--ink);
  margin: 0 0 6px;
}
.gb-calc-lead {
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-soft);
  margin: 0 0 4px;
}

.gb-calc-ui { display: grid; gap: 20px; margin-top: 20px; }
.gb-field { display: grid; gap: 9px; }
.gb-field[hidden] { display: none; }
.gb-label {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

/* --- Choice pills (level, board) ------------------------------------------ */
.gb-pills { display: flex; flex-wrap: wrap; gap: 8px; }
.gb-pill {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-soft);
  background: var(--paper);
  border: 1.5px solid var(--hairline);
  border-radius: 999px;
  padding: 8px 18px;
  cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}
.gb-pill:hover { border-color: var(--ink); }
.gb-pill[aria-pressed="true"] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, var(--paper));
  color: var(--ink);
  font-weight: 600;
}
.gb-pill:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* --- Selects (tier, year) ------------------------------------------------- */
.gb-select {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--ink);
  background: var(--paper);
  border: 1.5px solid var(--hairline);
  border-radius: 6px;
  padding: 10px 12px;
  max-width: 240px;
  cursor: pointer;
}
.gb-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }

/* --- Raw-mark inputs, one per paper --------------------------------------- */
.gb-hint { font-size: 14px; line-height: 1.55; color: var(--muted); margin: 0 0 4px; }
.gb-papers-grid {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.gb-paper { display: grid; gap: 6px; }
.gb-paper-label { display: flex; flex-direction: column; gap: 1px; }
.gb-paper-name { font-size: 14px; font-weight: 600; color: var(--ink); }
.gb-paper-max {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.gb-input {
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--ink);
  background: var(--paper);
  border: 1.5px solid var(--hairline);
  border-radius: 6px;
  padding: 9px 11px;
  width: 100%;
}
.gb-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }

.gb-go { align-self: start; }

/* --- Result --------------------------------------------------------------- */
.gb-result:empty { display: none; }
.gb-result {
  margin-top: 22px;
  padding: 22px;
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
}
.gb-result-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px; }
.gb-result-grade {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(30px, 4vw, 42px);
  line-height: 1;
  color: var(--ink);
}
.gb-result-score {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.03em;
  color: var(--muted);
}
.gb-result-dist { font-size: 15.5px; line-height: 1.55; color: var(--ink-soft); margin: 10px 0 0; }
.gb-result-msg { font-size: 15.5px; line-height: 1.55; color: var(--ink-soft); margin: 0; }

/* --- Boundary scale (0 .. total, tick + label per grade, marker at score) - */
.gb-scale { margin: 4px 0 2px; }
.gb-scale-track {
  position: relative;
  height: 6px;
  background: var(--paper-3);
  border-radius: 999px;
  margin: 46px 0 34px;
}
.gb-tick {
  position: absolute;
  top: 100%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
}
.gb-tick-line { width: 2px; height: 9px; background: var(--hairline); }
.gb-tick-label { font-family: var(--font-mono); font-size: 11px; color: var(--muted); margin-top: 3px; }
.gb-marker {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
}
.gb-marker-line { width: 3px; height: 22px; background: var(--accent); border-radius: 2px; }
.gb-marker-val {
  position: absolute;
  bottom: calc(50% + 15px);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  color: var(--paper);
  background: var(--accent);
  border-radius: 4px;
  padding: 2px 7px;
  white-space: nowrap;
}
.gb-scale-ends {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
}

/* --- Notes + tuition offer ------------------------------------------------ */
.gb-note {
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--muted);
  margin: 14px 0 0;
  padding-left: 12px;
  border-left: 2px solid var(--hairline);
}
.gb-note-approx { border-left-color: var(--accent-soft); }
.gb-offer {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 18px;
}
.gb-offer-text { font-size: 15.5px; line-height: 1.55; color: var(--ink); margin: 0; flex: 1 1 240px; }
.gb-offer-btn { flex: 0 0 auto; }

/* --- Reference tables, as collapsible disclosures -------------------------
   Each qualification's table is tucked behind a clickable heading bar (native
   <details>, same idea as the collapsible exam sections in the revision
   notes). <details> needs no JavaScript, so the tables stay fully reachable
   with JS off too — the calculator's static fallback is intact. */
.gb-tables { margin: 8px 0; }
.gb-tables > h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(23px, 2.6vw, 30px);
  line-height: 1.15;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 46px 0 6px;
}
.gb-tables-intro { font-size: 15px; line-height: 1.6; color: var(--ink-soft); margin: 0 0 18px; }

.gb-details {
  border: 1px solid var(--hairline);
  border-radius: 8px;
  margin: 0 0 10px;
  background: var(--paper);
  overflow: hidden;
}
.gb-summary {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 15px 20px;
  cursor: pointer;
  list-style: none;
  user-select: none;
  transition: background .15s;
}
.gb-summary::-webkit-details-marker { display: none; }   /* hide Safari's default triangle */
.gb-summary::marker { content: ""; }
.gb-summary:hover { background: var(--paper-2); }
.gb-summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.gb-summary-title {
  flex: 1 1 auto;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(18px, 2.1vw, 22px);
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0;
}
.gb-summary::after {
  content: "Show ↓";
  flex: none;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}
.gb-details[open] .gb-summary::after { content: "Hide ↑"; }
.gb-details[open] .gb-summary { border-bottom: 1px solid var(--hairline); background: var(--paper-2); }
.gb-details-body { padding: 18px 20px 8px; }
.gb-details-body > p { font-size: 15px; line-height: 1.6; color: var(--ink-soft); margin: 0 0 14px; }
.gb-details-body > p:first-child { margin-top: 0; }
/* "Higher tier" / "Foundation tier" label sitting directly above its table */
.gb-tier-head { margin: 20px 0 8px; color: var(--ink); font-size: 14px; }
.gb-tier-head + table { margin-top: 0; }
.gb-details-body small { font-size: 12.5px; color: var(--muted); }
.gb-details-body table { font-variant-numeric: tabular-nums; margin-bottom: 6px; }

@media (max-width: 600px) {
  /* Wide 8-column tables would overflow the article column on a phone; let
     each scroll horizontally instead of forcing the whole page to. */
  .gb-details-body table { display: block; overflow-x: auto; white-space: nowrap; }
}

/* ============================================================
   A-Level kinetics — figure trio grid + widget chrome
   (cs- collision sandbox, tan- draw-the-tangent, bz- M–B explorer,
    mk- mark-scheme tiles, cf- collision frequency, lev- capstone)
   ============================================================ */
.rn-figtrio { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px 14px; }
.rn-figtrio svg { display: block; width: 100%; height: auto; }
@media (max-width: 640px) {
  .rn-figtrio { grid-template-columns: 1fr; max-width: 300px; margin: 0 auto; }
}
.rn-cap-svg { display: block; width: 100%; height: auto; margin: 0 0 8px; }
.rn-cap-range-lab { display: inline-flex; align-items: center; gap: 10px; font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.07em; text-transform: uppercase; color: var(--ink-soft); }
.rn-cap-range { width: 168px; accent-color: var(--accent); min-height: 38px; }
.tan-ui { margin: 12px 0 4px; }
.tan-units-lab { font-size: 13px; color: var(--ink-soft); font-style: italic; }
.tan-h { cursor: grab; touch-action: none; }
.tan-h:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.mk-q, .lev-q { font-size: 14.5px; margin: 0 0 4px; }
.lev-q { min-height: 2.8em; }
.mk-pool, .lev-crow { display: grid; gap: 8px; margin: 10px 0 2px; }
.mk-tile { font-family: var(--font-sans); font-size: 13.5px; line-height: 1.45; text-align: left; padding: 10px 14px; border-radius: 8px; border: 1.5px solid var(--hairline); background: var(--paper); color: var(--ink); cursor: pointer; }
.mk-tile:hover { border-color: var(--ink-soft); }
.mk-tile:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.mk-tile[aria-pressed="true"] { border-color: var(--ink-soft); background: oklch(0.945 0.012 250); }
.mk-tile.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.95 0.045 150); color: oklch(0.32 0.08 150); }
.mk-tile.is-err { border-color: var(--accent); background: oklch(0.95 0.05 30); color: var(--accent); }
.mk-tile:disabled { cursor: default; }
.mk-answer { font-size: 14px; background: var(--paper); border: 1px solid var(--hairline); border-radius: 6px; padding: 12px 14px; margin: 0; }
.lev-step { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); margin: 14px 0 6px; }
.rn-cap-controls[hidden] { display: none; }

/* ============================================================
   AS/A2 gateway + rail — mixed pages (AS content, then an
   A-level-only block). First used on chemical-equilibria (Kp).
   ============================================================ */
.rn-a2-gateway { margin: 44px 0 30px; padding: 18px 22px; border-block: 2px solid oklch(0.78 0.07 165); background: oklch(0.972 0.018 165); border-radius: 10px; }
.rn-a2-gateway-badge { display: inline-flex; align-items: center; gap: 8px; font: 700 0.78rem/1 var(--font-sans); letter-spacing: 0.05em; text-transform: uppercase; color: oklch(0.40 0.08 165); }
.rn-a2-gateway p { margin: 0.55em 0 0; }
.rn-a2 { border-left: 4px solid oklch(0.82 0.06 165); padding-left: 22px; margin-top: 8px; }
@media (max-width: 600px) { .rn-a2 { padding-left: 14px; } }

/* ============================================================
   Chemical equilibria widgets (lc- Le Chatelier sandbox,
   kb- Kc builder, pc- position-vs-constant; kp- Kp stepper
   reuses the shared .me-* stepper chrome). Steppers, tiles,
   inputs and buttons all reuse the generic .rn-cap-*/.mk-tile/
   .me-* classes above — only the genuinely new pieces are here.
   ============================================================ */
/* W1 — the tipping balance. The beam <g> rotates about the pivot
   (viewBox point 200,150); reduced motion snaps instead of tweening. */
.lc-eq { font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-soft); margin: 0 0 10px; }
.lc-eq strong { color: var(--ink); }
.lc-beam { transform-box: view-box; transform-origin: 200px 150px; transition: transform 0.55s cubic-bezier(0.34, 1.12, 0.5, 1); }
@media (prefers-reduced-motion: reduce) { .lc-beam { transition: none; } }
.lc-read { display: flex; flex-wrap: wrap; gap: 8px 10px; align-items: center; margin-top: 12px; }
.lc-chip { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; padding: 5px 11px; border-radius: 999px; border: 1.5px solid var(--hairline); color: var(--ink-soft); background: var(--paper); }
.lc-chip b { color: var(--ink); font-weight: 600; }
.lc-chip.is-changed { border-color: oklch(0.62 0.15 30); background: oklch(0.96 0.04 30); color: var(--accent); }
.lc-chip.is-changed b { color: var(--accent); }

/* W2 — Kc builder: assign each species to the numerator or
   denominator, then read the assembled fraction back. */
.kb-rows { display: flex; flex-direction: column; gap: 8px; margin: 10px 0 4px; }
.kb-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.kb-row-sp { font-family: var(--font-mono); font-size: 14px; color: var(--ink); min-width: 74px; }
.kb-sides { display: inline-flex; gap: 6px; }
.kb-side.is-on { border-color: var(--ink-soft); background: oklch(0.945 0.012 250); color: var(--ink); }
.kb-sub { font-size: 13px; color: var(--ink-soft); margin: 0 0 8px; }
.kb-frac { display: inline-flex; align-items: center; gap: 10px; font-family: var(--font-mono); font-size: 16px; color: var(--ink); padding: 10px 16px; border: 1px solid var(--hairline); border-radius: 6px; background: var(--paper); margin: 8px 0; }
.kb-fbox { display: inline-flex; flex-direction: column; align-items: center; gap: 3px; }
.kb-bar { align-self: stretch; border-top: 1.6px solid var(--ink); min-width: 96px; }
.kb-part { padding: 2px 8px; min-height: 1.3em; text-align: center; }
.kb-empty { color: var(--muted); font-size: 12px; }
.kb-vlab, .kb-lhs { font-family: var(--font-mono); }

/* W-CAP — two-decision grid (effect on position, effect on K). */
.pc-decisions { display: grid; gap: 14px; margin: 12px 0 2px; }
@media (min-width: 560px) { .pc-decisions { grid-template-columns: 1fr 1fr; } }
.pc-dec-lab { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); margin: 0 0 8px; }
.pc-opts { display: grid; gap: 8px; }
.pc-intro { font-size: 13px; color: var(--ink-soft); margin: 0 0 10px; }
.pc-q, .lc-q, .kb-q { font-size: 15px; line-height: 1.5; color: var(--ink); font-weight: 500; margin: 4px 0 8px; }
.pc-opt.mk-tile[aria-pressed="true"] { border-color: oklch(0.5 0.14 255); background: oklch(0.95 0.03 255); }
/* W1 lever buttons: a toggled lever gets the accent-on state (reused .is-on) */
.lc-levers { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 2px; }
.lc-svg { max-width: 360px; margin: 6px auto 2px; }

/* ============================================================
   Inorganic A-level widgets (periodicity: bl block finder,
   ar radius explorer, ie/mp Period-3 explorers, tq trend quiz;
   reused by group 2 / group 7). Chrome reuses .rn-cap-*/.mk-tile.
   ============================================================ */
.bl-q, .tq-q, .ar-q, .p3-q { font-size: 15px; line-height: 1.5; color: var(--ink); font-weight: 500; margin: 4px 0 10px; }
.bl-opts, .tq-pick { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin: 4px 0 2px; }
.tq-reasons { display: grid; gap: 8px; margin: 4px 0 2px; }
.bl-q .rn-chem, .p3-q .rn-chem { font-weight: 600; }
/* Period-3 element chooser: a row of small square element buttons. */
.p3-els { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 12px; }
.p3-els[hidden] { display: none; }
.p3-el { font-family: var(--font-mono); font-size: 13px; min-width: 40px; min-height: 40px; padding: 4px 6px; border-radius: 8px; border: 1.5px solid var(--hairline); background: var(--paper); color: var(--ink); cursor: pointer; text-align: center; }
.p3-el:hover { border-color: var(--ink-soft); }
.p3-el:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.p3-el.is-on { border-color: var(--accent); background: oklch(0.96 0.03 30); color: var(--accent); font-weight: 600; }
/* readout panel for the explorers */
.p3-read { border: 1px solid var(--hairline); border-left: 3px solid var(--accent); border-radius: 6px; background: var(--paper); padding: 12px 14px; margin: 4px 0 0; font-size: 14px; line-height: 1.55; color: var(--ink); }
.p3-read[hidden] { display: none; }
.p3-read .p3-tag { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.02em; color: var(--muted); display: block; margin-bottom: 4px; }
.p3-read strong { color: var(--ink); }
/* W2 radius explorer: the atom circle scales smoothly (reduced motion snaps). */
.ar-svg { display: block; width: 100%; max-width: 420px; height: auto; margin: 4px auto 6px; }
.ar-atom { transition: r 0.4s cubic-bezier(0.34, 1.05, 0.5, 1); }
@media (prefers-reduced-motion: reduce) { .ar-atom { transition: none; } }
.ar-read { display: flex; flex-wrap: wrap; gap: 8px 10px; align-items: center; margin-top: 6px; }
.ar-chip { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.03em; padding: 5px 11px; border-radius: 999px; border: 1.5px solid var(--hairline); color: var(--ink-soft); background: var(--paper); }
.ar-chip b { color: var(--ink); font-weight: 600; }
/* A small mono lead line inside a figure (e.g. the reaction a multi-panel
   figure is drawn for), above the drawing. */
.rn-fig-lead { font-family: var(--font-mono); font-size: 12.5px; line-height: 1.5; color: var(--ink-soft); text-align: center; margin: 0 auto 8px; max-width: 60ch; }
.rn-fig-lead strong { color: var(--ink); }
/* Group 7: result-colour swatch in the displacement-lab readout. */
.ox-swatch { display: inline-block; width: 14px; height: 14px; border-radius: 4px; vertical-align: -2px; margin-right: 6px; border: 1px solid oklch(0.7 0.02 250); }
/* W3 group-2 solubility bar (fills the opposite way for hydroxides vs sulfates). */
.sol-bar-wrap { display: flex; align-items: center; gap: 12px; margin: 14px 0 6px; }
.sol-track { flex: 1; max-width: 340px; height: 22px; background: var(--paper); border: 1.5px solid var(--hairline); border-radius: 6px; overflow: hidden; }
.sol-bar { height: 100%; width: 8%; background: oklch(0.6 0.12 255); transition: width 0.4s cubic-bezier(0.34, 1.05, 0.5, 1), background-color 0.3s; }
@media (prefers-reduced-motion: reduce) { .sol-bar { transition: none; } }
.sol-bar-lab { font-family: var(--font-mono); font-size: 12.5px; font-weight: 600; color: var(--ink); min-width: 92px; }

/* ============================================================
   Redox A-level widgets (3.1.7): os oxidation-state checker,
   hb half-equation builder, cb combine, oa analyser.
   Chrome reuses .rn-cap-* / .mk-tile / .pc-*.
   ============================================================ */
.os-bank, .os-opts, .hb-bank { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 2px; }
.os-opts { margin-top: 8px; }
.os-opts .mk-tile { font-family: var(--font-mono); min-width: 46px; text-align: center; }
.os-q, .hb-task { font-size: 15px; line-height: 1.5; color: var(--ink); font-weight: 500; margin: 12px 0 4px; }
.os-q .rn-chem, .hb-eq .rn-chem { font-weight: 600; }
.os-work { font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-soft); background: var(--paper); border: 1px solid var(--hairline); border-left: 3px solid oklch(0.46 0.14 255); border-radius: 0 4px 4px 0; padding: 10px 13px; margin-top: 12px; line-height: 1.75; }
.os-work:empty { display: none; }
.os-work b { color: var(--ink); }

/* live equation display (hb builder) */
.hb-eq { font-family: var(--font-mono); font-size: 15px; color: var(--ink); background: var(--paper); border: 1.5px solid var(--hairline); border-left: 3px solid var(--accent); border-radius: 0 4px 4px 0; padding: 12px 14px; margin: 10px 0 12px; text-align: center; line-height: 1.7; }
.hb-eq .hb-add { color: oklch(0.46 0.14 255); font-weight: 700; }
.hb-eq .hb-add-e { color: oklch(0.40 0.11 150); font-weight: 700; }
.hb-steps { display: flex; flex-direction: column; gap: 10px; }
.hb-step { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; padding: 10px 12px; border: 1.5px solid var(--hairline); border-radius: 8px; background: var(--paper); }
.hb-step[hidden] { display: none; }
.hb-step.is-done { border-color: oklch(0.55 0.11 150); background: oklch(0.97 0.02 150); }
.hb-step-lab { font-size: 13.5px; color: var(--ink); flex: 1 1 190px; min-width: 150px; line-height: 1.45; }

/* stepper shared by hb + cb */
.rx-stp { display: inline-flex; align-items: center; border: 1.5px solid var(--hairline); border-radius: 999px; overflow: hidden; background: var(--paper); }
.rx-stp button { font-family: var(--font-mono); font-size: 15px; width: 34px; height: 34px; border: 0; background: var(--paper); color: var(--ink); cursor: pointer; line-height: 1; }
.rx-stp button:hover { background: var(--paper-2); }
.rx-stp button:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.rx-stp-n { font-family: var(--font-mono); font-size: 14px; min-width: 30px; text-align: center; color: var(--ink); font-weight: 600; }
.hb-side { display: inline-flex; gap: 6px; }
.hb-go { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; padding: 7px 12px; border-radius: 999px; border: 1.5px solid var(--hairline); background: var(--paper); color: var(--ink-soft); cursor: pointer; min-height: 34px; }
.hb-go:hover { border-color: var(--ink-soft); color: var(--ink); }
.hb-go:disabled { opacity: 0.5; cursor: default; }

/* cb combine */
.cb-halves { display: flex; flex-direction: column; gap: 10px; margin: 10px 0; }
.cb-half { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px; padding: 10px 12px; border: 1.5px solid var(--hairline); border-radius: 8px; background: var(--paper); }
.cb-half-eq { font-family: var(--font-mono); font-size: 14px; color: var(--ink); flex: 1 1 260px; min-width: 190px; }
.cb-mult { display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-mono); font-size: 12.5px; color: var(--muted); }
.cb-tally { font-family: var(--font-mono); font-size: 13px; color: var(--ink-soft); margin: 2px 0 0; }
.cb-tally b { color: var(--ink); }
.cb-tally.is-match b { color: oklch(0.42 0.10 150); }
.cb-result { font-family: var(--font-mono); font-size: 15px; text-align: center; color: var(--ink); background: oklch(0.95 0.05 150); border: 1.5px solid oklch(0.50 0.12 150); border-radius: 8px; padding: 12px 14px; margin-top: 12px; line-height: 1.7; }
.cb-result:empty { display: none; }

/* oa analyser */
.oa-eq { font-family: var(--font-mono); font-size: 15px; color: var(--ink); background: var(--paper); border: 1.5px solid var(--hairline); border-left: 3px solid var(--accent); border-radius: 0 4px 4px 0; padding: 12px 14px; margin: 6px 0 4px; text-align: center; line-height: 1.6; }

/* ══════════════════════════════════════════════════════════════════════════
   A-Level 3.3.1 intro-to-organic ChemDraw-style suite (.oc-* / per-widget
   sk- dw- nom- iso- ez- mech- fg-). Driven by site.js off the mounts
   [data-sk] [data-draw] [data-nom] [data-iso] [data-ez] [data-mech] [data-fg];
   chrome extends .rn-cap-* / .mk-tile.
   ══════════════════════════════════════════════════════════════════════════ */
.oc-stage { margin-top: 12px; background: var(--paper); border: 1px solid var(--hairline); border-radius: 8px; padding: 10px 8px; }
.oc-stage svg { display: block; width: 100%; height: auto; max-height: 300px; margin-inline: auto; touch-action: manipulation; }
.oc-h { fill: transparent; stroke: transparent; stroke-width: 2; cursor: pointer; outline: none; }
.oc-h:hover { stroke: var(--hairline); }
.oc-h:focus-visible { stroke: var(--ink); stroke-dasharray: 3 2; }
.oc-h.is-sel { stroke: var(--accent); stroke-width: 2.5; }
.oc-h.is-ring { stroke: oklch(0.55 0.11 150); stroke-dasharray: 4 3; }
.oc-h.is-ok { stroke: oklch(0.55 0.11 150); stroke-width: 2.5; fill: oklch(0.95 0.045 150 / 0.3); }
.oc-h.is-err { stroke: var(--accent); stroke-width: 2.5; fill: oklch(0.95 0.05 30 / 0.3); }
.oc-h.is-missed { stroke: oklch(0.55 0.11 150); stroke-width: 2.5; stroke-dasharray: 3 3; }
.dw-pick[aria-pressed="true"] { stroke: var(--ink); fill: oklch(0.945 0.012 250 / 0.35); }
.oc-palette { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.oc-palette[hidden] { display: none; }
.oc-chip { min-width: 44px; min-height: 40px; text-align: center; font-weight: 600; padding: 8px 10px; }
.oc-chip[aria-pressed="true"] { border-color: oklch(0.55 0.11 150); background: oklch(0.95 0.045 150); }
.oc-target { margin: 2px 0 0; font-size: 15px; }
.oc-target-name { color: var(--accent); }
.oc-target-fig { display: block; max-width: 320px; margin: 10px auto 0; padding: 8px; background: var(--paper); border: 1px solid var(--hairline); border-radius: 8px; }
.oc-target-fig svg { display: block; width: 100%; height: auto; max-height: 170px; }
.oc-readout { margin: 8px 0 0; font-size: 13.5px; color: var(--ink-soft); }
.oc-readout-note { color: var(--muted); font-size: 12.5px; }
.oc-vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.oc-msg-area .is-ok, .rn-cap-msg.is-ok { color: oklch(0.34 0.09 150); font-style: normal; }
.oc-msg-area .is-err, .rn-cap-msg.is-err { color: var(--accent); font-style: normal; }
.oc-step { display: inline-flex; align-items: center; gap: 8px; margin: 8px 14px 0 0; padding: 6px 10px; border: 1.5px solid var(--hairline); border-radius: 8px; background: var(--paper); }
.oc-step-lab { font-size: 13px; color: var(--ink-soft); }
.oc-step-val { min-width: 1.4em; text-align: center; font-weight: 700; font-variant-numeric: tabular-nums; }
.oc-step-unit { font-size: 13px; color: var(--muted); }
.oc-step .rn-cap-btn { min-height: 32px; padding: 4px 12px; }
.oc-step.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.95 0.045 150); }
.oc-step.is-err { border-color: var(--accent); background: oklch(0.95 0.05 30); }
.dw-controls[hidden] { display: none; }
.dw-reveal { opacity: 0; transition: opacity 0.45s ease; margin-top: 4px; }
.dw-reveal.is-shown { opacity: 1; }
.dw-reveal-lab { font-size: 13px; color: var(--ink-soft); margin: 10px 0 4px; }
.dw-reveal svg { display: block; width: 100%; max-width: 340px; height: auto; max-height: 190px; margin-inline: auto; }
@media (prefers-reduced-motion: reduce) {
  .dw-reveal { transition: none; }
}

/* W3 name-builder chips + W4 isomer studio */
.oc-chip-lab { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted); margin: 12px 0 6px; }
.oc-chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
.nom-chip[aria-pressed="true"] { border-color: var(--accent); background: oklch(0.96 0.03 30); }
.nom-built { margin: 12px 0 0; font-size: 14.5px; color: var(--ink-soft); }
.nom-nameui[hidden], .nom-drawui[hidden], .nom-stage[hidden], .iso-quiz[hidden] { display: none; }
.nom-stage svg, .iso-found svg { display: block; margin-inline: auto; }
.iso-bank { display: flex; flex-wrap: wrap; gap: 8px; }
.iso-quiz { margin-top: 12px; padding: 12px 14px; border: 1.5px solid var(--hairline); border-radius: 8px; background: var(--paper); }
.iso-quiz-q { margin: 0 0 8px; font-size: 14.5px; }
.iso-quiz-opts { display: flex; flex-wrap: wrap; gap: 8px; }
.iso-quiz-opt.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.95 0.045 150); }
.iso-quiz-opt.is-err { border-color: var(--accent); background: oklch(0.95 0.05 30); }
.iso-found { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.iso-card { margin: 0; padding: 8px 10px 6px; border: 1.5px solid var(--hairline); border-radius: 8px; background: var(--paper); width: 128px; }
.iso-card svg { width: 100%; height: 58px; }
.iso-card figcaption { font-size: 11.5px; color: var(--ink-soft); text-align: center; margin-top: 4px; line-height: 1.3; }
.iso-card-missed { border-style: dashed; border-color: var(--accent); }
.iso-missed-tag { color: var(--accent); font-weight: 600; text-transform: uppercase; font-size: 10px; letter-spacing: 0.05em; }

/* W5 E/Z picker + W6 arrow checker + W-CAP option tiles */
.ez-chip { font-size: 13px; }
.ez-stage svg, .mech-stage svg { display: block; margin-inline: auto; }
.mech-ghost { cursor: pointer; outline: none; }
.mech-ghost:focus-visible path { stroke: var(--ink); }
.mech-ghost:hover path:first-child { stroke: var(--ink-soft); }
.mech-ghost-dim { opacity: 0.3; }
.mech-ghost-bad path:first-child { stroke: var(--accent); opacity: 0.55; }
.fg-opts { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; margin-top: 12px; }
.fg-opts[hidden] { display: none; }
.fg-opt { display: flex; align-items: center; justify-content: center; min-height: 86px; padding: 10px; }
.fg-opt svg { width: 100%; max-width: 170px; max-height: 92px; height: auto; }
.fg-opt .fg-text { font-size: 15px; font-weight: 600; }
.fg-opt.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.95 0.045 150); }
.fg-opt.is-err { border-color: var(--accent); background: oklch(0.95 0.05 30); }
.fg-build[hidden] { display: none; }
.fg-inline-fig { display: block; max-width: 240px; margin: 8px auto 0; }
.fg-inline-fig svg { width: 100%; height: auto; max-height: 110px; display: block; }

/* intro-organic figure grids (F1–F6) */
.oc-figgrid { display: grid; gap: 10px; margin-top: 10px; grid-template-columns: 1fr; }
.oc-figgrid-2 { grid-template-columns: repeat(2, 1fr); }
.oc-figgrid-3 { grid-template-columns: repeat(3, 1fr); }
.oc-figgrid-fg { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.oc-figcell { border: 1px solid var(--hairline); border-radius: 8px; background: var(--paper); padding: 10px 12px 8px; min-width: 0; }
.oc-figcell svg { display: block; width: 100%; height: auto; max-height: 150px; margin-inline: auto; }
/* taller cap for full-width diagram cells (tube rows, flowcharts) that would
   otherwise be squished by the 150px molecule-diagram cap */
.oc-figcell--tall svg { max-height: 340px; }
/* wide diagram (e.g. the identification flowchart) — scroll horizontally on
   narrow screens instead of shrinking the text to nothing */
.oc-figscroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 -2px; }
.oc-figscroll svg { display: block; width: 100%; height: auto; max-height: 340px; min-width: 560px; margin-inline: auto; }
.oc-figcell-head { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-soft); margin: 0 0 6px; }
.oc-figcell-note { font-size: 12.5px; color: var(--muted); margin: 6px 0 0; line-height: 1.45; }
.oc-figcell-x { border: 1.5px dashed var(--accent); }
.oc-figcell-x .oc-figcell-head { color: var(--accent); }
.oc-f1-title { font-size: 14.5px; font-weight: 600; margin: 0 0 4px; }
.oc-f1-formula { font-size: 17px; margin: 18px 0; text-align: center; }
.oc-f1-wrong { max-width: 560px; }
.oc-fgcard svg { max-height: 62px; }
.oc-fgcard-gf { font-size: 13.5px; margin: 6px 0 0; text-align: center; }
.oc-f4pair { display: flex; align-items: center; gap: 8px; }
.oc-f4pair svg { flex: 1; min-width: 0; }
.oc-f4vs { font-family: var(--font-mono); font-size: 11px; color: var(--muted); flex: none; }
.oc-f4names { font-size: 12.5px; color: var(--ink-soft); text-align: center; margin: 6px 0 0; }
.oc-pri1 { color: var(--accent); }
@media (max-width: 640px) {
  .oc-figgrid-3 { grid-template-columns: 1fr; }
  .oc-figcell svg { max-height: 120px; }
}

/* structure figures inside exam questions */
.rn-exam-fig { margin: 10px auto 14px; padding: 10px; max-width: 300px; background: var(--paper); border: 1px solid var(--hairline); border-radius: 8px; }
.rn-exam-fig svg { display: block; width: 100%; height: auto; margin-inline: auto; }

.oc-hint { font-size: 12px; color: var(--muted); margin: 6px 0 0; }

/* W-ROT rotation panels */
.rb-wrap .oc-figcell svg { max-height: 200px; }
.rb-wrap .rn-cap-controls { justify-content: center; margin-top: 4px; }
.rb-wrap .rn-cap-msg { min-height: 3.6em; }

/* ============================================================
   ALKANES page (3.3.2). fd- animated fractional distillation —
   HOISTED from the GCSE crude-oil page (c7…/1-crude-oil-fuels-
   and-feedstock.html) so the SAME figure runs there and on the
   A-level alkanes page: markup stays per page, style lives here,
   script in site.js (guarded by #fdSvg). Also frs- radical-step
   sorter [data-frs] and alk- build-the-mechanism [data-alk];
   both mounts ship [hidden] (no-JS fallback: F4 + the mechanism
   callout), chrome reuses .rn-cap-*.
   ============================================================ */
/* fd- fractional distillation (shared GCSE + A-level) */
.fd-wrap { margin: 24px 0 28px; padding: 16px 12px 12px; background: var(--paper-2); border: 1px solid var(--hairline); border-radius: 4px; text-align: center; }
.fd-stage { display: block; width: 100%; max-width: 560px; margin: 0 auto 6px; overflow: visible; }
.fd-btn { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.07em; text-transform: uppercase; font-weight: 500; padding: 7px 18px; border-radius: 999px; border: 1.5px solid var(--hairline); cursor: pointer; background: var(--paper); color: var(--ink-soft); }
.fd-btn:hover:not(:disabled) { border-color: var(--ink-soft); color: var(--ink); }
.fd-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.fd-btn:disabled { opacity: 0.5; cursor: default; }
.fd-wrap .rn-img-caption { text-align: left; margin-top: 12px; }
/* frs- + alk- mechanism widgets */
.frs-q, .alk-q { font-size: 15px; line-height: 1.55; color: var(--ink); margin: 0 0 10px; }
.frs-eq { font-size: 17px; color: var(--ink); text-align: center; padding: 14px 10px; background: var(--paper); border: 1px solid var(--hairline); border-radius: 6px; margin: 0 0 12px; }
.frs-opts, .frs-bank, .alk-bank { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.frs-tile, .alk-tile { text-transform: none; letter-spacing: 0; font-family: var(--font-sans); font-size: 13px; }
.frs-tile[disabled], .alk-tile[disabled], .frs-lab[disabled] { opacity: 0.38; }
.frs-tile sub, .frs-tile sup, .alk-tile sub, .alk-tile sup, .frs-eq sub, .frs-eq sup { font-size: 0.72em; line-height: 0; position: relative; vertical-align: baseline; }
.frs-tile sub, .alk-tile sub, .frs-eq sub { bottom: -0.22em; }
.frs-tile sup, .alk-tile sup, .frs-eq sup { top: -0.45em; }
.frs-lab { text-transform: none; letter-spacing: 0; font-family: var(--font-sans); font-size: 13px; font-weight: 600; }
.frs-route, .alk-route { margin-bottom: 12px; }
.frs-route .rn-cap-chip, .alk-route .rn-cap-chip { cursor: pointer; }
.frs-route-num, .alk-route-num { font-family: var(--font-mono); font-size: 10px; color: var(--muted); margin-right: 6px; text-transform: uppercase; }
.frs-build[hidden] { display: none; }
.frs-planlead, .alk-planlead { font-size: 13.5px; color: var(--ink-soft); margin: 0 0 8px; }
/* F3 combustion panel grid — 2-up that stacks on small phones */
.alkx-grid { display: grid; gap: 10px; margin-top: 10px; grid-template-columns: repeat(2, 1fr); }
@media (max-width: 560px) { .alkx-grid { grid-template-columns: 1fr; } }
/* rn-oa — condition written OVER the reaction arrow (e.g. UV light above
   initiation). Reusable in .rn-eq lines and inside .rn-cap-chip/-btn tiles;
   sizes in em so it follows the surrounding font. */
.rn-oa { display: inline-flex; flex-direction: column; align-items: center; vertical-align: middle; margin: 0 4px; position: relative; top: -0.1em; }
.rn-oa-cond { font-family: var(--font-mono); font-size: 0.58em; font-weight: 600; letter-spacing: 0.04em; color: var(--accent); white-space: nowrap; padding: 0 3px 2px; text-transform: uppercase; }
.rn-oa-line { position: relative; height: 0; border-top: 1.8px solid currentColor; align-self: stretch; min-width: 3.2em; }
.rn-oa-line::after { content: ""; position: absolute; right: -1px; top: -4.3px; border-left: 0.42em solid currentColor; border-top: 0.24em solid transparent; border-bottom: 0.24em solid transparent; }

/* ── A-Level halogenoalkanes (3.3.3): responsive 2-panel figure grid + the
   halo/hydro chip groups, ozone counters and reveal panel. The -2m grid is
   the stacking variant of .oc-figgrid-2 (2-up on desktop, 1-up on phones)
   for panels too tall for the 150px figcell cap. */
.oc-figgrid-2m { grid-template-columns: repeat(2, 1fr); }
.oc-figgrid-2m .oc-figcell svg { max-height: 340px; }
@media (max-width: 640px) { .oc-figgrid-2m { grid-template-columns: 1fr; } }
.halo-groups { display: grid; gap: 12px; margin: 12px 0 2px; }
.halo-grouphead { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-soft); margin: 0 0 6px; }
.halo-opts { display: flex; flex-wrap: wrap; gap: 8px; }
.elim-opts { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 12px; }
.oz-state { font-size: 15px; font-weight: 600; color: var(--ink); margin: 0 0 6px; }
.oz-counts { display: flex; flex-wrap: wrap; gap: 10px 18px; margin: 10px 0 2px; font-size: 13.5px; color: var(--ink-soft); }
.oz-count-num { font-family: var(--font-mono); font-weight: 600; font-size: 15px; color: var(--ink); }
.hydro-reveal { margin-top: 12px; padding: 12px 14px; background: var(--paper); border: 1px solid var(--hairline); border-radius: 8px; font-size: 14px; line-height: 1.55; }

/* ── A-Level alkenes (3.3.4): the four widgets reuse the .rn-cap-* / .oc-* /
   .mk-tile chrome wholesale; the only new piece is the small mono label
   above a chip group ("Arrow 1 starts from…"). */
.rn-cap-sublead { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-soft); margin: 12px 0 2px; }
.nuc-opts { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 2px; }
.nuc-opt[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); background: oklch(0.96 0.03 30); }
/* Two-arrow progress: each mechanism needs BOTH arrows, so surface which one is
   still owed and keep a half-finished mechanism from being skipped by accident. */
.nuc-pip { display: inline-block; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; padding: 2px 9px; margin-left: 6px; border-radius: 999px; border: 1px solid var(--hairline); color: var(--muted); vertical-align: middle; }
.nuc-pip.is-done { border-color: var(--accent); color: var(--accent); }
.nuc-pip.is-done::before { content: "\2713\00a0"; }
.nuc-pip.is-now { background: var(--accent); color: #fff; border-color: var(--accent); }
.nuc-need2 .nuc-prompt { border-left: 3px solid var(--accent); background: oklch(0.96 0.03 30); padding: 8px 12px; border-radius: 0 6px 6px 0; }
.nuc-need2 .nuc-check { border-color: var(--accent); color: var(--accent); }
.nuc-need2 .nuc-new { opacity: 0.5; }

/* ── Greenhouse-effect animation (ghe) — shared by GCSE C9 Part 2 and
   A-Level organic-analysis (3.3.6, IR & global warming). JS in site.js. ── */
.ghe-wrap{margin:24px 0 28px;padding:16px 14px 14px;background:var(--paper-2);border:1px solid var(--hairline);border-radius:4px;text-align:center;}
.ghe-stage{display:block;width:100%;max-width:560px;margin:0 auto 4px;overflow:visible;}
.ghe-controls{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px 18px;max-width:520px;margin:6px auto 0;}
.ghe-slider{display:inline-flex;align-items:center;gap:9px;font-family:var(--font-mono);font-size:10.5px;letter-spacing:0.05em;text-transform:uppercase;color:var(--ink-soft);}
.ghe-slider input[type=range]{width:140px;accent-color:oklch(0.52 0.165 30);cursor:pointer;}
.ghe-lvl{min-width:3.4em;text-align:left;font-weight:600;color:var(--ink);}
.ghe-caption{font-size:13px;color:var(--ink-soft);margin:9px auto 9px;font-style:italic;min-height:3.4em;max-width:520px;line-height:1.45;}
.ghe-btn{font-family:var(--font-mono);font-size:11px;letter-spacing:0.07em;text-transform:uppercase;font-weight:500;padding:7px 18px;border-radius:999px;border:1.5px solid var(--hairline);cursor:pointer;background:var(--paper);color:var(--ink-soft);}
.ghe-btn:hover:not(:disabled){border-color:var(--ink-soft);color:var(--ink);}
.ghe-btn:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
.ghe-btn:disabled{opacity:0.5;cursor:default;}

/* organic-analysis W1 test-tube identifier — reagent-chip verdicts */
.ttr-opts .rn-cap-btn.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.95 0.045 150); color: oklch(0.32 0.08 150); }
.ttr-opts .rn-cap-btn.is-err { border-color: var(--accent); background: oklch(0.95 0.05 30); color: var(--accent); }

/* =========================================================================
   Whole-topic A2 pages — the LOCKED "subtle green accent" standard.
   .rn-hero--a2 goes on .article-hero: a faint green eyebrow rule above the
   hero text column + a green-tinted category chip (pairs with the green
   .rn-meta-badge.alevel that draft pages already ship). First used on nmr;
   thermodynamics et al. adopt the same class at ship.
   ========================================================================= */
.rn-hero--a2 .rn-hero-main::before { content: ""; display: block; width: 58px; height: 3px; border-radius: 2px; background: oklch(0.78 0.07 165); margin-bottom: 6px; }
.rn-hero--a2 .article-category { color: oklch(0.40 0.08 165); border-color: oklch(0.40 0.08 165 / 0.35); }

/* Hub A2 tile treatment: thin green top border + a small green "A2" chip
   (append <span class="rn-topic-a2">A2</span> inside .rn-topic-num when the
   card flips live; the "· A2" plain-text marker stays on coming-soon cards). */
.rn-topic-card--a2 { border-top: 3px solid oklch(0.78 0.07 165); }
.rn-topic-a2 { display: inline-block; font-family: var(--font-mono); font-size: 9px; font-weight: 700; letter-spacing: 0.05em; line-height: 1; padding: 3px 5px; border-radius: 4px; color: oklch(0.40 0.08 165); background: oklch(0.955 0.025 165); border: 1px solid oklch(0.82 0.06 165); vertical-align: 1px; }

/* =========================================================================
   NMR (3.3.15) — W1 shift-band explorer [data-nshift], W2 integration
   ratios [data-nint], W3 n+1 sandbox [data-nsplit], W4 flagship analyser
   [data-nmr], W5 mark scheme (.mknm-wrap). Chrome reuses .rn-cap-* /
   .elim-opts / .oc-stage / .mk-tile; everything below is nmr-specific.
   ========================================================================= */
.nmr-wrap [hidden] { display: none !important; }
.nmr-head { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; margin: 12px 0 10px; }
.nmr-pick-label { display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }
.nmr-pick { font: 500 13.5px/1.3 var(--font-sans); padding: 8px 10px; border: 1.5px solid var(--hairline); border-radius: 8px; background: var(--paper); color: var(--ink); max-width: 230px; }
.nmr-head .elim-opts { margin: 0; }
.nmr-booklet { margin: 10px 0; border: 1px solid var(--hairline); border-radius: 8px; background: var(--paper); }
.nmr-booklet > summary { cursor: pointer; padding: 9px 12px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-soft); }
.nmr-booklet-tables { display: grid; gap: 14px; padding: 4px 12px 12px; }
@media (min-width: 700px) { .nmr-booklet-tables { grid-template-columns: 1fr 1fr; align-items: start; } }
.nmr-booklet-tables table { width: 100%; border-collapse: collapse; font-size: 12px; }
.nmr-booklet-tables caption { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); text-align: left; padding-bottom: 5px; }
.nmr-booklet-tables th, .nmr-booklet-tables td { text-align: left; padding: 3px 8px 3px 0; border-bottom: 1px solid var(--hairline); font-weight: 400; }
.nmr-booklet-tables th { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em; color: var(--muted); }
.nmr-stage { background: var(--paper); border: 1px solid var(--hairline); border-radius: 8px; padding: 8px 8px 4px; margin: 10px 0; }
.nmr-stage svg { display: block; width: 100%; height: auto; }
.nmr-panel { border: 1px solid var(--hairline); border-radius: 8px; padding: 12px 14px; background: var(--paper); margin: 10px 0; }
.nmr-panel-title { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: 0.04em; color: var(--ink); margin: 0 0 8px; font-weight: 600; }
.nmr-row { display: grid; gap: 10px; margin: 8px 0 4px; }
@media (min-width: 640px) { .nmr-row { grid-template-columns: repeat(3, 1fr); } }
/* Read-a-spectrum panel has FOUR fields: three short selects on one line,
   the long Table-B select on its own full-width line */
@media (min-width: 640px) { .nmr-row--4 .nmr-field:last-child { grid-column: 1 / -1; } }
.nmr-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.nmr-field select { font: 500 13px/1.3 var(--font-sans); padding: 7px 8px; border: 1.5px solid var(--hairline); border-radius: 7px; background: var(--paper); color: var(--ink); width: 100%; min-width: 0; }
.nmr-field.is-ok select { border-color: oklch(0.55 0.11 150); background: oklch(0.95 0.045 150); }
.nmr-field.is-err select { border-color: var(--accent); background: oklch(0.95 0.05 30); }
.nmr-log { margin: 8px 0 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.nmr-log li { font-size: 13px; line-height: 1.5; padding: 8px 12px; border-left: 3px solid oklch(0.55 0.11 150); background: oklch(0.97 0.02 150); border-radius: 0 6px 6px 0; }
/* solved-peak line + its colour-coded fragment reveal side by side */
.nmr-log li.nmr-log-flex { display: flex; align-items: center; gap: 4px 14px; flex-wrap: wrap; }
.nmr-log-flex .nmr-log-text { flex: 1 1 250px; min-width: 0; }
.nmr-fragmol { flex: 0 0 auto; }
.nmr-fragmol svg { display: block; }
.nmr-log-title { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); margin: 14px 0 0; }
.nmr-log-legend { font-size: 11.5px; color: var(--muted); margin: 3px 0 0; }
.nmr-reveal { border: 1.5px solid var(--hairline); border-radius: 8px; padding: 14px; margin: 12px 0 4px; background: var(--paper); text-align: center; }
.nmr-struct { font-family: var(--font-mono); font-size: 17px; font-weight: 600; color: var(--ink); margin: 6px 0 2px; }
.nmr-struct-name { font-size: 13.5px; color: var(--ink-soft); margin: 0 0 4px; }
.nmr-arow { display: grid; gap: 10px; align-items: end; grid-template-columns: minmax(96px, 130px) 1fr; margin: 8px 0; }
.nmr-arow .nmr-row { margin: 0; }
.nmr-arow-tag { font-family: var(--font-mono); font-size: 12px; font-weight: 600; color: var(--ink); padding-bottom: 9px; }
.nmr-arow-tag .nmr-tick { color: oklch(0.45 0.11 150); }
@media (max-width: 560px) { .nmr-arow { grid-template-columns: 1fr; gap: 4px; } .nmr-arow-tag { padding-bottom: 0; } }

/* nmr chips — solved/wrong states (scoped so .nuc-opt[aria-pressed] can't
   out-specify them, per the redox gotcha) */
.nmr-wrap .rn-cap-btn.is-ok, .nin-wrap .rn-cap-btn.is-ok, .nsp-wrap .rn-cap-btn.is-ok, .nsh-wrap .rn-cap-btn.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.95 0.045 150); color: oklch(0.32 0.08 150); }
.nmr-wrap .rn-cap-btn.is-err, .nin-wrap .rn-cap-btn.is-err, .nsp-wrap .rn-cap-btn.is-err, .nsh-wrap .rn-cap-btn.is-err { border-color: var(--accent); background: oklch(0.95 0.05 30); color: var(--accent); }

/* Greek/maths symbols inside Instrument Serif display headings: the display
   face has no Greek glyphs, so a bare δ falls back with mismatched metrics
   and stray letter-spacing. Render the symbol in the sans face, slightly
   reduced, so it reads as deliberate notation. */
.rn-hsym { font-family: var(--font-sans); font-weight: 500; font-size: 0.78em; line-height: 1; }

/* peak chips carry a lowercase delta — never uppercase them */
.nmr-wrap .nmr-peakchip { text-transform: none; letter-spacing: 0.03em; font-size: 12px; }
/* isotope tokens in Instrument Serif headings: keep the heading's own serif
   face (its lining digits scale fine) — only raise and shrink the mass
   number. Never use Unicode ¹³ here (the serif lacks those glyphs and the
   fallback mixes fonts); never swap the token to the sans face (reads as a
   pasted-in foreign letter next to the serif). */
.rn-hiso { letter-spacing: 0; }
.rn-hiso sup { font-size: 0.55em; line-height: 0; position: relative; top: -0.48em; vertical-align: baseline; letter-spacing: 0; margin-right: 0.04em; }
/* isotope tokens inside mono/uppercase chrome (.rn-chem host): kill the
   letter-spacing that spreads the digits from the element symbol */
.rn-chem sup, .rn-chem sub { letter-spacing: 0; }

/* nmr — red/blue H convention (red = the H giving the signal, blue = the
   neighbour H doing the splitting; mirrors the Data Booklet's bold H) */
.nmr-hobs { color: oklch(0.52 0.165 30); font-weight: 600; }
.nmr-hnbr { color: oklch(0.44 0.10 250); font-weight: 600; }
/* displayed-formula blocks rendered by site.js molSvg() */
.nmr-mol { margin: 8px 0 4px; }
.nmr-mol svg { display: block; height: auto; margin-inline: auto; }
/* delta-window zoom control on the Read-a-spectrum stage */
.nmr-zoom { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 2px 0 8px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.04em; color: var(--muted); }
.nmr-zoom label { display: inline-flex; align-items: center; gap: 8px; }
.nmr-zoom input[type="range"] { width: min(240px, 50vw); accent-color: oklch(0.52 0.165 30); }
.nmr-zoomlab { color: var(--ink-soft); }

/* =========================================================================
   TRANSITION METALS (3.2.5) — W1 shape viewer [data-complex], W2 ligand-
   substitution explorer [data-ligand], W3 colour/ΔE explorer [data-colour],
   W6 substitution colour quiz [data-subquiz], W4 vanadium ladder
   [data-ox-state], W7 mark scheme (.mktm-wrap) and W5 redox titration
   (.rtitr-wrap, reusing the vt-* engine chrome). Buttons/chips/tiles all
   reuse the generic .rn-cap-* / .elim-opts / .mk-tile family.
   ========================================================================= */
/* mounts and sub-rows ship [hidden]; some (.elim-opts) have display rules
   that would defeat the attribute, so make [hidden] absolute in tm wraps */
.tmc-wrap [hidden], .tml-wrap [hidden], .tmk-wrap [hidden],
.tmq-wrap [hidden], .tmv-wrap [hidden] { display: none !important; }
.tm-stage { background: var(--paper); border: 1px solid var(--hairline); border-radius: 8px; padding: 10px 8px 6px; margin: 10px 0; }
.tm-stage svg { display: block; width: 100%; height: auto; max-width: 340px; margin-inline: auto; }
.tm-stage svg.tm-wide { max-width: 500px; }
.tm-swatch { display: inline-block; width: 20px; height: 14px; border-radius: 4px; border: 1px solid oklch(0.4 0.01 250 / 0.4); vertical-align: -2px; }
.rn-cap-chip .tm-swatch { margin-right: 7px; }
.tm-groups { display: grid; gap: 12px; margin: 0 0 10px; }
.rn-cap-chip.is-sel { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.tmk-modes .rn-cap-btn[aria-pressed="true"], .tmq-modes .rn-cap-btn[aria-pressed="true"] { border-color: var(--ink); color: var(--ink); background: oklch(0.95 0.01 250); }
/* W1 readout facts */
.tmc-read { display: flex; flex-wrap: wrap; gap: 6px 18px; font-size: 13.5px; margin: 8px 0 2px; }
.tmc-k { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); margin-right: 4px; }
/* W2 result panel */
.tml-result { border: 1px solid var(--hairline); border-radius: 8px; background: var(--paper); padding: 12px 14px; margin-top: 10px; font-size: 14px; }
.tml-result p { margin: 0 0 8px; }
.tml-result p:last-child { margin-bottom: 0; }
.tml-colline { font-weight: 600; }
.tml-arrow { margin: 0 6px; }
/* W6 quiz */
.tmq-q { font-size: 15px; font-weight: 600; margin: 4px 0 10px; }
.tmq-group { margin-bottom: 10px; }
.tml-eqinline { display: block; margin-top: 6px; font-size: 13.5px; }
/* W4 vanadium ladder */
.tmv-flex { display: grid; gap: 14px; align-items: center; }
@media (min-width: 640px) { .tmv-flex { grid-template-columns: 170px 1fr; } }
.tmv-stage svg { max-width: 120px; }
.tmv-state { font-size: 16px; font-weight: 600; margin: 0 0 6px; }
.tmv-chip { display: inline-block; font-family: var(--font-mono); font-size: 12px; font-weight: 700; padding: 3px 8px; border: 1.5px solid var(--ink-soft); border-radius: 6px; margin-right: 6px; }
.tmv-eq { margin: 8px 0; }
.tmv-note { font-size: 13px; color: var(--ink-soft); margin: 0; }
/* W3 colorimetry slider */
.tmk-slider { display: flex; gap: 10px; align-items: center; font: 500 11px/1.4 var(--font-mono); letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); max-width: 420px; margin: 4px auto 6px; }
.tmk-slider input[type="range"] { flex: 1; accent-color: oklch(0.52 0.165 30); }
.tmk-aval { font-size: 12px; color: var(--ink); }
/* W5 redox titration: gate the interactive chrome until site.js adds
   .vt-live (same no-JS pattern as the AS .vt-wrap) */
.rtitr-wrap:not(.vt-live) .rn-cap-controls,
.rtitr-wrap:not(.vt-live) .vt-read,
.rtitr-wrap:not(.vt-live) .rn-table-scroll,
.rtitr-wrap:not(.vt-live) .rtitr-modes { display: none; }
.rtitr-wrap .vt-svg { max-width: 390px; }

/* tm chips act as buttons, not drag handles — kill the inherited grab cursor */
.tmc-wrap .rn-cap-chip, .tml-wrap .rn-cap-chip, .tmk-wrap .rn-cap-chip,
.tmq-wrap .rn-cap-chip, .rtitr-wrap .rn-cap-chip { cursor: pointer; }

/* ── Reactions of Ions in Solution (3.2.6): aqq-/amp-/aqp-/mkai- widgets.
   All chrome reuses the generic .rn-cap-* / .tm-* / .mk-* families; the
   rules below are the only page-specific bits. */
.aqq-wrap [hidden], .amp-wrap [hidden], .aqp-wrap [hidden] { display: none !important; }
.aqq-wrap .rn-cap-chip, .amp-wrap .rn-cap-chip, .aqp-wrap .rn-cap-chip { cursor: pointer; }
.amp-stage svg { max-width: 460px; }
.amp-eq[hidden] { display: none; }

/* ── Organic Synthesis (3.3.14): F1 map + syn- pathway builder + mksy-.
   Widget chrome reuses the generic .rn-cap-* / .mk-* families; below is the
   page-specific layer only. */
/* F1 panels are tall node-and-arrow maps — lift the 340px figcell cap so the
   labels stay legible at full column width */
.syn-map .oc-figcell svg { max-height: 560px; }
/* each panel is the anchor for its own top-right zoom trigger */
.syn-map .oc-figcell { position: relative; }
/* F1 legend — arrow colour = reaction type (colours match the generator FAM map) */
.syn-legend { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 12.5px; color: var(--ink-soft); margin: 2px 0 10px; }
.syn-leg-item { white-space: nowrap; }
.syn-leg-dash { display: inline-block; width: 18px; height: 3px; border-radius: 2px; vertical-align: middle; margin-right: 6px; position: relative; top: -1px; }
/* syn- pathway builder (data-synthesis). Chrome reuses .rn-cap-*; below is the
   widget-specific layer. Chips act as buttons, not drag handles. */
.syn-wrap .rn-cap-chip { cursor: pointer; }
.syn-wrap [hidden] { display: none !important; }
.syn-wrap .rn-cap-chip[aria-pressed="true"] { border-color: var(--accent); background: oklch(0.96 0.03 30); color: var(--accent); }
.syn-banner { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 14px; margin: 12px 0 10px; padding: 10px 14px; border: 1px solid var(--hairline); border-radius: 8px; background: var(--paper); }
.syn-banner-goal { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.syn-banner-count { margin-left: auto; font-family: var(--font-mono); font-size: 12px; color: var(--ink-soft); white-space: nowrap; }
.syn-goal-f { font-weight: 600; }
.syn-goal-arrow { color: var(--muted); }
.syn-stage { display: grid; grid-template-columns: minmax(190px, 240px) 1fr; gap: 12px; margin: 12px 0; align-items: stretch; }
@media (max-width: 560px) { .syn-stage { grid-template-columns: 1fr; } }
.syn-mol { border: 1.5px solid var(--ink-soft); border-radius: 10px; background: var(--paper); padding: 14px 16px; text-align: center; }
.syn-mol-name { font-size: 14px; font-weight: 600; margin: 0 0 2px; }
.syn-mol-f { font-size: 24px; font-weight: 600; margin: 6px 0; overflow-wrap: anywhere; }
.syn-mol-meta { font-size: 12px; color: var(--muted); margin: 0; }
.syn-mol.is-new { animation: syn-pop 0.45s ease; }
@keyframes syn-pop { 0% { transform: scale(0.96); border-color: oklch(0.55 0.11 150); } 60% { transform: scale(1.015); } 100% { transform: scale(1); } }
.syn-mol.is-shake { animation: syn-shake 0.4s ease; }
@keyframes syn-shake { 0%, 100% { transform: translateX(0); } 20%, 60% { transform: translateX(-5px); } 40%, 80% { transform: translateX(5px); } }
@media (prefers-reduced-motion: reduce) { .syn-mol.is-new, .syn-mol.is-shake { animation: none; } }
.syn-feed { border: 1px solid var(--hairline); border-radius: 10px; background: var(--paper); padding: 12px 14px; font-size: 13.5px; line-height: 1.5; color: var(--ink-soft); display: flex; align-items: center; min-height: 76px; }
.syn-feed.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.97 0.025 150); color: oklch(0.30 0.07 150); }
.syn-feed.is-nr { border-color: var(--accent); background: oklch(0.97 0.025 30); color: oklch(0.36 0.11 30); }
.syn-feed.is-off { border-color: oklch(0.62 0.09 70); background: oklch(0.975 0.02 80); color: oklch(0.36 0.06 70); }
.syn-pal { display: grid; grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); gap: 8px; margin: 10px 0 2px; }
.syn-rg { font-family: var(--font-sans); text-align: left; padding: 8px 11px; border-radius: 8px; border: 1.5px solid var(--hairline); background: var(--paper); color: var(--ink); cursor: pointer; line-height: 1.35; }
.syn-rg:hover { border-color: var(--ink-soft); }
.syn-rg:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.syn-rg:disabled { opacity: 0.55; cursor: default; }
.syn-rg-l { display: block; font-size: 13px; font-weight: 600; }
.syn-rg-c { display: block; font-size: 11px; color: var(--muted); margin-top: 1px; }
.syn-plus1 { display: inline-block; font-family: var(--font-mono); font-size: 10px; font-weight: 700; padding: 2px 7px; border-radius: 999px; color: var(--accent); background: oklch(0.95 0.05 30); border: 1px solid var(--accent); vertical-align: 1px; }
.syn-log-h { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); margin: 16px 0 6px; }
.syn-log { list-style: none; margin: 0; padding: 0; font-size: 14px; }
.syn-log li { padding: 7px 2px; border-bottom: 1px dashed var(--hairline); overflow-wrap: anywhere; }
.syn-log-r { font-family: var(--font-mono); font-size: 12px; color: var(--ink-soft); }
.syn-log-m { color: var(--muted); }
.syn-done { border: 1.5px solid oklch(0.55 0.11 150); border-radius: 10px; background: oklch(0.97 0.025 150); padding: 14px 16px; margin-top: 14px; font-size: 14px; }
.syn-done-h { font-weight: 700; color: oklch(0.30 0.07 150); margin: 0 0 6px; }
.syn-done ul { margin: 6px 0 0; padding-left: 20px; }
.syn-done li { margin: 3px 0; font-size: 13px; }
.syn-picker { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 4px; }
/* review round: chip-tray reagent system builder */
.syn-tray-h { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); margin: 12px 0 6px; }
.syn-tray { margin-bottom: 4px; }
.syn-tray .rn-cap-chip { font-weight: 500; font-size: 12.5px; min-height: 34px; padding: 6px 11px; }
.syn-sel { font-size: 13px; color: var(--ink-soft); margin: 8px 0 0; min-height: 1.4em; }
.syn-react { border-color: var(--accent); color: var(--accent); }
.syn-react:hover { background: oklch(0.96 0.03 30); color: var(--accent); }

/* ── 3.1.11 Electrode potentials & cells — W1/W2/W3 widget furniture ──────
   (mark-scheme W4 reuses the shared .mk-pool/.mk-tile classes) */
.epc-intro { font-size: 14px; margin: 0 0 10px; }
.epc-svg { display: block; width: 100%; max-width: 560px; margin: 6px auto 2px; }
.epc-read { display: grid; gap: 7px; margin-top: 12px; }
.epc-read p { margin: 0; font-size: 14px; }
.epc-read .epc-eq { font-family: var(--font-mono); font-size: 13.5px; }
.epc-dim { color: var(--muted); font-size: 12px; }
.epc-note { font-size: 13px; color: var(--ink-soft); font-style: italic; margin: 10px 0 0; min-height: 1.4em; }
.epc-verdict { display: inline-block; font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase; font-weight: 600; padding: 3px 10px; border-radius: 999px; margin-right: 8px; }
.epc-verdict.is-yes { color: oklch(0.32 0.08 150); background: oklch(0.95 0.045 150); border: 1px solid oklch(0.55 0.11 150); }
.epc-verdict.is-no { color: var(--accent); background: oklch(0.95 0.05 30); border: 1px solid var(--accent); }
.epc-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
@media (max-width: 640px) { .epc-cols { grid-template-columns: 1fr; } }
.epc-series { margin: 10px 0 14px; border: 1px solid var(--hairline); border-radius: 6px; overflow: hidden; }
.epc-series-row { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 7px 12px; font-family: var(--font-mono); font-size: 12.5px; border-top: 1px solid var(--hairline); background: var(--paper); }
.epc-series-row:first-child { border-top: 0; }
.epc-series-row > span:last-child { white-space: nowrap; font-weight: 600; }

/* ── Hydrogen fuel-cell animation (.hf-*) — hoisted from GCSE C5 Part 3 so the
   A-level electrode-potentials page can share it (same ghe- hoist pattern).
   JS in site.js, gated on #hfSvg; [data-alevel] on the svg switches the caption
   terminology to negative/positive electrode. ─────────────────────────────── */
.hf-wrap { max-width: 460px; margin: 22px auto 26px; padding: 20px 16px 14px; background: var(--paper-2); border: 1px solid var(--hairline); border-radius: 4px; text-align: center; }
.hf-wrap svg.hf-stage { display: block; width: 100%; max-width: 330px; margin: 0 auto; overflow: visible; }
.hf-caption { font-size: 15px; color: var(--ink-soft); margin: 2px auto 14px; font-style: italic; line-height: 1.5; min-height: 4.6em; max-width: 600px; }
.hf-modes { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin: 16px auto 2px; }
.hf-mode { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.05em; text-transform: uppercase; font-weight: 500; padding: 9px 18px; border-radius: 999px; border: 1.5px solid var(--hairline); cursor: pointer; background: var(--paper); color: var(--ink-soft); transition: background .15s, border-color .15s, color .15s; }
.hf-mode:hover { border-color: var(--ink-soft); }
.hf-mode.is-active { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.hf-legend { display: flex; flex-wrap: wrap; justify-content: center; gap: 7px 16px; margin: 14px auto 0; max-width: 560px; font-size: 12px; color: var(--ink-soft); line-height: 1.4; }
.hf-leg { display: inline-flex; align-items: center; gap: 6px; }

/* =========================================================================
   SHARED CALCULATOR-WIDGET CHROME — blurb / input row / mode chips / working
   output. Introduced for acids & bases (3.1.12) as .ab-*; generalised to the
   neutral .rn-calc-* names when thermodynamics (3.1.8) and rate equations
   (3.1.9) needed the same chrome. Both name sets are the same rules — use
   .rn-calc-* on any NEW widget; .ab-* is retained for acids & bases.
   Wider chrome (buttons, wrap, messages, plots) reuses .rn-cap-* / .me-in / .mk-*.
   ========================================================================= */
.ab-blurb, .rn-calc-blurb { font-size: 13px; color: var(--muted); margin: 8px 0 4px; }
.ab-inrow, .rn-calc-inrow { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; margin: 8px 0 2px; }
.ab-inlab, .rn-calc-inlab { display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-mono); font-size: 11px; color: var(--ink-soft); }
.ab-in, .rn-calc-in { width: 110px; }
.ab-chips, .rn-calc-chips { display: inline-flex; gap: 8px; flex-wrap: wrap; }
.ab-chip[aria-pressed="true"], .rn-calc-chip[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); background: oklch(0.96 0.03 30); }
.ab-out, .rn-calc-out { margin-top: 12px; border-left: 3px solid var(--hairline); padding: 2px 0 2px 14px; }
.ab-out[hidden], .rn-calc-out[hidden] { display: none; }
.ab-wline, .rn-calc-wline { margin: 4px 0; font-family: var(--font-mono); font-size: 12.5px; line-height: 1.6; color: var(--ink-soft); }
.ab-wline strong, .rn-calc-wline strong { color: var(--ink); font-size: 14px; }
.ab-wnote, .rn-calc-note { margin: 7px 0 0; font-size: 12px; color: var(--muted); }
.ab-err, .rn-calc-err { margin: 6px 0 0; font-size: 12.5px; color: oklch(0.5 0.12 25); }
.ab-picklab { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }
.abt-stage { margin: 12px 0 4px; }
.abt-stage svg { display: block; width: 100%; max-width: 560px; height: auto; margin-inline: auto; }
.abt-ind[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); background: oklch(0.96 0.03 30); }

/* =========================================================================
   THERMODYNAMICS (3.1.8) + RATE EQUATIONS (3.1.9) widget layout.
   Chrome (wrap, buttons, chips, inputs, working lines, plots, mark-scheme
   tiles) all comes from .rn-cap-* / .rn-calc-* / .mk-* / .me-in above — the
   rules below are only the per-widget LAYOUT those shared pieces sit in.
   ========================================================================= */

/* shared: any widget that renders an inline SVG stage */
.bh-stage, .cd-ion, .en-ladder, .gib-stage, .hl-stage, .og-stage, .ar-stage { margin: 14px 0 4px; }
.cd-ion svg, .en-ladder svg, .gib-stage svg, .hl-stage svg, .og-stage svg, .ar-stage svg { display: block; width: 100%; max-width: 520px; height: auto; margin-inline: auto; }

/* W1 Born–Haber cycle builder — one grid row per cycle step */
.bh-target { font-size: 15px; margin: 10px 0 4px; }
.bh-rows { display: grid; gap: 8px; margin: 12px 0 2px; }
.bh-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 14px; align-items: center; padding: 10px 12px; border: 1.5px solid var(--hairline); border-radius: 8px; background: var(--paper); }
.bh-row.is-ok { border-color: oklch(0.55 0.11 150); background: oklch(0.97 0.03 150); }
.bh-row.is-err { border-color: var(--accent); background: oklch(0.97 0.03 30); }
.bh-desc { display: flex; flex-wrap: wrap; align-items: baseline; gap: 3px 10px; min-width: 0; }
.bh-name { font-size: 13.5px; color: var(--ink); }
.bh-eq { font-family: var(--font-mono); font-size: 12px; color: var(--muted); }
.bh-val { font-family: var(--font-mono); font-size: 13px; font-weight: 600; color: var(--ink); white-space: nowrap; }
.bh-pick { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.bh-mark { font-family: var(--font-mono); font-size: 11.5px; }
.bh-row.is-ok .bh-mark { color: oklch(0.42 0.09 150); }
.bh-row.is-err .bh-mark { color: var(--accent); }
@media (min-width: 620px) {
  .bh-row { grid-template-columns: minmax(0, 1fr) auto auto auto; }
  .bh-pick { grid-column: auto; }
}

/* W2 solution / hydration cycle solver */
.hy-egs { margin-top: 10px; }
.rn-calc-eglab { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }

/* W3 entropy calculator + disorder ladder */
.en-eq { margin: 10px 0 6px; }
.en-tablewrap { margin: 4px 0 2px; }
.en-tbl td { vertical-align: middle; }
.en-tbl .en-in { width: 78px; }
.en-grp td { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); background: var(--paper-2); }
.en-ladcap { text-align: center; }

/* W5 charge-density comparator */
.cd-presets-lab { margin: 12px 0 4px; }
.cd-read { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 10px 0 4px; }
.cd-val { font-family: var(--font-mono); font-size: 12px; color: var(--ink-soft); }
.cd-val b { color: var(--ink); }
.cd-bars { display: grid; gap: 14px; margin: 14px 0 4px; }
.cd-bar-lab { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-soft); margin: 0 0 5px; }
.cd-bar-track { height: 12px; border-radius: 999px; background: var(--paper-3); overflow: hidden; }
.cd-bar-fill { display: block; height: 100%; border-radius: 999px; background: var(--accent); transition: width 0.18s ease; }
.cd-bar-why { font-size: 12px; color: var(--muted); margin: 5px 0 0; }
.cd-scalenote, .cd-defn { margin-top: 6px; }

/* W1 rate-equation & units-of-k builder */
.rq-row { display: flex; flex-wrap: wrap; gap: 14px 26px; margin: 10px 0 2px; }
.rq-field p { margin: 0 0 6px; }

/* W2 initial-rates order finder */
.ir-table { margin: 8px 0 4px; }
.ir-pick { display: grid; gap: 6px; margin: 12px 0 2px; }
.ir-picklab { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); margin: 6px 0 0; }
.ir-orders { font-family: var(--font-mono); font-size: 12.5px; color: var(--ink); margin: 10px 0 0; }

/* W3 order-graph explorer */
.og-picks { margin-top: 4px; }
.og-opts { margin-top: 4px; }
.og-nextwrap[hidden] { display: none; }

/* W4 half-life reader */
.hl-slide { margin-top: 6px; }
.hl-range { width: 190px; }
.hl-read { margin: 8px 0 2px; }
.hl-guess[hidden] { display: none; }
.hl-table { margin: 8px 0 2px; }
.hl-table table { width: 100%; border-collapse: collapse; font-family: var(--font-mono); font-size: 12px; }
.hl-table th, .hl-table td { text-align: left; padding: 5px 9px; border-bottom: 1px solid var(--hairline); color: var(--ink-soft); }
.hl-table th { font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }

/* W5 Arrhenius tool */
.ar-const { text-align: center; }

/* ── Optical isomerism (3.3.7) W1: spot-the-chiral-centre ([data-chiral]) ──
   The molecule is a displayed formula (SVG) whose carbons are clickable;
   everything else reuses the generic .rn-cap-* / .oc-stage chrome. */
.chc-mol { margin: 12px 0 2px; }
.chc-hit { cursor: pointer; outline: none; }
.chc-hit circle { fill: transparent; }
.chc-hit:hover circle { stroke: var(--ink-soft); stroke-width: 1.5; stroke-dasharray: 4 4; }
.chc-hit:focus-visible circle { stroke: var(--ink); stroke-width: 2; stroke-dasharray: 4 4; }
.chc-hit.is-err circle { stroke: var(--accent); stroke-width: 2; }

/* ── Optical isomerism (3.3.7) W2: non-superimposable demo ([data-super]) ──
   A fixed enantiomer beside its rotatable mirror image; chrome reuses the
   generic .rn-cap-* family. */
.chs-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 18px; align-items: start; margin-top: 10px; }
.chs-cap { font: 600 11px/1.4 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); margin: 0 0 2px; text-align: center; }
.chs-cell svg { width: 100%; max-width: 230px; display: block; margin-inline: auto; }
.chs-slots { font-size: 14.5px; margin: 10px 0 0; }
.chs-ok { color: oklch(0.42 0.10 155); font-weight: 600; }
.chs-no { color: var(--accent); font-weight: 600; }
.chs-anim-x { animation: chs-spin-x .4s ease; }
.chs-anim-y { animation: chs-spin-y .4s ease; }
@keyframes chs-spin-x { 0% { transform: scaleX(1); } 50% { transform: scaleX(0.12); } 100% { transform: scaleX(1); } }
@keyframes chs-spin-y { 0% { transform: scaleY(1); } 50% { transform: scaleY(0.12); } 100% { transform: scaleY(1); } }
@media (prefers-reduced-motion: reduce) {
  .chs-anim-x, .chs-anim-y { animation: none; }
}

/* ============================================================
   EXAM QUESTION PRACTICE — /revision/aqa-a-level-chemistry/exam-questions
   Builder chips, player chrome, self-marking, summary bars and the
   printable worksheet. Question internals reuse the .rn-exam-* styles
   above; the wcqg-* content classes (parts, mark chips, mark-scheme
   notes) are emitted by _scripts/build-exam-question-data.mjs.
============================================================ */
.wcqg-layout { display: block; }
.wcqg-main { max-width: none; margin-inline: auto; }

/* ── Builder: the desk ──────────────────────────────────────────────────────
   Two things on the desk: the syllabus you tick, and the front cover of the
   paper it makes, filling in as you go. The cover is sticky on a wide screen
   and follows the choices on a phone; the print stylesheet prints the same
   cover, so screen and paper match.

   One selected colour on this page, ink, with the red pen tick on a topic.
   The teal is the marking colour and stays inside the mark scheme.

   --wcqg-teal     the mark scheme's rule, its label and its ticks
   --wcqg-overlap  how far the paper reaches up into the masthead          */
.wcqg-console {
  --wcqg-teal: oklch(0.40 0.12 200);
  --wcqg-teal-line: oklch(0.40 0.12 200 / 0.34);
  --wcqg-teal-wash: oklch(0.40 0.12 200 / 0.13);
  --wcqg-overlap: 200px;
  display: grid; grid-template-columns: minmax(0, 1fr) 400px; gap: 56px; align-items: start;
}
.wcqg-choices { min-width: 0; padding-top: 24px; }

/* the masthead the paper overlaps: eyebrow, title, standfirst, byline. The
   text keeps to the left so the paper has the right-hand side to itself. */
.wcqg-masthead { background: var(--paper-2); border-bottom: 1px solid var(--hairline); padding: 36px 0 64px; }
.wcqg-masthead .breadcrumb { margin-bottom: 30px; }
.wcqg-masthead-main { max-width: 720px; }
.wcqg-eyebrow { margin: 0 0 16px; font-family: var(--font-mono); font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent); }
.wcqg-title { margin: 0 0 18px; font-family: var(--font-display); font-weight: 400; font-size: clamp(42px, 5.4vw, 70px); line-height: 1.0; letter-spacing: -0.022em; color: var(--ink); max-width: 22ch; }
.wcqg-standfirst { margin: 0 0 24px; font-family: var(--font-display); font-style: italic; font-size: clamp(18px, 1.7vw, 24px); line-height: 1.45; color: var(--ink-soft); max-width: 42ch; }
.wcqg-byline { margin: 0; font-family: var(--font-mono); font-size: 11.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }
.wcqg-byline b { color: var(--ink); font-weight: 500; }

/* sections: a mono label with an ink rule, then its controls */
.wcqg-section { padding: 0 0 34px; }
.wcqg-section-label { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; margin: 0 0 16px; padding-bottom: 10px; border-bottom: 1.5px solid var(--ink); font-family: var(--font-mono); font-size: 11.5px; font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink); }
.wcqg-stepnote { font-family: var(--font-mono); font-size: 10.5px; font-weight: 400; letter-spacing: 0.04em; text-transform: none; color: var(--accent); }
.wcqg-steplinks { margin-left: auto; display: flex; gap: 14px; }
.wcqg-grouptally { font-family: var(--font-mono); font-size: 10px; font-weight: 400; letter-spacing: 0.03em; color: var(--accent); text-transform: none; }
.wcqg-minilink { background: none; border: none; padding: 0; font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.03em; color: var(--accent); text-decoration: underline; cursor: pointer; text-transform: none; }
.wcqg-minilink:hover { color: var(--ink); }

/* ── The syllabus: a tick box per topic ─────────────────────────────────────
   Three groups, each a grid of rows that fills the column, with All / Clear
   beside the group's name. A topic you have started keeps a thin progress
   rule under its name — ::before the track, ::after the fill, --wcqg-p
   (written by site.js) how far along you are; the figure itself is in the
   row's aria-label and title for anyone who wants it. */
.wcqg-group { display: block; margin: 0 0 22px; }
.wcqg-group:last-child { margin-bottom: 0; }
.wcqg-group-label { display: flex; align-items: center; gap: 12px; margin: 0 0 6px; padding: 0 0 7px; border-bottom: 1px solid var(--hairline); font-family: var(--font-mono); font-size: 10.5px; font-weight: 500; letter-spacing: 0.09em; text-transform: uppercase; color: var(--ink); }
.wcqg-groupall { margin-left: auto; }
.wcqg-chips { display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); gap: 0 22px; }
.wcqg-chip { position: relative; display: flex; align-items: center; min-height: 40px; padding: 6px 6px 6px 2px; border: 0; border-radius: 4px; background: none; font-family: inherit; font-size: 14.5px; line-height: 1.3; color: var(--ink-soft); text-align: left; cursor: pointer; transition: background .12s; }
.wcqg-chip:hover { background: var(--paper-2); }
.wcqg-chip:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.wcqg-chip-name { display: flex; align-items: center; gap: 11px; }
.wcqg-chip-name::before { content: ""; flex: none; width: 15px; height: 15px; border: 1.5px solid var(--ink-soft); border-radius: 3px; background: #fff; }
.wcqg-chip.is-on { color: var(--ink); font-weight: 600; }
.wcqg-chip.is-on .wcqg-chip-name::before { border-color: var(--ink); background: #fff url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M3 8.6 6.6 12.2 13.2 4' fill='none' stroke='%23b54a2a' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'/></svg>") center/14px no-repeat; }
.wcqg-chip.is-tried::before,
.wcqg-chip.is-tried::after { content: ""; position: absolute; left: 30px; bottom: 3px; height: 2px; border-radius: 999px; pointer-events: none; }
.wcqg-chip.is-tried::before { right: 8px; background: var(--hairline); }
.wcqg-chip.is-tried::after { width: calc((100% - 38px) * var(--wcqg-p, 0) / 100); background: var(--accent-soft); transition: width .3s ease; }
.wcqg-chip.is-on.is-tried::after { background: var(--accent); }
@media (prefers-reduced-motion: reduce) { .wcqg-chip.is-tried::after { transition: none; } }

/* filters: a mono label in a fixed gutter and its controls to the right */
.wcqg-filters { display: grid; gap: 12px; }
.wcqg-filter { display: grid; grid-template-columns: 108px minmax(0, 1fr); gap: 6px 18px; align-items: start; }
.wcqg-filterlabel { margin: 0; padding-top: 7px; font-family: var(--font-mono); font-size: 10.5px; font-weight: 500; letter-spacing: 0.09em; text-transform: uppercase; color: var(--muted); }
.wcqg-filter-opts { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; }
.wcqg-check { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--ink-soft); cursor: pointer; }
.wcqg-check input { accent-color: var(--ink); width: 16px; height: 16px; }
.wcqg-filter--checks .wcqg-filter-opts { gap: 8px 20px; padding-top: 2px; }
.wcqg-build .rn-cap-btn.is-on,
.wcqg-build .rn-cap-btn[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }

/* ── The paper ─────────────────────────────────────────────────────────────
   A white sheet with the dark band the site uses for its wordmark, reaching
   up into the masthead. It reads the same three numbers as the printed
   cover, lists the questions the draw holds, and carries Start and Print. */
.wcqg-paper-col { position: sticky; top: 96px; margin-top: calc(-1 * var(--wcqg-overlap)); }
.wcqg-paper { background: #fff; border: 1px solid var(--ink); border-radius: 3px; box-shadow: 0 30px 60px -36px oklch(0.2 0.02 250 / 0.55), 0 1px 0 oklch(0.2 0.02 250 / 0.08); }
.wcqg-paper-band { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 20px; background: var(--dark); color: var(--paper); }
.wcqg-paper-brand { display: inline-flex; align-items: center; gap: 9px; font-family: var(--font-display); font-size: 17px; }
.wcqg-paper-kind { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: oklch(0.78 0.015 250); }
.wcqg-paper-body { padding: 22px 22px 20px; }
.wcqg-paper-course { margin: 0 0 4px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.wcqg-paper .wcqg-paper-title { margin: 0 0 6px; padding: 0; border: 0; font-family: var(--font-display); font-weight: 400; font-size: 34px; line-height: 1.05; letter-spacing: -0.012em; text-transform: none; color: var(--ink); }
.wcqg-paper-desc { margin: 0; min-height: 21px; font-size: 14px; line-height: 1.5; color: var(--ink-soft); }
.wcqg-paper-desc:empty::before { content: "Tick topics and the paper fills itself in."; font-style: italic; color: var(--muted); }
.wcqg-cover { display: flex; margin: 16px 0 18px; padding: 14px 0; border-top: 1.5px solid var(--ink); border-bottom: 1px solid var(--hairline); }
.wcqg-cover-cell { flex: 1; padding: 0 14px; border-left: 1px solid var(--hairline); }
.wcqg-cover-cell:first-child { padding-left: 0; border-left: 0; }
.wcqg-cover dt { margin: 0 0 5px; font-family: var(--font-mono); font-size: 9.5px; font-weight: 400; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
.wcqg-cover dd { margin: 0; font-family: var(--font-display); font-weight: 400; font-size: 34px; line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.wcqg-cover-unit { font-size: 15px; color: var(--muted); }
.wcqg-cover-none { color: oklch(0.78 0.01 250); }
.wcqg-contents-head, .wcqg-contents li { display: grid; grid-template-columns: 24px minmax(0, 1fr) auto; gap: 10px; align-items: baseline; }
.wcqg-contents-head { padding: 0 0 5px; border-bottom: 1px solid var(--ink); font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.wcqg-contents { list-style: none; margin: 0 0 18px; padding: 0; }
.wcqg-contents li { padding: 6px 0; border-bottom: 1px solid var(--hairline); font-size: 13.5px; line-height: 1.35; color: var(--ink-soft); }
.wcqg-contents li.is-blank { height: 29px; }
.wcqg-contents li.is-more { color: var(--muted); font-style: italic; border-bottom: 0; }
.wcqg-contents-q { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
.wcqg-contents-m { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink); font-variant-numeric: tabular-nums; }
/* the actions: Start, Print, and the line that says what matched. The class
   is also what the observer in site.js watches, to know when the real Start
   is on screen and the phone's strip can stand down. */
.wcqg-bar { display: grid; gap: 8px; }
.wcqg-bar .btn { width: 100%; --btn-h: 48px; font-size: 14.5px; }
.wcqg-bar .btn:disabled { opacity: 0.38; pointer-events: none; }
.wcqg-bar .wcqg-count { margin: 4px 0 0; font-size: 13px; line-height: 1.45; color: var(--muted); }
.wcqg-paper-foot { margin: 16px 0 0; padding-top: 12px; border-top: 1px solid var(--hairline); font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }

/* ── The phone's start strip ───────────────────────────────────────────────
   Created by site.js inside .wcqg-build, so it vanishes with the builder.
   Shown only on a phone, only once there is a paper to start (body carries
   wcqg-canstart), and only while the paper's own Start is off screen
   (wcqg-barview is the observer's word that it is on screen) — so Start is
   never on screen twice. It takes the sticky enquiry bar's place while it
   shows; the two would otherwise stack. */
.wcqg-stickystart { display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 901; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px)); background: var(--dark); color: var(--paper); border-top: 1px solid color-mix(in srgb, var(--paper) 10%, transparent); box-shadow: 0 -6px 18px oklch(0.2 0.02 250 / 0.18); }
.wcqg-stickystart-text { margin: 0; min-width: 0; font-family: var(--font-mono); font-size: 12px; line-height: 1.35; letter-spacing: 0.02em; color: oklch(0.80 0.015 250); }
.wcqg-stickystart .btn { --btn-h: 42px; flex: none; font-size: 14px; }
@media (max-width: 1000px) {
  body.wcqg-canstart:not(.wcqg-barview) .wcqg-stickystart { display: flex; }
  body.wcqg-canstart:not(.wcqg-barview) .sticky-cta { display: none; }
  /* the analytics-consent banner owns the foot of the screen until it is
     answered, as it does for the enquiry bar */
  body:has(#wbc-cookie-banner) .wcqg-stickystart { display: none; }
}
@media (prefers-reduced-motion: no-preference) {
  .wcqg-stickystart { animation: wcqg-rise .22s ease-out; }
}
@keyframes wcqg-rise { from { transform: translateY(100%); } to { transform: none; } }

/* ── Narrower screens ──────────────────────────────────────────────────────
   Under 1000px the paper follows the choices instead of sitting beside them
   (the start strip carries Start meanwhile); under 760px the syllabus runs
   in two columns and everything tappable gets 44px. */
@media (max-width: 1000px) {
  .wcqg-masthead { padding-bottom: 32px; }
  .wcqg-console { grid-template-columns: 1fr; gap: 12px; }
  .wcqg-paper-col { position: static; margin-top: 0; max-width: 560px; }
}
@media (max-width: 760px) {
  .wcqg-masthead { padding: 24px 0 26px; }
  .wcqg-masthead .breadcrumb { margin-bottom: 18px; }
  .wcqg-section { padding-bottom: 26px; }
  .wcqg-chips { grid-template-columns: 1fr 1fr; gap: 0 14px; }
  .wcqg-chip { font-size: 13px; min-height: 44px; padding-right: 2px; }
  .wcqg-chip-name { gap: 9px; }
  .wcqg-filter { grid-template-columns: minmax(0, 1fr); gap: 7px; }
  .wcqg-filterlabel { padding-top: 0; }
  .wcqg-build .rn-cap-btn, .wcqg-selfmark .rn-cap-btn { min-height: 44px; }
  /* scoped to the builder: applying it to the play head's "End session" pushed
     that row onto a second line, making the sticky head 100px tall — a seventh
     of a phone screen, on every question. It keeps a 44px target via padding. */
  .wcqg-build .wcqg-minilink, .wcqg-reset { display: inline-flex; align-items: center; min-height: 44px; }
  .wcqg-playmeta .wcqg-minilink { padding: 10px 0; }
  .wcqg-build .wcqg-check input { width: 20px; height: 20px; }
  .wcqg-paper-body { padding: 18px 18px 16px; }
  .wcqg-cover dd { font-size: 29px; }
}

/* Unfinished session, offered back for seven days. Prominent enough to be
   seen above the desk, quiet enough not to shout at a first-time visitor
   (who never sees it at all). */
.wcqg-resume { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 18px; margin: 0 0 22px; padding: 14px 18px; border: 1px solid var(--hairline); border-left: 4px solid var(--ink); border-radius: 6px; background: var(--paper-2); }
.wcqg-resume[hidden] { display: none; }
.wcqg-resume-text { margin: 0; font-size: 15px; color: var(--ink-soft); }
.wcqg-resume-text strong { color: var(--ink); }
.wcqg-resume-actions { display: flex; flex-wrap: wrap; gap: 10px; }
/* saved-progress line, above the syllabus */
.wcqg-progressline { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 16px; margin: 0 0 20px; padding: 10px 14px; border: 1px solid var(--hairline); border-radius: 6px; background: var(--paper-2); font-size: 13px; color: var(--muted); }
.wcqg-progressline[hidden] { display: none; }
.wcqg-reset { background: none; border: none; padding: 0; font-family: inherit; font-size: 12px; color: var(--muted); text-decoration: underline; cursor: pointer; }
.wcqg-reset:hover { color: oklch(0.45 0.15 25); }
/* A finger is the same size on a tablet as on a phone, so the small text
   controls — End session, Select all, Clear, Reset saved progress — are sized
   by POINTER, not by viewport width. The 760px block above covers phones; this
   catches every other touch screen, where they were ~15px tall. */
@media (pointer: coarse) {
  .wcqg-build .wcqg-minilink, .wcqg-reset { display: inline-flex; align-items: center; min-height: 44px; }
  .wcqg-playmeta .wcqg-minilink { padding: 10px 0; }
}

/* ---- player ---- */
/* ── Player: a focus surface ────────────────────────────────────────────────
   While a session runs, everything on the page that explains or advertises the
   tool is hidden (it carries data-wcqg-dim in the markup) and the main column
   takes the full width, so the question is the only thing to look at. */
body.wcqg-focus [data-wcqg-dim] { display: none; }
body.wcqg-focus .wcqg-layout { grid-template-columns: minmax(0, 1fr); }
/* with the aside gone, hold the player to a reading width and centre it, so
   the space reads as deliberate rather than as a missing column */
body.wcqg-focus .wcqg-main { max-width: 920px; margin-inline: auto; }
/* The site's sticky "Enquire now" bar is fixed to the bottom of the viewport
   from 400px of scroll, which during a session is directly on top of Back,
   Skip and Next. Mid-question is the one moment on this site not to be selling
   anything, so it stands down until the session ends. */
body.wcqg-focus .sticky-cta { display: none; }
/* and it yields to the console's own action bar, which it would otherwise
   cover — see the IntersectionObserver in site.js */
body.wcqg-barview .sticky-cta { display: none; }

/* The head stays put under the site header: where you are, how you are doing,
   how long you have been going. */
.wcqg-playhead { position: sticky; top: 79px; z-index: 3; padding: 10px 0 9px; margin-bottom: 2px; background: var(--paper); border-bottom: 1px solid var(--hairline); }
.wcqg-playtrack { height: 4px; border-radius: 999px; background: var(--hairline); overflow: hidden; margin-bottom: 9px; }
.wcqg-playfill { display: block; height: 100%; border-radius: 999px; background: var(--ink); transition: width .25s ease; }
.wcqg-playmeta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 16px; font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-soft); }
.wcqg-playscore { color: var(--muted); }
.wcqg-playtime { margin-left: auto; color: var(--ink-soft); font-size: 11.5px; font-variant-numeric: tabular-nums; }
/* the time allowed sits beside the clock where the row has room; once the
   clock passes it, the clock takes the accent */
.wcqg-time-of { color: var(--muted); }
.wcqg-playtime.is-over { color: var(--accent); }
/* the sticky head says the same thing two ways; the phone gets the short one,
   and the sentence stays in the DOM for a screen reader either way */
.wcqg-pos-terse { display: none; }
@media (max-width: 560px) {
  .wcqg-pos-full { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .wcqg-pos-terse { display: inline; }
}
@media (prefers-reduced-motion: reduce) { .wcqg-playfill { transition: none; } }
/* on a phone the four items do not fit on one line: let them wrap in reading
   order instead of pinning the clock to a right edge it then sits against */
@media (max-width: 560px) {
  .wcqg-playmeta { gap: 4px 12px; font-size: 12px; }
  .wcqg-playtime { margin-left: 0; }
  .wcqg-time-of { display: none; }
}
/* ── The data booklet ───────────────────────────────────────────────────────
   What AQA hands out with the paper, open beside the question rather than a
   page away. Tabbed rather than scrolled, because a student reaching for the
   NMR table mid-question should not have to scroll a periodic table first. */
.wcqg-book { margin: 10px 0 0; border: 1px solid var(--hairline); border-radius: 10px; background: var(--paper); overflow: hidden; }
.wcqg-book[hidden] { display: none; }
.wcqg-book-inner { padding: 0; }
.wcqg-book-tabs { display: flex; flex-wrap: wrap; gap: 6px; padding: 12px 14px; border-bottom: 1px solid var(--hairline); background: var(--paper-2); }
.wcqg-book-tabs .rn-cap-btn[aria-selected="true"] { background: oklch(0.40 0.12 200); border-color: oklch(0.40 0.12 200); color: var(--paper); }
.wcqg-book-pane { padding: 14px; max-height: 62vh; overflow: auto; }
.wcqg-book-pane[hidden] { display: none; }
.wcqg-book-loading { margin: 0; padding: 16px; font-size: 14px; color: var(--muted); }
.wcqg-book-fig { margin: 0 auto; }
/* the Structures pane stacks three figures, which would otherwise touch */
.wcqg-book-fig + .wcqg-book-fig { margin-top: 22px; }
/* Drawn at their own scale, not stretched to the pane: every one of these is
   lettered at the same size, so blowing each up to the full pane width made
   the smaller drawings the biggest type on the page and pushed haem B off the
   bottom. Capped at natural size they all letter alike and shrink together on
   a phone. */
.wcqg-book-fig img, .wcqg-book-fig svg { display: block; width: 100%; height: auto; margin-inline: auto; }
.wcqg-book-note { margin: 10px 2px 0; font-size: 12.5px; line-height: 1.55; color: var(--muted); }
.wcqg-book-fig--aa { max-width: 480px; }
.wcqg-book-fig--sugars { max-width: 333px; }
.wcqg-book-fig--bases { max-width: 338px; }
.wcqg-book-fig--haem { max-width: 374px; }
.wcqg-book-zoom { display: block; margin: 10px auto 0; padding: 6px 13px; border: 1px solid var(--hairline); border-radius: 999px; background: var(--paper); font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); cursor: pointer; }
.wcqg-book-zoom:hover { border-color: var(--ink-soft); color: var(--ink); }
.wcqg-book-cap { margin: 10px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.wcqg-book-table { width: 100%; border-collapse: collapse; }
/* AQA's own case and symbols, so no uppercase transform anywhere near it —
   this table is full of delta, Cl, Br and sub/superscripts */
.wcqg-book-table caption { text-transform: none; letter-spacing: normal; text-align: left; font-family: var(--font-mono); font-size: 11px; color: var(--muted); padding-bottom: 8px; }
.wcqg-book-table th { text-transform: none; letter-spacing: normal; font-family: var(--font-body); font-size: 12.5px; font-weight: 600; color: var(--ink); text-align: left; padding: 6px 10px 6px 0; border-bottom: 1px solid var(--ink-soft); background: none; }
.wcqg-book-table td { font-size: 14px; padding: 7px 10px 7px 0; border-bottom: 1px solid var(--hairline); vertical-align: baseline; }
.wcqg-book-table td:last-child { font-variant-numeric: tabular-nums; white-space: nowrap; }
.wcqg-book-gloss { color: var(--muted); font-size: 12.5px; }
@media (pointer: coarse) { .wcqg-book-zoom { min-height: 44px; } }
@media (max-width: 560px) {
  .wcqg-book-tabs { padding: 10px; }
  .wcqg-book-pane { padding: 10px; max-height: 70vh; }
  .wcqg-book-table td { font-size: 13.5px; }
}
@media print { .wcqg-book { display: none !important; } }

/* the question sits on the same white sheet as the paper it came from */
.wcqg-play .rn-exam-q { border: 1px solid var(--ink); border-radius: 3px; margin-top: 16px; padding: 16px 20px 18px; background: #fff; box-shadow: 0 24px 48px -36px oklch(0.2 0.02 250 / 0.5); }
.wcqg-play .rn-exam-q:focus { outline: none; }
/* the question head is a real <h3> so focus and screen-reader navigation land
   on it; it should still look like the label it is, not like a heading */
.wcqg-play h3.rn-exam-qhead { font-family: inherit; font-size: inherit; font-weight: 400; margin-top: 0; }
.wcqg-play h3.rn-exam-qhead:focus { outline: none; }
.wcqg-play h3.rn-exam-qhead:focus-visible { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 4px; border-radius: 3px; }
.wcqg-qtags { display: inline-flex; align-items: center; gap: 8px; }
.wcqg-qtopic { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em; color: var(--muted); }
/* Provenance line under the question header — "June 2025 · Paper 1 · Q7".
   Only rendered where the question's paper is actually known (see srcLabel in
   site.js); it is the trust signal, so it stays quiet but legible. Not
   uppercased: the paper code and question number must read exactly. */
.wcqg-src { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em;
  color: var(--muted); margin: -2px 0 10px; text-transform: none; }
/* "This question also needs Alkenes and Aromatic chemistry." — a heads-up above
   a question that leans on a topic the student did not pick. Quiet: it is
   context, not a warning about their work, and it must not compete with the
   question itself. */
.wcqg-needs { font-size: 13px; line-height: 1.5; color: var(--muted); margin: 0 0 10px;
  padding: 6px 10px; border-radius: 5px; background: oklch(0.965 0.008 250); }
.wcqg-playfoot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; margin-top: 14px; }
/* Back sits opposite the forward pair — it is a way out, not a third thing to
   choose between. It is [hidden] on the first question. */
.wcqg-prevbtn { margin-right: auto; }
/* .btn sets its own display, which would defeat the hidden attribute */
.wcqg-playfoot .btn[hidden], .wcqg-done-actions .btn[hidden] { display: none; }
/* [hidden] loses to .btn's display:inline-flex, so the reveal button stayed on
   screen and in the tab order after it had been pressed — and pressing it again
   ran the whole reveal a second time, appending every typed answer into the
   comparison column twice. */
.wcqg-reveal[hidden] { display: none; }
.wcqg-noteslink { margin: 10px 2px 0; font-size: 13px; color: var(--muted); }
.wcqg-body p.wcqg-line { font-size: 15px; line-height: 1.65; color: var(--ink-soft); margin: 0 0 9px; }
.wcqg-part { color: var(--ink); font-weight: 600; }
.wcqg-pm { text-align: right; margin: 2px 0 14px; }
.wcqg-writehint { font-size: 13px; color: var(--muted); font-style: italic; margin: 12px 0; }
.wcqg-ms { margin-top: 12px; padding: 13px 16px; border: 1px solid oklch(0.82 0.04 200); border-radius: 6px; background: oklch(0.97 0.012 200); }
.wcqg-mslabel { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: oklch(0.40 0.12 200); margin: 0 0 9px; }
/* The mark scheme is the most-read thing on the page: a comfortable measure,
   marking points tight together, and the tariff acting as the rule that closes
   each group rather than floating in a column of its own. */
.wcqg-msinner { max-width: 62ch; }
.wcqg-msline { font-size: 15px; line-height: 1.62; color: var(--ink-soft); margin: 0 0 6px; }
.wcqg-msnote { font-size: 13.5px; line-height: 1.55; color: var(--muted); font-style: italic; margin: 0 0 6px; padding-left: 12px; border-left: 2px solid oklch(0.88 0.03 200); }
/* OCR levelled-response schemes: the Level 3/2/1 band headings, and the
   printed scheme's column-divider rule (emitted by the build's flatMs pass) */
.wcqg-mslevel { font-size: 15px; line-height: 1.5; color: var(--ink); font-weight: 600; margin: 14px 0 6px; }
.wcqg-mslevel:first-child { margin-top: 0; }
.wcqg-mshr { border: 0; border-top: 1px solid oklch(0.88 0.03 200); margin: 12px 0; }
/* OCR's two-column scheme — Answer | Examiner guidance, paired per part so
   the ALLOW/IGNORE rulings sit beside the marking points they qualify
   (site.js msWithGuide). Guidance cells wear the insight family's warm
   rule. On narrow screens the grid collapses to alternating blocks:
   part, its guidance, next part… */
.wcqg-msinner--two { max-width: none; }
.wcqg-two { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); column-gap: 20px; align-items: start; }
.wcqg-two > .wcqg-mslabel { margin-bottom: 6px; }
.wcqg-two-ms { min-width: 0; padding-bottom: 4px; }
.wcqg-two-g { min-width: 0; font-size: 13.5px; margin: 0 0 10px; padding: 8px 12px 5px;
  border-left: 3px solid oklch(0.80 0.10 85); border-radius: 0 5px 5px 0; background: oklch(0.985 0.012 85); }
.wcqg-two-g:empty { border: 0; background: none; padding: 0; margin: 0; }
@media (max-width: 719px) {
  .wcqg-two { display: block; }
  .wcqg-two-h2 { display: none; }
  .wcqg-two-g { margin: 2px 0 14px; }
  .wcqg-two-g:not(:empty)::before { content: "Examiner guidance"; display: block; font-family: var(--font-mono);
    font-size: 9.5px; letter-spacing: 0.05em; text-transform: uppercase; color: oklch(0.44 0.10 75); margin-bottom: 5px; }
}
.wcqg-msmark { display: flex; align-items: center; gap: 10px; text-align: right; margin: 0 0 14px; padding: 0; }
.wcqg-msmark::before { content: ""; flex: 1; height: 1px; background: oklch(0.88 0.03 200); }
/* What examiners said — a paraphrase of AQA's report on the examination, and
   the only thing in the reveal that is not AQA's own words. It sits inside the
   mark-scheme panel but is deliberately NOT styled like one: a warm rule marks
   it as commentary about the answer rather than part of it. Not every question
   has one. */
/* Its own quiet ground, because on a multiple-choice question this sits inside
   the right/wrong feedback panel — without it the examiners' note is tinted
   green or red by whether the student guessed correctly, which has nothing to
   do with what the note says. */
.wcqg-insight { margin: 14px 0 0; padding: 11px 14px 9px; border-left: 3px solid oklch(0.80 0.10 85);
  border-radius: 0 5px 5px 0; background: oklch(0.985 0.012 85); }
.wcqg-insight .wcqg-mslabel { color: oklch(0.44 0.10 75); }
.wcqg-insight-text { max-width: 62ch; font-size: 14.5px; line-height: 1.62; color: var(--ink-soft); margin: 0; }
.wcqg-insight-text em { font-style: normal; font-weight: 600; color: var(--ink); }
/* M1 / M2 / M3 where they lead a line, styled like the checkbox beside them */
.wcqg-mtag { display: inline-block; margin-right: 6px; padding: 1px 6px; border-radius: 999px; background: oklch(0.92 0.03 200); color: oklch(0.34 0.10 200); font-family: var(--font-mono); font-size: 11.5px; font-weight: 500; }
/* levels-of-response instructions arrive as a table header, which is black by
   default across the site — far too loud inside a mark scheme, and a toner
   sink in print */
/* AQA writes that instruction as a one-cell header row above a two-column
   table, so it renders as a black column header squeezed into the first
   column. Where the header row holds a single cell it is prose, not a column
   heading: let it run the full width and drop the black fill, which is far too
   loud inside a mark scheme and a toner sink in print. Real column headers
   elsewhere keep the site's normal table styling. */
.wcqg-ms .rn-table thead:has(th:only-child),
.wcqg-ms .rn-table thead:has(th:only-child) tr,
.wcqg-ms .rn-table thead:has(th:only-child) th { display: block; }
.wcqg-ms .rn-table thead:has(th:only-child) th { background: oklch(0.92 0.03 200); color: var(--ink); font-weight: 600; }
.wcqg-ul { margin: 0 0 10px; padding-left: 22px; }
.wcqg-ul li { font-size: 14.5px; line-height: 1.6; color: var(--ink-soft); margin: 0 0 5px; }
/* Self-marking: one checkbox per marking point, laid out beside the mark
   scheme so the scheme stays readable while the student ticks. Below 860px the
   grid collapses and the mark scheme sits above the checkboxes. */
.wcqg-msgrid { display: grid; grid-template-columns: minmax(0, 1fr) 236px; gap: 18px; align-items: start; }
/* the wide column: mark scheme, then the examiners' note under it */
.wcqg-mscol { min-width: 0; }
.wcqg-selfmark { border: 1px solid oklch(0.82 0.04 200); border-radius: 6px; background: var(--paper); padding: 12px 14px; position: sticky; top: 138px; }
.wcqg-selfmark-title { font-size: 14px; color: var(--ink); font-weight: 600; margin: 0 0 10px; }
/* ── Levels of response ─────────────────────────────────────────────────────
   A banded question is not marked point by point, so it does not get M1…Mn.
   Each band is a labelled group with the marks inside it to choose between —
   one press, and the band structure stays visible, which is the thing AQA is
   actually asking the student to judge. */
.wcqg-selfmark-hint { font-size: 12.5px; line-height: 1.5; color: var(--muted); margin: -4px 0 12px; }
.wcqg-bands { display: flex; flex-direction: column; gap: 7px; }
.wcqg-band { display: flex; align-items: center; gap: 10px; }
.wcqg-band-name { flex: none; min-width: 58px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }
.wcqg-band-marks { display: flex; flex-wrap: wrap; gap: 6px; }
.wcqg-lorbtn { min-width: 42px; font-variant-numeric: tabular-nums; }
.wcqg-selfmark .wcqg-lorbtn[aria-pressed="true"] { background: oklch(0.40 0.12 200); border-color: oklch(0.40 0.12 200); color: var(--paper); }
@media (pointer: coarse) { .wcqg-lorbtn { min-height: 44px; } }
.wcqg-markrow { display: flex; align-items: baseline; gap: 8px; margin: 0 0 8px; }
.wcqg-markrow-label { font-family: var(--font-mono); font-size: 12px; color: var(--muted); min-width: 24px; }
.wcqg-markboxes { display: flex; flex-wrap: wrap; gap: 6px; }
.wcqg-markbox { display: inline-flex; align-items: center; gap: 5px; padding: 5px 9px; border: 1px solid var(--hairline); border-radius: 999px; background: var(--paper-2); font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-soft); cursor: pointer; }
.wcqg-markbox input { accent-color: oklch(0.40 0.12 200); width: 15px; height: 15px; margin: 0; }
.wcqg-markbox:has(input:checked) { background: oklch(0.40 0.12 200); border-color: oklch(0.40 0.12 200); color: var(--paper); }
.wcqg-markbox:focus-within { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 1px; }
.wcqg-selfmark-actions { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 12px; }
.wcqg-tally { font-family: var(--font-mono); font-size: 12px; color: var(--muted); margin: 10px 0 0; }
@media (max-width: 860px) {
  .wcqg-msgrid { grid-template-columns: 1fr; }
  .wcqg-selfmark { position: static; }
  /* phones and small tablets: the ticks have to be finger-sized */
  .wcqg-markbox { min-height: 44px; padding-inline: 13px; }
}
/* and on any touch screen, whatever its width */
@media (pointer: coarse) {
  .wcqg-markbox { min-height: 44px; padding-inline: 13px; }
}

/* ---- summary: the paper, marked ---- */
.wcqg-done { max-width: 720px; background: #fff; border: 1px solid var(--ink); border-radius: 3px; box-shadow: 0 30px 60px -36px oklch(0.2 0.02 250 / 0.55); }
.wcqg-done[hidden] { display: none; }
.wcqg-done > h2 { margin: 0; padding: 11px 20px; border: 0; background: var(--dark); color: var(--paper); font-family: var(--font-display); font-weight: 400; font-size: 17px; line-height: 1.3; letter-spacing: normal; text-transform: none; }
.wcqg-done > [data-wcqg-summary] { padding: 22px 22px 0; }
.wcqg-doneline { margin: 0; font-size: 15px; color: var(--ink-soft); }
.wcqg-doneline strong { font-family: var(--font-display); font-size: 40px; font-weight: 400; line-height: 1; color: var(--ink); display: block; margin-bottom: 8px; }
.wcqg-topicbars { display: grid; gap: 12px; margin: 20px 0; }
.wcqg-topicbar-head { display: flex; justify-content: space-between; font-size: 14px; margin-bottom: 4px; }
.wcqg-topicbar-head span { font-family: var(--font-mono); font-size: 12px; color: var(--muted); }
.wcqg-topicbar-track { height: 8px; border-radius: 999px; background: var(--paper-2); border: 1px solid var(--hairline); overflow: hidden; }
.wcqg-topicbar-fill { height: 100%; background: var(--ink); border-radius: 999px; }
/* the one thing to do next, sitting above retry / new session / change topics */
.wcqg-next { margin: 20px 0 0; padding: 15px 18px; border: 1px solid var(--hairline); border-left: 4px solid var(--ink); border-radius: 6px; background: var(--paper-2); }
.wcqg-next-line { margin: 0; font-size: 15px; line-height: 1.6; color: var(--ink-soft); }
.wcqg-next-line strong { color: var(--ink); }
.wcqg-next .btn { margin-top: 12px; }
.wcqg-done-actions { display: flex; flex-wrap: wrap; gap: 10px; padding: 18px 22px 22px; }

/* ---- printable worksheet -------------------------------------------------
   A4, black and grey: a cover page, questions whose text keeps hold of the
   start of its answer space, and a running footer with page numbers. The
   page furniture is CSS only — no JavaScript pagination.

   The @page rule is NAMED (page: worksheet) so it applies to the worksheet
   and not to anyone printing an ordinary notes page. The margin boxes below
   are what put "whiteboardchemistry.com" and "Page 2 of 5" on every sheet;
   Chrome and Edge honour them. Where a browser does not (Safari and Firefox
   at the time of writing), the worksheet still prints correctly — it just
   loses the footer, and those browsers' own print headers can fill in. */
.wcqg-print { display: none; }

@page worksheet {
  size: A4;
  margin: 18mm 16mm;
  @bottom-left {
    content: "whiteboardchemistry.com";
    font-family: "IBM Plex Sans", sans-serif;
    font-size: 8.5pt;
    color: #444;
  }
  @bottom-right {
    content: "Page " counter(page) " of " counter(pages);
    font-family: "IBM Plex Sans", sans-serif;
    font-size: 8.5pt;
    color: #444;
  }
}
/* the cover carries no page number; the running footer's address stays */
@page worksheet:first {
  @bottom-right { content: none; }
}

@media print {
  /* No padding on the body: body:has(.sticky-cta) reserves 64px under the
     page for the enquiry bar, and on paper that reservation spilled a blank
     final page whenever the last mark scheme ended near the foot of one. */
  body.wcqg-printing { page: worksheet; padding: 0 !important; margin: 0; }
  body.wcqg-printing > *:not(.wcqg-print) { display: none !important; }
  /* A browser extension can put an element BEFORE <body> — Brisk injects a
     <plasmo-csui> host as the first child of <html>. On paper that box came
     first, on a page with no name, and the switch to the worksheet's named
     page forced a break: a blank first sheet, seen in Joe's Chrome and in
     no headless run. So while printing, the root carries the page name
     itself and nothing outside <body> is laid out at all. */
  html.wcqg-printing { page: worksheet; }
  html.wcqg-printing > *:not(head):not(body) { display: none !important; }
  body.wcqg-printing .wcqg-print { display: block; font-size: 11.5pt; line-height: 1.45; color: #000; }

  /* toner discipline: nothing on a worksheet carries a fill or a colour */
  .wcqg-print, .wcqg-print * { background: transparent !important; box-shadow: none !important; color: #000 !important; }
  /* the rule that closes each marking-point group is a pseudo-element, which
     the sweep above cannot reach — it keeps its tint unless told otherwise */
  .wcqg-print .wcqg-msmark::before { background: #999 !important; }
  .wcqg-print .rn-table th { border-bottom: 1.5pt solid #000; font-weight: 700; }
  .wcqg-print .rn-exam-mk, .wcqg-print .wcqg-mtag { border: 0.5pt solid #666; border-radius: 2pt; padding: 0 3pt; font-size: 8.5pt; }
  .wcqg-print p, .wcqg-print li { orphans: 3; widows: 3; }

  /* ---- the cover: page 1, alone by design ----
     The front of a real paper. Everything on it is sized so that a grid of
     up to 24 questions fits under the instructions on one A4 page. The
     greys need their own !important because the toner sweep above forces
     black on everything. */
  .wcqg-print-cover { break-after: page; }
  .wcqg-cover-brand { display: flex; align-items: center; gap: 7pt; padding-bottom: 8pt; border-bottom: 1.5pt solid #000; }
  .wcqg-print-wordmark { font-family: "Instrument Serif", Georgia, serif; font-size: 15pt; }
  .wcqg-cover-date { margin-left: auto; font-family: "IBM Plex Mono", monospace; font-size: 8.5pt; letter-spacing: 0.04em; color: #444 !important; }
  .wcqg-cover-course { margin: 28pt 0 4pt; font-family: "IBM Plex Mono", monospace; font-size: 9pt; letter-spacing: 0.14em; text-transform: uppercase; }
  .wcqg-print .wcqg-cover-title { font-family: "Instrument Serif", Georgia, serif; font-size: 34pt; font-weight: 400; line-height: 1.05; letter-spacing: -0.01em; margin: 0 0 8pt; }
  .wcqg-cover-desc { margin: 0 0 20pt; font-size: 11pt; line-height: 1.5; }
  /* the three numbers off the console's dark bar, in the same order */
  .wcqg-cover-nums { display: flex; margin: 0 0 22pt; padding: 12pt 0; border-top: 0.75pt solid #000; border-bottom: 0.75pt solid #000; }
  .wcqg-cover-nums > div { flex: 1; padding: 0 16pt; border-left: 0.5pt solid #999; }
  .wcqg-cover-nums > div:first-child { padding-left: 0; border-left: 0; }
  .wcqg-cover-nums dt { margin: 0 0 5pt; font-family: "IBM Plex Mono", monospace; font-size: 7.5pt; letter-spacing: 0.12em; text-transform: uppercase; color: #444 !important; }
  .wcqg-cover-nums dd { margin: 0; font-family: "Instrument Serif", Georgia, serif; font-size: 26pt; line-height: 1; white-space: nowrap; }
  /* name, class, date: a label and a line to write on */
  .wcqg-cover-fields { display: flex; gap: 16pt; margin: 0 0 22pt; }
  .wcqg-cover-field { flex: 1; border-bottom: 0.75pt solid #000; }
  .wcqg-cover-field--name { flex: 2; }
  .wcqg-cover-field--date { flex: 0.8; }
  .wcqg-cover-field span { display: block; margin-bottom: 22pt; font-family: "IBM Plex Mono", monospace; font-size: 7.5pt; letter-spacing: 0.1em; text-transform: uppercase; color: #444 !important; }
  .wcqg-cover-label { margin: 0 0 6pt; font-family: "IBM Plex Mono", monospace; font-size: 8pt; letter-spacing: 0.12em; text-transform: uppercase; break-after: avoid; }
  .wcqg-cover-instr { margin: 0 0 18pt; padding-left: 14pt; font-size: 10.5pt; line-height: 1.5; }
  .wcqg-cover-instr li { margin: 0 0 3pt; }
  /* the marks grid: one table, or two side by side past twelve questions */
  .wcqg-cover-grids { display: flex; gap: 18pt; align-items: flex-start; margin: 0 0 8pt; }
  .wcqg-print .wcqg-cover-grid { flex: 1; width: auto; border-collapse: collapse; font-size: 9.5pt; }
  .wcqg-cover-grid th { font-family: "IBM Plex Mono", monospace; font-size: 7.5pt; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; text-align: left; padding: 0 6pt 4pt 0; border-bottom: 0.75pt solid #000; }
  .wcqg-cover-grid td { padding: 2.5pt 6pt 2.5pt 0; height: 11pt; border-bottom: 0.5pt solid #999; }
  .wcqg-cover-grid td:nth-child(3), .wcqg-cover-grid th:nth-child(3) { text-align: right; }
  .wcqg-cover-grid td:last-child, .wcqg-cover-grid th:last-child { width: 40pt; border-left: 0.5pt solid #999; padding-left: 6pt; }
  .wcqg-cover-total { margin: 6pt 0 0; font-size: 10.5pt; }
  .wcqg-cover-word { font-family: "IBM Plex Mono", monospace; font-size: 8pt; letter-spacing: 0.1em; text-transform: uppercase; margin-right: 8pt; }
  .wcqg-cover-blank { display: inline-block; width: 44pt; height: 12pt; margin-right: 4pt; border-bottom: 0.75pt solid #000; vertical-align: baseline; }
  .wcqg-cover-gap { display: inline-block; width: 28pt; }
  .wcqg-cover-foot { margin: 22pt 0 0; padding-top: 8pt; border-top: 0.5pt solid #999; font-size: 8.5pt; line-height: 1.5; color: #444 !important; }
  /* on its own line, so it breaks only when it must and never mid-word */
  .wcqg-cover-url { display: block; margin-top: 2pt; font-family: "IBM Plex Mono", monospace; font-size: 8pt; overflow-wrap: anywhere; }

  /* the questions open on page 2 under their own heading, as the mark
     schemes do at the back */
  .wcqg-print h1 { font-family: "Instrument Serif", Georgia, serif; font-size: 19pt; font-weight: 400; margin: 0 0 4pt; }
  .wcqg-print-meta { font-size: 9.5pt; margin: 0; }
  .wcqg-print-questions > h1 { break-after: avoid; }
  .wcqg-print-questions > .wcqg-print-meta { margin-bottom: 10pt; break-after: avoid; }

  /* a question and everything belonging to it stays on one page */
  /* NOT break-inside:avoid — a tall question then shunts whole and leaves the
     previous page nearly empty. The per-part rules do the real work: each
     part avoids breaking, and the number and body avoid breaking AFTER, which
     is what keeps a heading with its text. */
  .wcqg-print-q { break-inside: auto; border-top: 0.75pt solid #999; padding: 9pt 0 6pt; }
  .wcqg-print-qnum { font-weight: 700; font-size: 9.5pt; margin: 0 0 6pt; break-after: avoid; }
  /* the "also needs …" note sits between the number and the question, so it
     has to hold on to what follows too — otherwise a page ends on a header and
     a note with the question itself overleaf */
  .wcqg-print .wcqg-needs { break-after: avoid; }
  .wcqg-print-body { break-after: avoid; }
  /* an MCQ stem is a line or two, so it can be kept whole; the long written
     preambles that share .wcqg-print-body cannot */
  .wcqg-print-stem { break-inside: avoid; }
  /* a part is one piece of paper: its label, its text and its answer space
     never straddle a page break (Joe, 2026-09-07: a question starting at the
     foot of one page with its lines on the next reads as broken). The cost is
     white space at the foot of a page before a tall part; the cover page
     means that can no longer leave a page with nothing on it. */
  .wcqg-print-part { break-inside: avoid; }
  .wcqg-print-part > p:first-child { break-after: avoid; }
  .wcqg-print .wcqg-pm, .wcqg-print .wcqg-msmark { text-align: right; break-after: avoid; }
  /* figures and tables scale to the column and stay whole */
  .wcqg-print svg, .wcqg-print img { max-width: 100%; height: auto; break-inside: avoid; }
  .wcqg-print table { break-inside: avoid; width: 100%; font-size: 10pt; }
  .wcqg-print .rn-table-scroll { overflow: visible !important; }

  /* multiple choice: tick boxes, no ruled lines */
  .wcqg-print-instr { font-style: italic; font-size: 10pt; margin: 4pt 0 6pt; break-after: avoid; }
  /* Four text options are a few lines, so keep them together — a break used to
     orphan option D at the top of the next page. Not when they are diagrams:
     that block can be most of a page, and forcing it whole would leave a
     half-empty sheet behind it. */
  .wcqg-print-opts { margin: 0 0 6pt; }
  .wcqg-print-opts:not(:has(svg)):not(:has(img)) { break-inside: avoid; }
  .wcqg-print-opt { display: flex; align-items: flex-start; gap: 7pt; padding: 3pt 0; break-inside: avoid; }
  .wcqg-print-box { flex: none; width: 11pt; height: 11pt; border: 0.75pt solid #000; margin-top: 1.5pt; }
  .wcqg-print-optletter { flex: none; font-weight: 700; width: 12pt; }

  /* ruled writing space, sized to the tariff, and welded to the question text
     above it: the whole space moves with its part rather than leaving the
     lines stranded at the top of a page or cut in two */
  .wcqg-print-space { break-before: avoid; break-inside: avoid; }
  .wcqg-rules { margin: 3pt 0 10pt; break-inside: avoid; }
  .wcqg-rules span { display: block; border-bottom: 0.5pt solid #999; height: 21pt; break-inside: avoid; }
  /* parts that ask for a drawing get an open box, not ruled lines: lines tell
     a student to write where the question wants a mechanism drawn */
  .wcqg-print-drawbox { margin: 3pt 0 10pt; border: 0.5pt solid #999; break-inside: avoid; }
  .wcqg-print-drawnote { margin: 3pt 0 10pt; font-size: 9pt; font-style: italic; }
  /* "complete the table" questions print a table whose answer cells are empty,
     and an empty cell collapses to nothing — there was nowhere to write. Which
     blanks are answer space and which are a data table's own structure is
     decided in sizeAnswerCells(), which sets the height inline; a plain data
     table keeps its natural row height. */
  .wcqg-print-q .wcqg-answer-table td { vertical-align: top; }
  .wcqg-print-q .wcqg-answer-table { break-inside: auto; }
  /* "Tick one box": AQA prints the box as artwork we do not carry, so the last
     cell of a tick list arrives empty and the student had nothing to mark.
     Draw the box, and keep the column narrow — this is a tick, not an answer. */
  .wcqg-print .rn-table-tick td:last-child { width: 18mm; text-align: center; }
  .wcqg-print .rn-table-tick td:last-child::after {
    content: ""; display: inline-block; width: 11pt; height: 11pt;
    border: 0.75pt solid #000; margin-top: 1pt;
  }

  /* mark schemes: fresh page, numbered to match, and free to split */
  .wcqg-print-answers { break-before: page; }
  .wcqg-print-answers h1 { margin-bottom: 4pt; }
  .wcqg-print-ms { break-inside: auto; border-top: 0.75pt solid #999; padding: 8pt 0 4pt; }
  .wcqg-print-answer { margin: 0 0 4pt; }
  .wcqg-print .wcqg-msline { font-size: 10.5pt; margin: 0 0 3pt; }
  /* a scheme is free to run over a page break; forcing keeps here only pushes
     the breaks somewhere worse */
  .wcqg-print .wcqg-msnote { font-size: 10pt; font-style: italic; border: 0; padding-left: 10pt; }
  .wcqg-print-src { margin-top: 12pt; padding-top: 6pt; border-top: 0.75pt solid #999; font-size: 8.5pt; }
}

/* ---- one answer box per part ---- */
.wcqg-partblock + .wcqg-partblock { border-top: 1px dashed var(--hairline); margin-top: 20px; padding-top: 16px; }
.wcqg-anspart { text-transform: none; letter-spacing: normal; color: var(--ink-soft); font-weight: 600; }
.wcqg-yourans-part { font-family: var(--font-mono); font-size: 11px; color: var(--muted); margin: 10px 0 2px; }
.wcqg-yourans-part:first-child { margin-top: 0; }
/* the ruled lines need no display rule of their own: they only ever live
   inside .wcqg-print, which is display:none until the worksheet prints. */

/* ---- typed answer for written questions ---- */
.wcqg-anspanel { display: block; margin: 14px 0 12px; }
.wcqg-anspanel[hidden] { display: none; }
.wcqg-anslabel { display: block; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); margin-bottom: 6px; }
.wcqg-answer { width: 100%; box-sizing: border-box; font-family: inherit; font-size: 14.5px; line-height: 1.55; color: var(--ink); padding: 10px 12px; border: 1px solid var(--hairline); border-radius: 6px; background: var(--paper); resize: vertical; }
.wcqg-answer:focus-visible { outline: 2px solid oklch(0.52 0.13 200); outline-offset: 1px; border-color: oklch(0.52 0.13 200); }
.wcqg-answer::placeholder { color: var(--muted); opacity: 0.6; }
.wcqg-compare { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; align-items: start; }
.wcqg-yourans { padding: 11px 14px; border: 1px solid var(--hairline); border-radius: 6px; background: var(--paper); }
.wcqg-yourans[hidden] { display: none; }
.wcqg-yourans-text { font-size: 14.5px; line-height: 1.6; color: var(--ink-soft); white-space: normal; overflow-wrap: break-word; }

/* ---- drawing an answer ----------------------------------------------------
   Parts that ask for a mechanism, a displayed formula or a tangent answer on a
   canvas instead of in a textarea. Every part carries both inputs and shows
   one; [data-mode] on the panel is the switch. */
.wcqg-vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.wcqg-anshead { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 6px; }
.wcqg-anshead .wcqg-anslabel { margin-bottom: 0; }
/* Two independent toggles, NOT a segmented either/or: an exam part is very
   often "State the name… Explain… Draw 3D representations", and both boxes
   need to be open at once. Kept as separate pills so they do not read as one
   switch with two positions. */
.wcqg-modeswitch { display: flex; gap: 6px; }
.wcqg-mode { padding: 5px 13px; min-height: 32px; font-size: 10.5px; border-radius: 999px; }
.wcqg-mode[aria-pressed="true"] { background: oklch(0.40 0.12 200); border-color: oklch(0.40 0.12 200); color: var(--paper); }
.wcqg-anspanel[data-type="0"] .wcqg-typebox,
.wcqg-anspanel[data-draw="0"] .wcqg-drawbox { display: none; }
.wcqg-anspanel[data-draw="1"][data-type="1"] .wcqg-drawbox { margin-top: 12px; }
/* A part drawn only on its figure has its canvas and tools up beside the
   figure, so the panel itself carries the toggles and a line saying where to
   go. The rule also covers the moment before the script has run, and the case
   where it cannot run at all: an empty bordered box under a question that
   says "draw on Figure 1" would only be confusing. d:3 keeps its box — that
   is the whole point of d:3. */
.wcqg-anspanel[data-d="2"] .wcqg-drawlayer { display: none; }
.wcqg-drawhint { margin: 0; font-size: 13px; color: var(--muted); }
.wcqg-drawhint[hidden] { display: none; }

/* the ink. One colour on a blank canvas; the accent over a figure, so the
   student's line is never confused with the artwork underneath. */
.wcqg-drawlayer { --wcqg-ink: oklch(0.30 0.06 250); position: relative; }
.wcqg-drawlayer--over { --wcqg-ink: oklch(0.55 0.20 28); display: block; width: fit-content; max-width: 100%; margin-inline: auto; line-height: 0; }
/* width:100% is load-bearing, not tidiness: with a width of `auto` an
   aspect-ratio box that hits its max-height gives up WIDTH to keep the ratio,
   which shrank a one-mark answer box to half the column. */
.wcqg-drawlayer:not(.wcqg-drawlayer--over) { display: block; width: 100%; aspect-ratio: 16 / 8; min-height: 150px; border: 1px solid var(--hairline); border-radius: 6px; background: var(--paper); background-image: radial-gradient(oklch(0.88 0.01 250) 1px, transparent 1px); background-size: 22px 22px; }
/* Sized by the tariff. The ratio governs a narrow screen, where the box would
   otherwise be a letterbox; the cap governs a wide one, where a ratio alone
   turns a one-mark formula into a slab half a screen tall.

   Doubled class names on purpose: the base rule above is written with :not(),
   which out-ranks a single class, so a plain .wcqg-drawlayer--sm would lose
   its ratio to it and every box would come out the same height. */
.wcqg-drawlayer.wcqg-drawlayer--sm { aspect-ratio: 16 / 7; max-height: 210px; }
.wcqg-drawlayer.wcqg-drawlayer--md { aspect-ratio: 16 / 8; max-height: 290px; }
.wcqg-drawlayer.wcqg-drawlayer--lg { aspect-ratio: 16 / 10; max-height: 390px; }
/* On touch the active canvas swallows the gesture, so the box must never fill
   the screen — the page is scrolled from what is left above and below it. */
@media (pointer: coarse) {
  .wcqg-drawlayer.wcqg-drawlayer--lg { max-height: min(390px, 58svh); }
  .wcqg-drawlayer.wcqg-drawlayer--md { max-height: min(290px, 58svh); }
}
/* Which element owns a touch gesture is settled by the compositor BEFORE the
   first pointerdown fires, so switching touch-action inside pointerdown — which
   is what this used to do — is far too late. The browser had already ruled the
   finger a page pan: it cancelled the stroke about 20px in, scrolled the page
   out from under the finger, and left the stub behind. Only strokes that STARTED
   near-horizontal survived, which is no use for a vertical bond, a curly-arrow
   tail or a curve, on the device most students use.
   So the canvas being answered into declares touch-action: none at rest. Every
   other canvas keeps pan-y, which is what the original note here was protecting:
   a finger swiping up the page over an idle drawing box still scrolls. */
.wcqg-drawcanvas { position: absolute; inset: 0; width: 100%; height: 100%; touch-action: pan-y; cursor: crosshair; }
.wcqg-anspanel[data-draw="1"] .wcqg-drawbox .wcqg-drawcanvas,
.wcqg-drawon.is-drawing .wcqg-drawlayer--over .wcqg-drawcanvas { touch-action: none; }
.wcqg-drawlayer[data-tool="erase"] .wcqg-drawcanvas { cursor: cell; }
.wcqg-drawlayer.is-locked .wcqg-drawcanvas { pointer-events: none; cursor: default; }

.wcqg-drawbar { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.wcqg-drawbar[hidden] { display: none; }
.wcqg-drawtools, .wcqg-drawacts { display: flex; gap: 6px; flex-wrap: wrap; }
.wcqg-drawtool, .wcqg-drawact { padding: 5px 12px; min-height: 34px; font-size: 10.5px; }
.wcqg-drawtool[aria-pressed="true"] { border-color: var(--ink); color: var(--ink); background: oklch(0.95 0.01 250); }
.wcqg-drawact[disabled] { opacity: 0.4; cursor: default; }
.wcqg-drawact[disabled]:hover { border-color: var(--hairline); color: var(--ink-soft); }

/* a figure being drawn on: the tools sit with it and travel with it */
.wcqg-drawon { margin: 14px 0; }
.wcqg-drawon .wcqg-fig { margin-block: 0; }
.wcqg-drawon.is-drawing .wcqg-drawlayer--over { outline: 1px dashed oklch(0.55 0.20 28 / 0.5); outline-offset: 5px; }

/* the answer, once it has moved beside the mark scheme */
.wcqg-yourans-draw { margin: 4px 0 2px; }
.wcqg-yourans-draw .wcqg-drawlayer:not(.wcqg-drawlayer--over) { min-height: 0; }
.wcqg-compare--wide { grid-template-columns: 1fr; }

@media (max-width: 640px) {
  .wcqg-drawtool, .wcqg-drawact, .wcqg-mode { min-height: 40px; }
  .wcqg-drawbar { gap: 8px; }
}

/* ---- redrawn AQA figures inside practice questions ---- */
/* Exam figures render at their NATURAL size. The extracted scans are 96 dpi,
   so 1 SVG unit = 1 CSS px = the size AQA printed it — on screen and on the
   printed worksheet alike. Stretching them to fill the box blew a 60 px
   cyclohexene up to 480 px, eight times exam size, which left no room to
   draw a mechanism beside it. Shrink to fit a narrow column, never grow. */
.wcqg-fig { position: relative; width: fit-content; max-width: 100%; margin: 14px auto; }
/* only appears on a figure the column has had to shrink — see
   markZoomableFigures() in site.js */
.wcqg-zoomfig { display: block; margin: 4px auto 0; padding: 5px 11px; border: 1px solid var(--hairline);
  border-radius: 999px; background: var(--paper); font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); cursor: pointer; }
.wcqg-zoomfig:hover { border-color: var(--ink-soft); color: var(--ink); }
@media (pointer: coarse) { .wcqg-zoomfig { min-height: 44px; } }
@media print { .wcqg-zoomfig { display: none !important; } }
.wcqg-fig svg { display: block; width: auto; max-width: 100%; height: auto; margin-inline: auto; }
.wcqg-optfig { display: block; width: fit-content; max-width: 100%; margin-top: 6px; }
.wcqg-optfig svg { display: block; width: auto; max-width: 100%; height: auto; }

/* ============================================================
   REVISION HUB — "the course, plotted" (revision/index.html)
   The landing page body is one figure: a whiteboard graph whose
   x-axis is the student's timeline and whose height is demand.
   The destinations are flat panels plotted on it; the course line
   climbs out of GCSE and FORKS at the summer into parallel A-Level
   tracks by exam board (upper = AQA notes + bank, lower = OCR bank),
   because students often switch boards at the jump. Namespace:
   rn-hub-* and rn-plot-* (NB .rn-hub-pager elsewhere is unrelated).

   GROWTH PATTERN — extend the fork, don't bolt on:
   · A new A-Level board (e.g. Edexcel) = one more .rn-plot in the
     exam-season stack (.rn-hub-col--stack) with its own --slot
     height between the track (120px) and the summit (312px), plus
     one .rn-hub-fork-path in the SVG from the fork point (497,371
     in its 1000×480 space) to the new dot (x 883, y = 480 − slot).
     With three tracks, compress the bank panels: drop the body
     line so each is eyebrow + title + link, and space the slots
     at least panel-height + ~15px apart so each branch line still
     has a visible channel to arrive through. Nothing else moves.
   · GCSE-level banks/boards belong at the LEFT of the timeline:
     make the Year 10–11 column a --stack the same way, with branch
     paths that MERGE INTO the main line at the bridge — tracks
     join at the jump, mirroring how A-Level tracks fork off it.
   · Never park a real destination off-chart (owner ruling
     2026-08-14: switching boards at the jump is a normal route,
     so a parallel track IS the course). Every destination gets a
     plotted panel, a dot, and a line that connects it.
============================================================ */
.rn-hub {
  padding: clamp(12px, 1.6vw, 20px) 0 clamp(28px, 3vw, 44px);
}

/* --- Masthead: topline (crumb + proof), then title left / lede right --- */
.rn-hub-head { margin-bottom: clamp(12px, 1.5vw, 18px); }
.rn-hub-topline {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.rn-hub-masthead {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(280px, 1fr);
  gap: 14px clamp(32px, 5vw, 80px);
  align-items: end;
  margin-top: 8px;
}
.rn-hub-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(36px, 3.35vw, 44px);
  line-height: 0.98;
  letter-spacing: -0.025em;
  margin: 0;
  color: var(--ink);
}
.rn-hub-title em.accent { font-style: italic; color: var(--accent); }
.rn-hub-lede {
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 47ch;
  margin: 0 0 4px;
}
.rn-hub-proof {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}

/* --- The board: four columns standing on a drawn axis.
   A fixed height on desktop pins the geometry so the curve in the
   background SVG registers with the px lifts of the plotted dots. --- */
.rn-hub-board { position: relative; }
.rn-hub-cols {
  position: relative;
  height: 480px;
  display: grid;
  grid-template-columns: 1.02fr 0.94fr 1.02fr 1.02fr;
  gap: 0 clamp(16px, 2vw, 28px);
  align-items: end;
  padding-left: 30px;                  /* origin lane for the y-axis */
}
/* y-axis (line + arrowhead) is drawn inside the .rn-hub-curve SVG,
   whose box is exactly the chart area. Its label: */
.rn-hub-ylabel {
  position: absolute;
  left: 8px;
  top: 118px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  writing-mode: vertical-rl;
  transform: rotate(180deg);
}
/* hand annotation under the steep section of the curve, pointing at it.
   The pointer's tip must stop CLEAR of the course line (site arrowhead
   rule: point at the destination, never overlap it) — the offsets below
   hold a visible gap between the head and the stroke. */
.rn-hub-anno {
  position: absolute;
  left: calc(28% + 6px);
  top: 444px;
  display: flex;
  align-items: flex-start;
  gap: 5px;
  color: var(--ink-soft);
  pointer-events: none;
  z-index: 1;
}
.rn-hub-anno em {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 17.5px;
  color: var(--ink-soft);
  white-space: nowrap;
  margin-top: 4px;
}
.rn-hub-curve {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
/* The route appears with ONE left-to-right wipe across the whole figure —
   a clip-path sweep in SCREEN space. (The earlier dash-drawn version could
   not be made smooth: a pathLength-normalised dash on a
   preserveAspectRatio="none" svg reveals in user-space arc length, so the
   tip lurched as the curve's stretch varied, and the fork branches needed
   a second hand-timed animation.) The wipe reveals the main line and both
   branches in pure x-order — exactly how the figure reads — and its end
   state is the untouched, fully solid route at full ink (the CSS
   stroke-opacity overrides the svg attribute's 0.6). */
.rn-hub-curve-path, .rn-hub-fork-path { stroke-opacity: 1; }
.rn-hub-curve {
  clip-path: inset(0 100% 0 0);
  animation: rn-hub-wipe 1.05s cubic-bezier(.35, .05, .25, 1) 0.15s both;
}
@keyframes rn-hub-wipe {
  to { clip-path: inset(0 0 0 0); }
}
@media (prefers-reduced-motion: reduce) {
  .rn-hub-curve { animation: none; clip-path: none; }
}

/* Each column lifts its panel --lift px above the axis and grounds
   itself with one dashed dropline. The plotted dot lives on each
   PANEL (see .rn-plot::before), so stacked tracks get theirs free. */
.rn-hub-col {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 12px;
  padding-bottom: var(--lift, 0px);
}
.rn-hub-col:nth-child(2) { --lift: 0px; }    /* GCSE — on the baseline */
.rn-hub-col:nth-child(3) { --lift: 92px; }   /* bridge — mid-climb */
.rn-hub-col:nth-child(4) { --lift: 165px; }  /* A-Level notes (AQA track) */
.rn-hub-col:nth-child(5) { --lift: 120px; }  /* exam-season stack — grounded at the OCR track */
.rn-hub-col::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  height: var(--lift, 0px);
  border-left: 1.5px dashed color-mix(in srgb, var(--ink) 30%, transparent);
}

/* The exam-season stack: parallel board tracks in one column.
   Panels anchor to the chart floor at their --slot height, so both
   plotted dots stay pinned no matter how their text wraps. */
.rn-hub-col--stack { display: block; }
.rn-hub-col--stack .rn-plot {
  position: absolute;
  left: 0;
  right: 0;
  bottom: var(--slot, 0px);
}
.rn-plot--summit { --slot: 312px; }   /* AQA bank — the summit */
.rn-plot--track  { --slot: 120px; }   /* OCR bank — the parallel track */

/* --- A plotted panel; the accent dot on its bottom edge is the
   plotted point the course line runs through --- */
.rn-plot {
  position: relative;
  z-index: 1;
  background: var(--paper);
  border: 1px solid var(--hairline);
  padding: 16px 18px 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: background .15s, border-color .15s;
}
.rn-plot::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
  transform: translate(-50%, 50%);
  z-index: 2;
}
.rn-plot:hover {
  background: var(--paper-2);
  border-color: color-mix(in srgb, var(--ink) 35%, var(--hairline));
}
.rn-plot-eyebrow {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 500;
  margin: 0;
}
/* the bridge is the "next step" — it carries the crosslink accent rule */
.rn-plot-bridge { box-shadow: inset 0 3px 0 0 var(--accent); }
.rn-plot h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 23px;
  line-height: 1.05;
  letter-spacing: -0.012em;
  margin: 0;
  color: var(--ink);
}
.rn-plot p:not(.rn-plot-eyebrow) {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-soft);
}
.rn-plot-links { margin-top: 4px; }
.rn-plot-links a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 44px;
  border-top: 1px solid var(--hairline);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
  transition: color .15s;
}
.rn-plot-links a:hover { color: var(--accent); }
.rn-plot-more { color: var(--muted) !important; }
.rn-plot-more:hover { color: var(--ink) !important; }
/* The primary link stretches over the whole panel; the secondary
   link stacks above it so both stay clickable. */
.rn-plot-main::after { content: ""; position: absolute; inset: 0; }
.rn-plot-more { position: relative; z-index: 3; }
.rn-plot-links a:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

/* --- The x-axis: drawn baseline, ticks, era labels, arrowhead --- */
.rn-hub-axis {
  position: relative;
  display: grid;
  grid-template-columns: 1.02fr 0.94fr 1.02fr 1.02fr;
  gap: 0 clamp(16px, 2vw, 28px);
  border-top: 2px solid var(--ink);
  padding-top: 9px;
  padding-left: 30px;                  /* match the cols' origin lane */
}
.rn-hub-axis::after {          /* arrowhead at the right end */
  content: "";
  position: absolute;
  right: -1px;
  top: -6px;
  width: 9px;
  height: 9px;
  border-top: 2px solid var(--ink);
  border-right: 2px solid var(--ink);
  transform: rotate(45deg);
}
.rn-hub-axis span {
  position: relative;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.rn-hub-axis span::before {   /* tick above each label */
  content: "";
  position: absolute;
  top: -9px;
  left: 50%;
  height: 5px;
  border-left: 2px solid color-mix(in srgb, var(--ink) 55%, transparent);
}
/* Era markers + "the jump." annotation exist twice: the desktop axis/anno
   (hidden on mobile) and these in-rail versions (hidden on desktop), so the
   rotated figure keeps its labels rather than dropping them. */
.rn-hub-era, .rn-hub-anno-m { display: none; }

/* --- Mobile: the graph rotates into a vertical rail timeline;
   the fork flattens into route order (both banks after A-Level) --- */
@media (max-width: 959px) {
  .rn-hub-masthead { display: block; }
  .rn-hub-title { margin-bottom: 14px; }
  .rn-hub-curve, .rn-hub-axis, .rn-hub-ylabel, .rn-hub-anno { display: none; }
  .rn-hub-board { padding-left: 22px; }
  .rn-hub-cols {
    display: block;
    height: auto;
    padding-left: 0;
  }
  .rn-hub-cols::before {       /* the rail — the same axis, rotated */
    content: "";
    position: absolute;
    left: -18px;
    top: 4px;
    bottom: -22px;
    border-left: 2px solid var(--ink);
  }
  .rn-hub-cols::after {        /* arrowhead pointing on down the course */
    content: "";
    position: absolute;
    left: -22px;
    bottom: -27px;
    width: 9px;
    height: 9px;
    border-right: 2px solid var(--ink);
    border-bottom: 2px solid var(--ink);
    transform: rotate(45deg);
  }
  .rn-hub-col { padding-bottom: 0; margin-bottom: 14px; }
  .rn-hub-col:last-child { margin-bottom: 0; }
  .rn-hub-col::after { display: none; }
  .rn-hub-col--stack .rn-plot {
    /* back into flow, but keep position:relative so each panel's
       ::before rail dot anchors to the panel itself */
    position: relative;
    bottom: auto;
  }
  .rn-hub-col--stack .rn-plot + .rn-plot { margin-top: 14px; }
  .rn-plot::before {           /* plotted point moves onto the rail */
    left: -18px;
    bottom: auto;
    top: 26px;
    transform: translate(-50%, 0);
  }
  /* Era labels ride the rail: same mono voice as the desktop axis, each
     with a tick reaching back to the rail line (the rotated axis tick). */
  .rn-hub-era {
    display: block;
    position: relative;
    margin: 0 0 7px;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .rn-hub-era::before {        /* tick from the rail to the label */
    content: "";
    position: absolute;
    left: -18px;
    top: 50%;
    width: 11px;
    border-top: 2px solid color-mix(in srgb, var(--ink) 55%, transparent);
  }
  /* "the jump." beside the bridging panel — italic hand note at the era
     line, with a short curved arrow dropping toward the panel's top edge.
     The head stops clear of the hairline (site rule: arrowheads never
     touch what they point at). */
  .rn-hub-anno-m {
    display: flex;
    position: absolute;
    top: -4px;
    right: 2px;
    align-items: flex-start;
    gap: 6px;
    color: var(--ink-soft);
    pointer-events: none;
    z-index: 2;
  }
  .rn-hub-anno-m em {
    font-family: var(--font-display);
    font-style: italic;
    font-size: 16.5px;
    white-space: nowrap;
  }
}

/* ============================================================
   SECTION-HUB FURNITURE — closing band + callout tick
============================================================ */
/* Notes hubs close on the shared dark .final-cta band; their verbatim CTA
   sentences are longer than the homepage title, so cap the display size. */
.final-cta-title--fit {
  font-size: clamp(30px, 3.6vw, 50px);
  line-height: 1.05;
}

/* Inline line-art tick for callout titles (replaces the ✅ emoji) —
   the exam-check tick shape, drawn in the title's own colour. */
.rn-callout-tick { flex: 0 0 auto; display: inline-flex; }
.rn-callout-tick svg { display: block; }

/* An <a class="btn btn-primary"> inside article prose: page.css's
   .article-body-inner a would force ink text + underline onto the dark
   pill — keep the standard button face (same guard as a.rn-exam-check). */
.article-body-inner a.btn { text-decoration: none; }
.article-body-inner a.btn-primary,
.article-body-inner a.btn-primary:hover { color: var(--paper); }

/* ============================================================
   ARTICLE FIGURE / TABLE LABELS (shared with insights articles)
============================================================ */
/* Figure label under an article figure (replaces per-page inline styles). */
.rn-fig-label {
  display: block;
  text-align: center;
  font-weight: 600;
  margin: 16px 0 6px;
}
/* Sub/superscripts in article prose: smaller and zero line-height so
   formulae don't open up the line box. */
.article-body-inner sub,
.article-body-inner sup { font-size: .72em; line-height: 0; }
/* Table caption as a block label. position:sticky pins it to the visible
   left edge, so when used as a <caption> inside a wide .rn-table-scroll
   table it sits OUTSIDE the horizontal pan instead of scrolling away. */
.rn-table-caption {
  display: block;
  position: sticky;
  left: 0;
  width: max-content;
  max-width: 100%;
  text-align: left;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.02em;
  /* NO text-transform: 20+ pre-existing captions carry chemistry ("The n+1
     rule", formulae) authored without .rn-chem wraps — uppercasing here
     corrupts case-significant symbols (n→N, Cl→CL). Sentence case, always. */
  color: var(--muted);
  margin: 0 0 8px;
}
/* Touch-width scroll cue: alongside the JS edge fade, an explicit mono
   hint while columns still sit off-screen to the right. Sticky-left so it
   stays put while the table pans (and clears the right-edge fade mask). */
@media (max-width: 700px), (pointer: coarse) {
  .rn-table-scroll.has-more-right::after {
    content: "scroll \2192";
    position: sticky;
    left: 0;
    display: block;
    width: max-content;
    padding: 6px 2px 0;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--muted);
  }
}

/* Public-site audit: keep anchor destinations below both sticky bars. */
.rn-content [id] { scroll-margin-top: var(--notes-scroll-offset, 160px); }
.rn-paper-heading[id], .quick-routes { scroll-margin-top: 110px; }
@media (max-width: 960px) { .rn-nav { top: var(--notes-header-height, 83px); } }
.quick-routes { display: flex; flex-wrap: wrap; gap: 10px; margin: 24px 0 30px; }
.quick-routes a { display: inline-flex; align-items: center; min-height: 44px; padding: 9px 16px; border: 1px solid var(--muted); border-radius: 6px; color: var(--ink); font-size: 15px; text-decoration: none; }
.quick-routes a:hover { border-color: var(--accent); color: var(--accent); }
.wcqg-compare { grid-template-columns: 1fr; }

.wcqg-mark-jump { display: inline-flex; align-items: center; min-height: 44px; margin-bottom: 12px; font-size: 14px; text-underline-offset: 3px; }
#wcqg-marking, #wcqg-scheme { scroll-margin-top: 150px; }
