/* ============================================================
   THE ANNOTATED NOTEBOOK — page shell (Phase 2).
   Everything OUTSIDE the components: the paper itself, shared topbar and
   footer placement, the reading container, and the JS-state
   classes the reused legacy scripts toggle. Those class names
   (.cn-children/.collapsed, html.note-focus-mode, .nt-top-progress,
   .sidebar-*) are FROZEN contracts owned by note-reading.js and
   noteviewer-sidebar.js — restyle, never rename.

   Discipline (test-enforced by pages/tests_notebook.py):
   · zero raw colors — every color enters as var(--nb-*)
   · every class is nb-prefixed OR on the documented contract
     allowlist in NotebookCssDisciplineTests
   ============================================================ */

/* ---------- 1 · The paper ----------------------------------------
   Same reset + dotted-grid pattern the approved demo page carries.
   The grid texture lives on --nb-paper ONLY; raised sheets (topbar,
   cards) sit plain on top of the gridded page. */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  min-height: 100%;
  background-color: var(--nb-paper); /* overscroll shows paper, not UA white */
  /* Programmatic scrolls (flashcards.js scrollIntoView, question-pager
     centerOnOpen) must clear the responsive shared topbar so the breadcrumb /
     eyebrow / H1 / back-link are never sliced under the bar. */
  scroll-padding-top: calc(var(--nb-chrome-h) + var(--nb-s4));
}

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  font-family: var(--nb-sans);
  font-size: var(--nb-text-base);
  line-height: 1.5;
  color: var(--nb-ink);
  background-color: var(--nb-paper);
  background-image: radial-gradient(var(--nb-grid-dot) 1px, transparent 1px);
  background-size: var(--nb-grid-size) var(--nb-grid-size);
}

/* Theme flips are INSTANT (site rule): nb_base's toggle handler adds
   this class for the swap frame only, so colors change all at once
   instead of a staggered per-element sweep. */
html.nb-theme-switching *,
html.nb-theme-switching *::before,
html.nb-theme-switching *::after {
  transition: none !important;
}

/* ---------- 2 · Shared chrome contract ----------------------------
   chrome-navbar.css owns the topbar layout; this shell consumes its height
   token for offsets and fades the shared .topbar during focus mode.
   This theme-independent layer also owns shared chrome typography on the
   isolated notebook base. The legacy-base equivalent lives in the late,
   nb_active-only notebook-typography.css bridge. */
html .topbar {
  font-family: var(--nb-sans);
}
html .topbar > a {
  font: var(--nb-type-title);
  font-weight: 700;
  letter-spacing: -0.02em;
}
html .topbar > nav > a,
html .topbar > div > a,
html #account-btn,
html #mobile-nav-drawer a,
html #mobile-nav-drawer button {
  font: var(--nb-type-control);
}
html .topbar > nav > a[aria-current="page"],
html #mobile-nav-drawer a[aria-current="page"],
html #mobile-nav-drawer .mobile-nav-row--program.is-active {
  font-weight: 700;
}
/* Programme links step one size above the flanking controls — keep in lockstep
   with the legacy-base bridge (notebook-typography.css). Placed after the
   control-role group so the later equal-specificity declaration wins. */
