/* ============================================================
   THE ANNOTATED NOTEBOOK — component layer, waves 1-3.
   Wave 1: actions, fields, chips, index tabs, breadcrumb,
   highlighter, examiner marks. Wave 2: cards + the signature
   pieces (ink-fill progress, self-drawing tick, callouts, empty
   state). Wave 3: chrome — navbar, footer, chapter rail,
   paywall. Consumed ONLY by /_notebook/ until Phase 2.

   Discipline (test-enforced by pages/tests_notebook.py):
   · zero raw colors — every color enters as var(--nb-*)
   · every class starts nb-
   Craft:
   · spacing rides the 4px grid via --nb-s* (two documented
     exceptions from DESIGN.md §5: nb-btn 10px vertical,
     nb-tab 14px horizontal)
   · every font-size is a --nb-text-* token
   · sans is the UI voice; serif italic is the examiner's ONLY
   · hover lift ≤1px at --nb-dur-1 var(--nb-ease); no glows,
     no gradients (the highlighter wash is the one sanctioned
     hard-stop wash, DESIGN.md §5), no left-accent borders

   Contents
     1 · Focus discipline
     2 · Actions          nb-btn (--primary --secondary --quiet), nb-link
     3 · Fields           nb-field, nb-label, nb-input, nb-select, nb-textarea
     4 · Chips            nb-chip
     5 · Index tabs       nb-tabs, nb-tab
     6 · Breadcrumb       nb-breadcrumb
     7 · Highlighter      nb-highlight
     8 · Examiner marks   nb-mark, nb-mark-note, nb-allocation
     9 · Cards            nb-card (--topic), eyebrow/title/meta/mastery
    10 · Ink-fill progress  nb-progress (fill + nib rider, .nb-is-inked)
    11 · Self-drawing tick  nb-tick (.nb-is-drawn)
    12 · Callouts         nb-callout (--note --examiner)
    13 · Empty state      nb-empty
    14 · Navbar           nb-navbar, nb-logo, tabs/actions/burger
    15 · Footer           nb-footer (tagline, links, legal row)
    16 · Chapter rail     nb-rail (vertical index tabs + mastery)
    17 · Paywall          nb-paywall (allocation wink, tick list)
   ============================================================ */

/* ---------- 1 · Focus discipline ------------------------------
   One ring everywhere: the student's blue pen takes focus. */
.nb-btn:focus-visible,
.nb-link:focus-visible,
.nb-tab:focus-visible,
.nb-breadcrumb a:focus-visible,
.nb-input:focus-visible,
.nb-select:focus-visible,
.nb-textarea:focus-visible,
a.nb-card:focus-visible,
.nb-logo:focus-visible,
.nb-navbar-burger:focus-visible,
.nb-footer a:focus-visible,
.nb-rail-tab:focus-visible {
  outline: 2px solid var(--nb-blue);
  outline-offset: 2px;
}

/* ---------- 2 · Actions --------------------------------------- */
.nb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--nb-s2);
  padding: 10px var(--nb-s4); /* 10px vertical is the documented button padding (DESIGN.md §5) */
  border: 1px solid transparent;
  border-radius: var(--nb-r-sm);
  font-family: var(--nb-sans);
  font-size: var(--nb-text-base);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color var(--nb-dur-1) var(--nb-ease),
    border-color var(--nb-dur-1) var(--nb-ease),
    color var(--nb-dur-1) var(--nb-ease),
    transform var(--nb-dur-1) var(--nb-ease);
}
.nb-btn:disabled {
  /* Explicit disabled inks, not opacity: the label stays legible
     (~3:1, the ink-3 tier) while the sunken fill + flat border +
     cursor keep it unmistakably inert in both themes. */
  background: var(--nb-paper-sunken);
  border-color: var(--nb-border);
  color: var(--nb-ink-3);
  cursor: not-allowed;
}
.nb-btn:active:not(:disabled) {
  transform: translateY(0); /* press settles back onto the paper */
}

.nb-btn--primary {
  background: var(--nb-blue);
  color: var(--nb-on-blue);
}
.nb-btn--primary:hover:not(:disabled) {
  background: var(--nb-blue-strong);
  transform: translateY(-1px);
}

