/* ============================================================
   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; the login gate's first pane
     wears the page's own dotted paper), 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 · Burger glyph     nb-burger-glyph (the rail's toggle)
    15 · Footer           site-footer (shared with every other page)
    16 · Chapter rail     nb-rail (vertical index tabs + mastery)
    17 · Paywall          nb-paywall (editorial headline, tick list)
    18 · Login gate       nb-gate (a dialog over a free chapter)
    19 · Premium dialog   nb-gate--premium (Get Premium over a sealed chapter)
   ============================================================ */

/* ---------- 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-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 quiet third ink) while the sunken fill + flat border +
     cursor keep it unmistakably inert in both themes. One ink is for
     words that are live; a disabled label keeps the quiet ink. */
  background: var(--nb-paper-sunken);
  border-color: var(--nb-border);
  color: var(--nb-quiet-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);
}
/* The hover layers below sit in (hover: hover) (audit S-028b): a finger
   leaves :hover stuck on the last button it tapped (Next, Shuffle, Focus
   mode stayed in their hover fill and lifted), so on a touch screen the
   button is back at rest the moment the finger lifts. */
@media (hover: hover) {
  .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);
}
@media (hover: hover) {
  .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);
}
@media (hover: hover) {
  .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 {
  /* an ephemeral hint, not content: full ink (one ink, owner 2026-09-26),
     set in italic so an empty field never reads as filled */
  color: var(--nb-ink);
  font-style: italic;
}
.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-quiet-2); /* a disabled field keeps the quiet ink, legible (it carries real information) and unmistakably inert */
  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);
}
@media (hover: hover) {
  .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 {
  /* A plain block (a flex item either way), so a long crumb wraps as
     ordinary text. min-width: 0 and break-word let a single word wider
     than the column (2x text, 200% zoom) break inside its own crumb
     instead of pushing the page sideways. */
  display: block;
  min-width: 0;
  overflow-wrap: break-word;
  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 */
}
/* The separator ENDS the crumb before it (audit N-011 / S-016): glued to
   that crumb's last word, it can close a line but never open one, and it
   rides the baseline of a crumb that wraps instead of floating beside it.
   Its 4px margin plus the row's 4px gap keep the old rhythm. */
.nb-breadcrumb li:not(:last-child)::after {
  content: "·";
  margin-inline-start: var(--nb-s1);
  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 [data-ui-current="page"] {
  color: var(--nb-ink);
}
/* Touch (audit N-018 / S-036): each link's hit box grows to 24px tall
   (WCAG 2.5.8: the 15px text box plus 4.5px above and below) and 4px
   into the gaps either side, with no layout moving: inline padding does
   not change the line, and the negative margin gives the 4px back.
   The rows open from 4px to 6px apart so the boxes of two wrapped
   rows never overlap. 24px, not 44px: the crumb is secondary
   navigation (every stop is also the back link and the menu), and a 44px
   pitch would double a four-row phone trail. */
@media (pointer: coarse) {
  .nb-breadcrumb ol {
    row-gap: 6px;
  }
  .nb-breadcrumb a {
    padding: 4.5px var(--nb-s1);
    margin-inline: calc(-1 * var(--nb-s1));
  }
}

/* ---------- 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); /* 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);
}

/* ---------- 14 · Burger glyph ----------------------------------
   THE NAVBAR MOVED OUT (owner, 2026-10-10: "make this the navbar default,
   delete any other navbar"). The site has one navbar, .topbar
   (pages/includes/site_navbar.html, chrome-navbar.css and
   notebook-navbar-skin.css). What used to be here, .nb-navbar with its
   .nb-logo, tabs, actions and compact burger, was a second, hand-built bar
   that only the design gallery drew, and it is gone. The drawn glyph stays:
   the chapter rail's toggle wears it. */
/* 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 -----------------------------------------
   MOVED OUT. The footer is no longer a notebook component: every page in
   the site now renders one shared footer (pages/includes/site_footer.html),
   its layout lives in site-footer.css and its colours in
   notebook-footer-skin.css. What used to be here — .nb-footer and its
   .nb-footer-* children — was a second, hand-built footer carrying the same
   words at a different size, and it is gone. No hook on it is left here
   either: the footer's focus ring moved to site-footer.css with the rest of
   it, so this sheet is back to styling nb-* classes and nothing else. */

/* ---------- 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);
}
/* The syllabus code after the subject's name, and the unit code after the
   module's (owner, 2026-10-01: "just add them as normal text", "make it the
   same size as font, even on chapterbar"): plain words in the name's own
   size and weight, no box and no colour. AP and SAT have none. */
.nb-rail-code {
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  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. No corner stamp: the [Premium]
   (and the login sheet's [Free]) allocation wink in the top-right
   corner was removed (owner, 2026-09-28), so the headline runs the
   full width. 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-title {
  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);
}
.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);
}

/* ---------- 18 · Login gate ---------------------------------------
   A free chapter asks a signed-out visitor to log in
   (FREE_CONTENT_REQUIRES_LOGIN; nb_login_gate.html). It lives on the
   subject's Resources page (owner, 2026-09-28: "show on the
   resources, not on the note page itself"): a click on a gated card
   opens it there, and a visitor who reached a free page directly is
   sent back there with it open. One raised sheet at --nb-shadow-3,
   two panes: what a free account opens, on the notebook's own dotted
   paper, then the site's own sign-in. It closes.

   A native <dialog> opened with showModal(): the top layer, so no
   z-index and no containing block can reach it; the page behind is
   inert, Esc closes. The backdrop is the page's own paper at 64% (the
   sheet grammar's paper veil, never an ink wash, stronger than a
   sheet's 32% because the dialog asks for a decision). Without
   script a ?next= arrival draws it open but not modal: a plain card
   above the Resources cards, whose form still works.

   The dotted grid on the first pane is the page's paper texture (the
   body's own radial-gradient at --nb-grid-size), not a decorative
   gradient: the one other pattern this sheet draws beside the
   highlighter's wash. */
dialog.nb-gate {
  container: nb-gate / inline-size;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--nb-ink);
  font-family: var(--nb-sans);
}
dialog.nb-gate:focus {
  outline: none; /* focused by script so a reader starts at its top; not a control */
}
/* Modal: centred in the window, scrolling inside itself when the
   window is short, its padding leaving room for the sheet's shadow. */