html .topbar > nav > a {
  font-size: var(--nb-text-md);
}
html #account-popup,
html #auth-modal {
  font-family: var(--nb-sans);
}
html #account-popup [class~="account-popup-heading"] {
  font: var(--nb-type-control);
  letter-spacing: normal;
}
html #account-popup [class~="account-popup-email"],
html #account-popup [class~="account-popup-support"],
html #account-popup [class~="account-popup-footer"] {
  font-family: var(--nb-sans);
  font-size: var(--nb-text-sm);
  font-weight: 400;
  line-height: 1.4;
}
html #account-popup a,
html #account-popup button {
  font: var(--nb-type-control);
}
html #account-popup [class~="account-popup-plan-badge"],
html #account-popup [class~="account-popup-link"] {
  font: var(--nb-type-label);
}
html #account-popup [class~="account-popup-action"],
html #account-popup [class~="account-popup-nav-link"],
html #account-popup [class~="account-popup-theme"],
html #account-popup [class~="account-popup-signout"] {
  font: var(--nb-type-control);
}
html #auth-modal [class~="auth-modal-title"] {
  font: var(--nb-type-headline);
  letter-spacing: -0.015em;
}
html #auth-modal [class~="auth-field"] label,
html #auth-modal [class~="acct-identity-label"],
html #auth-modal [class~="acct-plan-label"] {
  font: var(--nb-type-label);
}
html #auth-modal [class~="auth-field"] input {
  font: var(--nb-type-ui);
}
html #auth-modal [class~="auth-modal-close"],
html #auth-modal [class~="google-btn"],
html #auth-modal [class~="auth-btn"] {
  font: var(--nb-type-control);
}
html #auth-modal [class~="auth-divider"] span,
html #auth-modal [class~="auth-field-hint"] {
  font: var(--nb-type-label);
}
html #auth-modal [class~="auth-modal-footer"],
html #auth-modal [class~="auth-modal-footer-link"],
html #auth-modal [class~="auth-modal-switch-btn"],
html #auth-modal [class~="auth-modal-notice"] {
  font: var(--nb-type-ui);
}
html #auth-modal [class~="acct-name"] {
  font: var(--nb-type-title);
}
html #auth-modal [class~="acct-email"],
html #auth-modal [class~="acct-plan-premium-sub"],
html #auth-modal [class~="acct-plan-desc"] {
  font-family: var(--nb-sans);
  font-size: var(--nb-text-sm);
  font-weight: 400;
  line-height: 1.5;
}
html #auth-modal [class~="acct-plan-premium-title"],
html #auth-modal [class~="acct-plan-name"] {
  font: var(--nb-type-control);
}
html #auth-modal [class~="acct-upgrade-btn"],
html #auth-modal [class~="acct-nav-link"],
html #auth-modal [class~="acct-logout-btn"] {
  font: var(--nb-type-control);
}
/* ---------- 3 · Reading container --------------------------------- */
.nb-page-main {
  flex: 1 0 auto; /* pins the footer to the page bottom */
  width: 100%;
  max-width: 860px; /* the demo's reading measure */
  margin: 0 auto;
  padding: var(--nb-s7) var(--nb-s5) var(--nb-s10);
}

/* ---------- 4 · Top viewport progress ------------------------------
   note-reading.js writes width:% onto #nt-top-progress-fill. The bar
   rides above the shared topbar; ink is the student's pen. */
.nt-top-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 1100;
  pointer-events: none;
  background: transparent;
}
.nt-top-progress-fill {
  width: 0;
  height: 100%;
  background: var(--nb-blue);
}

/* ---------- 5 · Focus mode (the calm reading room) -----------------
   note-reading.js toggles html.note-focus-mode. The whole desk clears —
   topbar, rail, footer, breadcrumb, toolbar — and a single reading
   column is set alone on the dotted-grid paper, with a wider vertical
   rhythm and only the thin reading line up top and one
   quiet way back. Section 11 carries the reading-room specifics; this
   block owns the layout collapse. All CSS-only (the JS just flips the
   class). See §11. */
/* The rail sits inside the layout grid, so it must leave the flow entirely —
   the grid folds to a single column below and it would otherwise steal a row. */
html.note-focus-mode .nb-rail {
  display: none;
}
/* The topbar and footer are the chrome the reader watches recede: they FADE
   out rather than snapping away. The animation ends at opacity:0 +
   visibility:hidden (fill-mode forwards) so they stop taking clicks and drop
   from the a11y tree once gone. Duration-only reduced-motion guard zeroes
   --nb-dur-2, making the fade instant with no lingering transform. */
html.note-focus-mode .topbar,
html.note-focus-mode .nb-footer {
  animation: nb-chrome-out var(--nb-dur-2) var(--nb-ease) forwards;
}
@keyframes nb-chrome-out {
  from { opacity: 1; }
  to   { opacity: 0; visibility: hidden; }
}
/* The layout grid folds to one column and the page-main sheds its wide
   study measure so the reading column can sit centered on the paper. */
html.note-focus-mode .nb-page-layout {
  grid-template-columns: minmax(0, 1fr);
}
html.note-focus-mode .nb-page-main:has(.nb-page-layout) {
  max-width: none;
  padding-top: var(--nb-s9);
}

/* ---------- 6 · Sidebar JS contract ---------------------------------
   noteviewer-sidebar.js expands/collapses chapters by toggling
   .collapsed on the .cn-children container (sidebar_tree.html). */
.cn-children.collapsed {
  display: none;
}

/* ---------- 7 · Notes page layout (Task 3) --------------------------
   Rail + reading column. The rail is the notebook's edge (290px, the
   component layer's .nb-rail width); the reading column keeps the
   demo's calm measure. Below 861px the rail folds into the drawer —
   861 is noteviewer-sidebar.js's own breakpoint (syncDrawerForViewport
   force-closes the drawer above 860), so CSS and JS agree exactly. */