.nb-btn--secondary {
  background: transparent;
  color: var(--nb-blue);
  /* the style tile's 40%-strength pen outline, derived from the token */
  border-color: color-mix(in srgb, var(--nb-blue) 40%, transparent);
}
.nb-btn--secondary:hover:not(:disabled) {
  border-color: var(--nb-blue-strong);
  color: var(--nb-blue-strong);
  background: var(--nb-blue-wash);
  transform: translateY(-1px);
}

.nb-btn--quiet {
  background: transparent;
  color: var(--nb-blue);
}
.nb-btn--quiet:hover:not(:disabled) {
  color: var(--nb-blue-strong);
  background: var(--nb-blue-wash);
  transform: translateY(-1px);
}

/* Inline link — underlined like pen, 1.5px stroke sitting low. */
.nb-link {
  color: var(--nb-blue);
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  border-radius: var(--nb-r-sm); /* the focus ring hugs the text */
  transition: color var(--nb-dur-1) var(--nb-ease);
}
.nb-link:hover {
  color: var(--nb-blue-strong);
}

/* ---------- 3 · Fields -----------------------------------------
   Raised paper on a hairline. Functional voice throughout:
   errors are --nb-error + sans — the examiner treatment
   (serif italic + --nb-red) never appears in plumbing. */
.nb-field {
  font-family: var(--nb-sans);
}
.nb-label {
  display: block;
  margin-bottom: var(--nb-s2);
  font-size: var(--nb-text-sm);
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--nb-ink-2);
}
.nb-input,
.nb-select,
.nb-textarea {
  display: block;
  width: 100%;
  padding: 10px var(--nb-s3); /* the documented field padding (DESIGN.md §5) */
  background-color: var(--nb-paper-raised);
  border: 1px solid var(--nb-control-border);
  border-radius: var(--nb-r-md);
  box-shadow: var(--nb-shadow-1);
  color: var(--nb-ink);
  font-family: var(--nb-sans);
  font-size: var(--nb-text-base);
  line-height: 1.5;
  transition:
    border-color var(--nb-dur-1) var(--nb-ease),
    background-color var(--nb-dur-1) var(--nb-ease);
}
.nb-input::placeholder,
.nb-textarea::placeholder {
  color: var(--nb-ink-3); /* ephemeral hint, not content */
}
.nb-input:hover:not(:disabled):not(:focus),
.nb-select:hover:not(:disabled):not(:focus),
.nb-textarea:hover:not(:disabled):not(:focus) {
  border-color: var(--nb-border-strong);
}
html[class~="theme-light"] .nb-input:hover:not(:disabled):not(:focus),
html[class~="theme-light"] .nb-select:hover:not(:disabled):not(:focus),
html[class~="theme-light"] .nb-textarea:hover:not(:disabled):not(:focus) {
  border-color: var(--nb-control-border);
}
.nb-input:focus,
.nb-select:focus,
.nb-textarea:focus {
  border-color: var(--nb-blue);
}
.nb-input:disabled,
.nb-select:disabled,
.nb-textarea:disabled {
  background-color: var(--nb-paper-sunken);
  color: var(--nb-ink-2); /* read-only values carry real information */
  box-shadow: none;
  cursor: not-allowed;
}
.nb-textarea {
  resize: vertical;
}

/* Select: native arrow replaced by a token-inked chevron so it
   flips with the theme (the OS arrow can't). */
.nb-select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--nb-s8); /* room for the chevron */
}
.nb-select-wrap {
  position: relative;
}
.nb-select-wrap::after {
  content: "";
  position: absolute;
  top: 50%;
  right: var(--nb-s4);
  width: var(--nb-s2);
  height: var(--nb-s2);
  border-right: 1.5px solid var(--nb-ink-2);
  border-bottom: 1.5px solid var(--nb-ink-2);
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none;
}

.nb-field--error .nb-input,
.nb-field--error .nb-select,
.nb-field--error .nb-textarea {
  border-color: var(--nb-error);
}
.nb-field-error {
  margin-top: var(--nb-s2);
  color: var(--nb-error);
  font-size: var(--nb-text-sm);
  font-weight: 500;
}
.nb-field-hint {
  margin-top: var(--nb-s2);
  color: var(--nb-ink-2);
  font-size: var(--nb-text-sm);
}