dialog.nb-gate:modal {
  width: min(100%, 55rem);
  max-width: 100%;
  max-height: 100dvh;
  margin: auto;
  padding: var(--nb-s6) var(--nb-s5);
  overflow-y: auto;
  overscroll-behavior: contain;
}
dialog.nb-gate::backdrop {
  background: color-mix(in srgb, var(--nb-paper) 64%, transparent);
  transition: opacity var(--nb-dur-2) var(--nb-ease);
}
/* Nothing behind an open gate scrolls. */
html:has(dialog.nb-gate:modal) {
  overflow: hidden;
  scrollbar-gutter: stable;
}
/* Not modal (no script, or before it runs): a card in the page. */
dialog.nb-gate:not(:modal) {
  position: static;
  width: 100%;
  max-width: 52rem;
  margin: 0 auto var(--nb-s7);
}
.nb-gate .nb-gate-card {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  background: var(--nb-paper-raised);
  border: 1px solid var(--nb-border);
  border-radius: var(--nb-r-lg);
  box-shadow: var(--nb-shadow-3);
  overflow: hidden;
}
dialog.nb-gate[open] .nb-gate-card {
  transition:
    opacity var(--nb-dur-2) var(--nb-ease),
    transform var(--nb-dur-3) var(--nb-ease);
}
@starting-style {
  dialog.nb-gate[open] .nb-gate-card {
    opacity: 0;
    transform: translateY(var(--nb-s3)) scale(0.985);
  }
  dialog.nb-gate[open]::backdrop {
    opacity: 0;
  }
}
@container nb-gate (min-width: 700px) {
  .nb-gate .nb-gate-card {
    grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
  }
  .nb-gate .nb-gate-value {
    border-bottom: 0;
    border-right: 1px solid var(--nb-border); /* side by side: the page's edge */
  }
}