/* The rail stays pinned at the page's left edge (owner directive 2026-07-13);
   the reading column then centres inside the track to its right, so the notes
   read balanced instead of jammed hard-left with a vast empty right margin on
   wide screens. Focus mode (§5) drops the rail and centres the lone column. */
.nb-page-main:has(.nb-page-layout) {
  max-width: none;
  margin: 0;
  padding-inline: clamp(20px, 2.5vw, 48px);
}
.nb-page-layout {
  display: grid;
  grid-template-columns: 290px minmax(0, 1fr);
  gap: var(--nb-s9);
  align-items: start;
}
/* The reading column keeps a comfortable ~800px measure and centres inside its
   track (auto margins), so with the desk block centred the notes sit balanced
   rather than tethered hard to the rail. */
.nb-notes-column {
  min-width: 0;
  max-width: 800px;
  margin-inline: auto;
}
@media (max-width: 1100px) {
  .nb-page-layout {
    gap: var(--nb-s6);
  }
}
@media (max-width: 860px) {
  .nb-page-layout {
    grid-template-columns: minmax(0, 1fr);
  }
  .nb-notes-column {
    width: 100%;
    max-width: 100%;
    margin-inline: 0;
  }
  .nb-rail {
    display: none;
  }
  .nb-page-main {
    padding: var(--nb-s6) var(--nb-s4) var(--nb-s9);
  }
}

/* ---------- 8 · Chapter rail restyle ---------------------------------
   The demo's section 15 grammar drawn over the FROZEN sidebar contract:
   sidebar_tree.html markup (.sidebar-toggle/.sidebar-link/.cn-*) is
   included unchanged and restyled here — never renamed. Chapters are
   vertical index tabs fused to the page spine; lessons hang off a
   hairline thread; the active lesson fills with the student's pen.
   No mastery ink-lines in Phase 2 — no per-chapter mastery data exists,
   and the notebook never fakes what it cannot measure. */
.nb-rail {
  position: sticky;
  top: calc(var(--nb-chrome-h) + var(--nb-s6));
  max-height: calc(100vh - var(--nb-chrome-h) - var(--nb-s7));
  overflow-y: auto;
  padding-bottom: var(--nb-s6);
}

/* Custom scrollbar for the two chapter scroll containers — the sticky rail
   (desktop) and the drawer body (mobile). Owner pick 2026-07-03 (demo 15b,
   treatment B "student's margin"): HIDDEN AT REST — the rail reads as clean
   paper — and a slim blue thumb appears only while the pointer (or focus) is
   over the rail. Firefox uses the two-value scrollbar-color (thumb track);
   WebKit/Chromium uses the pseudo-elements below. Tokens only. */
.nb-rail,
.nb-rail-drawer-scroll {
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
}
.nb-rail:hover,
.nb-rail:focus-within,
.nb-rail-drawer-scroll:hover,
.nb-rail-drawer-scroll:focus-within {
  scrollbar-color: var(--nb-blue) transparent;
}
.nb-rail::-webkit-scrollbar,
.nb-rail-drawer-scroll::-webkit-scrollbar {
  width: 5px;
}
.nb-rail::-webkit-scrollbar-track,
.nb-rail-drawer-scroll::-webkit-scrollbar-track {
  background: transparent;
}
.nb-rail::-webkit-scrollbar-thumb,
.nb-rail-drawer-scroll::-webkit-scrollbar-thumb {
  background: transparent;
  border-radius: var(--nb-r-pill);
}
.nb-rail:hover::-webkit-scrollbar-thumb,
.nb-rail:focus-within::-webkit-scrollbar-thumb,
.nb-rail-drawer-scroll:hover::-webkit-scrollbar-thumb,
.nb-rail-drawer-scroll:focus-within::-webkit-scrollbar-thumb {
  background: var(--nb-blue);
}
.nb-rail::-webkit-scrollbar-thumb:hover,
.nb-rail-drawer-scroll::-webkit-scrollbar-thumb:hover {
  background: var(--nb-blue-strong);
}

.nb-rail-label {
  margin: 0 0 var(--nb-s3);
  font: var(--nb-type-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--nb-ink-2);
}
/* The chapters belong to the subject above them, so the label sits close
   under the header. "Study this topic" is a separate group and gets its own
   air (§ .nb-rail-siblings below). */
.nb-rail-siblings {
  margin-top: var(--nb-s7);
}

/* The chapters column carries the page spine on its right edge. */
.nb-rail-chapters {
  border-right: 1px solid var(--nb-border);
  padding: var(--nb-s2) 0;
}
.nb-rail-chapters .sidebar-tree {
  display: flex;
  flex-direction: column;
  gap: var(--nb-s2);
}