/* ---------- 4 · Chips ------------------------------------------
   Small neutral label. Programme/subject identity is TEXT here —
   the candy accent palette is retired (DESIGN.md §2). */
.nb-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--nb-s1);
  padding: var(--nb-s1) var(--nb-s3);
  background: var(--nb-paper-sunken);
  border: 1px solid var(--nb-border);
  border-radius: var(--nb-r-pill);
  color: var(--nb-ink-2);
  font-family: var(--nb-sans);
  font-size: var(--nb-text-sm);
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
}

/* ---------- 5 · Index tabs -------------------------------------
   The notebook's edge tabs: flat bottom, rounded top, sitting on
   the page-edge rule. Active = filled with the student's pen. */
.nb-tabs {
  display: flex;
  align-items: flex-end;
  gap: var(--nb-s1);
  border-bottom: 1px solid var(--nb-border);
}
.nb-tab {
  padding: var(--nb-s2) 14px; /* the documented index-tab padding (DESIGN.md §5) */
  white-space: nowrap; /* a tab label never wraps mid-phrase ("A Level") */
  text-decoration: none; /* the tab is a button OR a nav link */
  background: var(--nb-paper-sunken);
  border: 1px solid var(--nb-border);
  border-bottom: none;
  border-radius: var(--nb-r-md) var(--nb-r-md) 0 0;
  color: var(--nb-ink-2);
  font-family: var(--nb-sans);
  font-size: var(--nb-text-sm);
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  transition:
    background-color var(--nb-dur-1) var(--nb-ease),
    color var(--nb-dur-1) var(--nb-ease),
    transform var(--nb-dur-1) var(--nb-ease);
}
.nb-tab:hover:not(.nb-tab--active) {
  color: var(--nb-ink);
  transform: translateY(-1px); /* the tab eases out of the notebook edge */
}
.nb-tab--active {
  background: var(--nb-selection-fill);
  border-color: var(--nb-selection-border);
  color: var(--nb-selection-ink);
  box-shadow: inset 0 -3px 0 var(--nb-selection-marker);
}

/* ---------- 6 · Breadcrumb ------------------------------------- */
.nb-breadcrumb ol {
  display: flex;
  /* Prefer one line; still wraps on genuinely narrow columns / very long
     topic names. Tight gap + trimmed tracking keep the full trail on one
     row even in the narrower flashcard/question reading columns. */
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nb-s1);
  margin: 0;
  padding: 0;
  list-style: none;
}
.nb-breadcrumb li {
  display: inline-flex;
  align-items: center;
  gap: var(--nb-s1);
  font-family: var(--nb-sans);
  font-size: var(--nb-text-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--nb-ink-2); /* small text: the 4.5:1 tier, never ink-3 */
}
.nb-breadcrumb li + li::before {
  content: "·";
  color: var(--nb-ink-3); /* decorative separator */
}
.nb-breadcrumb a {
  color: inherit;
  text-decoration: none;
  border-radius: var(--nb-r-sm);
  transition: color var(--nb-dur-1) var(--nb-ease);
}
.nb-breadcrumb a:hover {
  color: var(--nb-blue);
}
.nb-breadcrumb [aria-current="page"] {
  color: var(--nb-ink);
}

/* ---------- 7 · Highlighter ------------------------------------
   The one sanctioned wash: a hard stop riding the lower 40% of
   the line, like a real highlighter swipe (DESIGN.md §5).
   Clone keeps the wash on every wrapped line. */