/* The close button: 44px, in the sheet's corner, the ink at rest. */
.nb-gate .nb-gate-close {
  position: absolute;
  top: var(--nb-s2);
  right: var(--nb-s2);
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: var(--nb-r-md);
  color: var(--nb-ink);
  cursor: pointer;
  transform: none; /* the legacy base's button:hover lift does not reach it */
  transition: background-color var(--nb-dur-1) var(--nb-ease);
}
@media (hover: hover) {
  .nb-gate .nb-gate-close:hover {
    background: var(--nb-paper-sunken);
  }
}
.nb-gate .nb-gate-close[hidden] {
  display: none;
}

/* What a free account opens, on the notebook's own paper. */
.nb-gate .nb-gate-value {
  display: flex;
  flex-direction: column;
  padding: var(--nb-s8) var(--nb-s7);
  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);
  border-bottom: 1px solid var(--nb-border); /* stacked: a hairline under the page */
}
/* The pitch sits in the middle of the pane's spare height. */
.nb-gate .nb-gate-pitch {
  margin-block: auto;
}
.nb-gate .nb-gate-where {
  margin: 0;
  font: var(--nb-type-label);
  line-height: 1.35;
  color: var(--nb-ink);
  text-wrap-style: balance;
}
.nb-gate .nb-gate-headline {
  margin: var(--nb-s2) 0 0;
  font-family: var(--nb-serif);
  font-size: var(--nb-text-lg);
  font-weight: 600;
  line-height: 1.3;
  color: var(--nb-ink);
  font-variant-numeric: lining-nums; /* Vollkorn's old-style 1 reads as a small capital I */
  text-wrap: balance;
}
.nb-gate .nb-gate-list {
  display: grid;
  gap: var(--nb-s3);
  margin: var(--nb-s6) 0 0;
  padding: 0;
  list-style: none;
}
.nb-gate .nb-gate-item {
  display: flex;
  align-items: flex-start;
  gap: var(--nb-s3);
  margin: 0;
  font: var(--nb-type-ui);
  color: var(--nb-ink);
  text-wrap: pretty;
}
.nb-gate .nb-gate-item .nb-tick {
  margin-top: 1px; /* optical: seats the tick on the first line */
  color: var(--nb-success);
}
/* The ticks draw when the script inks them; the plain card shows
   them already drawn, so nothing there waits on script. */
dialog.nb-gate:not(:modal) .nb-tick-path {
  stroke-dashoffset: 0;
}

/* The sign-in: the site's own login, the same fields and next. */
.nb-gate .nb-gate-auth {
  padding: var(--nb-s8) var(--nb-s8) var(--nb-s7);
}
.nb-gate .nb-gate-title {
  margin: 0 0 var(--nb-s6);
  padding: 0 var(--nb-s8) 0 0; /* clears the close button */
  border: none;
  font-family: var(--nb-sans);
  font-size: var(--nb-text-xl);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--nb-ink);
  text-wrap: balance;
}
.nb-gate .nb-gate-google {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--nb-s3);
  width: 100%;
  min-height: 44px;
  padding: 10px var(--nb-s4); /* the documented button padding (DESIGN.md §5) */
  background: var(--nb-paper-raised);
  border: 1px solid var(--nb-control-border);
  border-radius: var(--nb-r-md);
  box-shadow: var(--nb-shadow-1);
  font: var(--nb-type-control);
  color: var(--nb-ink);
  text-decoration: none;
  transition:
    border-color var(--nb-dur-1) var(--nb-ease),
    box-shadow var(--nb-dur-1) var(--nb-ease),
    transform var(--nb-dur-1) var(--nb-ease);
}
@media (hover: hover) {
  .nb-gate .nb-gate-google:hover {
    border-color: var(--nb-border-strong);
    box-shadow: var(--nb-shadow-2);
    transform: translateY(-1px);
  }
}
.nb-gate .nb-gate-google:active {
  transform: translateY(0);
}
.nb-gate .nb-gate-or {
  display: flex;
  align-items: center;
  gap: var(--nb-s3);
  margin: var(--nb-s5) 0;
  font-size: var(--nb-text-sm);
  font-weight: 500;
  color: var(--nb-ink);
}
.nb-gate .nb-gate-or::before,
.nb-gate .nb-gate-or::after {
  content: "";
  flex: 1;
  border-top: 1px solid var(--nb-border);
}
.nb-gate .nb-gate-form {
  display: grid;
  gap: var(--nb-s4);
  margin: 0;
}
.nb-gate .nb-gate-field {
  margin: 0;
}
/* The password field: Forgot password? follows the input in the DOM, so
   Tab runs email, password, Show, Forgot password?, Log in, and the
   grid seats it on the label row, the way the full login page does. */