/* Chapter head = one vertical index tab: rounded left, flat right,
   fused to the spine; eases OUT of the edge on hover (the vertical
   twin of the horizontal tab's -1px lift). */
.nb-rail-chapters .sidebar-toggle {
  display: flex;
  align-items: center;
  gap: var(--nb-s2);
  width: 100%;
  text-align: left;
  font-family: var(--nb-sans);
  cursor: pointer;
}
.nb-rail-chapters .cn-chapter-head {
  padding: var(--nb-s3) var(--nb-s3) 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);
  transition:
    background-color var(--nb-dur-1) var(--nb-ease),
    transform var(--nb-dur-1) var(--nb-ease);
}
.nb-rail-chapters .cn-chapter-head:hover {
  transform: translateX(-1px);
}
.nb-rail-chapters .cn-chapter-head:hover .cn-chapter-title {
  color: var(--nb-ink);
}
.nb-rail-chapters .cn-chapter-head.open {
  background: var(--nb-paper-raised);
}
.nb-rail-chapters .cn-chapter-head.open .cn-chapter-title {
  color: var(--nb-ink);
}
/* The chapter holding the page you are on writes its number in pen. */
.nb-rail-chapters .cn-chapter:has(.sidebar-link.is-active) > .cn-chapter-head .cn-chip--num,
.nb-rail-chapters .cn-chapter:has(.sidebar-link.is-active) > .cn-chapter-head .cn-chapter-num {
  color: var(--nb-blue);
}

/* Chapter numbers: quiet tabular ink. The icon-chip variant is retired
   notebook-wide (no candy icons) — hide it; the number variant stays. */
.nb-rail-chapters .cn-chip {
  display: none;
}
.nb-rail-chapters .cn-chip--num {
  display: inline-block;
  min-width: 1.5em; /* aligns single- and double-digit chapter numbers */
  background: none;
  border: none;
  padding: 0;
  text-align: right;
  font: var(--nb-type-label);
  font-variant-numeric: tabular-nums;
  color: var(--nb-ink-2); /* small text stays on the 4.5:1 ink tier */
}
.nb-rail-chapters .cn-chapter-num {
  min-width: 1.5em;
  text-align: right;
  font: var(--nb-type-label);
  font-variant-numeric: tabular-nums;
  color: var(--nb-ink-2);
}
.nb-rail-chapters .cn-chapter-title {
  flex: 1 1 auto;
  font: var(--nb-type-control);
  color: var(--nb-ink-2);
  transition: color var(--nb-dur-1) var(--nb-ease);
}

/* Chevron: drawn, quiet, turns when the chapter opens. */
.nb-rail-chapters .cn-chevron {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--nb-ink-3);
  transition: transform var(--nb-dur-1) var(--nb-ease);
}
.nb-rail-chapters .cn-chevron svg {
  width: 14px;
  height: 14px;
}
.nb-rail-chapters .sidebar-toggle.open .cn-chevron {
  transform: rotate(90deg);
}

/* Locked chapter: a bare, quiet padlock (owner pick 2026-07-03, demo 15b mix
   — the gold "Premium" pill read cheap). The markup's stroke padlock SVG
   (.cn-lock) is un-retired as the single per-row marker, in quiet ink; the
   word "Premium" lives once in the free/locked divider below. The gold
   .cn-badge pill is retired on chapter heads. */
.nb-rail-chapters .cn-chapter-head .cn-lock {
  display: inline-block;
  width: 14px;
  height: 14px;
  margin-left: auto;            /* trail to the row's edge, before the chevron */
  flex-shrink: 0;
  color: var(--nb-ink-3);
}
.nb-rail-chapters .cn-chapter-head .cn-badge {
  display: none;
}
/* Nested sub-groups (rare 3+ level content) have no .cn-lock in their frozen
   markup — their .cn-badge is restyled from gold pill to the same bare quiet
   padlock, drawn in CSS: ::before the shackle, ::after the body. */
.nb-rail-chapters .cn-subgroup-head .cn-badge {
  position: relative;
  display: inline-block;
  width: 14px;
  height: 14px;
  margin-left: auto;
  flex-shrink: 0;
  color: var(--nb-ink-3);
}
.nb-rail-chapters .cn-subgroup-head .cn-badge > span {
  /* "Premium" stays for screen readers only */
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}
.nb-rail-chapters .cn-subgroup-head .cn-badge::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 0;
  width: 8px;
  height: 6px;
  border: 1.5px solid currentColor;
  border-bottom: none;
  border-radius: var(--nb-r-pill) var(--nb-r-pill) 0 0;
}
.nb-rail-chapters .cn-subgroup-head .cn-badge::after {
  content: "";
  position: absolute;
  left: 1px;
  top: 5px;
  width: 12px;
  height: 9px;
  background: currentColor;
}
/* The crown SVG and the legacy timeline dot stay retired. */
.nb-rail-chapters .cn-badge-icon,
.nb-rail-chapters .cn-node {
  display: none;
}
/* ONE quiet boundary where the free chapters end (owner pick: demo B) — a
   centered small-caps PREMIUM rule on the first locked chapter that follows
   an unlocked one. Per-row pills are retired; rows below stay clean. */