.nb-highlight {
  background: linear-gradient(transparent 60%, var(--nb-hl) 60%);
  color: inherit;
  padding: 0 0.15em;
  margin: 0 -0.1em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* ---------- 8 · Examiner marks ---------------------------------
   --nb-red and Vollkorn italic travel together: judgment moments
   ONLY. Nothing here is ever used for functional errors. */
.nb-mark {
  display: inline-block;
  font-family: var(--nb-serif);
  font-size: var(--nb-text-lg);
  line-height: 1;
  color: var(--nb-red);
  transform: rotate(-4deg); /* the hand never stamps perfectly straight */
}
.nb-mark-note {
  font-family: var(--nb-serif);
  font-style: italic;
  font-size: var(--nb-text-md);
  line-height: 1.5;
  color: var(--nb-red);
}
.nb-allocation {
  font-family: var(--nb-serif);
  font-style: italic;
  font-weight: 600;
  font-size: var(--nb-text-xs);
  color: var(--nb-red);
  white-space: nowrap;
}

/* ---------- 9 · Cards -------------------------------------------
   A raised sheet of paper on the gridded page. Rest = shadow-1;
   only LINK cards answer hover (shadow-2 + the 1px lift) — a
   static sheet never pretends to be pressable. Radius is the
   card step, --nb-r-lg (DESIGN.md §4). */
.nb-card {
  display: block;
  padding: var(--nb-s5) var(--nb-s6); /* the documented card padding (DESIGN.md §5) */
  background: var(--nb-paper-raised);
  border: 1px solid var(--nb-border);
  border-radius: var(--nb-r-lg);
  box-shadow: var(--nb-shadow-1);
  font-family: var(--nb-sans);
  color: var(--nb-ink);
}
a.nb-card {
  text-decoration: none;
  transition:
    box-shadow var(--nb-dur-1) var(--nb-ease),
    transform var(--nb-dur-1) var(--nb-ease);
}
a.nb-card:hover {
  box-shadow: var(--nb-shadow-2);
  transform: translateY(-1px); /* the sheet lifts off the desk */
}

/* Topic card internals — the style tile's section 4, faithfully:
   blue caps eyebrow, sans 700 title, ink-fill line, meta row with
   the serif-italic mastery note in the STUDENT's own pen (blue —
   it is the student's margin note, not the examiner's). */
.nb-card-eyebrow {
  display: block;
  font-size: var(--nb-text-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--nb-blue);
}
.nb-card-title {
  display: block;
  margin-top: var(--nb-s1);
  font-size: var(--nb-text-lg);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.3;
  color: var(--nb-ink);
}
.nb-card--topic .nb-progress {
  margin-top: var(--nb-s3);
}
.nb-card-meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--nb-s3);
  margin-top: var(--nb-s2);
  font-size: var(--nb-text-sm);
  color: var(--nb-ink-2); /* small text: the 4.5:1 tier, never ink-3 */
}
.nb-card-mastery {
  font-family: var(--nb-serif);
  font-style: italic;
  color: var(--nb-blue);
  white-space: nowrap;
}

/* ---------- 10 · Ink-fill progress ------------------------------
   THE signature. Progress is a line filling with ink: a 3px track
   (the documented signature height, DESIGN.md §5), a blue fill
   scaling out from the left, and an 8px pen-nib dot riding the
   tip. The fraction comes from --nb-progress (0-1, set inline);
   the ink flows when .nb-is-inked lands on the bar or an ancestor.
   Reduced motion zeroes --nb-dur-3 → the ink snaps into place.

   Why the nib is NOT a counter-scaled child of the fill: at rest
   the fill is scaleX(0), so any child collapses with it, and mid-
   transition a constant counter-scale cannot cancel the animating
   parent scale — the dot would squash into an ellipse. Instead a
   full-width rider layer translates by the same fraction the fill
   scales by; identical duration + easing keeps the dot locked to
   the ink tip, and it never deforms.

   Markup contract:
     <div class="nb-progress" role="progressbar" style="--nb-progress: .68">
       <span class="nb-progress-fill"></span>
       <span class="nb-progress-nib" aria-hidden="true"></span>
     </div> */