.nb-gate .nb-gate-field--pass {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: var(--nb-s3);
}
.nb-gate .nb-gate-field--pass .nb-label {
  grid-row: 1;
  grid-column: 1;
}
.nb-gate .nb-gate-field--pass .nb-gate-pass {
  grid-row: 2;
  grid-column: 1 / -1;
}
.nb-gate .nb-gate-field--pass .nb-gate-forgot {
  grid-row: 1;
  grid-column: 2;
  justify-self: end;
}
.nb-gate .nb-gate-forgot {
  font-size: var(--nb-text-sm);
  font-weight: 500;
  color: var(--nb-blue);
  text-decoration: none;
}
.nb-gate .nb-gate-forgot:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.nb-gate .nb-gate-pass {
  position: relative;
  z-index: 1; /* the field and Show win over Forgot password?'s hit area */
}
/* The fields' own rest and focus, stated one step over the legacy base's
   input rules (the Resources page is a pages/base.html page). Their edge
   reaches 3:1 against the sheet in both themes: the control border by day
   (3.44:1), and by night, where that token is the 1.31:1 hairline, the ink
   at 40% into the sheet's paper (3.48:1). */
.nb-gate .nb-gate-field .nb-input {
  background-color: var(--nb-paper-raised);
  border-color: var(--nb-control-border);
  box-shadow: var(--nb-shadow-1);
}
html:not([class~="theme-light"]) .nb-gate .nb-gate-field .nb-input {
  border-color: color-mix(in srgb, var(--nb-ink) 40%, var(--nb-paper-raised));
}
.nb-gate .nb-gate-field .nb-input:focus,
html:not([class~="theme-light"]) .nb-gate .nb-gate-field .nb-input:focus {
  border-color: var(--nb-blue);
}
.nb-gate .nb-gate-pass .nb-input {
  padding-right: calc(var(--nb-s10) + var(--nb-s2)); /* clears Show */
}
.nb-gate .nb-gate-reveal {
  position: absolute;
  top: 0;
  right: var(--nb-s1);
  bottom: 0;
  display: flex;
  align-items: center;
  min-width: 44px;
  padding: 0 var(--nb-s3);
  background: transparent;
  border: 0;
  font-size: var(--nb-text-sm);
  font-weight: 600;
  color: var(--nb-blue);
  cursor: pointer;
  transform: none; /* stays put inside the field on hover */
}
.nb-gate .nb-gate-reveal[hidden] {
  display: none;
}
.nb-gate .nb-gate-submit {
  width: 100%;
  min-height: 44px;
  margin-top: var(--nb-s2);
}
.nb-gate .nb-gate-submit[data-ui-busy="true"] {
  cursor: progress;
}
.nb-gate .nb-gate-foot {
  margin: var(--nb-s6) 0 0;
  font: var(--nb-type-ui);
  color: var(--nb-ink);
}
.nb-gate .nb-gate-foot a {
  font-weight: 600;
  color: var(--nb-blue);
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
}
.nb-gate a:focus-visible,
.nb-gate button:focus-visible {
  outline: 2px solid var(--nb-blue);
  outline-offset: 2px;
  border-radius: var(--nb-r-sm);
}
.nb-gate .nb-gate-google:focus-visible,
.nb-gate .nb-gate-close:focus-visible {
  border-radius: var(--nb-r-md); /* their own corners, not the links' */
}
/* Touch: the small links get a larger hit where the paper around them
   allows it, without moving a line (the breadcrumb's recipe). */
@media (max-width: 860px), (pointer: coarse) {
  .nb-gate .nb-gate-forgot,
  .nb-gate .nb-gate-foot a {
    position: relative;
  }
  .nb-gate .nb-gate-forgot::after {
    content: "";
    position: absolute;
    /* grows up into the form gap, barely down toward the field */
    inset: calc(-1 * var(--nb-s3)) calc(-1 * var(--nb-s2)) calc(-1 * var(--nb-s1));
  }
  .nb-gate .nb-gate-foot a::after {
    content: "";
    position: absolute;
    inset: calc(-1 * var(--nb-s3)) calc(-1 * var(--nb-s2));
  }
}
/* A phone: a sheet from the bottom edge, the value pane above the
   form, the close button over the pane, the safe area kept clear. */