.nb-rail-chapters .cn-chapter:not(.cn-chapter--locked) + .cn-chapter--locked::before {
  content: "Premium";
  display: block;
  margin: var(--nb-s3) var(--nb-s2) var(--nb-s2);
  text-align: center;
  font: var(--nb-type-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--nb-ink-2);
  background:
    linear-gradient(var(--nb-border-strong), var(--nb-border-strong)) no-repeat left center / calc(50% - 46px) 1px,
    linear-gradient(var(--nb-border-strong), var(--nb-border-strong)) no-repeat right center / calc(50% - 46px) 1px;
}
.nb-rail-chapters .cn-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Lessons hang off a hairline thread inside the open chapter. */
.nb-rail-chapters .cn-timeline {
  display: flex;
  flex-direction: column;
  gap: var(--nb-s1);
  margin: var(--nb-s2) var(--nb-s2) var(--nb-s3) var(--nb-s4);
  padding-left: var(--nb-s3);
  border-left: 1px solid var(--nb-border); /* structural hairline, not an accent */
}
.nb-rail-chapters .cn-timeline--nested {
  margin: var(--nb-s1) 0 var(--nb-s2) var(--nb-s2);
}

/* 3-level nesting: the sub-group head is a quieter toggle between
   chapter tab and lesson rows (the proof leaf is 3 levels deep). */
.nb-rail-chapters .cn-subgroup-head {
  padding: var(--nb-s2);
  background: transparent;
  border: none;
  border-radius: var(--nb-r-sm);
  transition: color var(--nb-dur-1) var(--nb-ease);
}
.nb-rail-chapters .cn-subgroup-title {
  flex: 1 1 auto;
  font: var(--nb-type-control);
  color: var(--nb-ink-2);
}
.nb-rail-chapters .cn-subgroup-head:hover .cn-subgroup-title {
  color: var(--nb-ink);
}

/* Lesson rows: quiet ink at rest; hover answers in the pen's wash;
   the ACTIVE lesson fills with the student's pen (contract class). */
.nb-rail-chapters .sidebar-link {
  display: flex;
  align-items: baseline;
  gap: var(--nb-s2);
  padding: var(--nb-s2) var(--nb-s3);
  border-radius: var(--nb-r-sm);
  font: var(--nb-type-control);
  color: var(--nb-ink-2);
  text-decoration: none;
  transition:
    background-color var(--nb-dur-1) var(--nb-ease),
    color var(--nb-dur-1) var(--nb-ease);
}
.nb-rail-chapters .sidebar-link:hover {
  background: var(--nb-blue-wash);
  color: var(--nb-ink);
}
.nb-rail-chapters .cn-lesson-num {
  font: var(--nb-type-label);
  font-variant-numeric: tabular-nums;
  color: var(--nb-ink-2);
}
.nb-rail-chapters .cn-lesson-title {
  flex: 1 1 auto;
}
.nb-rail-chapters .sidebar-link.is-active {
  background: var(--nb-selection-fill);
  color: var(--nb-selection-ink);
  font-weight: 600;
  box-shadow:
    inset 3px 0 0 var(--nb-selection-marker),
    inset 0 0 0 1px var(--nb-selection-border);
}
.nb-rail-chapters .sidebar-link.is-active .cn-lesson-num {
  color: var(--nb-selection-ink);
}
/* Premium lesson: the same bare padlock as chapters (owner pick 2026-07-03),
   sized for the dense list — the markup's own stroke SVG, quiet ink, trailing
   the row. The gold "Premium" chip is retired. */
.nb-rail-chapters .sidebar-link.is-paid .cn-lock {
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-left: auto;
  flex-shrink: 0;
  align-self: center; /* the row aligns to baseline; the glyph centers */
  color: var(--nb-ink-3);
}

/* Free-user conversion card at the rail foot (owner-approved, demo 15b B).
   Rendered by nb_rail_sidebar.html only when the viewer has no subscription;
   the primary button is the one blue CTA in the rail. */