.nb-progress {
  position: relative;
  height: 3px;
  background: var(--nb-border);
  border-radius: var(--nb-r-pill);
}
.nb-progress-fill {
  position: absolute;
  inset: 0;
  background: var(--nb-blue);
  border-radius: var(--nb-r-pill);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--nb-dur-3) var(--nb-ease);
}
.nb-progress-nib {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* The rider anchors its RIGHT edge on the ink tip, so the unused
     span hangs LEFT of the bar — left overspill never widens the
     page's scrollable area (right overspill did, at phone widths). */
  transform: translateX(-100%);
  transition: transform var(--nb-dur-3) var(--nb-ease);
}
.nb-progress-nib::after {
  content: "";
  position: absolute;
  top: 50%;
  right: calc(-1 * var(--nb-s1)); /* dot centre sits on the ink tip */
  width: var(--nb-s2);           /* the 8px nib */
  height: var(--nb-s2);
  margin-top: calc(-1 * var(--nb-s1));
  border-radius: var(--nb-r-pill);
  background: var(--nb-blue);
}
/* descendant selector covers .nb-is-inked on the bar itself too */
.nb-is-inked .nb-progress-fill {
  transform: scaleX(var(--nb-progress, 0));
}
.nb-is-inked .nb-progress-nib {
  transform: translateX(calc((var(--nb-progress, 0) - 1) * 100%));
}

/* ---------- 11 · Self-drawing tick ------------------------------
   A checkmark that draws itself like a pen stroke: the path hides
   behind a full-length dash and .nb-is-drawn pulls the offset to
   zero over --nb-dur-2 (reduced motion: 0ms → it snaps). Ink comes
   from currentColor, so context picks the pen: --nb-red at
   judgment moments, --nb-success for plain UI confirmations.

   Markup contract (24×24 viewBox, canonical stroke ≈23.4 long):
     <svg class="nb-tick" viewBox="0 0 24 24" aria-hidden="true">
       <path class="nb-tick-path" d="M4 12.5 L9.5 18 L20 6.5"/>
     </svg> */
.nb-tick {
  display: inline-block;
  width: var(--nb-s5);
  height: var(--nb-s5);
  flex-shrink: 0;
  vertical-align: -0.2em;
}
.nb-tick-path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 24;  /* covers the canonical ≈23.4 path length */
  stroke-dashoffset: 24; /* fully hidden until drawn */
  transition: stroke-dashoffset var(--nb-dur-2) var(--nb-ease);
}
.nb-is-drawn .nb-tick-path {
  stroke-dashoffset: 0;
}

/* ---------- 12 · Callouts ---------------------------------------
   Quiet paper asides — NO left accent border (banned sitewide).
   --note is the student's study tip: blue wash, sans voice.
   --examiner is a judgment aside: red wash + the serif italic
   voice, stamped with the rotated tick (compose an .nb-mark in).
   Hairlines are the pen at low strength, like the secondary
   button's outline. */
.nb-callout {
  display: flex;
  align-items: flex-start;
  gap: var(--nb-s3);
  padding: var(--nb-s4) var(--nb-s5);
  background: var(--nb-paper-sunken);
  border: 1px solid var(--nb-border);
  border-radius: var(--nb-r-md);
  font-family: var(--nb-sans);
  font-size: var(--nb-text-base);
  line-height: 1.6;
  color: var(--nb-ink);
}
.nb-callout--note {
  background: var(--nb-blue-wash);
  border-color: color-mix(in srgb, var(--nb-blue) 25%, transparent);
}
.nb-callout--examiner {
  background: var(--nb-red-wash);
  border-color: color-mix(in srgb, var(--nb-red) 25%, transparent);
  font-family: var(--nb-serif);
  font-style: italic;
  font-size: var(--nb-text-md);
  line-height: 1.5;
  color: var(--nb-red);
}
.nb-callout--examiner .nb-mark {
  font-size: var(--nb-text-md); /* stamp scaled to the note text */
  margin-top: var(--nb-s1);     /* optically on the first baseline */
}

/* ---------- 13 · Empty state ------------------------------------
   Designed silence, never a bare "nothing here": a hollow nib dot
   (a pen that has not touched the page yet), one serif-italic
   line in the notebook's own hand, one quiet way forward. */
.nb-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--nb-s4);
  padding: var(--nb-s9) var(--nb-s6);
  text-align: center;
}
.nb-empty-glyph {
  width: var(--nb-s3);
  height: var(--nb-s3);
  border: 1.5px solid var(--nb-border-strong);
  border-radius: var(--nb-r-pill);
}
.nb-empty-note {
  max-width: 44ch;
  font-family: var(--nb-serif);
  font-style: italic;
  font-size: var(--nb-text-md);
  line-height: 1.5;
  color: var(--nb-ink-2);
}