@media (max-width: 860px) {
  dialog.nb-gate:modal {
    width: 100%;
    max-height: calc(100dvh - var(--nb-s6));
    margin: auto 0 0;
    padding: 0;
  }
  dialog.nb-gate:modal .nb-gate-card {
    border-bottom: 0;
    border-radius: var(--nb-r-lg) var(--nb-r-lg) 0 0;
    padding-bottom: env(safe-area-inset-bottom);
  }
  .nb-gate .nb-gate-value {
    padding: var(--nb-s6) var(--nb-s5) var(--nb-s5);
  }
  .nb-gate .nb-gate-pitch {
    padding-right: var(--nb-s8); /* clears the close button */
  }
  .nb-gate .nb-gate-list {
    margin-top: var(--nb-s4);
    gap: var(--nb-s2);
  }
  .nb-gate .nb-gate-auth {
    padding: var(--nb-s6) var(--nb-s5) var(--nb-s7);
  }
  .nb-gate .nb-gate-title {
    margin-bottom: var(--nb-s5);
    padding-right: 0;
  }
  @starting-style {
    dialog.nb-gate[open] .nb-gate-card {
      transform: translateY(var(--nb-s6));
    }
  }
}
/* From 768px the sheet is capped and centred, as every sheet is. */
@media (min-width: 768px) and (max-width: 860px) {
  dialog.nb-gate:modal {
    max-width: 40rem;
    margin-inline: auto;
  }
}

/* ---------- 19 · Premium dialog -----------------------------------
   A paid chapter is never opened as a page for a student without
   Premium (owner, 2026-09-29: "only the overlay when clicking on the
   paid chapter from the free chapter"): a click on one opens this over
   the page they are on, and a paid page reached directly lands on the
   subject's Resources page with it open (nb_premium_gate.html). It IS
   the login gate's sheet (section 18: the dialog, the veil, the two
   panes, the close button, the phone's bottom sheet), with one ask where
   the sign-in stands: a line on what Premium opens, Get Premium (to the
   pricing page, where the plans are chosen) and Not now. No plan and no
   price is drawn here ("show something like Get Premium, not our
   subscriptions"). */
.nb-gate--premium .nb-gate-auth {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.nb-gate--premium .nb-gate-title {
  margin-bottom: var(--nb-s3);
}
.nb-gate .nb-gate-lede {
  margin: 0 0 var(--nb-s6);
  font: var(--nb-type-ui);
  color: var(--nb-ink);
  text-wrap: pretty;
}
.nb-gate .nb-gate-actions {
  display: grid;
  gap: var(--nb-s3);
}
.nb-gate .nb-gate-action {
  width: 100%;
  min-height: 44px;
}
.nb-gate .nb-gate-action[hidden] {
  display: none; /* Not now waits for the script that makes it work */
}
/* On the Resources page (a pages/base.html page) the legacy a:hover and
   button:hover rules reach these; they keep the notebook's own inks. */
.nb-gate .nb-gate-action.nb-btn--primary,
.nb-gate .nb-gate-action.nb-btn--primary:hover {
  color: var(--nb-on-blue);
}
.nb-gate .nb-gate-action.nb-btn--quiet:hover {
  border-color: transparent;
}
.nb-gate--premium .nb-gate-foot {
  margin-top: var(--nb-s5);
}
/* One notebook sheet (owner, 2026-09-29: the ask's side "feels empty"; of
   the fixes offered, the whole sheet as the notebook's own paper). The card
   is the paper and its dots; the two pages lie on it clear, still parted by
   their hairline, and under them runs <notebook-sketches>
   (pages/js/notebook-sketches.js): faint sketches of the subject that draw
   themselves in the paper left free around the words, each on one page, and
   fade. The pen tip lights these same dots: the element reads their spacing
   and counts them from the card's corner, as the background does.
   The ask's page is the login dialog's solid sheet again (owner, 2026-10-02:
   the right side "like this instead of it having transparent background"):
   it covers the paper, so the sketches draw on the first page only. */
.nb-gate--premium .nb-gate-card {
  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);
}
.nb-gate--premium .nb-gate-value {
  background: none;
}
.nb-gate--premium .nb-gate-auth {
  background: var(--nb-paper-raised);
}
.nb-gate--premium .nb-gate-value,
.nb-gate--premium .nb-gate-auth {
  position: relative;
  z-index: 1; /* the words and buttons over the sketches */
}
.nb-gate--premium .nb-gate-close {
  z-index: 2; /* over the pages, which now stack over the sketches */
}
/* Out of the card's grid even before its script defines it, over the whole
   card, never taking a click. Its ink is the strong blue pen. */