.nb-rail-cta {
  margin-top: var(--nb-s6);
  padding: var(--nb-s4);
  background: var(--nb-paper-raised);
  border: 1px solid var(--nb-border);
  border-radius: var(--nb-r-md);
}
.nb-rail-cta-title {
  margin: 0 0 var(--nb-s1);
  font: var(--nb-type-label);
  color: var(--nb-ink);
}
.nb-rail-cta-sub {
  margin: 0 0 var(--nb-s3);
  font: var(--nb-type-ui);
  color: var(--nb-ink-2);
}
.nb-rail-cta .nb-btn {
  width: 100%;
  box-sizing: border-box;
  justify-content: center;
}

/* Focus ring for every interactive piece the rail restyles. */
.nb-rail-chapters .sidebar-toggle:focus-visible,
.nb-rail-chapters .sidebar-link:focus-visible,
.nb-rail-sibling:focus-visible,
.nb-rail-trigger:focus-visible,
.nb-rail-drawer-close:focus-visible,
.nb-focus-exit:focus-visible {
  outline: 2px solid var(--nb-blue);
  outline-offset: 2px;
}

/* Study this topic — links to the OTHER core resources; every entry is
   pre-filtered server-side, but if all three fall away (fuzzy siblings)
   the label would float alone, so hide the group on an empty list. */
.nb-rail-siblings:has(.nb-rail-sibling-list:empty) {
  display: none;
}
.nb-rail-sibling-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--nb-s1);
}
.nb-rail-sibling {
  display: block;
  padding: var(--nb-s1) var(--nb-s3);
  border-radius: var(--nb-r-sm);
  font: var(--nb-type-control);
  color: var(--nb-ink-2);
  text-decoration: none;
  transition:
    background-color var(--nb-dur-1) var(--nb-ease),
    color var(--nb-dur-1) var(--nb-ease);
}
.nb-rail-sibling:hover {
  color: var(--nb-ink);
  background: var(--nb-blue-wash);
}

/* ---------- 9 · Mobile drawer + trigger ------------------------------
   noteviewer-sidebar.js owns the behavior (.is-open, aria, body lock);
   this is only the paper. The scrim is a sheet of tracing paper — the
   page dims toward --nb-paper, never a black glass wash. */
.nb-rail-trigger {
  display: none;
  position: fixed;
  left: var(--nb-s5);
  bottom: var(--nb-s5);
  z-index: 120;
  align-items: center;
  gap: var(--nb-s2);
  padding: 10px var(--nb-s4); /* the documented button padding */
  background: var(--nb-paper-raised);
  border: 1px solid var(--nb-border);
  border-radius: var(--nb-r-pill);
  box-shadow: var(--nb-shadow-2); /* floating chrome rides above the page */
  color: var(--nb-blue);
  font: var(--nb-type-control);
  cursor: pointer;
  transition: opacity var(--nb-dur-2) var(--nb-ease),
              transform var(--nb-dur-2) var(--nb-ease);
}
@media (max-width: 860px) {
  .nb-rail-trigger {
    display: inline-flex;
    position: static;
    justify-self: start;
    min-block-size: 44px; /* touch target */
  }
}
/* When the footer scrolls into view the fixed trigger would sit on top of the
   .nb-footer wordmark. A nonce'd IntersectionObserver in nb_base.html adds
   .nb-rail-trigger--tucked to lift it clear (still tappable mid-page). */
.nb-rail-trigger--tucked {
  opacity: 0;
  transform: translateY(140%);
  pointer-events: none;
}
@media (max-width: 860px) {
  /* The footer observer still emits its historical fixed-control state. The
     compact trigger now lives in flow, so that state must be inert here. */
  .nb-rail-trigger--tucked {
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
}

.nb-rail-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1200;
  background: color-mix(in srgb, var(--nb-paper) 65%, transparent);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--nb-dur-2) var(--nb-ease);
}
.nb-rail-backdrop.is-open {
  opacity: 1;
  pointer-events: auto;
}