/* DEBUG-only specimen: notebook_demo.html still consumes this component; live study chrome uses .topbar. */
/* ---------- 14 · Navbar -----------------------------------------
   The top chrome: a raised sheet whose bottom hairline is the
   notebook's top edge — the programme links sit cleanly in its center,
   with only the current programme taking the blue-pill state. Grid keeps
   the tab strip truly
   centered whatever the side clusters weigh. Sticky use (Phase 2)
   adds --nb-shadow-2 only WHILE stuck — at rest the bar lies flat
   on the page (Lift-Is-Feedback). */
.nb-navbar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--nb-s4);
  min-height: var(--nb-s10); /* 64px chrome height */
  padding: 0 var(--nb-s5);
  background: var(--nb-paper-raised);
  border-bottom: 1px solid var(--nb-border);
  font-family: var(--nb-sans);
}

/* Wordmark: sans 700, quiet two-ink split — "Exam" written in ink,
   "StudyAid" in the student's own pen. No glyph, no glow. */
.nb-logo {
  justify-self: start;
  font-size: var(--nb-text-lg);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.2;
  color: var(--nb-ink);
  text-decoration: none;
  white-space: nowrap;
  border-radius: var(--nb-r-sm); /* the focus ring hugs the mark */
}
.nb-logo-accent {
  color: var(--nb-blue);
}

.nb-navbar-tabs {
  grid-column: 2;
  align-self: center;
  display: flex;
  align-items: center;
  gap: var(--nb-s1);
}
.nb-navbar-tabs .nb-tab {
  background: none;
  border: none;
  border-radius: var(--nb-r-pill);
  padding: 7px 16px;
  color: var(--nb-ink-2);
}
.nb-navbar-tabs .nb-tab:hover:not(.nb-tab--active) {
  color: var(--nb-blue);
  background: var(--nb-blue-wash);
  transform: none;
}
.nb-navbar-tabs .nb-tab--active {
  background: var(--nb-selection-fill);
  color: var(--nb-selection-ink);
  font-weight: 700;
  box-shadow:
    var(--nb-shadow-1),
    inset 0 -3px 0 var(--nb-selection-marker),
    inset 0 0 0 1px var(--nb-selection-border);
}

.nb-navbar-actions {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: var(--nb-s2);
}

/* Mobile collapse: logo + primary CTA + the hamburger. */
.nb-navbar--compact {
  display: flex;
  justify-content: space-between;
}
.nb-navbar-burger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--nb-s8); /* 40px hit target */
  height: var(--nb-s8);
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--nb-r-sm);
  color: var(--nb-blue); /* interactive = the student's pen */
  cursor: pointer;
  transition:
    background-color var(--nb-dur-1) var(--nb-ease),
    color var(--nb-dur-1) var(--nb-ease);
}
.nb-navbar-burger:hover {
  color: var(--nb-blue-strong);
  background: var(--nb-blue-wash);
}
/* The glyph is drawn, not iconed: two border strokes plus one
   painted line — no icon font, no SVG sprite, no shadow hack. */
.nb-burger-glyph {
  display: block;
  width: var(--nb-s4);
  height: var(--nb-s3);
  border-top: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
}
.nb-burger-glyph::before {
  content: "";
  display: block;
  height: 2px;
  margin-top: 3px; /* optical: centers the middle stroke in the 12px glyph */
  background: currentColor;
}

/* ---------- 15 · Footer -----------------------------------------
   The notebook's back cover: sunken paper under a hairline rule.
   Links follow the breadcrumb grammar — quiet ink that answers in
   blue. The serif-italic tagline is the one editorial accent. */