.nb-gate .nb-gate-sketches {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  color: var(--nb-blue-strong);
  --sketch-grid: var(--nb-grid-size);
  --sketch-alpha: 0.42;
}
/* The login dialog's own size (owner, 2026-09-29: "the exact same size as
   the one that pops up when you are not signed in"). Its sign-in is taller
   than this ask, so the card keeps the login sheet's measured height, in rem
   so it grows with the text: 778px as a phone's sheet, 707px as the 640px
   tablet sheet, 524px as the desk's two panes. Stacked, the extra goes to
   the ask (its words centred in it), as the sign-in takes it there. A
   phone's sheet is never taller than the screen it opens on (its own
   max-height), so on a short phone Get Premium is in view without a scroll.
   Side by side, the first page's width is a whole number of dots (0.92fr of
   the card, snapped to the grid), so no dot column runs along the hairline
   between the pages. */
.nb-gate--premium .nb-gate-card {
  grid-template-rows: auto 1fr;
  min-height: min(48.625rem, calc(100dvh - var(--nb-s6)));
}
@container nb-gate (min-width: 600px) {
  .nb-gate--premium .nb-gate-card {
    min-height: min(44.1875rem, calc(100dvh - var(--nb-s6)));
  }
}
@container nb-gate (min-width: 700px) {
  .nb-gate--premium .nb-gate-card {
    grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); /* a browser without round() */
    grid-template-columns: round(nearest, 46%, var(--nb-grid-size)) minmax(0, 1fr);
    grid-template-rows: none;
    min-height: 32.75rem;
  }
}
/* A landscape phone is too short for the stacked sheet: Get Premium would
   sit at the fold. It keeps the desk's two panes side by side instead. */
@media (max-width: 860px) and (max-height: 500px) and (orientation: landscape) {
  dialog.nb-gate--premium:modal {
    max-width: none;
  }
  .nb-gate--premium .nb-gate-card {
    grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); /* a browser without round() */
    grid-template-columns: round(nearest, 46%, var(--nb-grid-size)) minmax(0, 1fr);
    grid-template-rows: none;
    min-height: 0; /* the screen is shorter than either sheet: the ask stays in view */
  }
  .nb-gate--premium .nb-gate-value {
    border-bottom: 0;
    border-right: 1px solid var(--nb-border);
  }
  .nb-gate--premium .nb-gate-value,
  .nb-gate--premium .nb-gate-auth {
    padding: var(--nb-s5);
  }
  .nb-gate--premium .nb-gate-list {
    margin-top: var(--nb-s3);
  }
}

/* ---------- Mobile ergonomics ------------------------------------
   Touch targets: at phone widths AND on any touch screen (tablets,
   phone landscape: audit N-019a / S-037) every button and index tab
   meets the 44px minimum hit height. Padding tokens stay untouched —
   the extra height is empty paper. nb-btn is already inline-flex +
   centered, and a <button> tab centres its label natively. */
@media (max-width: 720px), (pointer: coarse) {
  .nb-btn,
  .nb-tab {
    min-height: 44px;
  }
}
/* At phone widths the tab (a button OR a nav link) also goes
   inline-flex, so an anchor tab honours min-height with its label
   centred. Kept to the phone query: on a touch tablet the display
   switch would re-flow the paper tabs' labels (the count loses its
   space), and every tab in use there is a <button>. */
@media (max-width: 720px) {
  .nb-tab {
    display: inline-flex;
    align-items: center;
  }
}