.nb-rail-drawer {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 1210;
  width: min(330px, 88vw);
  display: flex;
  flex-direction: column;
  background: var(--nb-paper-raised);
  border-right: 1px solid var(--nb-border);
  box-shadow: var(--nb-shadow-3); /* the one lifted sheet while open */
  transform: translateX(-102%);
  transition: transform var(--nb-dur-2) var(--nb-ease);
}
.nb-rail-drawer.is-open {
  transform: translateX(0);
}
.nb-rail-drawer-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--nb-s3);
  padding: var(--nb-s5) var(--nb-s5) var(--nb-s4);
  border-bottom: 1px solid var(--nb-border);
}
.nb-rail-drawer .nb-rail-head {
  padding: 0;
}
.nb-rail-drawer-close {
  display: inline-flex; /* flex centering — grid does not center a <button> */
  align-items: center;
  justify-content: center;
  width: var(--nb-s8);
  height: var(--nb-s8);
  flex-shrink: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--nb-r-sm);
  color: var(--nb-ink-2);
  cursor: pointer;
  transition:
    background-color var(--nb-dur-1) var(--nb-ease),
    color var(--nb-dur-1) var(--nb-ease);
}
.nb-rail-drawer-close:hover {
  color: var(--nb-blue);
  background: var(--nb-blue-wash);
}
.nb-rail-drawer-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 0 var(--nb-s5) var(--nb-s6);
}

/* ---------- 10 · Notes header chrome ---------------------------------
   Breadcrumb → chapter eyebrow → sans-700 title → meta/toolbar rule.
   The hairline under the toolbar is the notebook's margin rule; the
   reading rhythm starts beneath it. */
.nb-notes-header {
  margin-bottom: var(--nb-s7);
}
.nb-notes-header .nb-breadcrumb {
  margin-bottom: var(--nb-s5);
}
.nb-notes-eyebrow {
  margin-bottom: var(--nb-s2);
  font: var(--nb-type-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--nb-blue);
}
.nb-notes-title {
  font: var(--nb-type-headline);
  letter-spacing: -0.015em;
  color: var(--nb-ink);
  text-wrap: balance;
}
.nb-notes-toolbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--nb-s3);
  margin-top: var(--nb-s4);
  padding-bottom: var(--nb-s3);
  border-bottom: 1px solid var(--nb-border);
}
/* ---------- 11 · Focus mode — the reading room -----------------------
   With the chrome gone (§5), the notes become the whole room. Everything
   the reader does not read is hidden: the mobile trigger, the footer,
   the breadcrumb, and the toolbar (focus button). What remains is
   the title, the thin reading line up top, the note, and one quiet pill
   back out. The paywall is never reachable here — focus is only offered
   on readable content — so no gate styling is needed. */
html.note-focus-mode .nb-rail-trigger,
html.note-focus-mode .nb-footer,
html.note-focus-mode .nb-notes-header .nb-breadcrumb,
html.note-focus-mode .nb-notes-toolbar {
  display: none;
}

/* A single reading column, centered on the paper. The measure opens to a
   relaxed ~880px reading line (wider than the study view — focus is the
   roomy reading room, not a compact strip) and the top rhythm opens up so
   the title has room to breathe. */
html.note-focus-mode .nb-notes-column {
  max-width: min(880px, 100%);
  margin-inline: auto;
}
/* Focus relaxes the reading rather than blowing it up (owner directive
   2026-07-13 — keep the size close, just one gentle notch, and open it up):
   a subtle +6% size with a roomier line-height baked into each role, in the
   wider column above. The type ROLES are re-declared so `font: var(--nb-type-*)`
   consumers (prose, titles, callouts) grow when .nb-notes inherits the role
   whole — a bare scale-token override does not reach them, because the role's
   nested var() resolves against :root. The scale tokens are lifted the same
   +6% for the `font-size: var(--nb-text-*)` consumers (headings, kickers,
   inline & display KaTeX scale with them). Literals only, so nothing
   double-applies; scoped to the column, so normal reading is untouched.
   Custom-property declarations, so the font fingerprint is unmoved. */
html.note-focus-mode .nb-notes-column {
  --nb-type-ui: 400 calc(0.9375rem * 1.06)/1.65 var(--nb-sans);
  --nb-type-prose: 400 calc(1.0625rem * 1.06)/1.85 var(--nb-sans);
  --nb-type-control: 600 calc(0.9375rem * 1.06)/1.25 var(--nb-sans);
  --nb-type-label: 600 calc(0.8125rem * 1.06)/1.25 var(--nb-sans);
  --nb-type-title: 600 calc(1.25rem * 1.06)/1.4 var(--nb-sans);
  --nb-type-headline: 700 calc(1.875rem * 1.06)/1.25 var(--nb-sans);
  --nb-type-examiner: italic 400 calc(1.0625rem * 1.06)/1.7 var(--nb-serif);
  --nb-type-editorial: 600 calc(1.5rem * 1.06)/1.3 var(--nb-serif);
  --nb-text-xs: calc(0.75rem * 1.06);
  --nb-text-sm: calc(0.8125rem * 1.06);
  --nb-text-base: calc(0.9375rem * 1.06);
  --nb-text-md: calc(1.0625rem * 1.06);
  --nb-text-lg: calc(1.25rem * 1.06);
  --nb-text-xl: calc(1.5rem * 1.06);
  --nb-text-2xl: calc(1.875rem * 1.06);
  --nb-text-3xl: calc(2.375rem * 1.06);
}
html.note-focus-mode .nb-notes-header {
  margin-top: var(--nb-s4);
  margin-bottom: var(--nb-s8);
}