.nb-footer {
  padding: var(--nb-s8) var(--nb-s6) var(--nb-s5);
  background: var(--nb-paper-sunken);
  border-top: 1px solid var(--nb-border);
  font-family: var(--nb-sans);
  color: var(--nb-ink);
}
.nb-footer-main {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) 1fr 1fr;
  gap: var(--nb-s7);
}
@media (max-width: 720px) {
  .nb-footer-main {
    grid-template-columns: 1fr;
    gap: var(--nb-s6);
  }
}
.nb-footer-tagline {
  margin-top: var(--nb-s2);
  max-width: 30ch;
  font-family: var(--nb-serif);
  font-style: italic;
  font-size: var(--nb-text-md);
  line-height: 1.5;
  color: var(--nb-ink-2);
}
.nb-footer-heading {
  margin-bottom: var(--nb-s3);
  font-size: var(--nb-text-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--nb-ink-2);
}
.nb-footer-links {
  display: grid;
  gap: var(--nb-s2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.nb-footer-links a {
  color: var(--nb-ink-2); /* small text: the 4.5:1 tier */
  font-size: var(--nb-text-sm);
  font-weight: 500;
  text-decoration: none;
  border-radius: var(--nb-r-sm);
  transition: color var(--nb-dur-1) var(--nb-ease);
}
.nb-footer-links a:hover {
  color: var(--nb-blue);
}
.nb-footer-legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--nb-s3);
  margin-top: var(--nb-s7);
  padding-top: var(--nb-s4);
  border-top: 1px solid var(--nb-border);
  font-size: var(--nb-text-xs);
  color: var(--nb-ink-2);
}
.nb-footer-legal a {
  color: inherit;
  text-decoration: none;
  border-radius: var(--nb-r-sm);
  transition: color var(--nb-dur-1) var(--nb-ease);
}
.nb-footer-legal a:hover {
  color: var(--nb-blue);
}
.nb-footer-legal-sep {
  color: var(--nb-ink-3); /* decorative separator */
}

/* ---------- 16 · Chapter rail ------------------------------------
   The sidebar as the notebook's edge: the nb-tab grammar turned
   vertical. The rail's right rule is the page spine; every tab
   keeps its flat right edge fused to it (rounded LEFT, border-
   right: none) and eases OUT of the edge on hover — translateX(-1px),
   the vertical twin of the horizontal tab's -1px lift. */
.nb-rail {
  width: 290px; /* the rail's chrome width (Phase 2 layout) */
  max-width: 100%;
  flex-shrink: 0;
  font-family: var(--nb-sans);
}
.nb-rail-head {
  padding: 0 var(--nb-s4) var(--nb-s5) 0;
}
.nb-rail-eyebrow {
  display: block;
  font-size: var(--nb-text-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--nb-blue);
}
.nb-rail-title {
  display: block;
  margin-top: var(--nb-s1);
  font-family: var(--nb-sans);
  font-weight: 600;
  font-size: var(--nb-text-lg);
  line-height: 1.3;
  color: var(--nb-ink);
}
.nb-rail-tabs {
  display: flex;
  flex-direction: column;
  gap: var(--nb-s2);
  padding: var(--nb-s2) 0;
  border-right: 1px solid var(--nb-border); /* the page spine */
}
.nb-rail-tab {
  display: grid;
  grid-template-columns: auto 1fr auto;
  column-gap: var(--nb-s3);
  row-gap: var(--nb-s2);
  align-items: baseline;
  padding: var(--nb-s3) var(--nb-s4);
  background: var(--nb-paper-sunken);
  border: 1px solid var(--nb-border);
  border-right: none; /* flat edge fused to the spine */
  border-radius: var(--nb-r-md) 0 0 var(--nb-r-md);
  text-decoration: none;
  transition:
    background-color var(--nb-dur-1) var(--nb-ease),
    border-color var(--nb-dur-1) var(--nb-ease),
    transform var(--nb-dur-1) var(--nb-ease);
}
.nb-rail-tab-num {
  font-size: var(--nb-text-xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--nb-ink-2);
}
.nb-rail-tab-name {
  font-size: var(--nb-text-sm);
  font-weight: 600;
  line-height: 1.35;
  color: var(--nb-ink-2); /* small text: the 4.5:1 tier */
  transition: color var(--nb-dur-1) var(--nb-ease);
}
.nb-rail-tab .nb-progress {
  grid-column: 2 / -1; /* the mastery line runs under the name */
  align-self: center;
}
.nb-rail-tab:hover:not(.nb-rail-tab--active) {
  transform: translateX(-1px); /* the tab eases out of the notebook edge */
}
.nb-rail-tab:hover:not(.nb-rail-tab--active) .nb-rail-tab-name {
  color: var(--nb-ink);
}
.nb-rail-tab--active {
  background: var(--nb-selection-fill);
  border-color: var(--nb-selection-border);
  box-shadow: inset 3px 0 0 var(--nb-selection-marker);
}
.nb-rail-tab--active .nb-rail-tab-num,
.nb-rail-tab--active .nb-rail-tab-name {
  color: var(--nb-selection-ink);
}
/* Ink on selection: inside the filled tab the mastery line re-inks in
   the selection voice — track at 30% strength, fill and nib full
   (the same color-mix discipline as the pen outlines). */