/* ---------- 11a · Focus-mode entrance (the room settles) --------------
   Entering focus, the reading column arrives with a calm, premium settle —
   a gentle rise + fade, ~420ms on the canonical spring. The top reading
   line and the Exit pill follow a beat later so the eye lands on the note
   first. Keyframes (not transitions) so the choreography REPLAYS every time
   the class is toggled on. All motion is duration-driven: the reduced-motion
   guard zeroes --nb-dur-3, collapsing the keyframes to an instant, no-op
   settle with no transform left hanging (fill-mode is safe at 0ms). */
html.note-focus-mode .nb-notes-column {
  animation: nb-focus-rise var(--nb-dur-3) var(--nb-ease) both;
}
@keyframes nb-focus-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
/* The reading line draws in from the top edge, slightly delayed. */
html.note-focus-mode .nt-top-progress {
  animation: nb-focus-fade var(--nb-dur-3) var(--nb-ease) 90ms both;
}
/* The way-back pill is the last thing to appear, so it never pulls focus on
   arrival — a quiet, later fade. */
html.note-focus-mode .nb-focus-exit {
  animation: nb-focus-fade var(--nb-dur-2) var(--nb-ease) 200ms both;
}
@keyframes nb-focus-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* Reduced motion: the token guard already zeroes the DURATIONS, but the staged
   delays above are literal ms — zero them too so the room appears instantly,
   fully opaque, with nothing waiting behind a delay. */
@media (prefers-reduced-motion: reduce) {
  html.note-focus-mode .topbar,
  html.note-focus-mode .nb-footer,
  html.note-focus-mode .nb-notes-column,
  html.note-focus-mode .nt-top-progress,
  html.note-focus-mode .nb-focus-exit {
    animation-delay: 0s;
    animation-duration: 0s;
  }
}

/* Focus opens the vertical rhythm; the reading text itself is zoomed one notch
   larger via the scale-token re-scope on the column (above). */
html.note-focus-mode .nb-notes p,
html.note-focus-mode .nb-notes ul,
html.note-focus-mode .nb-notes ol {
  margin-bottom: var(--nb-s6);
}
html.note-focus-mode .nb-notes li {
  margin-bottom: var(--nb-s4);
}

/* The way back: a QUIET text pill (nb-btn--quiet grammar) — no raised
   sheet, no shadow. It rests as calm blue ink on the paper and only
   draws a hairline surface on hover, so it never competes with the note.
   "Exit focus · Esc" — the middot separator + a whisper-quiet key hint. */
.nb-focus-exit {
  display: none;
  position: fixed;
  top: var(--nb-s5);
  right: var(--nb-s5);
  z-index: 240;
  align-items: center;
  gap: var(--nb-s2);
  padding: var(--nb-s2) var(--nb-s3);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--nb-r-pill);
  color: var(--nb-blue);
  font: var(--nb-type-control);
  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);
}
html.note-focus-mode .nb-focus-exit {
  display: inline-flex;
}
.nb-focus-exit:hover {
  background: var(--nb-paper-raised);
  border-color: var(--nb-border);
  color: var(--nb-blue-strong);
}
/* "· Esc" — a faint key hint, no boxed chip: the middot separates it
   from the label and the key reads as a quiet whisper, not a control. */
.nb-focus-exit-kbd {
  font: var(--nb-type-label);
  color: var(--nb-ink-2); /* small text stays on the 4.5:1 tier */
}
.nb-focus-exit-kbd::before {
  content: "· ";
  color: var(--nb-ink-2);
}

/* On a phone the column drops below the fixed exit pill so nothing overlaps.
   The study-prose role remains unchanged across focus and viewport states. */
@media (max-width: 720px) {
  html.note-focus-mode .nb-notes-header {
    margin-top: var(--nb-s8);
  }
  .nb-focus-exit {
    top: var(--nb-s4);
    right: var(--nb-s4);
  }
}

/* The compact chapter drawer is modal on touch devices; its icon retains the
   same glyph while the surrounding hit box reaches the 44px target floor. */
@media (pointer: coarse) {
  .nb-rail-drawer-close {
    min-inline-size: 44px;
    min-block-size: 44px;
  }
}