.nb-rail-tab--active .nb-progress {
  background: color-mix(in srgb, var(--nb-selection-ink) 30%, transparent);
}
.nb-rail-tab--active .nb-progress-fill,
.nb-rail-tab--active .nb-progress-nib::after {
  background: var(--nb-selection-ink);
}
/* Locked chapter: the serif [Premium] allocation sits where a
   padlock icon would. Quiet ink, not red — navigation is not a
   judgment moment. */
.nb-rail-lock {
  font-family: var(--nb-sans);
  font-style: normal;
  font-weight: 600;
  font-size: var(--nb-text-sm);
  color: var(--nb-ink-2);
  white-space: nowrap;
}

/* ---------- 17 · Paywall -----------------------------------------
   The sealed chapter: one raised sheet resting at --nb-shadow-3
   (the ONE surface allowed modal depth at rest, DESIGN.md §4),
   an editorial serif headline, three drawn ticks in the plain
   success voice, one primary action. The wink: [Premium] marked
   in the corner the way the examiner allocates marks. NO backdrop
   blur — glass is banned; the page behind simply fades (opacity
   on the content itself). */
.nb-paywall {
  position: relative;
  max-width: 460px;
  padding: var(--nb-s7);
  background: var(--nb-paper-raised);
  border: 1px solid var(--nb-border);
  border-radius: var(--nb-r-lg);
  box-shadow: var(--nb-shadow-3);
  font-family: var(--nb-sans);
  color: var(--nb-ink);
}
.nb-paywall-allocation {
  position: absolute;
  top: var(--nb-s4);
  right: var(--nb-s5);
}
.nb-paywall-title {
  padding-right: var(--nb-s8); /* clears the corner allocation */
  font-family: var(--nb-serif);
  font-weight: 600;
  font-size: var(--nb-text-xl);
  line-height: 1.25;
  color: var(--nb-ink);
}
.nb-paywall-lede {
  margin-top: var(--nb-s3);
  font-size: var(--nb-text-base);
  line-height: 1.6;
  color: var(--nb-ink-2);
}
.nb-paywall-list {
  display: grid;
  gap: var(--nb-s3);
  margin: var(--nb-s5) 0 0;
  padding: 0;
  list-style: none;
}
.nb-paywall-item {
  display: flex;
  align-items: flex-start;
  gap: var(--nb-s3);
  font-size: var(--nb-text-base);
  line-height: 1.5;
  color: var(--nb-ink);
}
.nb-paywall-item .nb-tick {
  width: var(--nb-s4);
  height: var(--nb-s4);
  margin-top: 3px; /* optical: seats the 16px tick on the first line */
  color: var(--nb-success);
}
.nb-paywall-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nb-s3);
  margin-top: var(--nb-s6);
}

/* ---------- Mobile ergonomics ------------------------------------
   Touch targets: at phone widths every button and index tab meets
   the 44px minimum hit height. Padding tokens stay untouched — the
   extra height is empty paper. The tab (a button OR a nav link)
   goes inline-flex so anchors honor min-height and the label stays
   centered; nb-btn is already inline-flex + centered. */
@media (max-width: 720px) {
  .nb-btn,
  .nb-tab {
    min-height: 44px;
  }
  .nb-tab {
    display: inline-flex;
    align-items: center;
  }
}
