/* ============================================================================
   IT REVOLUTION — one stylesheet for the whole suite
   Library · Work Detail · Reader · Membership · Auth · My Library · AI Tutor
   ----------------------------------------------------------------------------
   Fonts (put this in <head>, before this sheet):

   <link rel="preconnect" href="https://fonts.googleapis.com">
   <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
   <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Sora:wght@400;500;600;700;800&family=Hanken+Grotesk:wght@400;500;600;700;800&family=Literata:opsz,wght@7..72,400;7..72,500;7..72,600&family=Atkinson+Hyperlegible:wght@400;700&family=Lexend:wght@400;500;600&display=swap">

   Atkinson Hyperlegible + Lexend are reader-only; they may be lazily loaded on
   /read/* if you want lighter marketing pages.

   THEMING CONTRACT
     <html data-theme="light|dark">          UI theme          (cookie-persisted)
     <html data-contrast="high">             AAA layer         (composes on top)
     <html data-hc="on">                     same layer, V3's name for it
     <div class="reader" data-reading-theme="light|sepia|dark">
                                             reading palette   (independent)
   Nav tokens (--nav-*) are NEVER re-themed: the bar is the constant across apps.

   TOKEN VOCABULARY — the design files ship two conflicting families.
   This sheet standardises on the "page" family. Translation table for anyone
   porting CSS out of Cover Card / Library Shelf / Work Detail / Site Footer:
       --text-strong  ->  --text
       --text         ->  --text2
       --muted2       ->  --faint
       --shadow       ->  --sh-md
   ========================================================================== */

/* ==========================================================================
   1. TOKENS — light / default
   ========================================================================== */

:root {
  /* ---- surfaces ------------------------------------------------------- */
  --paper:         #ffffff;   /* cards, sheets, base surface                */
  --card:          #ffffff;   /* floating card sitting on --bg              */
  --bg:            #eef3f6;   /* standalone screen field (auth, welcome-back)*/
  --bg-app:        #f4f7f9;   /* tinted app page (tutor, learning path)     */
  --ink:           #0c0c22;   /* dark bands, heroes, path cards             */
  --surface:       #f6fafb;   /* inset blocks, tinted cards                 */
  --surface-raise: #f6fafb;   /* inset box that must lift off --card        */
  --panel:         #f2f8fb;   /* cover well / segmented-control track       */
  --field:         #ffffff;   /* input fill                                 */
  --hair:          #e7edf0;   /* every 1px / 1.5px border                   */
  --hair-2:        #f0f4f6;   /* softer hairline                            */

  /* ---- text ----------------------------------------------------------- */
  --text:          #141428;   /* headings, strong                           */
  --text2:         #333a4c;   /* body copy (document default)               */
  --muted:         #5b6470;   /* secondary                                  */
  --faint:         #667085;   /* captions, tertiary meta — V3 AA fix, was
                                 #9299a8 (2.86:1 on --paper). 4.97:1 now.   */

  /* ---- accents -------------------------------------------------------- */
  --teal:          #0f9fbe;
  --teal-soft:     rgba(15,159,190,.10);  /* citation chip fill             */
  --teal-12:       rgba(15,159,190,.12);  /* active tab badge               */
  --teal-08:       rgba(15,159,190,.08);  /* active include toggle          */
  --green:         #22b083;
  --coral:         #ee5d74;
  --gold:          #c98a1a;   /* legacy ownership ONLY                      */
  --coming:        #c98a1a;   /* presale "Coming <date>" — gold's hue under
                                 its own name, so the ownership reservation
                                 above stays enforceable by grep             */
  --amber:         #e0a53a;   /* "Light–Meaningful" budget tag              */

  --grad:          linear-gradient(90deg,#0cabca 0%,#23b8b4 52%,#38c89b 100%);
  --grad-2:        linear-gradient(90deg,#0cabca,#38c89b);      /* nav pills */
  --grad-chip:     linear-gradient(135deg,#0cabca,#38c89b);     /* ≤52px sq  */
  --on-grad:       #06121a;   /* ink that sits ON a gradient                */

  /* ---- text on --ink bands (literals, never themed) -------------------- */
  --on-ink:        #ffffff;
  --on-ink-2:      #c7ccda;
  --on-ink-3:      #8b93a6;
  --on-ink-4:      #9aa2b4;
  --on-ink-accent: #3fc3dd;

  /* ---- controls ------------------------------------------------------- */
  --btn:           #0d0d22;
  --btn-t:         #ffffff;
  --btn-hover:     #23233f;
  --btn-disabled:  #c9ccd6;
  --focus:         var(--teal);

  /* ---- nav: ALWAYS dark, never re-themed ------------------------------ */
  --nav-bg:        #0b0b1c;
  --nav-line:      rgba(255,255,255,.09);
  --nav-text:      #ffffff;
  --nav-muted:     #b9c0d0;
  --nav-dim:       #8b93a6;
  --nav-panel:     #15152f;
  --nav-green:     #2fcf94;   /* member dot — brighter than --green         */
  --nav-quiet:     #d7dbe6;

  /* ---- typography ----------------------------------------------------- */
  --f-display: 'Sora', system-ui, sans-serif;
  --f-ui:      'Hanken Grotesk', system-ui, -apple-system, sans-serif;
  --f-read:    'Literata', Georgia, serif;
  --f-a11y:    'Atkinson Hyperlegible', sans-serif;
  --f-lexend:  'Lexend', sans-serif;

  --fs-display:  46px;  --fs-display-m: 34px;
  --fs-h1:       32px;
  --fs-h2:       23px;
  --fs-h3:       17px;
  --fs-body:     16px;
  --fs-body-sm:  15px;
  --fs-small:    13px;
  --fs-xs:       12px;
  --fs-eyebrow:  11px;
  --fs-btn:      14px;

  --lh-display: 1.04;
  --lh-heading: 1.25;
  --lh-body:    1.55;
  --lh-loose:   1.62;
  --lh-read:    1.72;

  --ls-display:  -.03em;
  --ls-heading:  -.02em;
  --ls-tight:    -.015em;
  --ls-eyebrow:  .16em;
  --ls-eyebrow-sm: .11em;
  --ls-tag:      .06em;

  /* ---- spacing (4px base) --------------------------------------------- */
  --s1:  4px;  --s2:  8px;  --s3: 12px;  --s4: 16px;  --s5: 20px;
  --s6: 26px;  --s7: 34px;  --s8: 44px;  --s9: 56px;

  /* ---- radii ---------------------------------------------------------- */
  --r-xs:    3px;   /* cover art inside a cover card                        */
  --r-cover: 5px;   /* large cover art                                      */
  --r-ctl:   8px;   /* segmented thumb, small controls                      */
  --r-sm:    9px;
  --r-md:   12px;   /* buttons, inputs                                      */
  --r-lg:   16px;   /* cards, sheets                                        */
  --r-xl:   20px;   /* hero cards, modals                                   */
  --r-pill: 999px;

  /* ---- elevation ------------------------------------------------------ */
  --sh-sm: 0 4px 14px rgba(12,12,34,.10);
  --sh-md: 0 12px 34px rgba(12,12,34,.12);
  --sh-lg: 0 24px 60px rgba(12,12,34,.18);
  --sh-xl: 0 34px 80px rgba(12,12,34,.22);
  --sh-menu: 0 16px 40px rgba(12,12,34,.16);  /* V3 dropdown panel; sits
                                 between --sh-md and --sh-lg, hence its own
                                 token rather than a literal                */
  --sh-cover:    0 9px 24px rgba(12,12,34,.30);
  --sh-cover-lg: 0 20px 44px rgba(12,12,34,.34);
  --sh-thumb:    0 1px 3px rgba(12,12,34,.14);
  --shadow: var(--sh-md);

  /* ---- layout --------------------------------------------------------- */
  --page-max:     1180px;
  --page-pad:       40px;
  --page-pad-m:     16px;
  --measure:       760px;
  --measure-wide:  820px;
  --measure-bio:   600px;
  --detail-rail:   360px;
  --detail-gap:     56px;
  --grid-min:      196px;   /* -> 5-up at the designed 1240px content width */
  --tap:            44px;

  /* ---- motion --------------------------------------------------------- */
  --dur-fast: .15s;
  --dur:      .2s;
  --ease:     ease;
}

/* ==========================================================================
   2. DARK THEME  (attribute-driven; hand-tuned, NOT a mechanical inversion)
   ========================================================================== */

[data-theme="dark"] {
  --paper:         #0a0a1c;
  --card:          #12122a;
  --bg:            #08081c;
  --bg-app:        #08081c;
  --ink:           #07071a;
  --surface:       #101028;
  --surface-raise: #191937;
  --panel:         #17173a;
  --field:         #12122c;
  --hair:          #25254e;
  --hair-2:        #1a1a3c;

  --text:          #f3f5fb;
  --text2:         #c7ccda;
  --muted:         #98a0b3;
  --faint:         #6b7288;

  --teal:          #3fc3dd;
  --teal-soft:     rgba(63,195,221,.14);
  --teal-12:       rgba(63,195,221,.14);
  --teal-08:       rgba(63,195,221,.10);
  --green:         #48d1a0;
  --coral:         #ff6f84;
  --gold:          #e3b45f;
  --coming:        #e3b45f;

  --btn:           #f4f6fb;
  --btn-t:         #0a0a1c;
  --btn-hover:     #ffffff;

  --sh-md:  0 16px 44px rgba(0,0,0,.55);
  --sh-lg:  0 24px 60px rgba(0,0,0,.6);
  --sh-menu: 0 16px 40px rgba(0,0,0,.6);   /* V3 gave no dark value; the light
                                 rgba(12,12,34,…) would vanish on #0a0a1c, so
                                 this follows --sh-lg's dark treatment       */
  --shadow: 0 16px 44px rgba(0,0,0,.55);
  /* --grad, --grad-2, --grad-chip, --on-grad, --nav-* deliberately unchanged */
}

/* ==========================================================================
   3. READING THEMES  — reader surface only, own --r* namespace
      Three palettes in their own right, not inversions.
   ========================================================================== */

.reader,
[data-reading-theme="light"] {
  --rbg:      #faf9f5;
  --rsurface: #ffffff;
  --rtext:    #20242c;
  --rmuted:   #6b7280;
  --rfaint:   #9aa1ab;
  --rline:    #e7e4dc;
  --rchrome:  rgba(250,249,245,.92);
  --ricon:    #3a3f48;
  --raccent:  #0f9fbe;
  --rcoral:   #ee5d74;            /* reserved — unused in the design         */
  --rhl:      rgba(255,206,84,.42);
  --rsel:     rgba(15,159,190,.20);
  --rsheet:   #ffffff;
  --rdim:     rgba(20,20,34,.34);
  --rband:    rgba(255,214,110,.30);
  --r-on-accent: #04222a;         /* ink on --raccent, all three themes      */
}

[data-reading-theme="sepia"] {
  --rbg:      #f3ead4;
  --rsurface: #faf3e1;
  --rtext:    #463a28;
  --rmuted:   #8a7a60;
  --rfaint:   #b3a483;
  --rline:    #e2d5b8;
  --rchrome:  rgba(243,234,212,.93);
  --ricon:    #5b4c37;
  --raccent:  #2f9c8b;            /* warmer green-teal, NOT the UI teal      */
  --rcoral:   #c96a52;
  --rhl:      rgba(210,150,40,.34);
  --rsel:     rgba(47,156,139,.22);
  --rsheet:   #faf3e1;
  --rdim:     rgba(75,63,47,.32);
  --rband:    rgba(210,160,60,.28);
}

[data-reading-theme="dark"] {
  --rbg:      #14161c;            /* warmer/softer than the UI dark          */
  --rsurface: #1c1f28;
  --rtext:    #c9cdd6;            /* deliberately not pure white             */
  --rmuted:   #8b93a1;
  --rfaint:   #5f6672;
  --rline:    #2a2e38;
  --rchrome:  rgba(18,20,26,.92);
  --ricon:    #aeb4bf;
  --raccent:  #3fc3dd;
  --rcoral:   #ff6f84;
  --rhl:      rgba(255,214,110,.20);
  --rsel:     rgba(63,195,221,.22);
  --rsheet:   #1c1f28;
  --rdim:     rgba(0,0,0,.58);
  --rband:    rgba(255,214,110,.14);
}

/* Annotation palette — canonical, ONE set everywhere (V3).
   The three families used to hold three different quartets on purpose;
   V3's spec card retitles the row "Annotation palette — canonical, one set
   everywhere" and captions it "Highlights, notes & the reading-ruler swatches
   all draw from this quartet", so the tints collapse onto --hl-*.
   The --sw-* / --ruler-* names are KEPT as aliases: ~a dozen call sites and
   the hiccup views name them, and keeping them documents the three contexts.
   KNOWN CONTRADICTION, not resolved here: design-v3/Reader Frame.dc.html:158
   still paints the selection-menu swatches #ffd76e / #f2a0c0 — the old --sw-*
   values. The spec card and Reader Settings both say otherwise; this sheet
   follows the spec card. Flip --sw-* back if the designer meant the inline
   instance. Store the semantic name (yellow/green/blue/pink), not the hex. */
:root {
  --hl-yellow: #ffcf5c;  --hl-green: #7ee0a6;
  --hl-blue:   #8fb8ff;  --hl-pink:  #f2a0c8;

  --sw-yellow: var(--hl-yellow);  --sw-green: var(--hl-green);  /* selection */
  --sw-blue:   var(--hl-blue);    --sw-pink:  var(--hl-pink);

  --ruler-yellow: var(--hl-yellow); --ruler-green: var(--hl-green); /* ruler */
  --ruler-blue:   var(--hl-blue);   --ruler-pink:  var(--hl-pink);
}

/* ==========================================================================
   4. HIGH CONTRAST  — a separate layer, composes over any theme (WCAG AAA)
   ========================================================================== */

/* The app writes data-contrast="high" on <html> (layout.clj). V3 names the
   same axis data-hc="on". Both are accepted so either markup drives the layer. */

/* ---- UI shell half ---- */
[data-contrast="high"],
[data-hc="on"] {
  --paper: #ffffff; --card: #ffffff; --bg: #ffffff; --surface: #ffffff;
  --surface-raise: #ffffff; --panel: #ffffff; --field: #ffffff;
  --text: #000000; --text2: #000000; --muted: #000000; --faint: #000000;
  --hair: #000000;
  --teal: #0a5e73; --green: #0a5e3a; --coral: #a3122b;
  --btn: #000000; --btn-t: #ffffff; --btn-hover: #22222c;
  --hc-border: 2px;
}

[data-contrast="high"][data-theme="dark"],
[data-hc="on"][data-theme="dark"] {
  --paper: #000000; --card: #000000; --bg: #000000; --surface: #000000;
  --surface-raise: #000000; --panel: #000000; --field: #000000;
  --text: #ffffff; --text2: #ffffff; --muted: #ffffff; --faint: #ffffff;
  --hair: #ffffff;
  --teal: #7fe3ff; --green: #7fffc4; --coral: #ff9aa8;
  --btn: #ffffff; --btn-t: #000000; --btn-hover: #e6e6ee;
}

/* ---- reader half (V3) ----------------------------------------------------
   Fifteen --r* tokens per mode, from Reader Frame.dc.html's [data-hc="on"].
   These MUST be declared on .reader itself, not on <html>: section 3 sets the
   --r* family on the .reader element, and an element's own declaration beats
   an inherited one, so the previous html-level --r* entries here never landed
   in the light case. Specificity: (0,2,0) light / (0,3,0) dark, over section
   3's (0,1,0).
   Unlike the old placeholders these do NOT flatten every text tier to pure
   black/white — muted and faint stay distinguishable and still clear AAA
   (light 13.21:1 / 9.77:1, dark 15.37:1 / 11.47:1).
   The reading-theme -> UI-theme coupling is unchanged from the previous rule:
   dark UI theme OR dark reading theme selects the dark reader HC palette. */
[data-contrast="high"] .reader,
[data-contrast="high"] [data-reading-theme],
[data-hc="on"] .reader,
[data-hc="on"] [data-reading-theme] {
  --rbg:      #ffffff;
  --rsurface: #ffffff;
  --rtext:    #000000;
  --rmuted:   #26313d;
  --rfaint:   #3a4551;
  --rline:    #000000;
  --rchrome:  rgba(255,255,255,.98);
  --ricon:    #000000;
  --raccent:  #0a5e73;
  --rcoral:   #a5122b;
  --rhl:      rgba(10,94,115,.30);
  --rsel:     rgba(10,94,115,.28);
  --rsheet:   #ffffff;
  --rdim:     rgba(0,0,0,.55);
  --rband:    rgba(10,94,115,.20);
}

[data-contrast="high"][data-theme="dark"] .reader,
[data-contrast="high"][data-theme="dark"] [data-reading-theme],
[data-contrast="high"] .reader[data-reading-theme="dark"],
[data-hc="on"][data-theme="dark"] .reader,
[data-hc="on"][data-theme="dark"] [data-reading-theme],
[data-hc="on"] .reader[data-reading-theme="dark"] {
  --rbg:      #000000;
  --rsurface: #000000;
  --rtext:    #ffffff;
  --rmuted:   #d7dde6;
  --rfaint:   #b9c0cc;
  --rline:    #ffffff;
  --rchrome:  rgba(0,0,0,.98);
  --ricon:    #ffffff;
  --raccent:  #7fe3ff;
  --rcoral:   #ff9db0;
  --rhl:      rgba(127,227,255,.32);
  --rsel:     rgba(127,227,255,.30);
  --rsheet:   #000000;
  --rdim:     rgba(0,0,0,.7);
  --rband:    rgba(127,227,255,.22);
}

/* V3 guard. This sheet ships no text-shadow today; kept as a standing rule so
   a later decorative shadow can't erode the contrast this layer buys. */
[data-contrast="high"] *,
[data-hc="on"] * { text-shadow: none !important; }

/* Shell rules below are a LOCAL addition with no V3 counterpart — the designer
   specified only the reader half. They still match the unchanged spec §07
   prose ("Every control gets a visible border and a 3px focus ring"), so they
   stay. */
[data-contrast="high"] button, [data-hc="on"] button,
[data-contrast="high"] input,  [data-hc="on"] input,
[data-contrast="high"] select, [data-hc="on"] select,
[data-contrast="high"] .btn,   [data-hc="on"] .btn,
[data-contrast="high"] .chip,  [data-hc="on"] .chip,
[data-contrast="high"] .control, [data-hc="on"] .control {
  border: 2px solid currentColor;
  border-radius: var(--r-ctl);
  font-family: var(--f-display);
  font-weight: 700;
}
[data-contrast="high"] a,
[data-hc="on"] a { text-decoration: underline; font-weight: 600; }
[data-contrast="high"] :focus-visible,
[data-hc="on"] :focus-visible { outline: 3px solid currentColor; outline-offset: 2px; }
[data-contrast="high"] .cover-card__art, [data-hc="on"] .cover-card__art,
[data-contrast="high"] .card,            [data-hc="on"] .card,
[data-contrast="high"] .plancard,        [data-hc="on"] .plancard { border-width: 2px; }

/* ==========================================================================
   5. RESET + BASE
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

/* NO scroll-behavior:smooth on the root: Chrome cancels the smooth scroll to
   a URL fragment during page load, so every server-round-trip #catalog anchor
   (chips, topic picks, search submits) landed at the TOP of the page and the
   filters looked broken. Instant-and-correct beats smooth-and-cancelled. */
html { scroll-behavior: auto; }

body {
  margin: 0;
  font-family: var(--f-ui);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  background: var(--paper);
  color: var(--text2);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Links carry no global colour: the system uses teal for UI links and coral
   for in-product action links, and the design files disagree about the
   default. Use .link-teal / .link-coral explicitly. */
a { color: inherit; text-decoration: none; }

img, svg, video { max-width: 100%; }
img { display: block; }

h1, h2, h3, h4 {
  font-family: var(--f-display);
  color: var(--text);
  margin: 0;
  letter-spacing: var(--ls-tight);
  font-weight: 700;
}
h1 { font-weight: 800; letter-spacing: var(--ls-display); }

p { margin: 0; }
ul, ol { margin: 0; padding: 0; }

button { font: inherit; color: inherit; }

hr.rule { height: 1px; background: var(--hair); border: 0; margin: 22px 0; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Global focus ring — the one the Design System specifies, made theme-safe. */
:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--paper), 0 0 0 5px var(--focus);
  border-radius: var(--r-sm);
}

/* --- ONE focus ring per control -------------------------------------------
   The rule above applies to everything, including a bare <input> sitting inside
   a styled box. Wherever a control ALSO recoloured its own border on focus, the
   two stacked: teal border, 3px white gap, teal ring — which reads as two
   concentric rounded rectangles around one field.

   This has now been reported three times on three different fields, each time
   fixed locally, each time reappearing on the next field someone built. So the
   contract lives here, once, next to the rule that causes it:

     · the element the reader SEES as the control draws the ring
     · a bare input inside a styled wrapper draws nothing
     · nothing recolours its border on focus AND draws a ring

   The ring is canonical (it is what the Design System specifies); the
   border-recolour was the ad-hoc addition, so the borders went, not the ring.

   Adding a new wrapper-style field? Add its class to BOTH lists below and give
   it no focus rules of its own. `:focus-within` rather than `:has(:focus-visible)`
   deliberately: it needs no `:has()` support, and text inputs match
   :focus-visible on mouse click anyway, so the two are equivalent here. */
:is(.field, .hl-search, .filterbar__search, .tut-field, .gnav-sheet-search, .dl-input, .acct__savebar)
  :is(input, textarea, select):focus-visible {
  box-shadow: none;
  outline: none;
}
:is(.field, .hl-search, .filterbar__search, .tut-field, .gnav-sheet-search, .dl-input, .acct__savebar):focus-within {
  box-shadow: 0 0 0 3px var(--paper), 0 0 0 5px var(--focus);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ==========================================================================
   6. TYPOGRAPHY UTILITIES
   ========================================================================== */

.t-display {
  font-family: var(--f-display); font-weight: 800; font-size: var(--fs-display);
  line-height: var(--lh-display); letter-spacing: var(--ls-display);
}
.t-h1 { font-family: var(--f-display); font-weight: 800; font-size: var(--fs-h1);
        line-height: 1.05; letter-spacing: var(--ls-display); }
.t-h2 { font-family: var(--f-display); font-weight: 700; font-size: var(--fs-h2);
        line-height: 1.2;  letter-spacing: var(--ls-heading); }
.t-h3 { font-family: var(--f-display); font-weight: 700; font-size: var(--fs-h3);
        line-height: 1.28; letter-spacing: var(--ls-tight); }

.t-body    { font-size: 16px;   line-height: 1.6;  color: var(--text2); }
.t-body-sm { font-size: 15px;   line-height: 1.55; color: var(--muted); }
.t-small   { font-size: 13px;   line-height: 1.55; color: var(--muted); font-weight: 600; }
.t-caption { font-size: 12.5px; line-height: 1.5;  color: var(--faint);  font-weight: 500; }
.t-num     { font-family: var(--f-display); font-variant-numeric: tabular-nums; }

.eyebrow {
  font-family: var(--f-display); font-weight: 700; font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow); text-transform: uppercase;
  color: var(--teal); margin: 0;
}
.eyebrow--wide  { letter-spacing: .16em; font-size: 12px; }
.eyebrow--sec   { letter-spacing: .14em; font-size: 12px; }
.eyebrow--card  { letter-spacing: .1em;  font-size: 12px; }
.eyebrow--sm    { letter-spacing: .11em; font-size: 10px; }
.eyebrow--green { color: var(--green); letter-spacing: .08em; }
.eyebrow--faint { color: var(--faint); }
.eyebrow--on-ink{ color: var(--on-ink-accent); }

.thead {
  font-family: var(--f-display); font-weight: 700; font-size: 11px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--faint);
}

.link-teal  { color: var(--teal);  font-weight: 600; cursor: pointer; }
.link-coral { color: var(--coral); font-weight: 600; cursor: pointer; }
.link-strong{ color: var(--text);  font-family: var(--f-display);
              font-weight: 600; font-size: 14px; cursor: pointer; }
.link-teal:hover, .link-coral:hover { opacity: .82; }

@media (max-width: 859px) { .t-display { font-size: var(--fs-display-m); } }

/* ==========================================================================
   7. BUTTONS   primary (ink pill) · secondary (outline) · gradient · ghost
      One primary action per surface. Gradient is reserved for the top-level
      membership offer — never an in-page primary. Prices live in text links.
   ========================================================================== */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--f-display); font-weight: 600; font-size: var(--fs-btn);
  line-height: 1.2; text-align: center; white-space: nowrap;
  border: none; background: none; cursor: pointer;
}

/* PRIMARY — ink pill */
/* A control that must be a <button> but should READ as a link.
   Needed because several actions have to POST rather than GET — resending a
   sign-in email, signing out — and a GET that sends mail or destroys a session
   is prefetch-bait. `.btn` is the only class that strips UA chrome, but it keeps
   the UA's padding and swaps the face to the display font, so a bare `.btn`
   inside a sentence sits crooked and in the wrong typeface. This is the
   in-sentence variant: body font, no padding, inherits the link colour it's
   given (.link-teal / .link-coral) rather than choosing one.

   V3 STATUS: blessed. The design system now carries a "Link-button — action
   that POSTs" card, and every clause of it already matches this rule (body
   font, padding 0, inherited colour, weight 600, 2px --teal focus ring at 2px
   offset). ONE divergence, kept deliberately: the spec's demo button carries
   no text-decoration, ours underlines. The spec's prose does not mention
   decoration either way, so this reads as unspecified rather than contradicted
   — and an underline is the accessible choice for an inline actionable. If the
   designer confirms the bare look, drop the two text-decoration lines below. */
.link-btn {
  font-family: inherit; font-size: inherit; font-weight: 600; line-height: inherit;
  padding: 0; border: 0; background: none; cursor: pointer;
  color: inherit; text-decoration: underline; text-underline-offset: 2px;
  vertical-align: baseline;
}
.link-btn:hover { text-decoration-thickness: 2px; }
.link-btn:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; border-radius: 2px; }

.btn-ink {
  background: var(--btn); color: var(--btn-t);
  padding: 13px 22px; border-radius: var(--r-md);
}
.btn-ink:hover { background: var(--btn-hover); }
.btn-ink--lg    { font-size: 15.5px; padding: 15px 26px; border-radius: 13px; }
.btn-ink--md    { font-size: 14.5px; padding: 13px 22px; }
.btn-ink--sm    { font-size: 13px;   padding: 10px 16px; border-radius: 10px; }
.btn-ink--block { display: block; width: 100%; padding: 15px; border-radius: 13px; }
.btn-ink--pill  { font-size: 15px; padding: 16px 30px; border-radius: var(--r-pill);
                  letter-spacing: .02em; }
.btn-ink--pay   { display: block; width: 100%; font-size: 15.5px; padding: 16px;
                  border-radius: 13px; }
.btn:disabled, .btn[aria-disabled="true"] {
  background: var(--btn-disabled); color: #fff; cursor: not-allowed;
}

/* SECONDARY — outline. For the alternate format / alternate path. */
.btn-outline {
  background: transparent; border: 1.5px solid var(--hair); color: var(--text);
  padding: 12.5px 20.5px; border-radius: var(--r-md);
}
.btn-outline:hover { border-color: var(--text); }
.btn-outline--strong { border-color: var(--btn); }
.btn-outline--sm  { font-size: 13px;   padding: 10px 16px; border-radius: 10px; }
.btn-outline--md  { font-size: 13.5px; padding: 11px 20px; border-radius: 11px; }
/* Same outer box as .btn-ink--pill (16px 30px + no border): the 1.5px border
   is taken out of the padding, so an ink pill and an outline pill side by
   side are the same height and the same type size (Alex, 2026-09-05). */
.btn-outline--pill{ font-size: 15px; padding: 14.5px 28.5px; border-radius: var(--r-pill);
                    border-color: var(--btn); letter-spacing: .02em; }
.btn-outline--block { display: block; width: 100%; padding: 13px; }

/* MEMBERSHIP ACCENT — gradient pill. Top-of-app offer only. */
.btn-grad {
  background: var(--grad-2); color: var(--on-grad); font-weight: 700;
  font-size: 13.5px; padding: 11px 18px; border-radius: var(--r-pill);
}
.btn-grad:hover { filter: brightness(1.06); }

/* WHITE pill on an --ink band */
.btn-light {
  background: #fff; color: var(--on-grad);
  font-size: 15.5px; padding: 15px 26px; border-radius: 13px;
}
.btn-light--md { font-size: 14.5px; padding: 13px 22px; border-radius: 12px; }
.btn-light:hover { background: #f2f5f8; }

/* GHOST — text-weight action, used on dark heroes */
.btn-ghost {
  color: #dfe3ec; font-family: var(--f-display); font-weight: 600;
  font-size: 14px; cursor: pointer;
}
.btn-ghost span { color: var(--on-ink-accent); }

.btn:active { transform: translateY(1px); }

/* commerce row — the ONLY place a price is allowed to appear */
.link-commerce {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13.5px; font-weight: 600; color: var(--text); cursor: pointer;
}
.link-commerce > span { color: var(--faint); }

/* ==========================================================================
   8. BADGES · TAGS · PILLS · CHIPS
      Award/bestseller: coral outline. New: gradient fill (rare).
      Beta: teal outline — calm, never apologetic. Member: green dot.
      Format tags: neutral outline, uppercase. ONE award badge per cover max.
   ========================================================================== */

.badge-award {
  font-size: 11px; font-weight: 700; letter-spacing: var(--ls-tag);
  text-transform: uppercase; color: var(--coral);
  border: 1px solid var(--coral); border-radius: var(--r-pill);
  padding: 4px 11px; white-space: nowrap;
}
.badge-new {
  font-size: 11px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--on-grad);
  background: var(--grad-2); border-radius: var(--r-pill); padding: 5px 11px;
}
.badge-beta, .pill-beta {
  font-size: 9.5px; font-weight: 700; letter-spacing: var(--ls-tag);
  text-transform: uppercase; color: var(--teal);
  border: 1px solid var(--teal); border-radius: var(--r-pill); padding: 2px 8px;
}
.pill-soon {
  font-size: 11px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--faint);
  border: 1px solid var(--hair); border-radius: var(--r-pill);
  padding: 2px 9px; margin-left: 6px;
}
.pill-talk {
  font-size: 10px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--teal);
  border: 1px solid var(--teal); border-radius: var(--r-pill);
  padding: 2px 8px; flex: 0 0 auto;
}
.pill-status {
  font-size: 10px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--green);
  border: 1px solid var(--green); border-radius: var(--r-pill); padding: 2px 9px;
}
.badge-member {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; font-weight: 600; letter-spacing: var(--ls-tag);
  text-transform: uppercase; color: var(--muted);
}
.badge-member::before {
  content: ""; width: 6px; height: 6px; border-radius: var(--r-pill);
  background: var(--nav-green);
}

.tag {
  font-size: 10px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--teal);
  border: 1px solid var(--hair); border-radius: var(--r-cover); padding: 2px 7px;
}
.tag--neutral { color: var(--muted); }
.tag--gold    { color: var(--gold); border-color: var(--gold); }

.rule-v { width: 1px; height: 24px; background: var(--hair); flex: 0 0 auto; }

/* access status = LABEL, not a button */
.access-owned {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--f-display); font-weight: 700; font-size: 12px; color: var(--text);
}
.access-check {
  width: 18px; height: 18px; border-radius: var(--r-pill); background: var(--teal);
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
}
.access-check--lg { width: 20px; height: 20px; }
.access-included, .access-free {
  font-family: var(--f-display); font-weight: 700; font-size: 11px;
  letter-spacing: var(--ls-eyebrow-sm); text-transform: uppercase; color: var(--teal);
}
.access-free { color: var(--green); }

/* filter chip */
.chip {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--f-display); font-weight: 600; font-size: 12.5px;
  color: var(--text2); background: transparent;
  border: 1px solid var(--hair); border-radius: var(--r-pill);
  padding: 8px 15px; cursor: pointer; white-space: nowrap;
}
.chip:hover { border-color: var(--muted); }
.chip.is-on, .chip[aria-pressed="true"], .chip[aria-current="page"] {
  background: var(--btn); color: var(--btn-t); border-color: transparent;
}
.chip--sm { font-size: 12px; padding: 6px 12px; }

/* budget tag (spec/docs surfaces) */
.budget      { font-size: 11px; font-weight: 700; letter-spacing: .04em;
               text-transform: uppercase; border-radius: var(--r-pill); padding: 3px 9px; }
.budget--none, .budget--light { color: var(--green); border: 1px solid var(--green); }
.budget--mixed { color: var(--amber); border: 1px solid var(--amber); }
.budget--heavy { color: var(--coral); border: 1px solid var(--coral); }

/* gradient icon chip */
.chip-icon {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--grad-chip); color: var(--on-grad); flex: 0 0 auto;
}
.chip-icon--38 { width: 38px; height: 38px; border-radius: 10px; }
.chip-icon--42 { width: 42px; height: 42px; border-radius: 11px; background: var(--grad); }
.chip-icon--52 { width: 52px; height: 52px; border-radius: 14px; }

/* ==========================================================================
   9. FORM CONTROLS
   ========================================================================== */

.label {
  display: block; font-size: 12px; font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: .05em;
}

.field {
  width: 100%; display: flex; align-items: center; gap: 10px;
  background: var(--field); border: 1.5px solid var(--hair);
  border-radius: var(--r-md); padding: 13px 15px;
  font-family: var(--f-ui); font-size: 15px; color: var(--text);
}
.field--sq { border-radius: 11px; gap: 0; }
.field input, .field textarea {
  flex: 1; min-width: 0; border: none; outline: none; background: transparent;
  font: inherit; color: inherit;
}
.field input::placeholder { color: var(--faint); }
/* focus: see "ONE focus ring per control" at the top — deliberately not here */
.field-error { border-color: var(--coral); }
.field-msg { font-size: 12.5px; color: var(--coral); margin-top: 6px; }

/* segmented control */
.seg {
  display: inline-flex; gap: 4px; background: var(--panel);
  border: 1px solid var(--hair); border-radius: 11px; padding: 4px;
}
.seg__opt {
  padding: 9px 20px; border-radius: var(--r-sm);
  font-family: var(--f-display); font-weight: 600; font-size: 13.5px;
  color: var(--muted); background: transparent; border: none;
  box-shadow: none; cursor: pointer;
}
.seg__opt.is-on, .seg__opt[aria-selected="true"] {
  background: var(--paper); color: var(--text); box-shadow: var(--sh-thumb);
}
.seg--sm { gap: 3px; border-radius: 10px; padding: 3px; }
.seg--sm .seg__opt { padding: 6px 14px; border-radius: 7px; font-size: 12px; }

/* toggle — 38x22 track, 18px knob, travels 2 -> 18 */
.toggle {
  width: 38px; height: 22px; border-radius: var(--r-pill);
  background: var(--hair); position: relative; flex: 0 0 auto;
  border: 0; padding: 0; cursor: pointer; transition: background var(--dur-fast);
}
.toggle__knob {
  position: absolute; top: 2px; left: 2px; width: 18px; height: 18px;
  border-radius: var(--r-pill); background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,.3); transition: left var(--dur-fast);
}
.toggle[aria-checked="true"] { background: var(--teal); }
.toggle[aria-checked="true"] .toggle__knob { left: 18px; box-shadow: none; }

/* slider */
.slider { width: 150px; height: 4px; background: var(--hair);
          border-radius: var(--r-sm); position: relative; }
.slider__fill { height: 100%; background: var(--teal); border-radius: var(--r-sm); }
.slider__thumb {
  position: absolute; top: 50%; transform: translate(-50%,-50%);
  width: 18px; height: 18px; border-radius: var(--r-pill);
  background: #fff; border: 2px solid var(--teal);
}

/* colour swatch */
.swatch { width: 26px; height: 26px; border-radius: var(--r-pill);
          border: 0; background: var(--c, var(--hl-yellow)); cursor: pointer; }
.swatch.is-on, .swatch[aria-selected="true"] {
  box-shadow: 0 0 0 2px var(--paper), 0 0 0 4px var(--teal);
}

/* custom checkbox */
.checkbox {
  appearance: none; width: 20px; height: 20px; border-radius: var(--r-cover);
  border: 1.5px solid var(--hair); background: var(--field); flex: 0 0 auto;
  margin: 1px 0 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.checkbox:checked { border-color: var(--teal); background: var(--teal); }
.checkbox:checked::after {
  content: ""; width: 12px; height: 12px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23fff' stroke-width='2.4'%3E%3Cpath d='M2.5 6.2 5 8.6 9.5 3.6'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* 6-digit code input */
.code { display: flex; gap: 9px; margin: 0 0 18px; padding: 0; border: none; }
.code__cell {
  flex: 1; min-width: 0; height: 54px;
  border: 1.5px solid var(--hair); border-radius: 11px;
  background: var(--field); color: var(--text);
  font-family: var(--f-display); font-weight: 700; font-size: 22px;
  text-align: center; outline: none;
}

/* "or" rule */
.orrule { display: flex; align-items: center; gap: 10px; margin: 20px 0; }
.orrule span { flex: 1; height: 1px; background: var(--hair); }
.orrule em { font-style: normal; font-size: 11px; color: var(--faint);
             text-transform: uppercase; letter-spacing: var(--ls-tag); }

/* progress bar primitive */
.bar { display: block; height: 5px; background: var(--hair);
       border-radius: var(--r-sm); overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--teal); }
.bar--on-ink { background: rgba(255,255,255,.16); height: 6px; }
.bar--on-ink > i { background: var(--grad); }

/* check list */
.checks { display: flex; flex-direction: column; gap: 11px; list-style: none; }
.checks li { display: flex; gap: 11px; align-items: flex-start;
             font-size: 14px; color: var(--text2); line-height: 1.45; }
.checks svg { flex: 0 0 auto; margin-top: 1px; }
.checks--sm li { gap: 10px; font-size: 13.5px; }

/* ==========================================================================
   10. LAYOUT PRIMITIVES
   ========================================================================== */

.wrap { max-width: var(--page-max); margin: 0 auto; padding: 72px var(--page-pad); }
.wrap--flush { padding-top: 0; }
.page { max-width: var(--page-max); margin: 0 auto; padding: 0 var(--page-pad); }

.card {
  background: var(--paper); border: 1px solid var(--hair);
  border-radius: var(--r-lg); padding: 24px;
}
.card--tint  { background: var(--surface); }
.card--float { box-shadow: var(--sh-md); }

.section {
  max-width: var(--page-max); margin: 0 auto;
  padding: 60px var(--page-pad); border-top: 1px solid var(--hair);
}

.stack   { display: flex; flex-direction: column; }
.row     { display: flex; align-items: center; }
.spread  { display: flex; align-items: center; justify-content: space-between; gap: 16px; }

@media (max-width: 859px) {
  .wrap { padding: 48px 24px; }
  .page { padding: 0 24px; }
}
@media (max-width: 559px) {
  .wrap { padding: 40px var(--page-pad-m); }
  .page { padding: 0 var(--page-pad-m); }
}

/* ==========================================================================
   11. GLOBAL NAV — the cross-app spine. Always dark, every theme, every app.
   ========================================================================== */

.gnav {
  position: relative; width: 100%;
  background: var(--nav-bg); border-bottom: 1px solid var(--nav-line);
  font-family: var(--f-ui); z-index: 50;
}
/* NB: no `color: inherit` here. `.gnav a` is specificity 0-1-1, which outranks
   `.gnav-link` (0-1-0) — it silently stole the inactive nav links' colour and
   inherited body `--text2` (#333a4c) onto the near-black bar: 1.72:1, fails AA.
   The global `a { color: inherit }` (0-0-1) covers the other nav anchors without
   outranking `.gnav-link`. */
.gnav a { text-decoration: none; }

@keyframes navDrop {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---- desktop bar ---- */
.gnav-bar {
  height: 62px; display: flex; align-items: center; justify-content: space-between;
  padding: 0 26px; gap: 22px;
}
.gnav-left  { display: flex; align-items: center; gap: 20px; min-width: 0; }
.gnav-right { display: flex; align-items: center; gap: 16px; flex: 0 0 auto; }

.gnav-logo { display: block; flex: 0 0 auto; }
.gnav-logo svg { height: 21px; width: auto; display: block; color: var(--nav-text); }
/* The wordmark as a mask over one cached asset: the supplied logo-white/ink.svg are
   byte-identical black, so an <img> renders black-on-black on the dark bar. Painting
   the mask with --nav-text makes a single file correct in every theme. */
.gnav-logo-mark {
  display: block; width: 125px; height: 21px; background: var(--nav-text);
  -webkit-mask: url(/assets/logo.svg) no-repeat left/contain;
          mask: url(/assets/logo.svg) no-repeat left/contain;
}
.gnav-divider { width: 1px; height: 24px; background: var(--nav-line); flex: 0 0 auto; }

.gnav-apps-btn {
  display: flex; align-items: center; gap: 8px; flex: 0 0 auto;
  padding: 6px 10px; margin: -6px -4px;
  border: 0; border-radius: var(--r-sm); background: transparent;
  color: var(--nav-dim); cursor: pointer; font: inherit;
}
.gnav-apps-label {
  font-family: var(--f-display); font-weight: 600; font-size: 15px;
  color: var(--nav-text); letter-spacing: -.01em; white-space: nowrap;
}
/* Every nav disclosure is a native <details class="gnav-dd">: summary is the
   trigger, the panel sits inside, [open] replaces the aria-expanded flips a
   never-written nav.js was supposed to perform. The <details> itself stays
   unpositioned so the absolute panels keep .gnav as their containing block. */
.gnav-dd { flex: 0 0 auto; }
.gnav-dd > summary { list-style: none; cursor: pointer; }
.gnav-dd > summary::-webkit-details-marker { display: none; }
.gnav-dd[open] > .gnav-apps-btn { background: rgba(255,255,255,.08); }
.gnav-dd[open] > .gnav-apps-btn .gnav-caret { transform: rotate(180deg); }
.gnav-caret { transition: transform .16s var(--ease); flex: 0 0 auto; }

.gnav-links { display: flex; align-items: center; gap: 20px; margin-left: 4px; flex: 0 0 auto; }
.gnav-link {
  display: flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase;
  color: var(--nav-muted); white-space: nowrap; padding: 21px 0; cursor: pointer;
}
.gnav-link.is-current { color: var(--nav-text); box-shadow: inset 0 -2px 0 var(--teal); }
.gnav-caret-sm { flex: 0 0 auto; color: var(--nav-dim); }
.gnav-section-dd { position: relative; flex: 0 0 auto; }
.gnav-section-dd > summary { list-style: none; }
.gnav-section-dd > summary::-webkit-details-marker { display: none; }
.gnav-section-dd[open] > summary { color: var(--nav-text); }
.gnav-section-dd[open] > summary .gnav-caret-sm { transform: rotate(180deg); }

/* (no .gnav-search here: the desktop bar carries no search field — the shelf
   owns search, and this box was both the collision victim at 860–1160px and a
   dead end pointing at a /search route that never existed) */

.gnav-login {
  font-size: 12.5px; font-weight: 600; color: var(--nav-quiet);
  cursor: pointer; white-space: nowrap;
}
.gnav-cta {
  font-size: 12.5px; font-weight: 700; color: var(--on-grad);
  background: var(--grad-2); padding: 9px 17px; border-radius: var(--r-pill);
  cursor: pointer; white-space: nowrap;
}
.gnav-cta--sm { font-size: 12px;   padding: 8px 15px; }
.gnav-cta--xs { font-size: 11.5px; padding: 7px 13px; }

.gnav-member {
  display: flex; align-items: center; gap: 7px;
  font-size: 11.5px; font-weight: 600; letter-spacing: var(--ls-tag);
  text-transform: uppercase; color: var(--nav-quiet); cursor: pointer; white-space: nowrap;
}
.gnav-dot {
  width: 6px; height: 6px; border-radius: var(--r-pill);
  background: var(--nav-green); box-shadow: 0 0 0 3px rgba(47,207,148,.2);
}

.gnav-acct-btn {
  display: flex; align-items: center; gap: 8px;
  border: 0; background: none; padding: 0; color: var(--nav-dim);
  cursor: pointer; font: inherit;
}
.gnav-acct-visible-name {
  max-width: 9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--nav-text); font-size: 12.5px; font-weight: 600;
}
.gnav-dd[open] > .gnav-acct-btn .gnav-caret { transform: rotate(180deg); }
.gnav-avatar {
  width: 32px; height: 32px; border-radius: var(--r-pill); background: var(--grad-2);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--f-display); font-weight: 700; font-size: 12px;
  color: var(--on-grad); flex: 0 0 auto; object-fit: cover; overflow: hidden;
}
.gnav-avatar--sm { width: 30px; height: 30px; font-size: 11px; }
.gnav-avatar--lg { width: 42px; height: 42px; font-size: 15px; }

/* ---- mobile bar ---- */
.gnav-bar-m {
  display: none; height: 56px; align-items: center; justify-content: space-between;
  padding: 0 14px;
}
.gnav-bar-m .gnav-left  { gap: 12px; }
.gnav-bar-m .gnav-right { gap: 14px; }
.gnav-bar-m .gnav-logo svg { height: 19px; }
.gnav-burger {
  display: inline-flex; border: 0; background: none; padding: 0;
  color: #fff; cursor: pointer; flex: 0 0 auto;
  min-width: var(--tap); min-height: var(--tap);
  align-items: center; justify-content: center; margin-left: -10px;
}
.gnav-burger .icon-x { display: none; }
/* the bars→X swap is the only visible close affordance on mobile — it now
   rides [open] on the parent <details>, not an aria-expanded nothing flips */
.gnav-dd[open] > .gnav-burger .icon-bars { display: none; }
.gnav-dd[open] > .gnav-burger .icon-x    { display: block; }
.gnav-search-icon-m {
  display: inline-flex; color: #cfd4e0;
  min-width: var(--tap); min-height: var(--tap);
  align-items: center; justify-content: center;
}

/* ---- dropdown panels ---- */
.gnav-menu {
  position: absolute; background: var(--nav-panel);
  border: 1px solid var(--nav-line); border-radius: 14px;
  box-shadow: 0 24px 60px rgba(0,0,0,.5); padding: 8px; z-index: 60;
  animation: navDrop .16s var(--ease);
}
.gnav-menu--apps    { top: 60px; left: 78px; width: 320px; }
.gnav-menu--account { top: 60px; right: 26px; width: 290px; }
.gnav-menu--section { top: 52px; right: -14px; width: 190px; padding: 7px; }
.gnav-section-link {
  display: block; padding: 11px 12px; border-radius: 8px; color: var(--nav-muted);
  font-size: 13px; font-weight: 600;
}
.gnav-section-link:hover, .gnav-section-link.is-current {
  color: var(--nav-text); background: rgba(255,255,255,.06);
}

.gnav-menu-head {
  font-family: var(--f-display); font-weight: 700; font-size: 10px;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--nav-dim); padding: 10px 12px 6px;
}

.gnav-app {
  display: flex; align-items: center; gap: 13px;
  padding: 11px 12px; border-radius: 10px; background: transparent; cursor: pointer;
}
.gnav-app.is-active { background: rgba(255,255,255,.06); }
.gnav-app-icon {
  width: 36px; height: 36px; border-radius: var(--r-sm);
  background: rgba(255,255,255,.08); color: #cfd4e0;
  display: flex; align-items: center; justify-content: center; flex: 0 0 auto;
}
.gnav-app.is-active .gnav-app-icon { background: var(--grad-2); color: var(--on-grad); }
.gnav-app-text { flex: 1; min-width: 0; }
.gnav-app-name {
  display: block; font-family: var(--f-display); font-weight: 600;
  font-size: 13.5px; color: var(--nav-text);
}
.gnav-app-desc { display: block; font-size: 11.5px; color: var(--nav-dim); margin-top: 1px; }
.gnav-app-check { color: var(--nav-green); flex: 0 0 auto; }

.gnav-acct-head {
  padding: 12px 12px 14px; display: flex; align-items: center; gap: 12px;
  border-bottom: 1px solid var(--nav-line); margin-bottom: 6px;
}
.gnav-acct-id { flex: 1; min-width: 0; }
.gnav-acct-name {
  font-family: var(--f-display); font-weight: 700; font-size: 14px; color: var(--nav-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gnav-acct-email {
  font-size: 11.5px; color: var(--nav-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gnav-plan {
  font-size: 9px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--nav-green); border: 1px solid rgba(47,207,148,.5);
  border-radius: var(--r-pill); padding: 3px 8px; flex: 0 0 auto; white-space: nowrap;
}
.gnav-acct-link {
  display: flex; align-items: center; gap: 11px; padding: 10px 12px;
  border-radius: var(--r-sm); color: var(--nav-text);
  font-size: 13px; font-weight: 500; cursor: pointer;
}
.gnav-acct-link--primary { font-weight: 600; }
.gnav-acct-link--quiet   { color: var(--nav-muted); }
.gnav-acct-icon { color: var(--nav-dim); display: inline-flex; flex: 0 0 auto; }
.gnav-acct-link--feedback {
  margin: 4px 0; background: var(--coral); color: #0b0b1c; font-weight: 700;
}
.gnav-acct-link--feedback .gnav-acct-icon { color: #0b0b1c; }

/* ---- mobile sheet ---- */
.gnav-sheet {
  position: absolute; top: 56px; left: 0; right: 0;
  background: var(--nav-bg); border-top: 1px solid var(--nav-line);
  padding: 16px 14px max(22px, env(safe-area-inset-bottom));
  max-height: calc(100dvh - 56px); overflow-y: auto;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  z-index: 60; animation: navDrop .18s var(--ease);
}
.gnav-sheet-search {
  display: flex; align-items: center; gap: 9px;
  background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.1);
  border-radius: 11px; padding: 11px 14px; color: var(--nav-dim); margin-bottom: 16px;
}
.gnav-sheet-search input {
  flex: 1; min-width: 0; background: none; border: 0; outline: none; padding: 0;
  font-family: inherit; font-size: 13px; color: var(--nav-text);
}
.gnav-sheet-head {
  font-family: var(--f-display); font-weight: 700; font-size: 10px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--nav-dim);
  margin-bottom: 8px;
}
.gnav-sheet-apps { display: flex; flex-direction: column; gap: 4px; margin-bottom: 16px; }
.gnav-sheet-app {
  display: flex; align-items: center; gap: 12px;
  padding: 10px; border-radius: 10px; background: transparent;
}
.gnav-sheet-app.is-active { background: rgba(255,255,255,.06); }
.gnav-sheet-app .gnav-app-icon { width: 32px; height: 32px; border-radius: var(--r-ctl); }
.gnav-sheet-app-name {
  flex: 1; font-family: var(--f-display); font-weight: 600;
  font-size: 14px; color: var(--nav-text);
}
.gnav-sheet-links {
  display: flex; flex-direction: column;
  border-top: 1px solid var(--nav-line); margin-bottom: 16px;
}
.gnav-sheet-link {
  padding: 13px 2px; border-bottom: 1px solid var(--nav-line);
  font-size: 14px; font-weight: 600; color: var(--nav-muted); min-height: var(--tap);
  display: flex; align-items: center;
}
.gnav-sheet-link.is-current { color: var(--nav-text); }
.gnav-sheet-directory { border-bottom: 1px solid var(--nav-line); padding: 10px 0 6px; }
.gnav-sheet-directory-label {
  display: block; padding: 3px 2px 7px; color: var(--nav-dim);
  font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
}
.gnav-sheet-link--child { border-bottom: 0; padding: 8px 2px 8px 14px; min-height: 40px; }
.gnav-sheet-cta {
  display: block; text-align: center; font-size: 14px; font-weight: 700;
  color: var(--on-grad); background: var(--grad-2);
  padding: 14px; border-radius: var(--r-md); margin-bottom: 10px;
}
.gnav-sheet-login {
  display: block; text-align: center; font-size: 13.5px; font-weight: 600;
  color: var(--nav-quiet); padding: 6px;
}
.gnav-sheet-acct { display: flex; flex-direction: column; }
.gnav-acct-head--sheet { padding: 4px 2px 14px; margin: 0; }
.gnav-sheet-acct .gnav-acct-link {
  padding: 12px 2px; font-size: 14px; border-radius: 0;
  border-bottom: 1px solid var(--nav-line); min-height: var(--tap);
}
.gnav-sheet-acct .gnav-acct-link--feedback {
  margin: 8px 0; padding: 12px; border: 0; border-radius: var(--r-sm);
}
.gnav-mobile-user {
  display: flex; align-items: center; gap: 8px; min-width: 0; color: var(--nav-text);
}
.gnav-mobile-name {
  max-width: 92px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 12px; font-weight: 600;
}

/* ---- nav states + responsive ---- */
@media (hover: hover) {
  .gnav-link:hover  { color: var(--nav-text); }
  .gnav-apps-btn:hover { background: rgba(255,255,255,.06); }
  .gnav-app:hover, .gnav-acct-link:hover, .gnav-sheet-app:hover { background: rgba(255,255,255,.06); }
  .gnav-acct-link--feedback:hover { background: #ff8293; }
  .gnav-cta:hover   { filter: brightness(1.06); }
  .gnav-login:hover, .gnav-member:hover { color: var(--nav-text); }
}
/* summary is in the list: every disclosure trigger is a <summary> now */
.gnav :is(a, button, input, summary):focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--nav-bg), 0 0 0 4px var(--teal);
  border-radius: var(--r-sm);
}

/* ONE breakpoint, tuned to the bar's measured need. The signed-in desktop bar
   now includes the saved display name, so it needs roughly 80px more than the
   old avatar-only treatment; 1024px keeps that identity visible without
   collision. Panels live inside their bars, so hiding a bar hides its menus. */
@media (max-width: 1023px) {
  .gnav-bar   { display: none; }
  .gnav-bar-m { display: flex; }
}
@media (max-width: 359px) {
  .gnav-search-icon-m { display: none; }
  .gnav-mobile-name { max-width: 80px; }
}

/* ==========================================================================
   12. SITE FOOTER  (+ the gradient membership CTA band, non-members only)
   ========================================================================== */

.foot { width: 100%; font-family: var(--f-ui); }

/* ---- gradient CTA band. Every colour here is a theme-invariant literal:
        the band sits on a fixed gradient and must look identical in dark. --- */
.cta-band { background: var(--grad); padding: 52px var(--page-pad); }
.cta-band__inner {
  max-width: var(--page-max); margin: 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: 40px; flex-wrap: wrap;
}
.cta-band__copy { max-width: 580px; }
.cta-band__copy h2 {
  font-family: var(--f-display); font-weight: 800; font-size: 31px;
  line-height: 1.08; color: #07141b; letter-spacing: var(--ls-heading); margin: 0;
}
.cta-band__copy p {
  margin: 11px 0 0; font-size: 15px; color: #0a2029; opacity: .84; font-weight: 500;
}
.cta-band__actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.cta-band__btn {
  border: none; background: #07141b; color: #fff;
  font-family: var(--f-display); font-weight: 600; font-size: 14px; letter-spacing: .02em;
  padding: 15px 26px; border-radius: var(--r-pill); cursor: pointer; white-space: nowrap;
}
.cta-band__btn:hover { background: #0d2430; }
.cta-band__link {
  color: #07141b; font-family: var(--f-display); font-weight: 600; font-size: 14px;
  cursor: pointer; white-space: nowrap;
}
.cta-band__link:hover { opacity: .75; }

/* ---- footer proper ---- */
.foot-main {
  background: var(--paper); border-top: 1px solid var(--hair);
  padding: 54px var(--page-pad) 30px;
}
.foot-grid {
  max-width: var(--page-max); margin: 0 auto;
  display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr; gap: 36px;
}
.foot-logo {
  display: block; width: 134px; height: 26px; background: var(--text);
  -webkit-mask: url(/assets/logo.svg) no-repeat left/contain;
          mask: url(/assets/logo.svg) no-repeat left/contain;
}
.foot-blurb {
  margin: 16px 0 18px; font-size: 13.5px; line-height: 1.62;
  color: var(--muted); max-width: 255px;
}
.foot-social { display: flex; gap: 8px; }
.foot-social-a {
  width: 32px; height: 32px; border: 1px solid var(--hair); border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; color: var(--muted);
}
.foot-social-a.is-glyph { font-size: 11px; }
.foot-social-a:hover { border-color: var(--teal); color: var(--teal); }

.foot-col-h {
  font-family: var(--f-display); font-size: 11.5px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--text); margin: 0 0 14px;
}
.foot-col-a {
  display: block; margin: 9px 0; font-size: 13.5px; color: var(--muted); cursor: pointer;
}
.foot-col-a:hover, .foot-legal a:hover { color: var(--text); }
.foot-col-a[aria-current="page"] { color: var(--text); font-weight: 600; }

.foot-bottom {
  max-width: var(--page-max); margin: 36px auto 0; padding-top: 20px;
  border-top: 1px solid var(--hair);
  display: flex; justify-content: space-between; gap: 16px;
  color: var(--faint); font-size: 12.5px;
}
.foot-legal { display: flex; gap: 22px; }
.foot-legal a { color: var(--faint); cursor: pointer; }

.foot :is(a, button):focus-visible {
  outline: none; box-shadow: 0 0 0 3px var(--paper), 0 0 0 5px var(--teal);
  border-radius: 6px;
}

@media (max-width: 1023px) {
  .foot-grid { grid-template-columns: 1fr 1fr 1fr; gap: 32px; }
  .foot-brand { grid-column: 1 / -1; }
}
@media (max-width: 639px) {
  .cta-band { padding: 36px 20px; }
  .cta-band__copy h2 { font-size: 25px; }
  .cta-band__actions { width: 100%; }
  .cta-band__btn { flex: 1; text-align: center; }
  .foot-main { padding: 40px 20px 26px; }
  .foot-grid { grid-template-columns: 1fr 1fr; gap: 28px; }
  .foot-col-a { padding: 10px 0; margin: 0; }   /* 44px tap target */
  .foot-bottom { flex-direction: column; gap: 12px; }
  .foot-legal { gap: 16px; flex-wrap: wrap; }
}

/* ==========================================================================
   13. COVER CARD — the atom of every directory.
       The FRAME is always 1/1.2 for every item type, so the grid never
       ragged-edges. Portrait art hits the 90% height cap; square art hits
       the 82% width cap. `shape` only drives the headphone puck.
   ========================================================================== */

.cover-card { display: block; width: 100%; font-family: var(--f-ui); color: inherit; }

.cover-card__art {
  position: relative; width: 100%; aspect-ratio: 1 / 1.2;
  background: var(--panel); border: 1px solid var(--hair); border-radius: var(--r-md);
  display: flex; align-items: center; justify-content: center;
  padding: 15px; overflow: hidden;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.cover-card__art img {
  max-width: 82%; max-height: 90%; width: auto; height: auto;
  object-fit: contain; border-radius: var(--r-xs); box-shadow: var(--sh-cover);
}
.cover-card:hover .cover-card__art {
  transform: translateY(-5px); box-shadow: var(--sh-md); border-color: var(--teal);
}
.cover-card:active .cover-card__art { transform: translateY(-2px); }
.cover-card:focus-visible { outline: none; box-shadow: none; }
.cover-card:focus-visible .cover-card__art {
  transform: translateY(-5px);
  box-shadow: 0 0 0 3px var(--paper), 0 0 0 5px var(--teal), var(--sh-md);
}
.cover-card:focus-visible .cover-card__title { text-decoration: underline; text-underline-offset: 2px; }
@media (hover: hover) { .cover-card:hover .cover-card__title { color: var(--teal); } }

/* badge: on a cover it is a SOLID coral pill (an outline would vanish on art).
   The outline pill (.badge-award) is the metadata-row treatment. */
.cover-card__badge {
  position: absolute; top: 11px; left: 11px; z-index: 2;
  background: var(--coral); color: #fff;
  font-size: 9.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  padding: 4px 9px; border-radius: var(--r-pill); white-space: nowrap;
}
.cover-card__audio {
  position: absolute; top: 11px; right: 11px; z-index: 2;
  width: 26px; height: 26px; border-radius: var(--r-pill);
  background: rgba(13,13,34,.62);
  display: flex; align-items: center; justify-content: center;
}
.cover-card__audio i {                    /* headphone arc */
  width: 11px; height: 8px; border: 2px solid #fff; border-bottom: none;
  border-radius: var(--r-ctl) var(--r-ctl) 0 0; display: block;
}

.cover-card__meta { margin-top: 13px; display: flex; flex-direction: column; gap: 5px; }
.cover-card__type {
  font-size: 10px; font-weight: 700; letter-spacing: var(--ls-eyebrow-sm);
  text-transform: uppercase; color: var(--teal); margin: 0;
}
.cover-card__title {
  font-family: var(--f-display); font-weight: 600; font-size: 14.5px;
  line-height: 1.28; color: var(--text); margin: 0; letter-spacing: normal;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  line-clamp: 2; overflow: hidden;
}
.cover-card__authors {
  font-size: 12.5px; font-weight: 500; color: var(--muted); margin: 0;
  /* every author, wrapped — a credit that ellipsizes people is wrong on a
     card for the same reason the detail byline stopped collapsing at four */
  line-height: 1.45;
}
.cover-card__access {
  margin: 2px 0 0; min-height: 20px;   /* reserves the row: tiles stay aligned */
  display: flex; align-items: center; gap: 8px;
  white-space: nowrap; font-weight: 600;
}
.cover-card__access--member   { font-size: 12.5px; color: var(--teal); }
.cover-card__access--owned    { font-size: 12px;   color: var(--teal); }
.cover-card__access--included { font-size: 12px;   color: var(--teal); }
.cover-card__access--free     { font-size: 12px;   color: var(--green); }

.cover-card__formats {
  display: flex; gap: 5px; flex-wrap: wrap; margin: 1px 0 0; padding: 0; list-style: none;
}
.cover-card__formats li {
  border: 1px solid var(--hair); border-radius: var(--r-cover); padding: 1px 6px;
  font-weight: 600; font-size: 9.5px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--faint);
}

@media (prefers-reduced-motion: reduce) {
  .cover-card__art { transition: none; }
  .cover-card:hover .cover-card__art,
  .cover-card:focus-visible .cover-card__art { transform: none; }
}

/* ==========================================================================
   14. LIBRARY HUB / SHELF  — hero(member|pitch) · continue · CC bar ·
       filter bar · cover grid · load more
   ========================================================================== */

/* ---- member hero ---- */
.lib-hero { padding: 42px var(--page-pad) 22px; }
.lib-hero__title {
  font-size: 38px; font-weight: 700; line-height: 1.05; margin: 12px 0 0;
  max-width: 720px; color: var(--text); letter-spacing: var(--ls-display);
}
.lib-hero__lede {
  font-size: 15.5px; color: var(--muted); max-width: 660px;
  margin: 14px 0 0; line-height: var(--lh-body);
}

/* ---- continue strip (member only) ---- */
.lib-continue { padding: 6px var(--page-pad) 30px; }
.lib-continue__label {
  font-family: var(--f-display); font-weight: 700; font-size: 14px;
  color: var(--text); margin: 0 0 14px; letter-spacing: normal;
}
.lib-continue__label span {
  font-family: var(--f-ui); font-weight: 500; font-size: 13px; color: var(--faint);
}
.lib-continue__row {
  display: flex; gap: 16px; margin: 0; padding: 0; list-style: none; flex-wrap: wrap;
}
.resume-card {
  flex: 1 1 260px; display: flex; gap: 13px;
  background: var(--surface); border: 1px solid var(--hair);
  border-radius: var(--r-md); padding: 13px; min-width: 0;
}
.resume-card__link { display: flex; gap: 13px; flex: 1; min-width: 0; color: inherit; }
.resume-card__cover {
  width: 46px; height: 66px; object-fit: cover; border-radius: 4px;
  box-shadow: 0 4px 12px rgba(12,12,34,.22); flex: 0 0 auto;
}
.resume-card__body { flex: 1; min-width: 0; }
.resume-card__title {
  font-family: var(--f-display); font-weight: 600; font-size: 13.5px; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin: 0;
}
.resume-card__meta { font-size: 12px; color: var(--muted); margin: 0; }
.resume-card .bar { margin-top: 11px; }
.resume-card__pos { font-size: 11px; color: var(--faint); margin: 6px 0 0; }

/* ---- Creative Commons notice bar (signed-out only) ---- */
.cc-bar {
  padding: 15px var(--page-pad); background: var(--surface);
  border-top: 1px solid var(--hair); border-bottom: 1px solid var(--hair);
  display: flex; align-items: center; gap: 10px; margin: 0;
  font-size: 13.5px; color: var(--text2);
}
.cc-bar__dot {
  width: 7px; height: 7px; border-radius: var(--r-pill);
  background: var(--green); flex: 0 0 auto;
}
.cc-bar b { color: var(--text); }

/* ---- signed-out membership pitch hero ---- */
.lib-pitch {
  padding: 50px var(--page-pad) 32px;
  background: linear-gradient(180deg, var(--surface), var(--paper));
}
.lib-pitch__grid {
  display: grid; grid-template-columns: 1.12fr .88fr; gap: 52px; align-items: center;
}
.lib-pitch__title {
  font-size: 46px; line-height: 1.02; margin: 14px 0 0;
  color: var(--text); letter-spacing: var(--ls-display);
}
.lib-pitch__lede {
  font-size: 16.5px; color: var(--text2); max-width: 600px;
  margin: 18px 0 0; line-height: var(--lh-body);
}
.lib-pitch__stats {
  display: flex; align-items: center; gap: 22px; flex-wrap: wrap; margin: 22px 0 0;
  font-family: var(--f-display); font-weight: 600; font-size: 13px; color: var(--text);
}
.lib-pitch__stats i { color: var(--hair); font-style: normal; }
.lib-pitch__actions { display: flex; align-items: center; gap: 14px; margin-top: 26px; flex-wrap: wrap; }

.perk-card {
  background: var(--paper); border: 1px solid var(--hair);
  border-radius: var(--r-xl); padding: 28px; box-shadow: var(--sh-md);
}
.perk-card__title {
  font-family: var(--f-display); font-weight: 700; font-size: 19px; color: var(--text); margin: 0;
}
.perk-card__sub { font-size: 13.5px; color: var(--muted); margin: 4px 0 0; }
.perk-card__list {
  /* bottom margin is load-bearing: the block CTA follows with no top margin
     of its own, and without it the button crashes into the last perk row */
  margin: 20px 0 22px; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: 13px;
}
.perk-card__list li {
  display: flex; align-items: center; gap: 11px;
  font-size: 14px; color: var(--text2); font-weight: 500;
}
.tick {
  width: 20px; height: 20px; border-radius: var(--r-pill); background: var(--teal);
  display: flex; align-items: center; justify-content: center; flex: 0 0 auto;
}
.perk-card__fine { text-align: center; font-size: 12px; color: var(--faint); margin: 12px 0 0; }

/* ---- filter bar ---- */
.filterbar {
  padding: 18px var(--page-pad); border-bottom: 1px solid var(--hair);
  background: var(--paper); display: flex; flex-direction: column; gap: 14px;
}
.filterbar__row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.filterbar__controls { display: flex; align-items: center; gap: 16px; }
.control {
  font-size: 13px; color: var(--muted); cursor: pointer; white-space: nowrap;
  background: none; border: none; padding: 0; font-family: var(--f-ui);
  display: inline-flex; align-items: center; gap: 8px;
}
.control b { color: var(--text); }
.control--boxed {
  border: 1px solid var(--hair); border-radius: var(--r-sm);
  padding: 8px 12px; font-size: 12.5px;
}
.filterbar__count { font-size: 13px; color: var(--muted); margin: 0; }

/* ---- shelf grid ---- */
.shelf { padding: 34px var(--page-pad) 46px; }
.shelf__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--grid-min), 1fr));
  gap: 34px 26px;
}
/* The related rail is ONE ROW at every width — a scroll-snap shelf, not a
   grid. A grid opens however many tracks fit and the rail's fixed supply
   either falls short (699px of empty track at 1920) or wraps to a second row
   on a phone. A shelf with fixed-width cards fills what it fills and scrolls
   for the rest, which is also what a "more like this" rail is in every
   bookshop interface a reader already knows. */
.shelf__grid--related {
  display: flex; gap: 24px; overflow-x: auto;
  scroll-snap-type: x proximity; overscroll-behavior-inline: contain;
  padding-bottom: 10px;              /* the scrollbar's lane, not a gap */
  scrollbar-width: thin;
}
.shelf__grid--related > .cover-card {
  flex: 0 0 196px; min-width: 0; scroll-snap-align: start;
}
@media (max-width: 640px) {
  .shelf__grid--related > .cover-card { flex-basis: 164px; }
}
.shelf__more { display: flex; justify-content: center; margin-top: 42px; }

/* ---- empty / zero-results (not designed; system-consistent) ---- */
.shelf__empty {
  text-align: center; padding: 60px 0; color: var(--muted);
  max-width: 460px; margin: 0 auto;
}
.shelf__empty h2 { font-size: 20px; margin-bottom: 8px; }

@media (max-width: 859px) {
  .lib-hero    { padding: 30px 24px 18px; }
  .lib-hero__title { font-size: clamp(28px, 5vw, 38px); }
  .lib-continue { padding: 6px 24px 26px; }
  .lib-pitch   { padding: 34px 24px 26px; }
  .lib-pitch__grid { grid-template-columns: 1fr; gap: 32px; }
  .lib-pitch__title { font-size: clamp(30px, 6vw, 46px); }
  .cc-bar, .filterbar { padding-left: 24px; padding-right: 24px; }
  .shelf { padding: 26px 24px 40px; }
  .chip  { padding: 11px 15px; }        /* honour the 44px tap minimum */
}
@media (max-width: 559px) {
  .lib-hero, .lib-continue, .lib-pitch, .shelf,
  .cc-bar, .filterbar { padding-left: var(--page-pad-m); padding-right: var(--page-pad-m); }
  .lib-continue__row { flex-direction: column; }
  /* The desktop flex-basis is the card's minimum WIDTH. Once this list becomes
     a column that same basis applies to HEIGHT, producing a 260px-tall card
     around 66px of content. Let content determine the mobile card height. */
  .resume-card { flex: 0 0 auto; }
  /* minmax(0,1fr), NOT bare 1fr: bare 1fr is minmax(auto,1fr), and the cover
     art's intrinsic minimum then drives the track — measured 1099px-wide cards
     inside a 343px container, giving every phone 1590px of horizontal scroll. */
  .shelf__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 16px; }
  .filterbar__controls { width: 100%; justify-content: space-between; }
}

/* ==========================================================================
   15. WORK DETAIL — breadcrumb · sticky rail (cover, format, action panel)
       · main column (head, endorsements, tabs, panels, ask, authors)
       · related rail
   ========================================================================== */

/* ---- breadcrumb ---- */
.crumbs {
  padding: 16px var(--page-pad); border-bottom: 1px solid var(--hair);
  font-size: 12.5px; color: var(--muted);
}
.crumbs ol { list-style: none; margin: 0; padding: 0; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--text); }
.crumbs__sep { color: var(--faint); }
.crumbs__current { color: var(--text); font-weight: 600; }

/* ---- two-column layout ---- */
.work {
  display: grid; grid-template-columns: var(--detail-rail) 1fr;
  gap: var(--detail-gap); padding: 44px var(--page-pad) 20px;
}
/* NOT sticky any more: the signed-out panel (samples, sellers, print rows)
   outgrew a laptop viewport, and a sticky rail taller than the screen just
   pins its overflow out of reach. Normal flow scrolls with the page. */
.work-rail { align-self: start; }
/* positioned, because the tab radios are absolutely positioned and must stay
   INSIDE this box. Without a positioned ancestor they resolve against the
   initial containing block and get carried to the top-left of the document —
   where a 1px transparent control still takes focus and still scrolls the page
   to reach it. The rail gets this free from `position: sticky`. */
.work-main { min-width: 0; position: relative; }
/* the saved-for-later toggle under the action panel — the rail has no gap
   of its own (its children mostly self-space), so the form carries it */
.rail-save { margin-top: 12px; }
/* the home base's curated strip head, below the continue rows */
.ml-rec-head { font-size: 17px; font-weight: 700; margin: 34px 0 14px; }
/* account settings cards */
.acct__form { display: flex; flex-direction: column; gap: 12px; margin-top: 12px;
              align-items: flex-start; }
.acct__savebar {
  width: min(100%, 460px); display: flex; align-items: center; gap: 8px;
  background: var(--field); border: 1.5px solid var(--hair);
  border-radius: var(--r-md); padding: 5px 6px 5px 14px;
}
.acct__savebar input {
  flex: 1 1 auto; min-width: 0; border: 0; outline: 0; background: transparent;
  color: var(--text); font: inherit; font-size: 15px;
}
.acct__savebar .btn { flex: 0 0 auto; }
.acct__urlrow { width: 100%; display: flex; align-items: center; gap: 10px; }
.acct__prefix { flex: 0 0 auto; color: var(--text2); font-size: 14px; }
.acct__savebar--handle { width: min(100%, 300px); }
.acct__check { display: flex; gap: 10px; align-items: baseline; cursor: pointer; }
.acct__check input { accent-color: var(--btn); }
.acct__saved { font-size: 13px; color: var(--green); margin: 8px 0 0;
              font-weight: 600; }
.phoneauth__sendrow {
  width: min(100%, 460px); display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: stretch; gap: 8px;
}
.phoneauth__sendrow .acct__savebar { width: 100%; }
.phonefield { gap: 0; padding: 0; overflow: hidden; }
.phonefield__country {
  align-self: stretch; flex: 0 0 96px; width: 96px; min-width: 0;
  border: 0; border-right: 1px solid var(--hair); border-radius: 0;
  background: var(--field); color: var(--text); cursor: pointer;
  font: inherit; font-size: 13px; font-weight: 600; padding: 0 8px 0 12px;
}
.phonefield input { padding: 10px 12px; }
.field.phonefield input { padding: 13px 15px; }
.phoneauth__hint { color: var(--faint); font-size: 11.5px; line-height: 1.45;
                   margin: 6px 0 0; }
.phoneauth-linked { display: flex; align-items: center; justify-content: space-between;
                    gap: 14px; margin-top: 16px; }
.phoneauth-linked[hidden], #phone-auth-ready[hidden], #phone-auth-verify[hidden],
#phone-link-form[hidden], #phone-link-code-form[hidden], #phone-remove[hidden] { display: none; }
.phoneauth__legal { color: var(--faint); font-size: 11.5px; line-height: 1.5;
                    margin: 14px 0 0; }
.phoneauth__msg { color: var(--muted); font-size: 12.5px; line-height: 1.5;
                  margin: 10px 0 0; }
/* learning paths */
/* the Paths tab's create block — the tab's primary action, so it is a card
   at the TOP rather than a lone input under an empty state (Alex, 2026-09-09) */
.ml-newpath { margin-top: 22px; background: var(--surface); border: 1px solid var(--hair);
              border-radius: var(--r-lg); padding: 20px 22px 22px; }
.ml-newpath__h { display: flex; align-items: center; gap: 9px; margin: 0;
                 font-family: var(--f-display); font-weight: 700; font-size: 16px; color: var(--text); }
.ml-newpath__h svg { color: var(--teal); flex: none; }
.ml-newpath__sub { margin: 6px 0 0; font-size: 13.5px; color: var(--muted); line-height: var(--lh-body); }
.ml-newpath__row { display: flex; gap: 10px; margin-top: 14px; align-items: stretch; flex-wrap: wrap; }
.ml-newpath__field { flex: 1 1 300px; max-width: 440px; }
/* the curated example path under the create block: a quiet card whose rows
   ARE step rows, so the preview cannot drift from the real thing */
.lp-ex { margin-top: 30px; border: 1px solid var(--hair); border-radius: var(--r-lg);
         padding: 20px 22px 22px; background: var(--paper); }
.lp-ex__eyebrow { display: inline-flex; align-items: center; gap: 7px; margin: 0;
                  font-family: var(--f-display); font-weight: 700; font-size: 11px;
                  letter-spacing: .1em; text-transform: uppercase; color: var(--teal); }
.lp-ex__title { font-family: var(--f-display); font-weight: 700; font-size: 19px;
                margin: 10px 0 0; letter-spacing: -.015em; }
.lp-ex__desc { font-size: 13.5px; color: var(--muted); line-height: var(--lh-body); margin: 8px 0 0; max-width: 62ch; }
.lp-ex__list { list-style: none; margin: 14px 0 0; padding: 0; }
.lp-step--flat { background: transparent; border-color: transparent; box-shadow: none; }
.lp-ex__go { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 16px;
             padding-top: 16px; border-top: 1px solid var(--hair); }
.lp-ex__start { font: inherit; font-family: var(--f-display); font-weight: 600; font-size: 14px;
                color: #fff; background: var(--ink); border: 0; border-radius: 999px;
                padding: 11px 22px; cursor: pointer; }
.lp-ex__start:hover { background: #2a2f45; }
.lp-ex__hint { font-size: 12.5px; color: var(--faint); flex: 1 1 240px; min-width: 0; }

.rail-path { margin-top: 10px; }
.rail-path__btn { cursor: pointer; font-size: 13.5px; font-weight: 600;
                  color: var(--faint); padding: 6px 2px; list-style: none; }
.rail-path__btn::before { content: "＋ "; }
.rail-path[open] .rail-path__btn { color: var(--text); }
.rail-path__form { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.rail-path__field select, .rail-path__field input {
  width: 100%; font: inherit; padding: 9px 10px; border: 0; background: none; }
/* professional profile — the editor keeps its account-page dress; the
   member-facing card wears the AUTHOR HERO's identity language (.ap-hero
   classes, reused on purpose — one person-page vocabulary product-wide) */
.pf-lede { max-width: 60ch; }
.pf-namehint { font-size: 13px; font-weight: 400; color: var(--faint); }
.pf-form { display: flex; flex-direction: column; gap: 14px; margin-top: 14px;
           align-items: flex-start; }
.pf-row { display: flex; flex-direction: column; gap: 6px; width: 100%;
          max-width: 480px; }
.pf-row__label { font-size: 13px; font-weight: 600; }
.pf-photo { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.pf-photo__img {
  width: 88px; height: 88px; border-radius: var(--r-pill); object-fit: cover;
  flex: 0 0 88px; border: 1px solid var(--hair); box-shadow: var(--sh-sm);
}
.pf-photo input[type="file"] { max-width: 100%; min-width: 0; }
.pf-row textarea {
  width: 100%; font: inherit; border: 0; background: none;
  padding: 10px 12px; resize: vertical;
  /* `rows="4"` in the markup sizes the box off the UA's own row metric, which
     runs shorter than our line-height — real multi-paragraph answers ("Testing
     the beta end to end.\n\nSecond paragraph here.") showed a sliced last line
     on both desktop and phone. Set height in this same line-height explicitly,
     so the box and the text it's sized for can never disagree; 6 lines gives
     the "sentence or three" placeholder room to run into a second paragraph
     before anyone needs to drag the resize handle. */
  line-height: 1.5;
  min-height: calc(1.5em * 6 + 20px);
}
.pf-visrow { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.pf-pub { padding: 0; }  /* the hero band IS the page; footer follows its rule */
.pf-hero { border-top: 1px solid var(--hair); }
.pf-hero .ap-hero__inner { padding-top: 30px; }
.pf-draftnote { border: 1.5px dashed var(--hair); border-radius: 12px;
                padding: 10px 16px; font-size: 13.5px; color: var(--muted);
                margin: 0 0 22px; max-width: max-content; }
/* consecutive bio paragraphs: the hero style carries a 24px top margin
   meant for the single-block author bio */
.pf-bio-wrap .ap-hero__bio + .ap-hero__bio { margin-top: 12px; }
.pf-chips { margin-top: 26px; }
.pf-chips__h {
  font-family: var(--f-display); font-weight: 700; font-size: 11px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--faint);
  margin: 0 0 10px; }
.pf-chips__row { display: flex; gap: 8px; flex-wrap: wrap; }
.pf-chip--static { cursor: default; }
.pf-chip--static:hover { border-color: var(--hair); }
/* the download opt-in — a disclosure that reads like a checkbox row */
.dlopt { margin-top: 14px; }
.dlopt__row { display: flex; gap: 10px; align-items: flex-start; cursor: pointer;
              list-style: none; font-size: 13.5px; color: var(--text2); line-height: 1.45; }
.dlopt__row::-webkit-details-marker { display: none; }
.dlopt__box { flex: 0 0 auto; width: 16px; height: 16px; margin-top: 2px;
              border: 1.5px solid var(--muted); border-radius: 4px; background: none; }
.dlopt[open] .dlopt__box { background: var(--btn); border-color: var(--btn);
                           box-shadow: inset 0 0 0 3px var(--surface, #fff); }
.dlopt__form { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.dlopt__fine { font-size: 12px; color: var(--faint); margin: 0; }
.dlopt__thanks { font-size: 13.5px; color: var(--green); font-weight: 600; margin: 12px 0 0; }
/* beta-ops (read-only admin) */
.ops { max-width: 980px; margin: 0 auto; padding: 30px 20px 80px; }
.ops-panel__heading { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.ops-panel__retry { border: 1px solid var(--hair); border-radius: 6px; padding: 8px 12px; background: var(--paper); color: var(--ink); cursor: pointer; font: inherit; }
.ops-panel__retry:hover { background: var(--teal-12); }
.ops-panel__retry:focus-visible { outline: 2px solid var(--teal); outline-offset: 3px; }
.ops-skeleton { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin: 16px 0 30px; }
.ops-skeleton span { display: block; height: 80px; border-radius: 10px; background: var(--hair); opacity: .45; }
.ops-chart { margin: 0; padding: 24px 0; border-bottom: 1px solid var(--hair); }
.ops-chart h3 { margin: 0 0 8px; font-size: 18px; letter-spacing: -.025em; text-wrap: balance; }
.ops-chart .ops-note { max-width: 76ch; }
.ops-chart__plot { display: block; width: 100%; height: auto; overflow: visible; }
.ops-chart__grid { stroke: var(--hair); stroke-width: 1; }
.ops-chart__axis { fill: var(--muted); font: 12px var(--f-mono, monospace); font-variant-numeric: tabular-nums; }
.ops-chart__series { stroke: var(--teal); fill: var(--teal); stroke-width: 2.5; }
.ops-chart__series polyline { fill: none; stroke-linejoin: round; stroke-linecap: round; }
.ops-chart__series--1 { stroke: var(--text); fill: var(--paper); }
.ops-chart__series--1 polyline { stroke-dasharray: 6 5; }
.ops-chart__legend { display: flex; flex-wrap: wrap; gap: 10px 24px; margin: 4px 0 12px; padding: 0; list-style: none; font-size: 13px; }
.ops-chart__legend li { display: flex; align-items: center; gap: 8px; }
.ops-chart__legend li::before { content: ''; width: 22px; border-top: 3px solid var(--teal); }
.ops-chart__legend .ops-chart__legend--1::before { border-color: var(--text); border-top-style: dashed; }
.ops-chart .ops-tbl { font-variant-numeric: tabular-nums; }
@media (max-width: 600px) { .ops-chart__axis { font-size: 24px; } .ops-chart h3 { font-size: 17px; } }
.ops-h1 { font-family: var(--f-display); font-size: clamp(26px, 4vw, 34px);
          margin: 0 0 4px; }
.ops-sub { color: var(--faint); margin: 0 0 22px; }
.ops-q { font-family: var(--f-mono, monospace); font-size: .8em; }
.ops-stats { display: flex; gap: 12px; flex-wrap: wrap; margin: 0 0 8px; }
.ops-stat { border: 1px solid var(--hair); border-radius: 14px;
            padding: 14px 18px; min-width: 150px; display: flex;
            flex-direction: column; gap: 2px; background: var(--surface); }
.ops-stat__n { font-family: var(--f-display); font-weight: 800; font-size: 26px;
               font-variant-numeric: tabular-nums; }
.ops-stat__l { font-size: 12.5px; font-weight: 600; color: var(--muted); }
.ops-stat__d { font-size: 12px; color: var(--faint); }
.ops-sec { margin-top: 30px; }
.ops-sec__h { font-size: 16px; margin: 0 0 10px; }
/* Every ops table (admin_beta.clj's one `ops-table` helper is the only place
   any of them get built) renders through this div, so the fix here covers
   all of them — the beta-admits roll, the feedback log, the royalty tables,
   every one. `overflow-x: auto` is the scroll itself; the four-layer
   background is Lea Verou's scroll-shadow trick turned sideways — two
   `local` gradients that scroll WITH the table and mask the two `scroll`
   gradients (fixed to the viewport) except right at whichever edge still has
   more to show. No JS, and it just isn't there once a table is short enough
   to need no scrolling at all. */
.ops-scroll {
  overflow-x: auto;
  background:
    linear-gradient(to right, var(--paper) 50%, rgba(0,0,0,0)) left / 30px 100% no-repeat local,
    linear-gradient(to left,  var(--paper) 50%, rgba(0,0,0,0)) right 0 / 30px 100% no-repeat local,
    radial-gradient(farthest-side at 0% 50%,   rgba(0,0,0,.18), rgba(0,0,0,0)) left / 14px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.18), rgba(0,0,0,0)) right 0 / 14px 100% no-repeat scroll;
}
.ops-tbl { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.ops-tbl th { text-align: left; font-size: 11px; text-transform: uppercase;
              letter-spacing: .08em; color: var(--faint); font-weight: 700;
              padding: 6px 12px 6px 0; border-bottom: 1px solid var(--hair); }
.ops-tbl td { padding: 8px 12px 8px 0; border-bottom: 1px solid var(--hair);
              font-variant-numeric: tabular-nums; }
.ops-empty { color: var(--faint); font-size: 13.5px; }
.ops-find { display: flex; gap: 10px; flex-wrap: wrap; align-items: stretch; }
.ops-find__field { flex: 1 1 240px; max-width: 380px; }
.ops-slugs { font-size: 13px; color: var(--muted); line-height: 1.8; }
.ops-actives { font-size: 13px; color: var(--muted); margin: 4px 0 0; }
.ops-note { font-size: 12.5px; color: var(--faint); margin: 0 0 10px;
            max-width: 68ch; }
/* the exclusion footnote and the "also active" line sit UNDER a statement
   rather than above a table, so they need the gap the section-leading
   variant doesn't have — without it they read as one run-on paragraph */
.ops-stats + .ops-note,
.ops-actives + .ops-note { margin-top: 14px; }
.ops-never { color: var(--faint); }

/* beta ops, task-first: reporting stays quiet and scannable; account writers
   live on the distinct .ops-admin surface so they cannot be mistaken for
   ordinary dashboard navigation. */
.ops-hero { padding: 4px 0 2px; }
.ops-kicker {
  margin: 0 0 7px; color: var(--teal); font-size: 11px; font-weight: 750;
  letter-spacing: .12em; text-transform: uppercase;
}
.ops-hero .ops-sub { max-width: 62ch; text-wrap: pretty; }
.ops-stats--hero {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px;
}
.ops-stats--hero .ops-stat { min-width: 0; }
.ops-attention { border-top: 1px solid var(--hair); }
.ops-attn {
  display: grid; grid-template-columns: 38px minmax(0, 1fr) 44px;
  gap: 14px; align-items: start; padding: 16px 0; border-bottom: 1px solid var(--hair);
}
.ops-attn__n {
  display: grid; place-items: center; width: 34px; height: 34px;
  background: var(--teal-12); color: var(--teal); border-radius: 9px;
  font-family: var(--f-display); font-size: 17px; font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.ops-attn__body h3 { margin: 0; font-size: 14px; }
.ops-attn__body > p { margin: 4px 0 0; color: var(--muted); font-size: 13px; line-height: 1.45; }
.ops-attn__body .ops-attn__people { color: var(--faint); font-size: 12px; }
.ops-attn__go {
  display: grid; place-items: center; width: 44px; height: 44px;
  color: var(--teal); font-size: 20px; border-radius: 10px;
}
.ops-attn__go:hover, .ops-attn__go:focus-visible { background: var(--teal-12); }

.ops-people { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.ops-person { padding: 17px 18px; background: var(--surface); border: 1px solid var(--hair); border-radius: 14px; }
.ops-person__head { display: flex; justify-content: space-between; gap: 14px; align-items: flex-start; }
.ops-person__head h3 { margin: 0; font-size: 14px; overflow-wrap: anywhere; }
.ops-person__head p { margin: 4px 0 0; font-size: 12px; overflow-wrap: anywhere; }
.ops-badge {
  flex: 0 0 auto; padding: 4px 7px; border-radius: 5px; background: var(--panel);
  color: var(--muted); font-size: 9px; font-weight: 750; letter-spacing: .07em;
  line-height: 1.2; text-transform: uppercase;
}
.ops-badge--member, .ops-badge--feedback-praise { background: var(--teal-12); color: var(--teal); }
.ops-person__facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin: 16px 0 0; }
.ops-person__facts div { min-width: 0; }
.ops-person__facts dt { color: var(--faint); font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
.ops-person__facts dd { margin: 4px 0 0; color: var(--text2); font-size: 12px; line-height: 1.35; overflow-wrap: anywhere; }
.ops-person__go { display: inline-flex; min-height: 44px; align-items: center; margin-top: 10px; font-size: 12.5px; font-weight: 650; }
.ops-more { margin-top: 12px; }
.ops-more > summary {
  display: flex; align-items: center; justify-content: center; min-height: 44px;
  border: 1px solid var(--hair); border-radius: 10px; color: var(--muted);
  cursor: pointer; font-size: 12.5px; font-weight: 650; list-style: none;
}
.ops-more > summary::-webkit-details-marker { display: none; }
.ops-more__hide { display: none; }
.ops-more[open] { display: flex; flex-direction: column; }
.ops-more[open] > .ops-people { order: 1; margin-bottom: 12px; }
.ops-more[open] > summary { order: 2; color: var(--text); }
.ops-more[open] .ops-more__show { display: none; }
.ops-more[open] .ops-more__hide { display: inline; }

.ops-rank { border-top: 1px solid var(--hair); }
.ops-rank__row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto 32px; gap: 12px;
  align-items: center; min-height: 54px; padding: 9px 0; border-bottom: 1px solid var(--hair);
}
.ops-rank__title { color: var(--text); font-size: 13.5px; font-weight: 650; }
.ops-rank__meta { color: var(--faint); font-size: 12px; white-space: nowrap; }
.ops-rank__arrow { color: var(--teal); text-align: right; }
.ops-links { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.ops-link {
  display: flex; justify-content: space-between; align-items: center; gap: 18px;
  padding: 15px 16px; border: 1px solid var(--hair); border-radius: 12px; color: var(--text);
}
.ops-link > span:first-child { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ops-link strong { font-size: 13.5px; }
.ops-link small { color: var(--faint); font-size: 11.5px; line-height: 1.4; }
.ops-link__arrow { color: var(--teal); font-size: 18px; }
.ops-link:hover, .ops-link:focus-visible { border-color: var(--teal); }

.ops-admin {
  margin-top: 34px; padding: 20px 22px 23px; background: var(--surface);
  border: 1px solid var(--hair); border-left: 4px solid var(--teal); border-radius: 12px;
}
.ops-admin > h2 { margin: 0; font-size: 18px; }
.ops-admin > p:not(.ops-kicker) { max-width: 64ch; margin: 7px 0 16px; color: var(--muted); font-size: 13px; line-height: 1.5; }
.ops-admin .ops-sec { margin-top: 18px; }

.ops-compare { border-top: 1px solid var(--hair); }
.ops-compare__head, .ops-compare__row {
  display: grid; grid-template-columns: minmax(0, 1fr) 110px 110px; gap: 14px;
  align-items: center; border-bottom: 1px solid var(--hair);
}
.ops-compare__head { padding: 6px 0; color: var(--faint); font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.ops-compare__row { min-height: 58px; padding: 9px 0; }
.ops-compare__metric { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ops-compare__metric strong { font-size: 13px; }
.ops-compare__metric small { color: var(--faint); font-size: 11.5px; line-height: 1.35; }
.ops-compare__value > span { display: none; }
.ops-compare__value strong { font-size: 14px; font-variant-numeric: tabular-nums; }
.ops-funnel-wrap { margin-bottom: 24px; }
.ops-funnel { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
.ops-funnel__step { padding: 12px; background: var(--surface); border: 1px solid var(--hair); border-radius: 10px; display: flex; flex-direction: column; gap: 2px; }
.ops-funnel__step strong { font-family: var(--f-display); font-size: 20px; font-variant-numeric: tabular-nums; }
.ops-funnel__step span { color: var(--muted); font-size: 11px; font-weight: 650; }
.ops-funnel__step small { color: var(--teal); font-size: 10px; font-weight: 700; }

/* Scorecard: the first screen is a decision surface; the complete accounting
   remains immediately available without making every reader traverse it. */
.ops-cohort { margin-top: 34px; }
.ops-cohort + .ops-cohort { margin-top: 42px; }
.ops-cohort__head { margin-bottom: 16px; }
.ops-cohort__head h2 { margin: 0; font-size: 22px; letter-spacing: -.02em; }
.ops-cohort__head > p:last-child {
  max-width: 66ch; margin: 6px 0 0; color: var(--muted); font-size: 13px; line-height: 1.5;
}
.ops-cohort--qa {
  padding: 22px; background: var(--surface); border: 1px solid var(--hair);
  border-radius: 16px;
}
.ops-score-pulse, .ops-royalty-pulse {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px;
  margin-bottom: 22px;
}
.ops-score-pulse .ops-stat, .ops-royalty-pulse .ops-stat {
  min-width: 0; padding: 13px 14px;
}
.ops-score-pulse .ops-stat__n, .ops-royalty-pulse .ops-stat__n { font-size: 22px; }
.ops-callout {
  margin: 0 0 18px; padding: 12px 14px; border-left: 3px solid var(--teal);
  background: var(--teal-12); color: var(--text2); font-size: 13px; line-height: 1.45;
}
.ops-report-details {
  margin-top: 12px; border-top: 1px solid var(--hair); border-bottom: 1px solid var(--hair);
}
.ops-report-details + .ops-report-details { margin-top: -1px; }
.ops-report-details > summary {
  display: flex; align-items: center; min-height: 48px; color: var(--muted);
  cursor: pointer; font-size: 12.5px; font-weight: 650;
}
.ops-report-details > summary::after {
  content: "+"; margin-left: auto; color: var(--teal); font-size: 18px; font-weight: 500;
}
.ops-report-details[open] > summary { color: var(--text); }
.ops-report-details[open] > summary::after { content: "−"; }
.ops-report-details > .ops-compare { margin-bottom: 16px; }
.ops-report-details > .ops-note { margin: 0 0 16px; overflow-wrap: anywhere; }
.ops-report-details > .ops-sec { margin: 0 0 22px; padding: 4px 0 0; }
.ops-cohort .ops-sec { margin-top: 28px; }

.ops-filter { display: flex; gap: 7px; flex-wrap: wrap; margin: 20px 0 16px; }
.ops-filter a {
  display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 8px 11px;
  border: 1px solid var(--hair); border-radius: 8px; color: var(--muted); font-size: 12.5px; font-weight: 650;
}
.ops-filter a span { color: var(--faint); font-size: 10.5px; }
.ops-filter a.is-active { border-color: var(--teal); background: var(--teal-12); color: var(--text); }
.ops-pagecount { margin: 0 0 12px; color: var(--faint); font-size: 11.5px; }
.ops-feedback-list { display: flex; flex-direction: column; gap: 12px; }
.ops-feedback { padding: 18px 20px; background: var(--surface); border: 1px solid var(--hair); border-radius: 14px; }
.ops-feedback__head { display: flex; justify-content: space-between; gap: 12px; align-items: center; }
.ops-feedback__head time { color: var(--faint); font-size: 11.5px; font-variant-numeric: tabular-nums; }
.ops-feedback blockquote { margin: 16px 0; color: var(--text); font-size: 15px; line-height: 1.55; white-space: pre-wrap; }
.ops-feedback__meta, .ops-feedback__actions { display: flex; gap: 8px 14px; flex-wrap: wrap; align-items: center; }
.ops-feedback__meta { color: var(--faint); font-size: 11.5px; }
.ops-feedback__actions { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--hair); font-size: 12px; }
.ops-feedback__actions a { min-height: 32px; display: inline-flex; align-items: center; font-weight: 650; }
.ops-contact { color: var(--faint); font-size: 10px; font-weight: 750; letter-spacing: .05em; text-transform: uppercase; }
.ops-contact--yes { color: var(--teal); }
.ops-pages { display: flex; justify-content: space-between; gap: 16px; margin-top: 18px; }
.ops-pages a { display: inline-flex; align-items: center; min-height: 44px; font-size: 12.5px; font-weight: 650; }

.ops-progress-list { border-top: 1px solid var(--hair); }
.ops-progress { display: flex; justify-content: space-between; gap: 18px; align-items: center; min-height: 54px; padding: 9px 0; border-bottom: 1px solid var(--hair); color: var(--text); }
.ops-progress > span:first-child { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ops-progress strong { font-size: 13px; }
.ops-progress small { color: var(--teal); font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.ops-progress__pct { flex: 0 0 auto; font-family: var(--f-display); font-size: 15px; font-weight: 750; font-variant-numeric: tabular-nums; }
.ops-history { margin-top: 18px; border-top: 1px solid var(--hair); border-bottom: 1px solid var(--hair); }
.ops-history + .ops-history { margin-top: -1px; }
.ops-history > summary { min-height: 48px; display: flex; align-items: center; color: var(--muted); cursor: pointer; font-size: 12.5px; font-weight: 650; }
.ops-history[open] > summary { color: var(--text); }
.ops-audit { margin-top: 24px; }
.ops-audit[open] { padding-bottom: 12px; }
.ops-audit .ops-note { margin: 8px 0; overflow-wrap: anywhere; }

@media (max-width: 639px) {
  .ops { padding: 24px 16px 60px; }
  .ops-stats--hero { grid-template-columns: 1fr 1fr; }
  .ops-stats--hero .ops-stat:first-child { grid-column: 1 / -1; }
  .ops-stat { min-width: 0; padding: 13px 14px; }
  .ops-stat__n { font-size: 23px; }
  .ops-sec { margin-top: 26px; }
  .ops-sec__h { font-size: 15px; }
  .ops-attn { grid-template-columns: 34px minmax(0, 1fr) 44px; gap: 10px; }
  .ops-people, .ops-links { grid-template-columns: 1fr; }
  .ops-person__facts { grid-template-columns: 1fr 1fr; }
  .ops-rank__row { grid-template-columns: minmax(0, 1fr) 24px; }
  .ops-rank__meta { grid-column: 1; grid-row: 2; white-space: normal; }
  .ops-rank__arrow { grid-column: 2; grid-row: 1 / span 2; }
  .ops-admin { padding: 18px 16px 20px; }
  .ops-compare__head { display: none; }
  .ops-compare__row { grid-template-columns: 1fr 1fr; gap: 10px 16px; padding: 13px 0; }
  .ops-compare__metric { grid-column: 1 / -1; }
  .ops-compare__value { display: flex; flex-direction: column; gap: 2px; }
  .ops-compare__value > span { display: block; color: var(--faint); font-size: 10px; text-transform: uppercase; letter-spacing: .05em; }
  .ops-funnel { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ops-funnel__step:first-child { grid-column: 1 / -1; }
  .ops-cohort { margin-top: 30px; }
  .ops-cohort + .ops-cohort { margin-top: 34px; }
  .ops-cohort--qa { margin-right: -4px; margin-left: -4px; padding: 18px 14px; }
  .ops-score-pulse, .ops-royalty-pulse { grid-template-columns: 1fr 1fr; }
  .ops-score-pulse .ops-stat, .ops-royalty-pulse .ops-stat { padding: 12px; }
  .ops-feedback { padding: 16px; }
  .ops-feedback blockquote { font-size: 14px; }
  .ops-note-input { min-width: 0; width: 100%; }
  .ops-action { align-items: stretch; flex-direction: column; }
  .ops-action .btn { width: 100%; justify-content: center; }
  .ops-until { align-items: flex-start; flex-direction: column; }
}

/* ---- cover panel ---- */
.cover-panel {
  margin: 0; background: var(--panel); border: 1px solid var(--hair);
  border-radius: var(--r-lg); padding: 26px;
  display: flex; align-items: center; justify-content: center;
  /* FIXED, not min-: the well has to be identical for every format or switching
     to the square audiobook art shrinks the box and the whole rail jumps.

     474 = 420 image + 26 padding twice + 1 border twice. The border is the part
     the original 472 forgot, and because these boxes are border-box the missing
     2px made the min-height SMALLER than the content: at a viewport wide enough
     for the ebook cover to reach its 420px cap (~900px) the portrait well grew
     to 474 while the square one stayed pinned at 472, so switching format moved
     the rail by 2px. Every format is identical at every width now. */
  min-height: 474px;
}
.cover-panel img {
  max-width: 90%; max-height: 420px; width: auto; height: auto;
  border-radius: var(--r-cover); box-shadow: var(--sh-cover-lg);
}

/* ---- format selector (books only) ---- */
.fmt { display: flex; gap: 9px; margin-top: 18px; }
.fmt__opt {
  flex: 1; border: 1.5px solid var(--hair); border-radius: 11px;
  padding: 10px; text-align: center; cursor: pointer; display: block;
}

/* ---- guidance-paper download gate ----
   The in-panel version: a <details> whose <summary> wears the primary button's
   clothes, so the control the reader clicks is the control they expected and
   the form unfolds beneath it without leaving the page. */
/* The auto-download carrier. Not display:none — a hidden iframe is not
   guaranteed to load, and this one's whole job is to load. */
.dl-auto {
  position: absolute; width: 0; height: 0; border: 0;
  visibility: hidden; pointer-events: none;
}
.dlgate { margin-top: 24px; }   /* same separation the .action primary CTA gets */
.dlgate__btn {
  /* deliberately identical to `.action .btn-primary` — a reader must not be
     able to tell that this control opens a form rather than starting a file */
  display: block; width: 100%; text-align: center; cursor: pointer;
  background: var(--btn); color: var(--btn-t); border: none;
  font-family: var(--f-display); font-weight: 600; font-size: 15px;
  padding: 15px; border-radius: var(--r-md);
  list-style: none;
}
.dlgate__btn::-webkit-details-marker { display: none; }   /* Safari */
.dlgate__btn::marker { content: ""; }
.dlgate__btn:hover { background: var(--btn-hover); }
.dlgate__btn:focus-visible { box-shadow: 0 0 0 3px var(--paper), 0 0 0 5px var(--focus); }
.dlgate[open] .dlgate__btn { border-radius: var(--r-md) var(--r-md) 0 0; }
.dlgate__body {
  border: 1px solid var(--hair); border-top: none;
  border-radius: 0 0 var(--r-md) var(--r-md);
  padding: 15px; background: var(--panel);
}
.dlgate__note {
  font-size: 13px; line-height: 1.5; color: var(--muted); margin: 0 0 12px;
}
.dlgate__body .field { padding: 11px 13px; }

.dl-consent {
  display: flex; align-items: flex-start; gap: 9px;
  margin: 4px 0 18px; font-size: 13px; line-height: 1.45;
  color: var(--muted); cursor: pointer;
}
.dl-consent input { margin-top: 2px; flex: none; }

/* ---- format tabs: zero-JS, zero-navigation -------------------------------
   Each format's cover well and action panel are BOTH in the page; the checked
   radio decides which pair is visible. Nothing here navigates, so switching
   format can't move the scroll position — which is the entire point. The radio
   is the control (keyboard arrows work natively); the `.fmt__opt` label is its
   skin. Formats are a closed set, so three literal rules beat any cleverness. */
.work-rail > .fmtradio {
  position: absolute; width: 1px; height: 1px; opacity: 0;
  margin: 0; pointer-events: none;
}
.work-rail > .fmt-pane { display: none; }
#fmt-epub:checked  ~ .cover-panel.fmt-pane--epub,
#fmt-pdf:checked   ~ .cover-panel.fmt-pane--pdf,
#fmt-audio:checked ~ .cover-panel.fmt-pane--audio { display: flex; }
#fmt-epub:checked  ~ .action.fmt-pane--epub,
#fmt-pdf:checked   ~ .action.fmt-pane--pdf,
#fmt-audio:checked ~ .action.fmt-pane--audio { display: block; }
#fmt-epub:checked  ~ .fmt label[for="fmt-epub"],
#fmt-pdf:checked   ~ .fmt label[for="fmt-pdf"],
#fmt-audio:checked ~ .fmt label[for="fmt-audio"] {
  border-color: var(--btn); background: var(--surface);
}
/* the radio is invisible, so its focus ring has to land on the label instead —
   without this the tabs are keyboard-operable but silently so. */
#fmt-epub:focus-visible  ~ .fmt label[for="fmt-epub"],
#fmt-pdf:focus-visible   ~ .fmt label[for="fmt-pdf"],
#fmt-audio:focus-visible ~ .fmt label[for="fmt-audio"] {
  outline: 2px solid var(--btn); outline-offset: 2px;
}
.fmt__label {
  display: block; font-family: var(--f-display); font-weight: 700; font-size: 13px;
  color: var(--text);
}
.fmt__meta { display: block; font-size: 11px; color: var(--muted); margin-top: 1px; }

/* ---- action panel: one shell, four mutually exclusive bodies ---- */
.action {
  margin-top: 16px; border: 1px solid var(--hair); border-radius: var(--r-lg);
  padding: 22px; background: var(--surface);
}
.action__eyebrow {
  font-family: var(--f-display); font-weight: 700; font-size: 11px;
  letter-spacing: var(--ls-eyebrow-sm); text-transform: uppercase;
  color: var(--teal); margin: 0;
}
.action__eyebrow--green { color: var(--green); }
.action__headline {
  font-family: var(--f-display); font-weight: 700; font-size: 18px;
  color: var(--text); margin: 8px 0 0; line-height: var(--lh-heading);
}
.action .btn-primary {
  /* 24, not 16: this is the card's primary CTA and it has to read as separate
     from the copy block above it. At 16 it sat only 8px further from the
     headline than the headline sat from the eyebrow, so the button looked glued
     to the text. The note below stays at 11 so it reads as belonging to the
     button rather than floating between the two. */
  display: block; width: 100%; margin-top: 24px;
  background: var(--btn); color: var(--btn-t); border: none;
  font-family: var(--f-display); font-weight: 600; font-size: 15px;
  padding: 15px; border-radius: var(--r-md); cursor: pointer; text-align: center;
}
.action .btn-primary:hover { background: var(--btn-hover); }
.action .btn-secondary {
  display: block; width: 100%; margin-top: 10px;
  background: transparent; border: 1.5px solid var(--btn); color: var(--text);
  font-family: var(--f-display); font-weight: 600; font-size: 14px;
  padding: 13px; border-radius: var(--r-md); cursor: pointer; text-align: center;
}
.action__note { font-size: 12px; color: var(--muted); margin: 11px 0 0;
                text-align: center; line-height: 1.5; }
.action__fine { font-size: 12px; color: var(--faint); margin: 14px 0 0;
                text-align: center; line-height: 1.5; }
.action__rule { height: 1px; background: var(--hair); margin: 18px 0; }
.action__row {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 13.5px; font-weight: 600; color: var(--text);
  cursor: pointer; margin-bottom: 12px;
}
.action__row--last { margin-bottom: 0; }
.action__row span { color: var(--faint); }
.action__link {
  display: block; text-align: center; font-size: 13px; font-weight: 600;
  color: var(--coral); cursor: pointer; margin-top: 14px;
}
.action__login { color: var(--faint); margin-top: 16px; text-align: center; }
.action__login a { color: var(--coral); cursor: pointer; }

/* state B — in progress */
.action .progress {
  height: 7px; background: var(--hair); border-radius: var(--r-sm);
  margin: 13px 0 6px; overflow: hidden;
}
.action .progress__fill { height: 100%; background: var(--teal); }
.progress__meta { font-size: 12px; color: var(--muted); margin: 0; }
.action--progress .btn-primary { margin-top: 15px; }
.switch {
  display: flex; align-items: flex-start; gap: 8px; margin-top: 14px;
  font-size: 12.5px; color: var(--muted); line-height: 1.5;
}
.dot { width: 7px; height: 7px; border-radius: var(--r-pill); flex: 0 0 auto; margin-top: 5px; }
.dot--green { background: var(--green); }
.dot--teal  { background: var(--teal); }

/* state C — owned */
.owned { display: flex; align-items: center; gap: 8px; margin: 0; }
.owned__check {
  width: 20px; height: 20px; border-radius: var(--r-pill); background: var(--teal);
  display: flex; align-items: center; justify-content: center; flex: 0 0 auto;
}
.owned__label {
  font-family: var(--f-display); font-weight: 700; font-size: 14px; color: var(--text);
}

/* booksellers (signed-out, books only) */
.sellers { margin-top: 15px; padding-top: 15px; border-top: 1px solid var(--hair); }
.sellers__label {
  font-size: 11px; text-transform: uppercase; letter-spacing: var(--ls-tag);
  color: var(--faint); font-weight: 600; margin: 0 0 9px;
}
.sellers__list { display: flex; gap: 8px; flex-wrap: wrap; }
.sellers__chip {
  font-size: 12.5px; font-weight: 600; color: var(--text);
  border: 1px solid var(--hair); border-radius: var(--r-ctl);
  padding: 6px 11px; cursor: pointer; white-space: nowrap;
}

/* cross-format reassurance under the panel */
.rail-note {
  margin-top: 14px; font-size: 12.5px; color: var(--muted);
  display: flex; gap: 8px; align-items: flex-start; line-height: 1.5;
}

/* ---- main column head ---- */
.work-title {
  font-size: 46px; line-height: 1.02; margin: 14px 0 0;
  color: var(--text); letter-spacing: var(--ls-display);
}
.work-subtitle {
  font-size: 19px; color: var(--text2); margin: 14px 0 0;
  font-family: var(--f-display); font-weight: 400; line-height: 1.35;
}
.byline {
  display: flex; align-items: center; gap: 14px; margin: 16px 0 0; flex-wrap: wrap;
  font-size: 15px; color: var(--muted);
}
.byline__names { color: var(--text); font-weight: 600; }
.work-sponsor { display: flex; align-items: center; gap: .5rem; margin: .6rem 0 0; font-size: 14px; color: var(--muted); }
.work-sponsor__logo { height: 20px; width: auto; display: inline-block; vertical-align: middle; }
/* a guidance paper credits each author's employer beside the name — real data,
   but subordinate to the person it follows, so it drops both color and weight */
.byline__org { color: var(--muted); font-weight: 400; }

/* ---- endorsements ----
   1-2 quotes render as the V3 stack. 3+ become `.praise`, a one-up scroll-snap
   rail — which replaced a <details> that had 206 of the 318 harvested quotes
   behind a click. Nothing is hidden now: every quote is in normal flow, in
   source order, with no display:none anywhere.

   The rail is a native carousel before a single byte of script runs: swipe,
   trackpad, shift+wheel, scrollbar drag and — because the track is focusable —
   arrow keys, all from `overflow-x: auto` + `scroll-snap-type`. The script only
   adds the counter, the arrows and the auto-advance. */
.endorsements { display: flex; flex-direction: column; gap: 16px; margin-top: 26px; }
.quote { border-left: 3px solid var(--teal); padding: 2px 0 2px 18px; margin: 0; }
.quote__q { margin: 0; }
.quote__text {
  /* 400, not 500 — at 16px Sora italic the medium weight read as bold against
     the description below it. A pull-quote should carry by its rule and its
     italic, not by weight. */
  font-family: var(--f-display); font-weight: 400; font-size: 16px;
  color: var(--text2); line-height: 1.5; font-style: italic; margin: 0;
}
/* the design draws the quotation marks in the template, not the copy — keeping
   them in CSS means a blurb that already arrived quoted cannot end up double-
   quoted, and the marks stay out of the text a screen reader announces */
.quote__text::before { content: "\201C"; }
.quote__text::after  { content: "\201D"; }
/* the attributions ARE the argument here — 309 of 318 name a title and a
   company — so the person reads at full strength and the affiliation trails */
.quote__by { font-size: 13px; color: var(--muted); margin-top: 8px; }
.quote__by b { color: var(--text); font-weight: 600; }

/* A PANEL, not a bare block. These are other people's words about the book and
   they were reading as page copy — the tint and the heading say "this is what
   the room thinks", which is a different register from the description below. */
.praise {
  margin-top: 26px; background: var(--surface);
  border: 1px solid var(--hair); border-radius: var(--r-lg);
  padding: 20px 22px 16px;
}
.praise__head {
  font-family: var(--f-display); font-weight: 700; font-size: 13px;
  letter-spacing: .01em; color: var(--text); margin: 0 0 14px;
}
.praise__track {
  display: flex; gap: 28px; overflow-x: auto; overscroll-behavior-inline: contain;
  scroll-snap-type: x mandatory; list-style: none; margin: 0; padding: 0;
  align-items: center;
  scrollbar-width: none;              /* the control bar is the affordance */
}
.praise__track::-webkit-scrollbar { display: none; }
.praise__slide { flex: 0 0 100%; min-width: 0; scroll-snap-align: start; scroll-snap-stop: always; }
/* THE height bound. All slides share one flex line, so the track is as tall as
   its tallest quote — and per-work longest quote has a median of 458 characters
   (max 1098), so unclamped this would save nothing on exactly the jackets that
   carry the most quotes. Five lines is the same modest box on all 46 works, and
   the clamp hides the overflow visually while leaving the text in the DOM. */
.praise__slide .quote__text {
  display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical;
  line-clamp: 5; overflow: hidden;
}
/* the credit needs clamping too. Marshall Goldsmith's runs to four lines on a
   phone — "Thinkers50 #1 Executive Coach and New York Times bestselling author
   of The Earned Life, Triggers, and What Got You Here Won't Get You There" —
   which made the attribution taller than the quote it attributes. */
.praise__slide .quote__by {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  line-clamp: 2; overflow: hidden;
}
/* The control is the ROSTER, not an index. 309 of 318 attributions carry a
   title and a company, and for this reader that list is the argument — "1 / 32"
   is a position, "Courtney Kissler" is a reason to click. */
.praise__bar {
  display: none;                      /* until the script adds .is-live, so a
                                         no-JS page never ships a row of dead
                                         buttons */
  align-items: center; gap: 10px; margin-top: 12px;
}
.praise.is-live .praise__bar { display: block; }
.praise__names {
  display: flex; gap: 14px; overflow-x: auto; min-width: 0;
  padding-bottom: 3px; scrollbar-width: none;
  /* The fade means "there is more this way" — so it has to be absent at the
     ends, or the last name reads as cut off when you have in fact reached it.
     The script sets these two widths from the real scroll position. */
  --fade-l: 0px;
  --fade-r: 0px;
  mask-image: linear-gradient(90deg, transparent 0,
              #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
  -webkit-mask-image: linear-gradient(90deg, transparent 0,
              #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
}
.praise__names::-webkit-scrollbar { display: none; }
.praise__name {
  flex: 0 0 auto; background: none; border: 0; padding: 3px 0; margin: 0;
  font: inherit; font-size: 12.5px; white-space: nowrap; cursor: pointer;
  /* --muted, not --faint: these are interactive controls at 12.5px, and --faint
     measures 4.09:1 on the dark ground — under AA. --faint is for captions that
     sit on --paper, where it was tuned to 4.97:1. */
  color: var(--muted); border-bottom: 2px solid transparent;
}
.praise__name:hover { color: var(--text); }
.praise__name[aria-current="true"] {
  color: var(--text); font-weight: 600; border-bottom-color: var(--teal);
}

@media (prefers-reduced-motion: reduce) {
  /* auto-advance never starts here at all — the rail is a plain scroll-snap
     list a reader pushes themselves */
  .praise__track { scroll-behavior: auto; }
}
@media print {
  .praise__track { display: block; overflow: visible; }
  .praise__slide { break-inside: avoid; margin-bottom: 14px; }
  .praise__slide .quote__text,
  .praise__slide .quote__by { -webkit-line-clamp: unset; line-clamp: unset;
                              display: block; overflow: visible; }
  .praise__bar { display: none !important; }
}

/* the cross-format "Switch to the audiobook." control is a <label> driving the
   format radio, not a link — so it needs the affordances an <a> gave it free */
.switch__to { cursor: pointer; text-decoration: underline; }
#fmt-epub:focus-visible  ~ .action .switch__to[for="fmt-epub"],
#fmt-pdf:focus-visible   ~ .action .switch__to[for="fmt-pdf"],
#fmt-audio:focus-visible ~ .action .switch__to[for="fmt-audio"] {
  outline: 2px solid var(--btn); outline-offset: 2px;
}

/* ---- tabs: zero-JS, zero-navigation ---------------------------------------
   Same mechanism as the format switch in the rail, for the same reason. All
   three panels are in the page and the checked radio decides which one shows,
   so a tab cannot navigate — which is the fix for a real bug: as links, each
   tab's href was built from the URL's `?format=` rather than from the format
   radio the reader had clicked, so choosing Ebook on a `?format=audio` page and
   then opening Details reloaded straight back to the audiobook.

   The active tab is drawn by a `:checked ~` rule, NOT by a class or an
   `aria-selected` attribute the server baked in — CSS cannot rewrite an
   attribute, so a server-rendered active state freezes on whichever tab the URL
   named while a different panel is on screen. Tabs are a closed set of three,
   so three literal rules beat any cleverness. */
/* Absolute, so the radios take no space where they sit — and they sit right
   above `.tabs`, which is what keeps a tab click from scrolling the page. */
.work-main > .tabradio {
  position: absolute; width: 1px; height: 1px; opacity: 0;
  margin: 0; pointer-events: none;
}
.tabs { margin-top: 34px; border-bottom: 1px solid var(--hair); display: flex; gap: 28px; overflow-x: auto; }
.tab {
  font-family: var(--f-display); font-weight: 600; font-size: 14px;
  color: var(--muted); padding: 0 0 14px; cursor: pointer; white-space: nowrap; flex: 0 0 auto;
}
.work-main > .tabpanel { display: none; padding-top: 22px; }
#tab-about:checked   ~ .tabpanel.tabpane--about,
#tab-details:checked ~ .tabpanel.tabpane--details,
#tab-extras:checked  ~ .tabpanel.tabpane--extras { display: block; }
#tab-about:checked   ~ .tabs label[for="tab-about"],
#tab-details:checked ~ .tabs label[for="tab-details"],
#tab-extras:checked  ~ .tabs label[for="tab-extras"] {
  color: var(--text); box-shadow: inset 0 -2px 0 var(--teal);
}
/* the radio is invisible, so its focus ring has to land on the label instead —
   without this the tabs are keyboard-operable but silently so */
#tab-about:focus-visible   ~ .tabs label[for="tab-about"],
#tab-details:focus-visible ~ .tabs label[for="tab-details"],
#tab-extras:focus-visible  ~ .tabs label[for="tab-extras"] {
  outline: 2px solid var(--btn); outline-offset: 2px;
}

/* about panel */
.prose { font-size: 16px; line-height: 1.62; color: var(--text2); margin: 0 0 16px; }
.prose--last { margin-bottom: 20px; }
.inside__heading {
  font-family: var(--f-display); font-weight: 700; font-size: 14px;
  color: var(--text); margin: 0 0 12px;
}
.inside { display: flex; flex-direction: column; gap: 14px; list-style: none; margin: 0; padding: 0; }
.inside__item {
  display: flex; gap: 11px; align-items: flex-start;
  font-size: 15px; color: var(--text2); line-height: 1.5;
}
.inside__bullet {
  width: 18px; height: 18px; border-radius: var(--r-pill);
  background: var(--panel); border: 1px solid var(--hair);
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 auto; margin-top: 2px;
}
.inside__bullet::after {
  content: ""; width: 5px; height: 5px; border-radius: var(--r-pill); background: var(--teal);
}
/* the publisher's Features block leads each point with a short label; it sits on
   the same line, distinguished by weight and colour rather than a second row */
.inside__label { font-weight: 700; color: var(--text); }

/* ---- an author's talks, inside the author block ----
   The video library's card at two-thirds scale. It lives in the author's own
   body, so on a multi-author work it costs nothing until someone opens the
   author they were curious about. */
.atalks { margin-top: 14px; }
.atalks__head {
  /* the link sits BESIDE the label — pushed to the far edge it read as part of
     whatever was above it, a column of empty inches away from its own heading */
  display: flex; align-items: baseline; gap: 12px; margin-bottom: 9px;
}
.atalks__label {
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--faint);
}
.atalks__all { font-size: 12px; color: var(--teal); text-decoration: none; white-space: nowrap; }
.atalks__all:hover { text-decoration: underline; }
.atalks__grid {
  display: grid; gap: 12px;
  /* a FIXED-ish track, never 1fr: these are a footnote inside a bio, so a card
     is the same small size whether the author has one talk or three. With 1fr
     an author with two talks got two 880px heroes. */
  grid-template-columns: repeat(auto-fill, minmax(126px, 148px));
}
.vtalk { display: flex; flex-direction: column; gap: 7px; text-decoration: none; }
.vtalk__thumb {
  position: relative; aspect-ratio: 16 / 9; overflow: hidden;
  border-radius: var(--r-md); background: var(--panel);
  border: 1px solid var(--hair);
}
.vtalk__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vtalk:hover .vtalk__thumb { border-color: var(--teal); }
/* the overlay sits on an arbitrary video still, so it carries its own scrim
   rather than trusting the image behind it */
.vtalk__dur {
  position: absolute; right: 5px; bottom: 5px; font-size: 10px; line-height: 1;
  padding: 3px 5px; border-radius: 4px; color: #fff;
  background: rgba(6, 12, 22, .78); font-variant-numeric: tabular-nums;
}
.vtalk__ph { position: absolute; inset: 0; background: var(--panel); }
.vtalk__t {
  font-family: var(--f-display); font-weight: 600; font-size: 12px;
  line-height: 1.32; color: var(--text); margin: 0;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden;
}
.vtalk:hover .vtalk__t { color: var(--teal); }
.vtalk__s { font-size: 10.5px; color: var(--faint); margin: 2px 0 0; }

/* ---- In this issue — a journal's table of contents ----
   Built on the author-row scale from the design rather than as a new pattern:
   hairline separators, title in the display face, credit and page in muted. */
.contents { margin-top: 34px; padding-top: 30px; border-top: 1px solid var(--hair); }
.contents__heading {
  font-family: var(--f-display); font-weight: 700; font-size: 14px;
  color: var(--text); margin: 0 0 4px;
}
.contents__list { list-style: none; margin: 0; padding: 0; }
.contents__item {
  display: flex; align-items: baseline; gap: 16px;
  padding: 13px 0; border-bottom: 1px solid var(--hair);
}
.contents__item:last-child { border-bottom: 0; }
.contents__main { flex: 1 1 auto; min-width: 0; }
.contents__title {
  font-family: var(--f-display); font-weight: 600; font-size: 15px;
  color: var(--text); line-height: 1.4; text-decoration: none;
}
a.contents__title:hover { color: var(--teal); text-decoration: underline; }
.contents__authors { font-size: 13px; color: var(--muted); margin: 3px 0 0; line-height: 1.45; }
/* the employer beside a contributor's name — one step quieter again than the
   already-muted names line (the byline's own org rule is .byline__org) */
.contents__org { color: var(--faint); }
/* tabular so the numbers form a column no matter how wide the titles run */
.contents__page {
  font-size: 12.5px; color: var(--faint); flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
}

/* details panel — hairline grid built from 1px gaps */
.details {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
  background: var(--hair); border: 1px solid var(--hair);
  border-radius: var(--r-md); overflow: hidden; margin: 0;
}
.details__cell { background: var(--paper); padding: 15px 18px; }
.details__cell dt {
  font-size: 12px; color: var(--faint); text-transform: uppercase;
  letter-spacing: var(--ls-tag); font-weight: 600;
}
.details__cell dd { font-size: 15px; color: var(--text); margin: 4px 0 0; font-weight: 500; }

/* extras panel */
.extras { display: flex; flex-direction: column; gap: 12px; }
.extra {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  border: 1px solid var(--hair); border-radius: var(--r-md);
  padding: 15px 18px; cursor: pointer;
}
.extra__left { display: flex; align-items: center; gap: 12px; }
.extra__kind {
  font-size: 10px; font-weight: 700; letter-spacing: .05em; color: var(--muted);
  border: 1px solid var(--hair); border-radius: var(--r-cover); padding: 3px 7px;
}
.extra__label { font-size: 14.5px; font-weight: 600; color: var(--text); }
.extra__action { color: var(--coral); font-weight: 600; font-size: 13px; white-space: nowrap; }

/* extras panel, V3 — the tab is now three stacked blocks, not one flat list:
   a companion-title card, then the file rows above (unchanged, byte for byte),
   then a standing footnote that renders even when both blocks are empty.
   NOTE for the handler: the template now prints "{{ action }} →", so :action
   must be the bare word ("Download"), not "Download →". */
.extras__h {
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 12px;
}
.extras__h--files { margin-top: 26px; }        /* only when a guide card precedes */
.extras__h--files:first-child { margin-top: 0; }

/* companion title — a Reader's Guide is a WORK, so it gets cover + byline and
   an "Open in catalog →" CTA, never a PDF row with a Download. */
.guide {
  display: flex; align-items: center; gap: 16px;
  border: 1px solid var(--hair); border-radius: 14px;   /* matches .ask / .hl */
  padding: 16px 18px; cursor: pointer; text-decoration: none;
}
.guide__cover {
  width: 52px; height: 72px; object-fit: cover; border-radius: 4px; flex: 0 0 auto;
  box-shadow: 0 6px 16px rgba(12,12,34,.22);
}
.guide__body { flex: 1; min-width: 0; }
.guide__kind {                                  /* .extra__kind, but teal + caps */
  font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--teal); border: 1px solid var(--hair);
  border-radius: var(--r-cover); padding: 3px 7px;
}
.guide__title {
  font-family: var(--f-display); font-weight: 700; font-size: 15px;
  color: var(--text); margin: 8px 0 0; line-height: 1.3;
}
.guide__meta { font-size: 12.5px; color: var(--muted); margin: 3px 0 0; }
.guide__go {
  color: var(--coral); font-weight: 600; font-size: 13px;
  white-space: nowrap; flex: 0 0 auto;
}

/* standing note — replaces the invented "no companion downloads yet" empty
   string; build spec §9.12 ("no empty states anywhere") is now satisfied by
   the design itself. */
.extras__note {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: 12.5px; color: var(--muted); line-height: 1.5; margin-top: 18px;
}
.extras__note svg { flex: 0 0 auto; margin-top: 2px; color: var(--teal); }

/* ---- "Ask this book" teaser (books only; inert) ---- */
.ask {
  margin-top: 30px; border: 1px dashed var(--hair); border-radius: 14px;
  padding: 20px 22px; background: var(--surface);
  display: flex; align-items: center; gap: 16px;
}
.ask__icon {
  width: 40px; height: 40px; border-radius: 11px; background: var(--grad);
  flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
}
.ask__body { flex: 1; }
.ask__title {
  font-family: var(--f-display); font-weight: 700; font-size: 15px;
  color: var(--text); margin: 0;
}
.ask__sub { font-size: 13.5px; color: var(--muted); margin: 3px 0 0; }

/* ---- authors ---- */
.authors { margin-top: 34px; padding-top: 30px; border-top: 1px solid var(--hair); }
.authors__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap; margin-bottom: 18px;
}
.authors__heading {
  font-family: var(--f-display); font-weight: 700; font-size: 14px; color: var(--text);
}
.authors__count { color: var(--faint); font-weight: 500; font-size: 13px; font-family: var(--f-ui); }

.avatar {
  background: var(--grad); color: #07141b;
  font-family: var(--f-display); font-weight: 800;
  display: flex; align-items: center; justify-content: center; flex: 0 0 auto;
}
.avatar--xl { width: 82px; height: 82px; border-radius: var(--r-xl); font-size: 24px; }
.avatar--sm { width: 38px; height: 38px; border-radius: 11px; font-size: 13px; }

.author-solo { display: flex; gap: 22px; align-items: flex-start; }
.author-solo__body { flex: 1; min-width: 0; }
.author-solo__name {
  font-family: var(--f-display); font-weight: 700; font-size: 20px; color: var(--text); margin: 0;
}
.author-solo__role { font-size: 14px; color: var(--muted); margin: 3px 0 0; }
/* the current affiliation, shown against the '(at publication)' role line —
   the pair is the then/now of an author who has moved since the paper */
.author-now { font-size: 13px; color: var(--muted); margin: 6px 0 0; }
.author-row__body .author-now { margin: 0 0 8px; }
/* Provenance, not identity: when an affiliation was last verified is a
   footnote on the role line, so it steps down a size and to --faint rather
   than sharing the job title's weight. In the multi-author accordion it is
   not on the summary line at all — see detail/author-block. */
.author-asof__inline { font-size: 0.85em; color: var(--faint); font-weight: 400; }
.author-asof { font-size: 12.5px; color: var(--faint); margin: 0 0 8px; }
.author-solo__bio {
  font-size: 15px; line-height: 1.62; color: var(--text2);
  margin: 13px 0 0; max-width: var(--measure-bio);
}

/* cross-app talk chip */
.talk {
  display: inline-flex; align-items: center; gap: 11px; margin-top: 16px;
  border: 1px solid var(--hair); border-radius: var(--r-md);
  padding: 10px 16px 10px 12px; cursor: pointer; background: var(--surface);
}
.talk__play {
  width: 32px; height: 32px; border-radius: var(--r-pill); background: var(--grad);
  flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
}
.talk__eyebrow {
  display: block; font-size: 10px; letter-spacing: var(--ls-tag);
  text-transform: uppercase; color: var(--teal); font-weight: 700;
}
.talk__title {
  display: block; font-family: var(--f-display); font-weight: 600; font-size: 13.5px;
  color: var(--text); margin-top: 2px;
}
.talk__meta { color: var(--muted); font-weight: 400; }
.talk--sm { gap: 10px; margin-top: 13px; border-radius: 11px; padding: 9px 15px 9px 11px; }
.talk--sm .talk__play  { width: 28px; height: 28px; }
.talk--sm .talk__title { font-size: 13px; margin-top: 0; }

/* multi-author accordion rows */
.author-rows { display: flex; flex-direction: column; border-top: 1px solid var(--hair); }
.author-row  { border-bottom: 1px solid var(--hair); }
.author-row__head {
  display: flex; align-items: center; gap: 14px; padding: 14px 2px;
  cursor: pointer; width: 100%; background: none; border: 0; text-align: left;
}
.author-row__head::-webkit-details-marker { display: none; }
.author-row__head { list-style: none; }
.author-row__id   { flex: 1; min-width: 0; }
.author-row__name {
  font-family: var(--f-display); font-weight: 700; font-size: 15px; color: var(--text);
}
.author-row__role { font-size: 13px; color: var(--faint); margin-left: 10px; }
.author-row__caret { color: var(--faint); font-size: 12px; flex: 0 0 auto; }
.author-row[open] .caret-down, .author-row__caret .caret-up { display: none; }
.author-row[open] .caret-up { display: inline; }
.author-row__body { padding: 2px 0 20px 52px; }
.author-row__bio {
  font-size: 14.5px; line-height: 1.6; color: var(--text2);
  margin: 0; max-width: var(--measure-bio);
}

/* ---- related rail ---- */
.related { padding: 20px var(--page-pad) 46px; }
.related__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; margin-bottom: 20px;
}
.related__title { font-size: 23px; color: var(--text); }
.related__all { color: var(--coral); font-weight: 600; font-size: 13px; cursor: pointer; }

@media (max-width: 1023px) {
  .work { grid-template-columns: 1fr; gap: 28px; }
  .work-rail { position: static; max-width: 420px; }
}
@media (max-width: 859px) {
  .crumbs, .work, .related { padding-left: 24px; padding-right: 24px; }
  .work { padding-top: 28px; }
  .work-title { font-size: clamp(28px, 6vw, 46px); }
  .work-subtitle { font-size: 17px; }
  .details { grid-template-columns: 1fr; }
  .author-solo { flex-direction: column; gap: 16px; }
  .tabs { gap: 20px; }
}
@media (max-width: 559px) {
  .crumbs, .work, .related {
    padding-left: var(--page-pad-m); padding-right: var(--page-pad-m);
  }
  /* same fixed-well rule as desktop, scaled: image cap + padding twice, so the
     phone box also holds portrait and square art at one size. */
  /* same arithmetic at the narrow breakpoint: 280 + 18*2 + 1*2 */
  .cover-panel { min-height: 318px; padding: 18px; }
  .cover-panel img { max-height: 280px; }
  .author-row__body { padding-left: 0; }
}

/* ==========================================================================
   16. MEMBERSHIP PAGE (2026-09 redesign) — ink band · MCP · compare · join
   Prefix .mp-. The ink band uses the never-themed --on-ink tokens; everything
   below it runs on page tokens so the dark theme follows.
   ========================================================================== */

.mp { overflow-x: clip; }
html.mp-locked { overflow: hidden; }
.mp-wrap { max-width: var(--page-max); margin: 0 auto; padding-left: var(--page-pad); padding-right: var(--page-pad); }
.mp-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.mp-eyebrow { margin: 0; font-family: var(--f-ui); font-size: var(--fs-eyebrow); font-weight: 700;
  letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--teal); }
.mp-eyebrow--ink { color: var(--on-ink-accent); }
.mp-eyebrow--muted { color: var(--on-ink-3); }
.mp-eyebrow--free { color: #48d1a0; }
.mp-h2 { margin: 0; font-family: var(--f-display); font-weight: 700; font-size: 40px; line-height: 1.08;
  letter-spacing: -.03em; color: var(--text); text-wrap: balance; }
.mp-h2--ink { color: var(--on-ink); font-size: 48px; line-height: 1.04; }
.mp-h2--sm { font-size: 34px; }
.mp-lede { margin: 0; font-size: 16px; line-height: 1.6; color: var(--muted); text-wrap: pretty; }
.mp-lede--ink { color: var(--on-ink-4); font-size: 17px; }
.mp-head { display: flex; flex-direction: column; gap: 12px; margin-bottom: 32px; }
.mp-head--center { align-items: center; text-align: center; max-width: 820px; margin: 0 auto 8px; }
.mp-head--split { display: grid; grid-template-columns: minmax(0, 1fr) 440px; gap: 48px; align-items: end; }
.mp-head--split > div { display: flex; flex-direction: column; gap: 12px; }

.mp-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 50px;
  padding: 0 24px; border-radius: var(--r-md); font-family: var(--f-ui); font-size: 15px; font-weight: 700;
  white-space: nowrap; text-decoration: none;
  border: 0; appearance: none; cursor: pointer;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              filter var(--dur) var(--ease), color var(--dur) var(--ease);
  will-change: transform; }
.mp-btn--grad { background: var(--grad); color: var(--on-grad); }
.mp-btn--grad:hover, .mp-btn--grad:focus-visible { color: #ffffff; filter: brightness(1.06);
  transform: translateY(-1px); box-shadow: 0 8px 22px rgba(63,195,221,.22); }
.mp-btn--grad:active { transform: translateY(1px) scale(.99); }
.mp-btn--line { background: transparent; color: var(--on-ink); border: 1.5px solid rgba(255,255,255,.2); }
.mp-btn--line:hover, .mp-btn--line:focus-visible { background: rgba(255,255,255,.08); color: var(--on-ink); }
.mp-btn--ink { background: var(--btn); color: var(--btn-t); }
.mp-btn--ink:hover { background: var(--btn-hover); color: var(--btn-t); }
.mp-btn--block { display: flex; width: 100%; height: 54px; font-size: 16px; }
.mp-btn--sm { height: 38px; padding: 0 16px; font-size: 14px; }

.mp-tick { display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 20px; height: 20px; border-radius: 999px; color: #ffffff; }
.mp-tick--teal { background: var(--teal); }
.mp-tick--green { background: var(--green); }
.mp-dash { color: var(--faint); }

.mp-cover { display: block; flex: none; border-radius: var(--r-cover); object-fit: cover; box-shadow: 0 20px 44px rgba(0,0,0,.5); }
.mp-cover--sq { border-radius: 8px; }
.mp-cover--paper { border-radius: 4px; }
.mp-photo { display: block; flex: none; width: 176px; height: 176px; border-radius: 10px; object-fit: cover; box-shadow: 0 20px 44px rgba(0,0,0,.5); }

/* ---- the ink band ------------------------------------------------------ */
.mp-ink { background: var(--ink); color: var(--on-ink-2); }
.mp-hero { position: relative; padding: 92px var(--page-pad) 0; text-align: center; }
.mp-hero__glow { position: absolute; left: 50%; top: -160px; width: 1000px; max-width: 100%; height: 620px;
  transform: translateX(-50%); background: radial-gradient(closest-side, rgba(15,159,190,.28), rgba(12,12,34,0)); pointer-events: none; }
.mp-hero__inner { position: relative; display: flex; flex-direction: column; align-items: center; gap: 22px; }
.mp-hero__h { margin: 0; font-family: var(--f-display); font-weight: 800; font-size: 80px; line-height: .98;
  letter-spacing: -.04em; color: var(--on-ink); }
.mp-hero__promise { margin: 0; font-family: var(--f-display); font-size: 24px; font-weight: 500; letter-spacing: -.02em; color: var(--on-ink); }
.mp-hero__lede { margin: 0; max-width: 600px; font-size: 17px; line-height: 1.6; color: var(--on-ink-4); text-wrap: pretty; }
.mp-hero__cta { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 8px; }
.mp-hero__fine { margin: 0; font-size: 13px; color: var(--on-ink-3); }
.mp-hero__fine a { color: var(--on-ink-accent); }

.mp-strip { position: relative; margin-top: 52px; padding-bottom: 64px; overflow: hidden; }
.mp-strip::before, .mp-strip::after { content: ""; position: absolute; top: 0; bottom: 0; width: 90px; z-index: 1; pointer-events: none; }
.mp-strip::before { left: 0; background: linear-gradient(90deg, var(--ink), rgba(12,12,34,0)); }
.mp-strip::after { right: 0; background: linear-gradient(270deg, var(--ink), rgba(12,12,34,0)); }
.mp-strip__row { display: flex; align-items: flex-end; justify-content: center; gap: 14px; width: 1440px;
  position: relative; left: 50%; transform: translateX(-50%); }
.mp-strip__sample { position: relative; display: block; flex: none; border-radius: var(--r-cover);
  border: 2px solid var(--on-ink-accent); box-shadow: 0 20px 44px rgba(0,0,0,.5);
  transform-origin: center bottom;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease); }
.mp-strip__sample--static { cursor: default; }
.mp-strip__sample .mp-cover { box-shadow: none; }
.mp-strip__sample:hover, .mp-strip__sample:focus-visible { border-color: var(--on-ink-accent);
  transform: none;
  box-shadow: 0 0 30px rgba(63,195,221,.58), 0 0 0 2px rgba(63,195,221,.7),
              0 24px 50px rgba(0,0,0,.55); }
.mp-strip__sample:active { transform: none; }
.mp-strip__pill { position: absolute; left: 50%; bottom: -13px; transform: translateX(-50%); display: inline-flex;
  align-items: center; gap: 6px; height: 26px; padding: 0 11px 0 9px; border-radius: 999px; background: var(--on-ink-accent);
  color: #06121a; font-size: 12px; font-weight: 700; white-space: nowrap; box-shadow: 0 6px 16px rgba(0,0,0,.45); }
.mp-strip__pill svg { width: 13px; height: 13px; }

.mp-coursetile { flex: none; width: 264px; box-sizing: border-box; display: grid; grid-template-columns: 56px minmax(0, 1fr);
  gap: 12px; align-items: center; padding: 14px 14px 14px 12px; border-radius: 12px; background: #123548;
  border: 1px solid rgba(63,195,221,.45); box-shadow: 0 20px 44px rgba(0,0,0,.5); text-align: left; }
.mp-coursetile__faces { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.mp-coursetile__faces img { display: block; width: 48px; height: 48px; border-radius: 999px; object-fit: cover; border: 2px solid var(--on-ink-accent); }
.mp-coursetile__title { margin: 0; font-family: var(--f-display); font-weight: 600; font-size: 14px; line-height: 1.25; color: #ffffff; }
.mp-coursetile__meta { margin: 4px 0 0; font-size: 12px; line-height: 1.4; color: #a9d9e4; }

.mp-proof { padding: 32px 0 0; }
.mp-stats { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); margin: 0; border-top: 1px solid #25254e; border-bottom: 1px solid #25254e; }
.mp-stat { min-width: 0; padding: 26px 14px; border-right: 1px solid #25254e; text-align: left; }
.mp-stat:first-child { padding-left: 0; }
.mp-stat:last-child { border-right: none; }
.mp-stat__v { font-family: var(--f-display); font-weight: 800; font-size: clamp(28px, 2.6vw, 38px); letter-spacing: -.04em; line-height: 1; white-space: nowrap; color: var(--on-ink); }
.mp-stat__l { margin: 8px 0 0; font-size: 13px; color: var(--on-ink-3); }
.mp-logos { display: flex; flex-direction: column; align-items: center; gap: 18px; padding: 32px 0 0; }
.mp-logos__h { margin: 0; font-size: 12px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: var(--on-ink-3); }
.mp-logos__grid { list-style: none; margin: 0; padding: 0; width: 100%; display: grid; grid-template-columns: repeat(15, minmax(0, 1fr)); gap: 16px 14px; justify-items: center; }
.mp-logo img { display: block; box-sizing: content-box; width: 22px; height: 22px; padding: 6px 10px; border-radius: 6px; background: #f3f5fb; object-fit: contain; }
.mp-logos__credit { margin: 0; font-size: 11px; }
.mp-logos__credit a { color: var(--on-ink-3); }

.mp-thread { padding: 112px var(--page-pad) 96px; }
.mp-thread__list { position: relative; list-style: none; margin: 24px auto 0; padding: 0; max-width: var(--page-max); display: flex; flex-direction: column; gap: 56px; }
.mp-thread__list::before { content: ""; position: absolute; left: 50%; top: 0; bottom: 0; width: 2px; margin-left: -1px;
  background: linear-gradient(180deg,#0cabca 0%,#23b8b4 52%,#38c89b 100%); opacity: .8; }
.mp-stop { display: grid; grid-template-columns: minmax(0, 1fr) 120px minmax(0, 1fr); align-items: center; }
.mp-stop__text { display: flex; flex-direction: column; gap: 8px; }
.mp-stop--left .mp-stop__text { align-items: flex-end; text-align: right; padding-right: 8px; }
.mp-stop--right .mp-stop__text { align-items: flex-start; padding-left: 8px; }
.mp-stop--left .mp-stop__art { display: flex; justify-content: flex-start; padding-left: 8px; }
.mp-stop--right .mp-stop__art { display: flex; justify-content: flex-end; padding-right: 8px; }
.mp-stop__dot { justify-self: center; position: relative; z-index: 1; width: 14px; height: 14px; border-radius: 999px; background: var(--ink); border: 3px solid #23b8b4; }
.mp-stop__h { margin: 0; font-family: var(--f-display); font-size: 24px; font-weight: 700; letter-spacing: -.02em; color: var(--on-ink); }
.mp-stop__p { margin: 0; font-size: 15px; color: var(--on-ink-4); max-width: 420px; }
.mp-chip { display: inline-flex; align-items: center; gap: 8px; height: 30px; padding: 0 12px; border-radius: 999px; background: #12122a;
  border: 1px solid #25254e; color: var(--on-ink); font-size: 12px; font-weight: 700; }
.mp-chip svg { width: 12px; height: 12px; color: var(--on-ink-accent); }
.mp-chip--free { border-color: rgba(72,209,160,.4); }
.mp-chip--free svg { color: #48d1a0; }
.mp-cover--lg { width: 150px; height: auto; }
.mp-cover--lgsq { width: 176px; height: 176px; }
.mp-stop__play { position: relative; display: block; }
.mp-stop__playbtn { position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); width: 48px; height: 48px; border-radius: 999px;
  background: rgba(255,255,255,.92); color: #0c0c22; display: flex; align-items: center; justify-content: center; }
.mp-stop__playbtn svg { width: 16px; height: 16px; }
.mp-still { display: block; width: 320px; max-width: 100%; height: auto; aspect-ratio: 16 / 9; border-radius: 12px; object-fit: cover; box-shadow: 0 20px 44px rgba(0,0,0,.5); }
.mp-lessons { width: 300px; max-width: 100%; box-sizing: border-box; padding: 18px; border-radius: 14px; background: #12122a; border: 1px solid #25254e; box-shadow: 0 20px 44px rgba(0,0,0,.5); }
.mp-lessons__course { margin: 0 0 12px; font-family: var(--f-display); font-weight: 600; font-size: 15px; color: #ffffff; }
.mp-lessons ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; font-size: 13px; color: var(--on-ink-3); }
.mp-lessons li { display: flex; align-items: center; gap: 10px; }
.mp-lessons li.is-done { color: #48d1a0; }
.mp-lessons li.is-done .mp-tick { width: 16px; height: 16px; }
.mp-lessons li.is-now { color: #ffffff; font-weight: 600; }
.mp-lessons__ring { width: 16px; height: 16px; flex: none; border-radius: 999px; border: 1.6px solid #25254e; display: inline-flex; align-items: center; justify-content: center; }
.is-now .mp-lessons__ring { border-color: var(--on-ink-accent); color: var(--on-ink-accent); }
.is-now .mp-lessons__ring svg { width: 8px; height: 8px; }

/* ---- MCP ---------------------------------------------------------------- */
.mp-mcp { background: var(--bg); border-bottom: 1px solid var(--hair); padding: 88px 0 96px; }
.mp-ev { display: grid; grid-template-columns: 420px minmax(0, 1fr); border: 1px solid #25254e; border-radius: 12px; overflow: hidden;
  box-shadow: 0 24px 60px rgba(12,12,34,.18); background: #0c0c22; }
.mp-ev__ask { padding: 26px 28px; border-right: 1px solid #25254e; background: #12122a; display: flex; flex-direction: column; gap: 14px; }
.mp-ev__label { margin: 0; font-size: 11px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: var(--on-ink-3); }
.mp-ev__chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.mp-ev__chip { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 9px; border-radius: 999px; background: #1f1f44;
  border: 1px solid #2f2f5e; color: var(--on-ink-2); font-size: 11.5px; font-weight: 600; }
.mp-ev__dot { width: 6px; height: 6px; border-radius: 999px; background: #2fcf94; }
.mp-ev__chip--lib { background: rgba(63,195,221,.14); border-color: rgba(63,195,221,.4); color: var(--on-ink-accent); font-weight: 700; }
.mp-ev__chip--lib .mp-ev__dot { background: var(--on-ink-accent); }
.mp-ev__q { margin: 4px 0 0; font-family: var(--f-read); font-size: 21px; line-height: 1.35; color: #ffffff; }
.mp-ev__a { margin: 0; font-size: 14px; line-height: 1.55; color: var(--on-ink-4); }
.mp-ev__foot { margin: auto 0 0; display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--on-ink-3); }
.mp-ev__row { display: grid; grid-template-columns: 120px minmax(0, 1fr) 140px; gap: 16px; align-items: center; padding: 16px 24px; border-bottom: 1px solid #25254e; }
.mp-ev__row:last-child { border-bottom: none; }
.mp-ev__row--head { padding-top: 14px; padding-bottom: 14px; font-size: 11px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: var(--on-ink-3); }
.mp-ev__src { display: flex; align-items: center; gap: 10px; }
.mp-ev__tag { font-size: 11px; font-weight: 700; text-transform: uppercase; color: var(--on-ink-accent); }
.mp-ev__title { margin: 0; font-size: 14px; font-weight: 600; color: #ffffff; }
.mp-ev__meta { margin: 2px 0 0; font-size: 13px; color: var(--on-ink-4); }
.mp-ev__open { font-size: 13px; font-weight: 700; color: var(--on-ink-accent); }
.mp-ev--yours { color: var(--on-ink-2); }
.mp-ev__board { width: 56px; height: 36px; border-radius: 3px; background: #1f1f44; border: 1px dashed #3a3a6e; display: flex; align-items: center; justify-content: center; color: var(--on-ink-2); }
.mp-ev__cover { display: block; width: 30px; height: 45px; border-radius: 3px; object-fit: cover; }
.mp-ev__still { display: block; width: 56px; height: 32px; border-radius: 3px; object-fit: cover; }

/* ---- compare ------------------------------------------------------------ */
.mp-compare { background: var(--paper); padding: 96px 0 64px; }
.mp-table { width: 100%; border-collapse: collapse; font-size: 15px; color: var(--text2); }
.mp-table th, .mp-table td { padding: 14px 0; border-top: 1px solid var(--hair); text-align: center; font-weight: 400; }
.mp-table tbody tr:last-child th, .mp-table tbody tr:last-child td { border-bottom: 1px solid var(--hair); }
.mp-table tbody th { text-align: left; padding-right: 16px; }
.mp-table thead th { border-top: none; padding-top: 0; font-size: 11px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: var(--muted); }
.mp-table td, .mp-table thead th + th { width: 180px; }
.mp-table .mp-tick { width: 22px; height: 22px; }
.mp-compare__free { margin: 20px 0 0; font-size: 15px; font-weight: 600; }
.mp-compare__free a { color: var(--teal); }

/* ---- join --------------------------------------------------------------- */
.mp-join { background: var(--bg); border-top: 1px solid var(--hair); border-bottom: 1px solid var(--hair); padding: 80px 0; }
.mp-join__grid { display: grid; grid-template-columns: minmax(0, 1fr) 460px; gap: 48px; align-items: start; }
.mp-join__copy { display: flex; flex-direction: column; gap: 20px; }
.mp-includes { list-style: none; margin: 6px 0 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 24px; }
.mp-includes li { display: flex; gap: 10px; align-items: flex-start; font-size: 15px; color: var(--text2); }
.mp-includes .mp-tick { width: 18px; height: 18px; margin-top: 2px; }
.mp-enterprise { margin-top: 10px; padding: 16px 18px; border-radius: 12px; border: 1px dashed var(--faint); display: flex; align-items: center; gap: 14px; }
.mp-enterprise p { margin: 0; font-size: 14px; color: var(--muted); }
.mp-enterprise strong { color: var(--text); font-weight: 600; }
.mp-enterprise__tag { flex: none; padding: 3px 8px; border-radius: 4px; font-size: 11px; font-weight: 700; letter-spacing: .06em; background: rgba(201,138,26,.14); color: #a06e12; }
.mp-plan { padding: 32px; border-radius: var(--r-lg); background: var(--card); box-shadow: var(--sh-md); display: flex; flex-direction: column; gap: 16px; }
.mp-plan__options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 0; padding: 0; border: 0; min-width: 0; }
.mp-option { position: relative; display: block; cursor: pointer; }
.mp-option__radio { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.mp-option__card { position: relative; height: 100%; box-sizing: border-box; padding: 18px 16px; border-radius: 12px; border: 2px solid var(--hair); display: flex; flex-direction: column; gap: 6px; transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease); }
.mp-option:hover .mp-option__card { border-color: var(--faint); }
.mp-option__radio:checked + .mp-option__card { border-color: var(--teal); background: var(--teal-08); }
.mp-option__radio:focus-visible + .mp-option__card { outline: 2px solid var(--teal); outline-offset: 2px; }
.mp-option__badge { position: absolute; right: 12px; top: -11px; padding: 3px 8px; border-radius: 4px; background: var(--teal); color: #ffffff; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.mp-option__label { font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.mp-option__radio:checked + .mp-option__card .mp-option__label { color: var(--teal); }
.mp-option__price { display: flex; align-items: baseline; gap: 4px; }
.mp-option__amount { font-family: var(--f-display); font-weight: 800; font-size: 40px; letter-spacing: -.04em; line-height: 1; color: var(--text); }
.mp-option__unit { font-size: 14px; color: var(--muted); }
.mp-option__note { font-size: 13px; color: var(--faint); }
.mp-plan__terms { margin: 0; font-size: 13px; color: var(--muted); }
.mp-plan__apps { margin: 0; font-size: 13px; color: var(--faint); text-align: center; }

/* ---- terms + faq -------------------------------------------------------- */
.mp-terms { background: var(--paper); padding: 80px 0 72px; }
.mp-terms__grid { display: grid; grid-template-columns: 360px minmax(0, 1fr); gap: 64px; }
.mp-terms__side { display: flex; flex-direction: column; gap: 14px; }
.mp-restore { margin-top: 8px; padding: 22px; border-radius: 12px; background: var(--surface); border: 1px solid var(--hair); display: flex; flex-direction: column; gap: 10px; }
.mp-restore__tag { align-self: flex-start; padding: 3px 8px; border-radius: 4px; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; background: rgba(201,138,26,.14); color: #a06e12; }
.mp-restore__h { margin: 0; font-family: var(--f-display); font-weight: 600; font-size: 16px; color: var(--text); }
.mp-restore__p { margin: 0; font-size: 14px; color: var(--muted); }
.mp-restore a { font-size: 14px; font-weight: 600; color: var(--teal); }
.mp-faq { margin: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 40px; }
.mp-faq__item { padding-top: 16px; border-top: 1px solid var(--hair); }
.mp-faq dt { font-size: 16px; font-weight: 600; color: var(--text); }
.mp-faq dd { margin: 6px 0 0; font-size: 14px; line-height: 1.55; color: var(--muted); }

/* ---- closing ------------------------------------------------------------ */
.mp-close { background: var(--paper); padding: 0 0 80px; }
.mp-close__bar { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 40px; align-items: center; padding: 40px 0;
  border-top: 1px solid var(--text); border-bottom: 1px solid var(--text); }
.mp-close__bar > div { display: flex; flex-direction: column; gap: 10px; }

/* ---- the free sample dialog -------------------------------------------- */
.mp-sample { width: min(1344px, calc(100vw - 48px)); height: calc(100vh - 48px); max-width: none; max-height: none; padding: 0;
  border: none; border-radius: 16px; overflow: hidden; background: var(--paper); box-shadow: 0 34px 80px rgba(0,0,0,.6); }
.mp-sample[open] { display: flex; flex-direction: column; }
.mp-sample::backdrop { background: rgba(6,6,18,.72); }
.mp-sample__bar { flex: none; height: 60px; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 0 16px; border-bottom: 1px solid var(--hair); }
.mp-sample__close { display: inline-flex; align-items: center; gap: 8px; height: 38px; padding: 0 12px; border-radius: 10px; border: 1px solid var(--hair);
  background: var(--surface); color: var(--text); font: 600 14px var(--f-ui); cursor: pointer; }
.mp-sample__title { display: inline-flex; align-items: center; gap: 10px; font-family: var(--f-display); font-weight: 600; font-size: 15px; color: var(--text); }
.mp-sample__tag { padding: 3px 8px; border-radius: 4px; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; background: rgba(34,176,131,.12); color: #1a8f69; }
.mp-sample__frame { flex: 1; width: 100%; border: 0; display: block; }

/* ---- responsive --------------------------------------------------------- */
@media (max-width: 1180px) {
  .mp-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .mp-stat { border-right: none; padding-left: 0; }
}
@media (max-width: 1100px) {
  .mp-hero__h { font-size: 64px; }
  .mp-logos__grid { grid-template-columns: repeat(10, minmax(0, 1fr)); }
  .mp-head--split, .mp-join__grid, .mp-terms__grid { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  .mp-ev { grid-template-columns: minmax(0, 1fr); }
  .mp-ev__ask { border-right: none; border-bottom: 1px solid #25254e; }
}
@media (max-width: 760px) {
  .mp-wrap { padding-left: var(--page-pad-m); padding-right: var(--page-pad-m); }
  .mp-hero { padding: 64px var(--page-pad-m) 0; }
  .mp-hero__h { font-size: 44px; }
  .mp-hero__promise { font-size: 20px; }
  .mp-hero__cta { flex-direction: column; align-items: stretch; width: 100%; }
  .mp-hero__cta .mp-btn { white-space: normal; }
  /* the strip becomes a swipe row on phones, Vibe Coding first */
  .mp-strip { margin-top: 36px; padding-bottom: 40px; }
  .mp-strip::before { display: none; }
  .mp-strip::after { width: 48px; }
  .mp-strip__row { width: auto; left: 0; transform: none; justify-content: flex-start; gap: 12px;
    overflow-x: auto; padding: 16px var(--page-pad-m) 24px; scroll-padding-left: var(--page-pad-m); scroll-snap-type: x proximity; scrollbar-width: none; }
  .mp-strip__row::-webkit-scrollbar { display: none; }
  .mp-strip__row > * { scroll-snap-align: start; }
  .mp-strip__sample { order: -1; }
  .mp-h2 { font-size: 30px; }
  .mp-h2--ink { font-size: 34px; }
  .mp-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mp-stat__v { font-size: 34px; }
  .mp-logos__grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .mp-thread { padding: 72px var(--page-pad-m) 64px; }
  .mp-thread__list::before { left: 7px; margin-left: 0; }
  .mp-stop, .mp-stop--left, .mp-stop--right { grid-template-columns: 16px minmax(0, 1fr); gap: 8px 18px; align-items: start; }
  .mp-stop__dot { grid-column: 1; grid-row: 1; justify-self: start; margin-top: 4px; }
  .mp-stop .mp-stop__text { grid-column: 2; grid-row: 1; align-items: flex-start; text-align: left; padding: 0; }
  .mp-stop .mp-stop__art { grid-column: 2; grid-row: 2; justify-content: flex-start; padding: 0; }
  .mp-still { width: 100%; max-width: 400px; }
  .mp-lessons { width: 100%; max-width: 400px; }
  .mp-ev__row { grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 14px 18px; }
  .mp-ev__row--head { display: none; }
  .mp-table td, .mp-table thead th + th { width: 64px; }
  .mp-table thead th { font-size: 10px; letter-spacing: .06em; }
  .mp-includes, .mp-faq, .mp-plan__options { grid-template-columns: minmax(0, 1fr); }
  .mp-plan { padding: 22px; }
  .mp-close__bar { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .mp-close__bar .mp-btn { white-space: normal; }
  .mp-sample { width: 100vw; height: 100vh; border-radius: 0; }
  .mp-sample__title { display: none; }
}


/* ==========================================================================
   17. CHECKOUT
   ========================================================================== */

.cobar {
  background: var(--ink); height: 56px;
  display: flex; align-items: center; justify-content: space-between; padding: 0 26px;
}
.cobar__logo   { height: 19px; }
.cobar__secure { display: inline-flex; align-items: center; gap: 7px;
                 font-size: 12px; color: var(--on-ink-4); }

/* V3 inverts this: the order summary moved to the FIRST grid track and the
   ratio flipped (was 1.1fr .9fr, form left). `.cosum { order: -1 }` does the
   move without touching the hiccup, and is already what the mobile rule does. */
.cowrap {
  max-width: 960px; margin: 0 auto; padding: 54px var(--page-pad);
  display: grid; grid-template-columns: .85fr 1.15fr; gap: 34px; align-items: start;
}
.cowrap .cosum { order: -1; }
.coform__h1   { font-size: 26px; }
.coform__lead { font-size: 14px; color: var(--muted); margin: 8px 0 24px; }
.coform .field { margin: 7px 0 18px; }
.coform__trust {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  font-size: 12px; color: var(--faint); margin-top: 14px;
}

/* Stripe Elements mounts inside .cardbox */
.cardbox {
  border: 1.5px solid var(--hair); border-radius: 11px; overflow: hidden;
  margin: 7px 0 18px; background: var(--field);
}
.cardbox__row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 13px 15px; border-bottom: 1px solid var(--hair);
}
.cardbox__num    { font-size: 15px; color: var(--text); letter-spacing: .06em; }
.cardbox__brands { display: flex; gap: 4px; }
.brand      { width: 26px; height: 16px; border-radius: 3px; display: block; }
.brand--visa{ background: linear-gradient(90deg,#1a1f71,#2b3a9c); }
.brand--mc  { background: linear-gradient(90deg,#eb001b,#f79e1b); }
.cardbox__split { display: flex; }
.cardbox__cell  { flex: 1; padding: 13px 15px; font-size: 15px; color: var(--text); }
.cardbox__cell:first-child { border-right: 1px solid var(--hair); }

.cosum {
  background: var(--paper); border: 1px solid var(--hair);
  border-radius: 18px; padding: 24px;
}
.cosum__price  { display: flex; align-items: baseline; gap: 7px; margin: 10px 0 0; }
.cosum__amount { font-family: var(--f-display); font-weight: 800; font-size: 32px; color: var(--text); }
.cosum__unit   { font-size: 14px; color: var(--muted); }
.cosum .checks { margin: 18px 0; }
.cosum__code   { font-size: 13px; color: var(--coral); font-weight: 600; cursor: pointer; }
.cosum__due    { display: flex; justify-content: space-between; font-size: 14px;
                 color: var(--text2); margin: 0; }
.cosum__total  { font-family: var(--f-display); font-weight: 700; color: var(--text); }
.cosum__renew  { font-size: 12px; color: var(--faint); margin: 10px 0 0; line-height: 1.5; }

@media (max-width: 859px) {
  .cowrap { padding: 32px 20px; grid-template-columns: 1fr; }
  /* the summary-first `order: -1` moved up to .cowrap .cosum — V3 puts the
     summary first at every width, so the mobile-only override is redundant */
}

/* ==========================================================================
   18. WELCOME / FIRST RUN
   ========================================================================== */

.welcome { max-width: 940px; margin: 0 auto; padding: 54px var(--page-pad); text-align: center; }
.okball {
  width: 60px; height: 60px; border-radius: var(--r-pill); background: var(--green);
  display: flex; align-items: center; justify-content: center; margin: 0 auto 20px;
}
.welcome__h1   { font-size: 40px; }
.welcome__lead { font-size: 16px; color: var(--muted); max-width: 520px;
                 margin: 14px auto 0; line-height: var(--lh-body); }

.unlocked {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin: 34px 0;
  text-align: left; list-style: none; padding: 0;
}
.unlock    { background: var(--paper); border: 1px solid var(--hair);
             border-radius: 15px; padding: 20px; }
.unlock__t { font-family: var(--f-display); font-weight: 700; font-size: 14.5px; color: var(--text); }
.unlock__m { font-size: 12.5px; color: var(--muted); margin: 3px 0 0; }

.firstmove {
  background: var(--ink); border-radius: var(--r-xl); padding: 32px;
  display: grid; grid-template-columns: 1.4fr .6fr; gap: 24px;
  align-items: center; text-align: left;
}
.firstmove__h2   { font-size: 24px; color: #fff; margin: 10px 0 0; line-height: 1.15; }
.firstmove__body { font-size: 14px; color: var(--on-ink-2); margin: 10px 0 18px; line-height: 1.5; }
.firstmove__alt  { display: inline-block; color: var(--on-ink-accent);
                   font-family: var(--f-display); font-weight: 600; font-size: 13.5px;
                   margin-left: 16px; cursor: pointer; }
.firstmove__art  { display: flex; justify-content: center; }
.firstmove__art img { height: 190px; border-radius: var(--r-cover);
                      box-shadow: 0 18px 40px rgba(0,0,0,.4); }

@media (max-width: 859px) {
  .welcome { padding: 32px 20px; }
  .welcome__h1 { font-size: 32px; }
  .unlocked { grid-template-columns: 1fr 1fr; }
  .firstmove { grid-template-columns: 1fr; padding: 24px; }
  .firstmove__art img { height: 150px; }
}

/* ==========================================================================
   19. ACCOUNT / MY MEMBERSHIP
   ========================================================================== */

.acct { max-width: 840px; margin: 0 auto; padding: 54px var(--page-pad); }
.crumb { font-size: 12.5px; color: var(--muted); margin-bottom: 16px; }
.crumb span[aria-hidden] { color: var(--faint); }
.crumb__now { color: var(--text); font-weight: 600; }
.acct__h1   { font-size: 28px; margin-bottom: 22px; }
.acct__card { border-radius: 18px; padding: 26px; margin-bottom: 16px; }
/* A card that follows anything but another card gets its own top gap: the
   intro line (.acct__meta) is a caption with no bottom margin, so pages that
   open with a sentence above a card were butting them together (Alex,
   2026-09-05). Vertical margins collapse, so an h1's 22px stays 22px and a
   card stack stays 16px apart. */
.acct > :not(.acct__card) + .acct__card { margin-top: 18px; }
.acct__head { display: flex; justify-content: space-between; align-items: flex-start;
              flex-wrap: wrap; gap: 16px; }
.acct__plan { display: flex; align-items: center; gap: 9px; margin: 0; }
.acct__planname { font-family: var(--f-display); font-weight: 700; font-size: 18px; color: var(--text); }
.acct__meta    { font-size: 13.5px; color: var(--muted); margin: 6px 0 0; }
.acct__actions { display: flex; gap: 10px; flex-wrap: wrap; }
.acct__pm { display: flex; align-items: center; gap: 12px; margin: 0;
            font-size: 13.5px; color: var(--text2); }
.pmchip { width: 40px; height: 26px; border-radius: var(--r-cover); flex: 0 0 auto; }
.pmchip--visa { background: linear-gradient(90deg,#1a1f71,#2b3a9c); }

.acct__sub { font-family: var(--f-display); font-weight: 700; font-size: 15px;
             color: var(--text); margin: 0 0 14px; }
.invoices  { list-style: none; margin: 0; padding: 0; }
.invoice   { display: flex; align-items: center; justify-content: space-between;
             gap: 16px; padding: 12px 0; border-bottom: 1px solid var(--hair); }
.invoice:last-child { border-bottom: none; }
.invoice__date  { font-size: 14px; color: var(--text); font-weight: 600; margin: 0; }
.invoice__desc  { font-size: 12px; color: var(--faint); margin: 0; }
.invoice__right { display: flex; align-items: center; gap: 16px; }
.invoice__amt   { font-size: 14px; color: var(--text2); font-family: var(--f-display); }
.invoice__dl    { font-size: 12.5px; font-weight: 600; color: var(--coral); cursor: pointer;
                  padding: 12px 0; }

/* cancellation: normal-weight outline button, always visible, no retention maze */
.cancel {
  background: var(--surface); border: 1px solid var(--hair); border-radius: 18px;
  padding: 24px; display: flex; justify-content: space-between; align-items: center;
  gap: 16px; flex-wrap: wrap;
}
.cancel__t { font-family: var(--f-display); font-weight: 700; font-size: 15px; color: var(--text); }
.cancel__b { font-size: 13px; color: var(--muted); margin: 4px 0 0; max-width: 440px; line-height: 1.5; }
.cancel__btn { white-space: nowrap; }

@media (max-width: 859px) {
  .acct { padding: 32px 20px; }
  .acct__urlrow { align-items: flex-start; flex-direction: column; gap: 7px; }
  .acct__savebar--handle { width: min(100%, 460px); }
}

/* ==========================================================================
   20. CONTEXTUAL GATE  (reader paywall — always the LIGHT reading surface)
       The blurred layer is real free-preview content, aria-hidden. Never ship
       gated text to the client; blur is decoration, not access control.
   ========================================================================== */

.gate {
  position: relative; width: 100%; min-height: 760px; min-height: 100dvh;
  overflow: hidden; background: #faf9f5;
}
.gate__content {
  position: absolute; inset: 0; padding: 70px 12% 0;
  filter: blur(3px); opacity: .5;
  font-family: var(--f-read); font-size: 19px; line-height: 1.7; color: #20242c;
}
.gate__chap {
  font-family: var(--f-display); font-weight: 600; font-size: 12px;
  letter-spacing: .14em; text-transform: uppercase; color: #9aa1ab; margin-bottom: 22px;
}
.gate__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(to bottom, rgba(250,249,245,.2), rgba(250,249,245,.92) 55%);
}
.gate__invite {
  position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
  width: 640px; max-width: 94%;
  background: var(--paper); border: 1px solid var(--hair);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  box-shadow: 0 -20px 60px rgba(12,12,34,.2);
  padding: 36px 40px 44px; text-align: center;
}
.gate__h    { font-size: 30px; margin: 12px 0 0; line-height: 1.15; }
.gate__body { font-size: 14.5px; color: var(--muted); max-width: 460px;
              margin: 12px auto 0; line-height: var(--lh-body); }
.gate__cta  { display: flex; gap: 12px; justify-content: center; margin-top: 22px; flex-wrap: wrap; }
.gate__escape { font-size: 12.5px; color: var(--faint); margin-top: 16px; }

@media (max-width: 859px) {
  .gate { min-height: 680px; min-height: 100dvh; }
  .gate__invite { padding: 28px 22px 34px; }
  .gate__h { font-size: 24px; }
}

/* ==========================================================================
   21. RETURNING-CUSTOMER RECOGNITION  (/welcome-back)
   ========================================================================== */

.retscreen {
  background: var(--bg); min-height: 100vh; min-height: 100dvh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 48px;
}
.retcard {
  width: 560px; max-width: 100%; background: var(--card);
  border: 1px solid var(--hair); border-radius: 22px;
  box-shadow: 0 30px 70px rgba(12,12,34,.16); overflow: hidden;
}
.retcard__top  { background: var(--ink); padding: 40px 40px 36px; text-align: center; }
.retcard__logo { height: 20px; margin: 0 auto 20px; }
.retcard__h1   { font-size: 32px; color: #fff; line-height: 1.12; }
.retcard__lead { font-size: 15px; color: var(--on-ink-2); max-width: 480px;
                 margin: 14px auto 0; line-height: var(--lh-body); }
.retcard__lead b { color: #fff; }

.retcard__covers { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;
                   margin: 24px 0 0; padding: 0; list-style: none; }
.retcard__covers li  { position: relative; }
.retcard__covers img { height: 118px; border-radius: 4px; box-shadow: 0 14px 30px rgba(0,0,0,.4); }
.owncheck {
  position: absolute; top: -7px; right: -7px; width: 22px; height: 22px;
  border-radius: var(--r-pill); background: var(--green); border: 2px solid var(--ink);
  display: flex; align-items: center; justify-content: center;
}

.retcard__body { padding: 28px; }
.consent {
  display: flex; gap: 12px; align-items: flex-start;
  background: var(--surface); border: 1px solid var(--hair);
  border-radius: var(--r-md); padding: 15px; cursor: pointer;
}
.consent__text { font-size: 13.5px; color: var(--text2); line-height: 1.5; }
/* V3 makes the consent box real: unchecked by DEFAULT, and it gates the CTA.
   Unchecked border darkens --hair -> --muted so the empty box is visible.
   SCOPED ON PURPOSE: V3 also wants the disabled CTA at --hair on --faint,
   which is far lower contrast than the global --btn-disabled/#fff pairing.
   One screen is not enough to redefine .btn[aria-disabled] globally, so this
   variant lives on .retcard__go only. Flagged for the designer. */
.consent .checkbox           { border-color: var(--muted); }
.consent .checkbox:checked   { border-color: var(--teal); }
.retcard__go   { margin-top: 18px; }
.retcard__go[aria-disabled="true"],
.retcard__go:disabled {
  background: var(--hair); color: var(--faint); cursor: not-allowed;
}
.retcard__foot { font-size: 12.5px; color: var(--faint); text-align: center;
                 margin-top: 14px; line-height: 1.5; }

@media (max-width: 859px) {
  .retscreen { padding: 24px 18px; }
  .retcard__top  { padding: 30px 24px; }
  .retcard__h1   { font-size: 26px; }
  .retcard__covers img { height: 92px; }
  .retcard__body { padding: 22px; }
}

/* ==========================================================================
   22. AUTH  — one card shell, six bodies. Passwordless: no password field,
       no "forgot password" link exists anywhere in this system.
   ========================================================================== */

.auth {
  min-height: 100vh; min-height: 100dvh; background: var(--bg);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 100%; max-width: 100vw; overflow-x: hidden;
  padding: 48px 24px; font-family: var(--f-ui); color: var(--text2);
}
.auth__logo { height: 22px; margin-bottom: 28px; }
.auth__card {
  width: 440px; max-width: 100%; background: var(--card);
  border: 1px solid var(--hair); border-radius: var(--r-xl);
  box-shadow: 0 24px 60px rgba(12,12,34,.14); padding: 34px;
}
.auth__foot { font-size: 12px; color: var(--faint); margin-top: 22px;
              text-align: center; max-width: 360px; line-height: 1.5; }

.auth h1 { font-size: 24px; }
.auth__h1--sm { font-size: 23px; }
.auth__lead { font-size: 14.5px; color: var(--muted); line-height: var(--lh-body); margin: 10px 0 22px; }
.auth__lead b { color: var(--text); }
.auth__lead--tight { margin-bottom: 20px; }

.authicon {
  width: 52px; height: 52px; border-radius: 14px;
  display: flex; align-items: center; justify-content: center; margin-bottom: 20px;
}
.authicon--grad    { background: var(--grad-chip); }
.authicon--ok      { border-radius: var(--r-pill); background: var(--green); }
.authicon--neutral { background: var(--surface-raise); border: 1px solid var(--hair); }

.authnote {
  background: var(--surface-raise); border-radius: var(--r-md);
  padding: 14px 16px; margin-top: 18px;
  font-size: 13px; color: var(--muted); line-height: 1.5;
}
.authnote--tight { padding: 13px 16px; }
.auth__alt {
  display: block; text-align: center; font-size: 13px; color: var(--muted);
  margin-top: 14px; cursor: pointer; padding: 10px 0;
}
.auth__cc { font-size: 11.5px; color: var(--faint); text-align: center;
            line-height: 1.5; margin: 18px 0 0; }
.authfield { margin: 8px 0 16px; }

.oauth { display: flex; flex-wrap: wrap; gap: 10px; }
.oauth__btn {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 9px;
  border: 1.5px solid var(--hair); border-radius: var(--r-md); padding: 13px;
  font-family: var(--f-display); font-weight: 600; font-size: 13.5px;
  color: var(--text); cursor: pointer; min-height: var(--tap);
}
.oauth__btn:hover { border-color: var(--text); }
.oauth__btn--wide { flex-basis: 100%; background: transparent; }
.phoneauth { border-top: 1px solid var(--hair); margin-top: 16px; padding-top: 18px; }
.phoneauth[hidden], #phone-send-form[hidden], #phone-code-form[hidden] { display: none; }
.phoneauth__intro { color: var(--muted); font-size: 13px; line-height: 1.5;
                    margin: 0 0 14px; }

/* redirecting state */
.prog { height: 5px; background: var(--hair); border-radius: var(--r-sm); overflow: hidden; }
.prog__bar { height: 100%; background: var(--teal); animation: authProg 1s linear forwards; }
@keyframes authProg { from { width: 0; } to { width: 100%; } }
@media (prefers-reduced-motion: reduce) { .prog__bar { animation: none; width: 72%; } }
.auth__continue {
  display: block; text-align: center; font-family: var(--f-display);
  font-weight: 600; font-size: 14px; color: var(--text); margin-top: 20px; cursor: pointer;
}

@media (max-width: 859px) {
  .auth { padding: 32px 18px; }
  .auth__card { padding: 26px; }
}

@media (max-width: 520px) {
  .auth { padding: 24px 18px; }
  .auth__card { width: calc(100vw - 36px); min-width: 0; padding: 26px 22px; }
  .auth h1 { font-size: 22px; }
  .auth__foot { max-width: 100%; }
  .oauth { display: grid; grid-template-columns: minmax(0, 1fr); }
  .oauth__btn, .oauth__btn--wide { width: 100%; min-width: 0; }
  .phoneauth__sendrow { grid-template-columns: 1fr; }
  .phoneauth__sendrow .btn { width: 100%; }
}

/* ==========================================================================
   23. MY LIBRARY — only what you've touched, across every app, with your
       place in each. Zero-JS page: tabs and filters are server routes.
   ========================================================================== */

.ml { max-width: var(--page-max); margin: 0 auto; padding: 40px var(--page-pad) 60px; }
.ml-head { display: flex; align-items: flex-end; justify-content: space-between;
           gap: 20px; flex-wrap: wrap; }
.ml-head h1      { font-size: 34px; font-weight: 700; }
.ml-head__sub    { font-size: 15px; color: var(--muted); margin: 8px 0 0; }
.ml-head__link   { font-size: 13px; font-weight: 600; color: var(--coral); white-space: nowrap; }

/* tabs */
.ml-tabs {
  display: flex; gap: 26px; border-bottom: 1px solid var(--hair);
  margin-top: 26px; overflow-x: auto;
}
.ml-tab {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--f-display); font-weight: 600; font-size: 14px; color: var(--muted);
  padding: 10px 0 14px; white-space: nowrap; flex: 0 0 auto; cursor: pointer;
}
.ml-tab.is-active, .ml-tab[aria-current="page"] {
  color: var(--text); box-shadow: inset 0 -2px 0 var(--teal);
}
.ml-tab__n {
  font-size: 11px; font-weight: 700; color: var(--faint);
  background: var(--surface); border-radius: var(--r-pill); padding: 1px 7px;
}
.ml-tab.is-active .ml-tab__n { color: var(--teal); background: var(--teal-12); }

@media (max-width: 560px) {
  /* Six tabs at 26px gaps don't fit 390px, and `overflow-x: auto` alone just
     hides the last one with no signal there's more (the page is zero-JS, so
     there's no scroll listener to drive a `.praise__names`-style fade). Wrap
     to two rows instead — every tab, including whichever is active, stays on
     screen without help from JS. */
  .ml-tabs { flex-wrap: wrap; overflow-x: visible; row-gap: 4px; column-gap: 18px; }
  .ml-tab { padding-bottom: 10px; }
}

/* filter + sort bar */
.ml-bar { display: flex; align-items: center; justify-content: space-between;
          gap: 14px; margin-top: 18px; flex-wrap: wrap; }
.ml-bar__filters { display: flex; gap: 8px; flex-wrap: wrap; }
.ml-sort > summary {
  display: inline-flex; align-items: center; gap: 8px; list-style: none;
  font-size: 12.5px; color: var(--muted);
  border: 1px solid var(--hair); border-radius: var(--r-sm);
  padding: 10px 12px; cursor: pointer;
}
.ml-sort > summary::-webkit-details-marker { display: none; }
.ml-sort { position: relative; }
/* The open panel is designed as of V3 (it was borrowed from My Library while
   build spec §9.9 said it had never been drawn). The <details> disclosure
   stays — V3 drives it from component state, but the zero-JS version is the
   contract here; only the fixed-inset outside-click scrim is unreproducible
   and stays a progressive enhancement. Shared rule: this retune also lands on
   My Library's sort and the hub's topic dropdown. */
.ml-sort__menu {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 20; min-width: 190px;
  /* Anchored to the RIGHT of a control that sits near the left edge, a 190px
     menu hung 81px off the left of a 375px screen with its options half cut
     off. `max-width` plus a left clamp keeps every option on the phone. */
  max-width: calc(100vw - 24px);
  background: var(--paper); border: 1px solid var(--hair); border-radius: var(--r-md);
  box-shadow: var(--sh-menu); padding: 6px;
}
@media (max-width: 560px) {
  /* left-anchor it instead: the control lives on the left of the row */
  .ml-sort__menu { right: auto; left: 0; }
  /* The Library filter bar has two adjacent disclosures. Its second control
     lives at the right edge, so left-anchoring that menu widens the document. */
  .filterbar__controls > .ml-sort + .ml-sort .ml-sort__menu {
    right: 0; left: auto;
  }
}
.ml-sort__opt {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 12px; min-height: 44px; border-radius: var(--r-ctl);
  font-size: 13.5px; font-weight: 500; color: var(--text2); cursor: pointer;
}
.ml-sort__opt:hover { background: var(--surface); }
.ml-sort__opt[aria-current="true"] {
  color: var(--text); font-weight: 700; background: var(--surface);
}
.ml-sort__opt svg { flex: 0 0 auto; }   /* the teal check, active row only */

/* ---- Continue: one row per WORK (never per format) ---- */
.ml-rows { list-style: none; margin: 22px 0 0; padding: 0;
           display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 14px; }
.ml-row  { position: relative; display: grid; grid-template-columns: 118px minmax(0,1fr);
           gap: 16px; align-items: center; background: var(--paper);
           border: 1px solid var(--hair); border-radius: 15px; padding: 16px;
           min-width: 0; transition: border-color .2s ease, box-shadow .2s ease,
           background-color .2s ease, transform .2s ease; }
.ml-row:hover { background: var(--surface); border-color: var(--teal);
                box-shadow: 0 10px 24px rgba(12,12,34,.08); transform: translateY(-1px); }
.ml-row:active { transform: translateY(0); }
.ml-row__media {
  width: 118px; height: 96px; border-radius: 10px; overflow: hidden; position: relative;
  display: flex; align-items: center; justify-content: center; background: var(--panel);
  border: 1px solid var(--hair);
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
  pointer-events: none;
}
.ml-row:hover .ml-row__media { background: var(--paper); border-color: transparent; }
.ml-row__media img { max-width: 76%; max-height: 84%; width: auto; height: auto;
                     object-fit: contain; border-radius: 3px;
                     box-shadow: 0 4px 12px rgba(12,12,34,.2); }
.ml-row__media--video img { width: 90%; max-width: 90%; max-height: 90%;
                            object-fit: contain; box-shadow: 0 3px 10px rgba(12,12,34,.2); }
.ml-row__play {
  position: absolute; z-index: 1; width: 26px; height: 26px; border-radius: var(--r-pill);
  background: rgba(10,10,20,.55); display: flex; align-items: center; justify-content: center;
}

/* no-artwork stand-in, designed in V3. Draws a book spine — deliberately NOT
   the .ml-row__thumb video gradient, which would label a book as a talk. This
   is what my_library.clj's row-art nil branch was waiting on. Keep the SVG in
   hiccup (18px / stroke 1.5 for the row, 26px / stroke 1.4 for the tile). */
.ml-ph {
  background: var(--surface); border: 1px solid var(--hair);
  display: flex; align-items: center; justify-content: center;
  color: var(--muted); position: relative; overflow: hidden;
}
.ml-ph::before { content: ""; position: absolute; background: var(--hair); }

/* row variant — same 44px portrait / 64px square split as .ml-row__cover.
   Shadow is lighter than a real cover's (.2 -> .12): nothing is floating. */
.ml-row__ph { position: absolute; inset: 12px; border-radius: 4px; }
.ml-row__ph::before { left: 7px; top: 8px; bottom: 8px; width: 1.5px; }
.ml-row__body  { flex: 1; min-width: 0; }
.ml-row__tags  { display: flex; align-items: center; justify-content: space-between;
                 gap: 8px; min-height: 28px; }
.ml-row__tagset { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
.ml-row__controls { position: relative; z-index: 3; margin-left: auto; flex: 0 0 auto; }
.ml-row__open { display: inline-flex; align-items: center; justify-content: center;
                width: 28px; height: 28px; color: var(--faint); font-size: 18px; }
.ml-row__title {
  font-family: var(--f-display); font-weight: 700; font-size: 15px; color: var(--text);
  margin: 7px 0 0; line-height: 1.25; text-wrap: balance;
}
/* Cover and title are both doors into the work — the row's button is no
   longer the only live pixel on it. Neither is styled AS a link (no colour,
   no underline at rest): the row already reads as one object, and colouring
   the title would make a shelf of them look like a list of hyperlinks. */
.ml-row__titlelink { color: inherit; text-decoration: none; }
.ml-row__titlelink::after { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: 15px; }
.ml-row__titlelink:hover { text-decoration: none; }
/* focus ring: the global :focus-visible rule already owns it — nothing here. */
.ml-row__by   { font-size: 12.5px; color: var(--muted); margin: 3px 0 0; }
.ml-row__by--course { width: min(100%, 300px); min-width: 0;
                      white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ml-row__prog { display: flex; flex-direction: column; gap: 6px; margin-top: 11px; min-width: 0; }
.ml-row__meter { display: flex; align-items: center; gap: 9px; width: min(100%, 300px); }
.ml-row__meter .bar { flex: 1 1 auto; min-width: 0; }
.ml-row__pct { width: 4ch; flex: 0 0 4ch; text-align: right; font-size: 12px;
               color: var(--muted); font-variant-numeric: tabular-nums; }
.ml-row__pct--label { width: auto; flex-basis: auto; white-space: nowrap; }
.ml-row__pos  { display: block; max-width: 100%; min-width: 0; font-size: 12px;
                color: var(--muted); white-space: nowrap; overflow: hidden;
                text-overflow: ellipsis; }
.ml-row__more { position: relative; margin-left: auto; }
.ml-row__more > summary { list-style: none; cursor: pointer; color: var(--muted);
                          font-weight: 700; letter-spacing: 2px; padding: 4px 2px; }
.ml-row__more > summary::-webkit-details-marker { display:none; }
.ml-row__secondary { position: absolute; z-index: 4; right: 0; top: calc(100% + 4px);
                     margin: 0; min-width: 142px; padding: 5px; background: var(--paper);
                     border: 1px solid var(--hair); border-radius: 9px;
                     box-shadow: 0 10px 24px rgba(12,12,34,.14); }
.ml-row__secondary button { width: 100%; border: 0; background: transparent; color: var(--text);
                            padding: 8px 10px; text-align: left; cursor: pointer; font: inherit; }
.ml-row__secondary button:hover { background: var(--surface); }
/* ---- Saved / Finished grid ---- */
.ml-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(146px, 1fr));
           gap: 26px 22px; margin-top: 24px; }
.ml-tile { display: block; }
.ml-tile__link { display: block; cursor: pointer; text-decoration: none; color: inherit; }
.ml-tile__well {
  position: relative; display: flex; align-items: center; justify-content: center;
  background: var(--panel); border: 1px solid var(--hair); border-radius: 10px;
  padding: 14px; aspect-ratio: 2/3;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.ml-tile__well--square { aspect-ratio: 1/1; }
.ml-tile__well--landscape { aspect-ratio: 16/9; padding: 0; overflow: hidden; }
.ml-tile__well--landscape img { width: 100%; height: 100%; object-fit: cover; }
.ml-tile__well img { max-height: 100%; max-width: 100%; border-radius: var(--r-xs);
                     box-shadow: 0 8px 20px rgba(12,12,34,.24); }
/* tile variant of the spine placeholder. inset:10px deliberately overrides the
   well's own 14px padding — the stand-in sits 4px proud of where art would.
   .ml-tile__well is already position:relative; .ml-tile__owned still stacks. */
.ml-tile__ph { position: absolute; inset: 10px; border-radius: 4px; }
.ml-tile__ph::before {
  left: 9px; top: 10px; bottom: 10px; width: 2px; border-radius: 2px;
}
.ml-tile__owned {
  position: absolute; top: 8px; left: 8px;
  font-size: 9px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: #fff; background: var(--gold); border-radius: var(--r-cover); padding: 2px 7px;
}
.ml-tile__title { display: block; font-family: var(--f-display); font-weight: 700;
                  font-size: 13px; color: var(--text); margin-top: 10px; line-height: 1.25; }
.ml-tile__meta  { display: block; font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.ml-tile__action { margin-top: 9px; }
.ml-tile__action .btn { width: 100%; }
.ml-tile__link:hover .ml-tile__well {
  transform: translateY(-5px); border-color: var(--teal); box-shadow: var(--sh-md);
}
.ml-tile__link:active .ml-tile__well { transform: translateY(-2px); }
.ml-tile__link:focus-visible { outline: none; }
.ml-tile__link:focus-visible .ml-tile__well {
  transform: translateY(-5px);
  border-color: var(--teal);
  box-shadow: 0 0 0 3px var(--paper), 0 0 0 5px var(--teal), var(--sh-md);
}
@media (hover: hover) {
  .ml-tile__link:hover .ml-tile__title { color: var(--teal); }
}
.ml-row__secondary { margin: 0; }

/* ---- Paths tab: always-dark ink cards (literals inside, never tokens) ---- */
.ml-paths { display: flex; flex-direction: column; gap: 14px; margin-top: 24px; }
.ml-path  { background: var(--ink); border-radius: var(--r-lg); padding: 22px 24px;
            color: #fff; display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.ml-path__body    { flex: 1; min-width: 200px; }
.ml-path__eyebrow { font-family: var(--f-display); font-weight: 700; font-size: 11px;
                    letter-spacing: .1em; text-transform: uppercase; color: #3fc3dd; }
.ml-path__title   { font-family: var(--f-display); font-weight: 700; font-size: 18px;
                    color: #fff; margin: 8px 0 0; }
.ml-path__prog    { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
.ml-path__prog .bar { width: 160px; max-width: 40vw; flex: 0 0 auto; }
.ml-path__meta    { font-size: 12.5px; color: #c7ccda; }

/* ---- Notes & highlights: the cross-book personal knowledge asset ---- */
.hl-search, .filterbar__search {
  display: flex; align-items: center; gap: 10px;
  background: var(--field); border: 1.5px solid var(--hair);
  border-radius: var(--r-md); padding: 12px 15px;
}
.hl-search { margin-top: 22px; }   /* the filterbar's own gap spaces the shelf copy */
.hl-search input, .filterbar__search input {
  flex: 1; border: 0; background: transparent; outline: none;
  font-family: inherit; font-size: 14px; color: var(--text); min-width: 0;
}
.hl-search input::placeholder, .filterbar__search input::placeholder { color: var(--faint); }
/* ONE focus affordance, not three: the wrapper carries the design system's
   ring, and the input inside it must NOT also draw the global :focus-visible
   ring (text inputs always match :focus-visible, so without the suppression a
   click stacks wrapper ring + wrapper border + inner ring — measured on prod
   as the "way too many blue lines" bug). */
/* the visible submit — .sr-only has no focus unclip, so an invisible button
   would be an invisible focus stop; and mice deserve a target too. */
.filterbar__go {
  flex: 0 0 auto; border: 0; cursor: pointer;
  font-family: var(--f-display); font-weight: 600; font-size: 13px;
  letter-spacing: .02em; padding: 8px 18px; border-radius: 999px;
  background: var(--btn); color: var(--btn-t);
}

.hl-books { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.hl-count { font-size: 12.5px; color: var(--faint); margin: 18px 0 12px; }

.hl-wall { columns: 2; column-gap: 16px; }
.hl {
  break-inside: avoid; margin-bottom: 16px; background: var(--paper);
  border: 1px solid var(--hair); border-left: 4px solid var(--hl, var(--hl-yellow));
  border-radius: 14px; padding: 16px;
}
.hl__quote { font-family: var(--f-read); font-size: 14.5px; line-height: var(--lh-body);
             color: var(--text); margin: 0; }
.hl__note  { margin: 10px 0 0; background: var(--surface); border-radius: var(--r-ctl);
             padding: 9px 12px; font-size: 12.5px; color: var(--muted); line-height: 1.45; }
.hl__foot  { display: flex; align-items: center; justify-content: space-between;
             gap: 10px; margin-top: 12px; }
.hl__src   { min-width: 0; }
.hl__book  { display: block; font-family: var(--f-display); font-weight: 600;
             font-size: 12.5px; color: var(--text);
             white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hl__where { display: block; font-size: 11px; color: var(--faint); }

/* ---- empty state ---- */
.ml-empty { text-align: center; padding: 44px 0; max-width: 600px; margin: 0 auto; }
.ml-empty__icon {
  width: 64px; height: 64px; border-radius: 18px; background: var(--surface);
  border: 1px solid var(--hair); color: var(--teal);
  display: inline-flex; align-items: center; justify-content: center;
}
.ml-empty h2  { font-size: 24px; margin: 20px 0 0; }
.ml-empty > p { font-size: 15px; color: var(--muted); line-height: var(--lh-body); margin: 12px 0 26px; }
/* NOTE: .ml-empty is capped at 600px, so a 210px floor + 14px gap resolves to
   TWO tracks on desktop — three cards wrap 2 + 1. That is what V3's numbers
   produce; a 3-up row would need the floor at <=190px. Query out to design. */
.ml-empty__cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
                   gap: 14px; text-align: left; }
.ml-empty__card  { background: var(--surface); border: 1px solid var(--hair);
                   border-radius: var(--r-lg); padding: 20px; }
.ml-empty__cover { height: 96px; border-radius: 4px; box-shadow: 0 10px 24px rgba(12,12,34,.2); }
.ml-empty__badge { width: 44px; height: 44px; border-radius: var(--r-md);
                   display: inline-flex; align-items: center; justify-content: center; }
.ml-empty__badge--grad  { background: var(--grad-chip); color: var(--on-grad); }
.ml-empty__badge--panel { background: var(--panel); border: 1px solid var(--hair); color: var(--teal); }
.ml-empty__t { font-family: var(--f-display); font-weight: 700; font-size: 14px;
               color: var(--text); margin-top: 14px; }
.ml-empty__d { font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.ml-empty__a { display: inline-block; font-family: var(--f-display); font-weight: 600;
               font-size: 13px; color: var(--coral); margin-top: 10px; }

@media (max-width: 859px) {
  .ml { padding: 22px var(--page-pad-m) 40px; }
  .ml-head h1 { font-size: 28px; }
  .ml-grid { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
  .hl-wall { columns: 1; }
  .ml-empty { padding: 26px 0; }
  .ml-empty__cards { grid-template-columns: 1fr; }
  .ml-rows { grid-template-columns: 1fr; }
  .ml-row { grid-template-columns: 88px minmax(0,1fr); gap: 12px; padding: 12px; }
  .ml-row__media { width: 88px; height: 76px; }
  .ml-row__title { font-size: 14px; }
}
/* the 559px .ml-grid override is gone: V3 has no third breakpoint here, and
   the minmax(96px,1fr) track does that job continuously. */

/* ==========================================================================
   24. AI TUTOR — "a librarian, not an oracle."
       One component, two scopes: [data-scope="library"|"book"].
       The cited answer is the unit everything is built around; the sources
       panel is the visible face of the author-royalty split.
   ========================================================================== */

.tut {
  display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 100%;
  background: var(--paper); color: var(--text2); overflow: hidden;
}
.tut-head  { flex: 0 0 auto; border-bottom: 1px solid var(--hair); padding: 16px 20px 0; }
.tut-conv  { flex: 1; overflow: auto; padding: 22px 24px; }
.tut-conv__inner  { max-width: 720px; margin: 0 auto; }
.tut-input { flex: 0 0 auto; border-top: 1px solid var(--hair); padding: 14px 24px 18px; }
.tut-input__inner { max-width: 720px; margin: 0 auto; }
.tut[data-scope="book"] .tut-conv__inner,
.tut[data-scope="book"] .tut-input__inner { max-width: 100%; }

/* header */
.tut-head__top { display: flex; align-items: center; justify-content: space-between; }
.tut-id   { display: flex; align-items: center; gap: 10px; min-width: 0; }
.tut-mark { width: 30px; height: 30px; border-radius: var(--r-sm); background: var(--grad);
            flex: 0 0 auto; display: flex; align-items: center; justify-content: center; }
.tut-id__text  { min-width: 0; }
.tut-id__title { font-family: var(--f-display); font-weight: 700; font-size: 14.5px;
                 color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tut-id__sub   { font-size: 11.5px; color: var(--faint);
                 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tut-head__right { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.tut-close { background: none; border: 0; padding: 0; color: var(--faint); cursor: pointer;
             display: inline-flex; align-items: center; justify-content: center;
             min-width: var(--tap); min-height: var(--tap); margin-right: -10px; }

.tut-modes { display: flex; gap: 18px; margin-top: 14px; }
.tut-mode  { font-family: var(--f-display); font-weight: 600; font-size: 12.5px;
             color: var(--muted); padding-bottom: 9px; cursor: pointer; }
.tut-mode.is-active { color: var(--text); box-shadow: inset 0 -2px 0 var(--teal); }

/* first run */
.tut-first { text-align: center; padding: 22px 0 26px; }
.tut-first__mark { width: 52px; height: 52px; border-radius: 15px; background: var(--grad);
                   display: inline-flex; align-items: center; justify-content: center; }
.tut-first h2 { font-size: 23px; margin: 16px 0 0; }
.tut-first p  { font-size: 14px; color: var(--muted); max-width: 440px;
                margin: 10px auto 0; line-height: var(--lh-body); }
.tut-sugg__h  { margin-bottom: 10px; }
.tut-sugg     { display: flex; flex-direction: column; gap: 8px; }
.tut-sugg--learn { margin-bottom: 22px; }
.tut-q {
  display: flex; align-items: center; gap: 10px; background: var(--paper);
  border: 1px solid var(--hair); border-radius: var(--r-md); padding: 13px 15px; cursor: pointer;
}
.tut-q:hover { border-color: var(--teal); }
.tut-q span { font-size: 13.5px; color: var(--text); }
.tut-q svg  { flex: 0 0 auto; }

/* question bubble — no matching assistant bubble: answers are typeset, not chatted */
.tut-ask { display: flex; justify-content: flex-end; margin-bottom: 18px; }
.tut-ask__b {
  max-width: 80%; margin: 0; background: var(--ink); color: #fff;
  border-radius: 14px 14px 3px 14px; padding: 11px 15px; font-size: 14px; line-height: 1.45;
}

/* thinking — grounding trace, not a spinner. Names the real titles retrieved. */
@keyframes tPulse { 0%,100% { opacity: .35 } 50% { opacity: 1 } }
@keyframes tBlink { 0%,100% { opacity: 1 }   50% { opacity: 0 } }
.tut-think { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.tut-think__mark { width: 26px; height: 26px; border-radius: var(--r-ctl); background: var(--grad);
                   flex: 0 0 auto; display: flex; align-items: center; justify-content: center; }
.tut-think__label{ font-family: var(--f-display); font-weight: 600; font-size: 13px; color: var(--muted); }
.tut-trace { list-style: none; margin: 0; padding-left: 36px;
             display: flex; flex-direction: column; gap: 9px; }
.tut-trace li { display: flex; align-items: center; gap: 9px; font-size: 12.5px;
                color: var(--muted); animation: tPulse 1.4s ease-in-out infinite; }
.tut-trace i  { width: 6px; height: 6px; border-radius: var(--r-pill);
                background: var(--teal); flex: 0 0 auto; }
.tut-caret { display: inline-block; width: 2px; height: 1em; vertical-align: -.15em;
             background: var(--teal); animation: tBlink 1s step-end infinite; }

/* the cited answer */
.tut-kicker {
  display: inline-flex; align-items: center; gap: 6px; margin-bottom: 12px;
  font-family: var(--f-display); font-weight: 700; font-size: 10.5px;
  letter-spacing: var(--ls-tag); text-transform: uppercase;
}
.tut-kicker--learn { color: var(--teal); }
.tut-kicker--find  { color: var(--muted); }

.tut-answer { font-family: var(--f-read); font-size: 15px; line-height: 1.68; color: var(--text); }
.tut-answer p { margin: 0 0 14px; }

/* THE citation chip. Rendered ONLY from the retrieval payload — never invented
   client-side; a wrong source misattributes a royalty. */
.cite {
  display: inline-flex; align-items: center; gap: 3px; vertical-align: baseline;
  font-family: var(--f-display); font-weight: 700; font-size: 10.5px; letter-spacing: .01em;
  color: var(--teal); background: var(--teal-soft); border: 1px solid var(--teal);
  border-radius: 6px; padding: 0 5px; margin: 0 1px;
  line-height: 1.5; translate: 0 -1px; white-space: nowrap; cursor: pointer;
}
.cite:hover, .cite:focus-visible { background: var(--teal); color: #fff; }

/* "Drawn from" sources panel */
.src { margin-top: 20px; border: 1px solid var(--hair); border-radius: 15px; overflow: hidden; }
.src__head { display: flex; align-items: center; gap: 8px; padding: 12px 16px;
             background: var(--surface); border-bottom: 1px solid var(--hair); flex-wrap: wrap; }
.src__title{ font-family: var(--f-display); font-weight: 700; font-size: 12.5px; color: var(--text); }
.src__note { font-size: 11.5px; color: var(--faint); margin-left: auto; }
.src__row  { display: flex; align-items: center; gap: 13px; padding: 13px 16px;
             border-bottom: 1px solid var(--hair); cursor: pointer; }
.src__row:last-child { border-bottom: 0; }
.src__row:hover { background: var(--surface); }
.src__row img { width: 34px; height: 50px; object-fit: cover; border-radius: var(--r-xs);
                flex: 0 0 auto; box-shadow: 0 3px 8px rgba(12,12,34,.18); }
.src__body { flex: 1; min-width: 0; }
.src__book { font-family: var(--f-display); font-weight: 700; font-size: 13px; color: var(--text);
             white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.src__where{ font-size: 11.5px; color: var(--muted); margin-top: 1px; }
.src__share{ display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.src__bar  { flex: 1; max-width: 120px; height: 4px; background: var(--hair);
             border-radius: var(--r-sm); overflow: hidden; }
.src__bar > i { display: block; height: 100%; background: var(--grad); }
.src__pct  { font-size: 10.5px; font-weight: 600; color: var(--teal); }
.src__open { font-size: 12px; font-weight: 600; color: var(--coral); flex: 0 0 auto; }

.tut-follow { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 18px; }
.tut-follow__c { font-size: 12.5px; font-weight: 600; color: var(--text);
                 border: 1px solid var(--hair); border-radius: var(--r-pill);
                 padding: 8px 14px; cursor: pointer; }
.tut-follow__c:hover { border-color: var(--teal); }

/* discovery answer — locator rows ARE the sources; never render both panels */
.tut-lead { font-size: 14px; color: var(--muted); line-height: var(--lh-body); margin: 0 0 14px; }
.loc { display: flex; flex-direction: column; gap: 10px; }
.loc__row { display: flex; align-items: center; gap: 13px;
            border: 1px solid var(--hair); border-radius: 13px; padding: 14px 16px; cursor: pointer; }
.loc__row:hover { border-color: var(--teal); }
.loc__row img { width: 38px; height: 56px; object-fit: cover; border-radius: var(--r-xs);
                flex: 0 0 auto; box-shadow: 0 3px 8px rgba(12,12,34,.18); }
.loc__body { flex: 1; min-width: 0; }
.loc__title{ font-family: var(--f-display); font-weight: 700; font-size: 13.5px; color: var(--text); }
.loc__ch   { font-size: 12px; font-weight: 600; color: var(--teal); margin-top: 2px; }
.loc__note { font-size: 12px; color: var(--muted); margin-top: 3px; line-height: 1.4; }
.loc__open { font-family: var(--f-display); font-weight: 600; font-size: 12.5px;
             color: var(--coral); flex: 0 0 auto; white-space: nowrap; }
.tut-foot  { display: flex; align-items: flex-start; gap: 7px; font-size: 12px;
             color: var(--faint); margin: 14px 0 0; }
.tut-foot__dot { width: 6px; height: 6px; border-radius: var(--r-pill);
                 background: var(--muted); flex: 0 0 auto; margin-top: 5px; }

/* "not in our library" — the honest boundary, offered well. Neutral, not red. */
.nf { display: flex; gap: 12px; align-items: flex-start; background: var(--surface);
      border: 1px solid var(--hair); border-radius: 15px; padding: 18px; }
.nf__icon { width: 30px; height: 30px; border-radius: var(--r-pill); background: var(--panel);
            border: 1px solid var(--hair); color: var(--muted); flex: 0 0 auto;
            display: flex; align-items: center; justify-content: center; }
.nf__title{ font-family: var(--f-display); font-weight: 700; font-size: 15px; color: var(--text); }
.nf__body { font-size: 13.5px; color: var(--muted); line-height: var(--lh-body); margin: 8px 0 0; }
.nf__h    { margin: 20px 0 10px; }
.nf__adj  { display: flex; flex-direction: column; gap: 8px; }
.nf__row  { display: flex; align-items: center; justify-content: space-between; gap: 12px;
            border: 1px solid var(--hair); border-radius: var(--r-md); padding: 12px 15px; cursor: pointer; }
.nf__row span:first-child { font-size: 13.5px; font-weight: 600; color: var(--text); }
.nf__arrow{ color: var(--coral); font-weight: 600; font-size: 12.5px; }

/* input bar — dots and send button are mutually exclusive */
.tut-field { display: flex; align-items: center; gap: 10px;
             background: var(--field); border: 1.5px solid var(--hair);
             border-radius: 13px; padding: 11px 14px; }
.tut-field input { flex: 1; border: 0; background: transparent; outline: none;
                   font-family: inherit; font-size: 13.5px; color: var(--text); }
.tut-field input::placeholder { color: var(--faint); }
.tut-dots { display: inline-flex; gap: 3px; }
.tut-dots span { width: 6px; height: 6px; border-radius: var(--r-pill);
                 background: var(--teal); animation: tPulse 1s infinite; }
.tut-dots span:nth-child(2) { animation-delay: .2s; }
.tut-dots span:nth-child(3) { animation-delay: .4s; }
.tut-send { width: 30px; height: 30px; border-radius: var(--r-sm); background: var(--btn);
            border: 0; flex: 0 0 auto; display: flex; align-items: center;
            justify-content: center; cursor: pointer; }
.tut-disclaimer { font-size: 11px; color: var(--faint); margin: 9px 0 0;
                  text-align: center; line-height: 1.4; }

/* in-reader composition: a companion, never a takeover */
.reader-split { display: flex; height: 100%; background: #faf9f5; }
.reader-page  { flex: 1; padding: 52px 56px; overflow: auto; font-family: var(--f-read); }
.reader-page__ch { font-family: var(--f-display); font-weight: 600; font-size: 12px;
                   letter-spacing: .14em; text-transform: uppercase;
                   color: #9aa1ab; margin-bottom: 22px; }
.reader-page p { font-size: 19px; line-height: var(--lh-read); color: #20242c; margin: 0 0 22px; }
.reader-tutor { width: 420px; flex: 0 0 auto; border-left: 1px solid var(--hair); }

@media (max-width: 859px) {
  .tut-head  { padding: 14px 16px 0; }
  .tut-conv  { padding: 18px 16px; }
  .tut-input { padding: 12px 16px 16px; }
  .tut-first { padding: 12px 0 26px; }
  .tut-first h2 { font-size: 21px; }
  .reader-page  { padding: 28px 20px; }
  .reader-tutor { position: fixed; inset: 0; width: auto; border-left: 0; z-index: 60; }
}
@media (prefers-reduced-motion: reduce) {
  .tut-trace li, .tut-dots span, .tut-caret { animation: none; opacity: 1; }
}

/* ==========================================================================
   25. LEARNING PATH — a first-class object, not a transcript.
   ========================================================================== */

/* THE PLAYLIST LAYOUT (Alex, 2026-09-07 — after the video library's /playlists
   page): the app ground paints the whole page; a 1240px shell; a sticky 372px
   panel (the path card, then the builder) on the left and the steps on the
   right, 40px gutter. One column under 880px. */
.lp { background: var(--bg-app); }
.lp-shell { max-width: 1240px; margin: 0 auto; padding: 22px 28px 88px; }
.lp-crumbs { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--muted);
             margin: 0 0 22px; }
.lp-crumbs a { color: var(--muted); text-decoration: none; }
.lp-crumbs a:hover { color: var(--text); }
.lp-crumbs__sep { color: var(--faint); }
.lp-crumbs__cur { color: var(--text); font-weight: 500; white-space: nowrap; overflow: hidden;
                  text-overflow: ellipsis; max-width: 40ch; }
.lp-layout { display: grid; grid-template-columns: 372px minmax(0, 1fr); gap: 40px; align-items: start; }
/* z-index: sticky makes the panel its own stacking context, so the builder's
   pop-out (z 30 INSIDE it) was painted under anything positioned later in the
   page — the footer's wordmark showed through the results on a short path
   (Alex's screenshot, 2026-09-07). 10 lifts the panel above the page body and
   stays under the nav (50). */
.lp-panel { position: sticky; top: 80px; z-index: 10; display: flex; flex-direction: column; gap: 14px; }
@media (max-width: 880px) {
  .lp-layout { grid-template-columns: 1fr; }
  .lp-panel { position: static; }
}

.lp-hero { background: var(--ink); border-radius: var(--r-lg); padding: 22px 22px 24px;
           color: #fff; position: relative; overflow: visible; }  /* the delete ask pops out of it */
.lp-hero__eyebrow { display: inline-flex; align-items: center; gap: 7px;
                    font-family: var(--f-display); font-weight: 700; font-size: 11px;
                    letter-spacing: .1em; text-transform: uppercase; color: #3fc3dd; }
.lp-hero__eyebrow span { color: #8b93a6; font-weight: 600; letter-spacing: 0; text-transform: none; }
.lp-hero h1 { font-size: 23px; color: #fff; margin: 12px 0 0; line-height: 1.18; letter-spacing: -.018em; }
.lp-hero__by { display: flex; align-items: center; gap: 10px; margin-top: 16px; }
.lp-hero__av { width: 30px; height: 30px; border-radius: 50%; flex: none; display: flex;
               align-items: center; justify-content: center; background: var(--teal); color: #fff;
               font-size: 13px; }
.lp-hero__tx { font-size: 13px; color: #c7ccda; line-height: 1.35; }
.lp-hero__tx b { display: block; color: #fff; }
.lp-hero__prog { display: flex; align-items: center; gap: 12px; margin-top: 18px; }
.lp-hero__prog .bar { flex: 1; }
.lp-hero__meta { font-family: var(--f-display); font-weight: 600; font-size: 13px; color: #dfe3ec;
                 white-space: nowrap; }
.lp-hero__empty { font-size: 13.5px; color: #c7ccda; margin: 16px 0 0; line-height: 1.5; }
.lp-hero__cta { display: flex; gap: 9px; margin-top: 20px; }
.lp-hero__go { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
               background: #fff; color: var(--ink); font-family: var(--f-display); font-weight: 600;
               font-size: 14px; border-radius: 10px; padding: 11px 18px; text-decoration: none; }
.lp-hero__go:hover { background: #eef3f6; }
.lp-hero__del { margin: 0; flex: none; position: relative; }
.lp-hero__delbtn { display: inline-flex; align-items: center; height: 100%; list-style: none;
                   font: inherit; font-family: var(--f-display); font-weight: 600; font-size: 13px;
                   color: #ff8095; background: transparent; border: 1px solid rgba(238,93,116,.55);
                   border-radius: 10px; padding: 11px 13px; cursor: pointer; }
.lp-hero__delbtn::-webkit-details-marker { display: none; }
.lp-hero__delbtn:hover, .lp-hero__del[open] .lp-hero__delbtn { color: #fff; background: #ee5d74; border-color: #ee5d74; }
.lp-hero__confirm { position: absolute; right: 0; top: calc(100% + 8px); z-index: 20; width: 280px;
                    background: var(--paper); color: var(--text); border: 1px solid var(--hair);
                    border-radius: 12px; padding: 14px 16px; box-shadow: 0 18px 44px rgba(12,12,34,.22); }
.lp-hero__confirm-t { font-family: var(--f-display); font-weight: 700; font-size: 14px; margin: 0; }
.lp-hero__confirm-b { font-size: 12.5px; color: var(--muted); margin: 6px 0 12px; line-height: 1.45; }
.lp-hero__confirm-yes { font: inherit; font-family: var(--f-display); font-weight: 600; font-size: 13px;
                        color: #fff; background: #ee5d74; border: 0; border-radius: 999px;
                        padding: 8px 14px; cursor: pointer; }
.lp-hero__confirm-yes:hover { background: #d94a61; }
/* public paths: the pill, the description, the edit panel, share, follow */
.lp-hero__pub { color: #7fd7c6 !important; font-weight: 700 !important; letter-spacing: .06em !important;
                text-transform: uppercase !important; }
.lp-hero__desc { font-size: 14px; color: #c7ccda; margin: 10px 0 0; line-height: 1.5; }
.lp-hero__ghost { font: inherit; font-family: var(--f-display); font-weight: 600; font-size: 13px;
                  color: #c7ccda; background: transparent; border: 1px solid rgba(255,255,255,.28);
                  border-radius: 10px; padding: 11px 13px; cursor: pointer; height: 100%; white-space: nowrap; }
.lp-hero__ghost:hover { color: #fff; border-color: rgba(255,255,255,.6); }
.lp-hero__follow { flex: 1; margin: 0; display: flex; }
/* the quiet row under the card: Share left, Delete right — same size, red */
/* align-items: flex-END so Delete sits on the row's BOTTOM edge — a fixed
   distance from the card's bottom — whether the share block beside it is the
   one-line Share summary or the two-line public state. flex-start moved it
   every time sharing was turned on (Alex, 2026-09-08). */
.lp-hero__foot { display: flex; justify-content: space-between; align-items: flex-end; gap: 12px; margin-top: 16px; }
.lp-hero__foot > .lp-hero__share, .lp-hero__foot > .lp-hero__sharebox { flex: 1; min-width: 0; margin-top: 0; }
.lp-hero__foot .lp-hero__del { flex: none; }
.lp-hero__foot .lp-hero__delbtn { height: auto; padding: 0; border: 0; border-radius: 0; font-size: 13px; color: #ff8095; background: transparent; }
.lp-hero__foot .lp-hero__delbtn:hover, .lp-hero__foot .lp-hero__del[open] .lp-hero__delbtn { color: #fff; background: transparent; border-color: transparent; text-decoration: underline; text-underline-offset: 3px; }
/* share: private until shared; the control names the consequence first */
.lp-hero__share { margin-top: 14px; }
.lp-hero__sharerow { display: flex; align-items: center; gap: 8px; min-width: 0; }
.lp-hero__sharerow .lp-hero__link { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lp-hero__copy { flex: none; font: inherit; font-family: var(--f-display); font-weight: 600; font-size: 12.5px;
                 color: var(--ink); background: #fff; border: 0; border-radius: 999px; padding: 6px 12px; cursor: pointer; }
.lp-hero__copy:hover { background: #eef3f6; }
.lp-hero__vis { margin: 6px 0 0; }
.lp-hero__vislink { font: inherit; font-size: 12px; color: #c7ccda; background: none; border: 0; padding: 0;
                    cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.lp-hero__vislink:hover { color: #fff; }
.lp-hero__sharebox { position: relative; margin-top: 14px; }
.lp-hero__sharebtn { display: inline-flex; align-items: center; gap: 6px; list-style: none; cursor: pointer;
                     font-family: var(--f-display); font-weight: 600; font-size: 13px; color: #c7ccda; }
.lp-hero__sharebtn::-webkit-details-marker { display: none; }
.lp-hero__sharebtn::before { content: "🔒"; font-size: 12px; }
.lp-hero__sharebtn:hover, .lp-hero__sharebox[open] .lp-hero__sharebtn { color: #fff; }
.lp-hero__sharebox .lp-hero__confirm { left: 0; right: auto; width: 300px; }
.lp-hero__confirm-go { font: inherit; font-family: var(--f-display); font-weight: 600; font-size: 13px;
                       color: #fff; background: var(--ink); border: 0; border-radius: 999px; padding: 8px 14px; cursor: pointer; }
.lp-hero__confirm-go:hover { background: #2a2f45; }
.lp-hero__follow .lp-hero__go { width: 100%; border: 0; cursor: pointer; font: inherit;
                                font-family: var(--f-display); font-weight: 600; font-size: 14px; }
/* edit: a pencil at the card's top-right, the form as a popover under it */
.lp-hero__edit { position: absolute; top: 14px; right: 14px; margin: 0; }
.lp-hero__editbtn { list-style: none; cursor: pointer; width: 32px; height: 32px; border-radius: 9px;
                    display: flex; align-items: center; justify-content: center; color: #8b93a6;
                    border: 1px solid rgba(255,255,255,.14); background: transparent; }
.lp-hero__editbtn::-webkit-details-marker { display: none; }
.lp-hero__editbtn:hover, .lp-hero__edit[open] .lp-hero__editbtn { color: #fff; }
.lp-hero__editbtn:hover, .lp-hero__edit[open] .lp-hero__editbtn { color: #fff; background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.3); }
/* the edit pop-out is the SAME paper surface as the share and delete
   pop-outs — one popover look on the card (Alex, 2026-09-08) */
.lp-hero__editform { position: absolute; right: 0; top: calc(100% + 8px); z-index: 20; width: 320px;
                     margin: 0; display: flex; flex-direction: column; gap: 6px; text-align: left;
                     background: var(--paper); color: var(--text); border: 1px solid var(--hair);
                     border-radius: 12px; padding: 14px 16px 16px;
                     box-shadow: 0 18px 44px rgba(12,12,34,.22); }
.lp-hero__lbl { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--faint);
                font-family: var(--f-display); font-weight: 700; margin-top: 4px; }
.lp-hero__input { font: inherit; font-size: 13.5px; padding: 8px 10px; border: 1px solid var(--hair);
                  border-radius: 8px; background: var(--paper); color: var(--text); width: 100%;
                  box-sizing: border-box; resize: vertical; }
.lp-hero__input:focus { outline: none; border-color: var(--teal); }
.lp-hero__input::placeholder { color: var(--faint); }
.lp-hero__check { display: flex; gap: 9px; align-items: flex-start; font-size: 12.5px; color: var(--muted);
                  margin-top: 6px; line-height: 1.4; cursor: pointer; }
.lp-hero__check input { accent-color: var(--teal); margin-top: 2px; flex: none; }
.lp-hero__check b { color: var(--text); font-family: var(--f-display); font-weight: 700; }
.lp-hero__editacts { display: flex; justify-content: flex-end; margin-top: 4px; }
.lp-hero__save { font: inherit; font-family: var(--f-display); font-weight: 600; font-size: 13px;
                 color: #fff; background: var(--ink); border: 0; border-radius: 999px; padding: 8px 16px;
                 cursor: pointer; }
.lp-hero__share { font-size: 12px; color: #8b93a6; margin: 12px 0 0; word-break: break-all; }
.lp-hero__link { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px;
                 color: #dfe3ec; }

/* includes: books+papers are the static spine, cross-app media is opt-in */
.lp-inc { display: flex; align-items: center; gap: 9px; margin-top: 22px; flex-wrap: wrap; }
.lp-inc__label  { margin-right: 2px; }
.lp-inc__static { display: inline-flex; align-items: center; gap: 7px;
                  font-family: var(--f-display); font-weight: 600; font-size: 12.5px;
                  color: var(--muted); border: 1px solid var(--hair);
                  border-radius: var(--r-pill); padding: 7px 13px; }
.lp-inc__tog {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--f-display); font-weight: 600; font-size: 12.5px;
  color: var(--faint); border: 1.5px solid var(--hair); background: transparent;
  border-radius: var(--r-pill); padding: 8px 13px; cursor: pointer;
}
.lp-inc__tog.is-on { color: var(--text); border-color: var(--teal); background: var(--teal-08); }
.lp-inc__box {
  width: 15px; height: 15px; border-radius: 4px; border: 1.5px solid var(--hair);
  background: transparent; color: var(--on-grad); font-size: 10px; font-weight: 800;
  display: inline-flex; align-items: center; justify-content: center;
}
.lp-inc__tog.is-on .lp-inc__box { border-color: var(--teal); background: var(--teal); }

.lp-listhead { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; min-height: 36px; }
.lp-listhead h2 { font-size: 19px; line-height: 1.2; letter-spacing: -.01em; font-weight: 600;
                  color: var(--text); margin: 0; }
.lp-listhead__meta { margin-left: auto; font-size: 12.5px; color: var(--faint); }
.lp-steps { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
/* a playlist row: number (with the arrows), the media well, the body, the actions */
.lp-step { display: grid; grid-template-columns: 30px 96px minmax(0, 1fr) auto; align-items: center;
           gap: 16px; padding: 12px 14px; border-radius: 12px; border: 1px solid transparent; }
.lp-step:hover { background: var(--paper); border-color: var(--hair);
                 box-shadow: 0 1px 3px rgba(16,24,40,.07), 0 1px 2px rgba(16,24,40,.04); }
.lp-step--current { background: var(--paper); border: 2px solid var(--teal);
                    box-shadow: 0 12px 30px rgba(15,159,190,.14); }
.lp-step--current:hover { border-color: var(--teal); }
.lp-step__ix { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.lp-step__num { font-family: var(--f-display); font-weight: 700; font-size: 13px; color: var(--faint);
                display: flex; align-items: center; justify-content: center; min-height: 20px; }
.lp-step__num.is-done { color: var(--green); }
.lp-step__num.is-current { color: var(--teal); }
.lp-step__mvgap { display: block; height: 16px; }
/* ONE SQUARE for every kind (Alex, 2026-09-07): a cover centred on the cover
   well, a talk thumbnail filling it, a bare link the puck alone — so the text
   column starts in the same place whether a step is a book or a talk */
.lp-step__media, .pb-row__media {
  flex: 0 0 auto; border-radius: 10px; overflow: hidden; position: relative;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel); border: 1px solid var(--hair);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease); }
.lp-step:hover .lp-step__media {
  transform: translateY(-2px); border-color: var(--teal); box-shadow: var(--sh-sm);
}
.lp-step__media { width: 96px; height: 76px; }
.pb-row__media  { width: 48px; height: 48px; border-radius: 8px; }
.lp-step__media img, .pb-row__media img { max-width: 78%; max-height: 82%; width: auto; height: auto;
  object-fit: contain; border-radius: 3px; box-shadow: 0 3px 10px rgba(12,12,34,.22); }
/* a talk sits on the same well as a book, zoomed OUT to fit (Alex, 2026-09-07):
   the whole 16:9 frame, letterboxed, never a crop */
.lp-step__media--video img, .pb-row__media--video img { max-width: 88%; max-height: 88%; width: 88%;
  height: auto; object-fit: contain; border-radius: 3px; box-shadow: 0 3px 10px rgba(12,12,34,.22); }
.lp-step__media--video .lp-step__play, .pb-row__media--video .lp-step__play { position: absolute; }
.lp-step__media .lp-step__play, .pb-row__media .lp-step__play { z-index: 1; }
.lp-step__play  { width: 26px; height: 26px; border-radius: var(--r-pill);
                  background: rgba(10,10,20,.55);
                  display: flex; align-items: center; justify-content: center; }
.lp-step__body  { min-width: 0; }
.lp-step__meta  { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.lp-step__time  { font-size: 11.5px; color: var(--faint); }
.lp-step__title { font-family: var(--f-display); font-weight: 600; font-size: 15px; letter-spacing: -.01em;
                  color: var(--text); margin-top: 6px; line-height: 1.25; }
.lp-step__src   { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.lp-step__next  { font-family: var(--f-display); font-weight: 700; font-size: 11px;
                  letter-spacing: .08em; text-transform: uppercase; color: var(--teal); }
.lp-step__title a { color: inherit; text-decoration: none; }
.lp-step__title a:hover { text-decoration: none; }
.lp-step--done .lp-step__card { opacity: .72; }
/* the member's controls — a path you built, you can walk, tick and prune */
.lp-step__acts { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.lp-step__acts .btn { min-width: 84px; justify-content: center; }
.lp-step__form { margin: 0; }
.lp-step__done { border: 0; background: none; cursor: pointer; font: inherit;
                 font-size: 12.5px; font-weight: 600; color: var(--teal); padding: 2px 4px; }
.lp-step__done[aria-pressed="true"] { color: var(--muted); font-weight: 500; }
.lp-step__rm   { border: 0; background: none; cursor: pointer; font: inherit;
                 font-size: 12px; color: var(--faint); padding: 2px 4px; }
.lp-step__rm:hover { color: var(--coral); }
/* the step's note — the "why this is here" line */
.lp-step__note { font-size: 13px; color: var(--text); margin: 8px 0 0; line-height: 1.45;
                 border-left: 2px solid var(--teal); padding-left: 9px; }
.lp-step__notebox { margin-top: 6px; }
.lp-step__notebox summary { cursor: pointer; font-size: 12px; color: var(--faint);
                            list-style: none; width: max-content; }
.lp-step__notebox summary::-webkit-details-marker { display: none; }
.lp-step__notebox[open] summary { color: var(--muted); }
.lp-step__noteform { display: flex; gap: 8px; align-items: center; margin-top: 6px;
                     flex-wrap: wrap; }
.lp-step__noteform input { flex: 1 1 240px; font: inherit; font-size: 13px; padding: 7px 9px;
                           border: 1px solid var(--hair); border-radius: 8px;
                           background: var(--paper); color: var(--text); }
/* the move arrows stack around the number */
.lp-step__ix .lp-step__form { margin: 0; line-height: 0; }
.lp-step__mv { border: 0; background: none; cursor: pointer; font: inherit;
               font-size: 9px; color: #9aa3ae; padding: 3px 8px; line-height: 1; }
.lp-step__mv:hover, .lp-step__mv:focus-visible { color: var(--text); }
/* the quiet row under the body: Edit note · Choose part · Remove */
.lp-step__links { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 8px;
                  font-size: 12px; color: var(--faint); }
.lp-step__links .lp-step__form { margin: 0; }
.lp-step__link { color: var(--faint); text-decoration: none; }
.lp-step__link:hover { color: var(--text); text-decoration: underline; }
.lp-step__links .lp-step__notebox { margin: 0; }
.lp-step__links .lp-step__notebox[open] { flex-basis: 100%; }
.lp-step__rm { padding: 0; }

/* THE BUILDER — one box, a few rows per kind, an Add on each */
.pb { margin: 0; position: relative; background: var(--paper); border: 1px solid var(--hair);
      border-radius: var(--r-lg); padding: 18px 20px; }
.pb__h { font-size: 15px; margin: 0 0 10px; }
.pb__form { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.pb__field { flex: 1 1 180px; display: flex; align-items: center; gap: 8px;
             padding: 0 0 0 10px; min-height: 38px; color: var(--faint); }
.pb__field input { flex: 1; border: 0; background: none; font: inherit; font-size: 14px;
                   padding: 8px 6px; color: var(--text); min-width: 0; }
.pb__field input:focus { outline: none; }
/* Results stay in normal document flow. A floating/nested scroller looked
   compact, but its bottom could extend beyond the page's scroll range on a
   phone, making the last choices impossible to reach. */
.pb-results { display: none; }
.pb-results--open { display: block; position: relative; width: 100%;
                    margin-top: 10px; padding: 6px 0 4px;
                    background: var(--paper); border: 1px solid var(--hair);
                    border-width: 1px 0 0; border-radius: 0;
                    max-height: none; overflow: visible; }
.pb-results__bar { display: flex; justify-content: space-between; align-items: center;
                   gap: 12px; padding: 6px 0 2px; }
.pb-results__for { font-size: 12.5px; color: var(--faint); overflow: hidden;
                   text-overflow: ellipsis; white-space: nowrap; }
.pb-results__clear { font-size: 12.5px; color: var(--muted); text-decoration: none;
                     white-space: nowrap; }
.pb-results__clear:hover { color: var(--text); }
.pb-empty { font-size: 13px; color: var(--faint); margin: 8px 0 0; }
.pb-group { margin-top: 14px; }
.pb-group__h { font-family: var(--f-display); font-weight: 700; font-size: 11px;
               letter-spacing: .1em; text-transform: uppercase; color: var(--faint);
               margin: 0 0 6px; }
.pb-rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column;
           gap: 8px; }
.pb-row { display: flex; align-items: center; gap: 12px; background: var(--paper);
          border: 1px solid var(--hair); border-radius: 12px; padding: 10px 12px; }
.pb-row__body { flex: 1; min-width: 0; }
.pb-row__title { font-family: var(--f-display); font-weight: 700; font-size: 14px;
                 color: var(--text); margin-top: 4px; line-height: 1.25; }
.pb-row__src { font-size: 12.5px; color: var(--muted); margin-top: 2px;
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pb-row__add { display: flex; gap: 8px; align-items: center; flex: 0 0 auto;
               margin: 0; flex-wrap: wrap; justify-content: flex-end; }
.pb-row__name { font: inherit; font-size: 13px; padding: 7px 9px; border: 1px solid var(--hair);
                border-radius: 8px; background: var(--paper); color: var(--text);
                width: 180px; }
@media (max-width: 560px) {
  .pb-row { flex-wrap: wrap; }
  .pb-row__add { width: 100%; }
}

.pb-row__part { font-size: 12.5px; color: var(--faint); text-decoration: none; white-space: nowrap; }
.pb-row__part:hover { color: var(--text); text-decoration: underline; }
.lp-step__auto { font-size: 12px; color: var(--green); font-weight: 600; white-space: nowrap; }

/* THE PICKER — part of a work, part of a talk */
.pk { max-width: 760px; margin: 0 auto; padding: 26px var(--page-pad) 80px; }
.pk__head { display: flex; gap: 16px; align-items: center; margin: 8px 0 18px; }
.pk__head img { width: 56px; height: 82px; object-fit: cover; border-radius: 4px;
                box-shadow: 0 4px 12px rgba(12,12,34,.2); }
.pk__h1 { font-size: clamp(22px, 3.4vw, 28px); margin: 0 0 4px; }
.pk__sub { color: var(--faint); margin: 0; font-size: 13.5px; }
.pk__list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--hair);
            border-radius: 12px; background: var(--paper); overflow: hidden; }
.pk__row { display: flex; align-items: center; gap: 12px; padding: 10px 14px;
           border-top: 1px solid var(--hair); cursor: pointer; }
.pk__row:first-child { border-top: 0; }
.pk__row:hover { background: var(--surface, var(--bg)); }
.pk__row input { width: 17px; height: 17px; accent-color: var(--teal); flex: 0 0 auto; }
.pk__label { flex: 1; min-width: 0; font-size: 14px; color: var(--text); }
.pk__pages { font-size: 12px; color: var(--faint); white-space: nowrap; }
.pk__note { margin-top: 16px; max-width: 520px; }
.pk__acts { display: flex; gap: 10px; align-items: center; margin-top: 16px; flex-wrap: wrap; }
.pk__cancel { font-size: 13px; color: var(--faint); }
.pk__times { display: grid; grid-template-columns: repeat(2, minmax(120px, 180px)); gap: 12px;
             margin-top: 14px; }
.pk__times label { display: block; font-size: 12px; color: var(--faint); margin-bottom: 4px; }
.pk__times input { width: 100%; font: inherit; font-size: 15px; padding: 8px 10px;
                   border: 1px solid var(--hair); border-radius: 8px; background: var(--paper);
                   color: var(--text); }
.pk__hint { font-size: 12.5px; color: var(--faint); margin: 8px 0 0; }
.pk__thumb { width: 96px; height: 62px; border-radius: 8px; overflow: hidden; position: relative;
             flex: 0 0 auto; background: linear-gradient(135deg,#123c4a,#1d6b6b); }
.pk__thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
                 border-radius: 0; box-shadow: none; }

/* THE ADD-INTENT PAGE — one landing for every in-content capture */
.pa__quote { font-family: var(--f-read, Georgia, serif); font-size: 15px; line-height: 1.5;
             color: var(--text); border-left: 3px solid var(--teal); padding: 2px 0 2px 12px;
             margin: 12px 0 0; max-width: 60ch; }
.pa__which { margin-top: 18px; }
.pa__which select { width: 100%; max-width: 420px; font: inherit; padding: 9px 10px;
                    border: 1px solid var(--hair); border-radius: 8px; background: var(--paper);
                    color: var(--text); }
.pa__newname { margin-top: 8px; max-width: 420px; }
.pa__choice { display: flex; gap: 8px; align-items: center; font-size: 13.5px; margin-top: 10px;
              cursor: pointer; }
.pa__choice input { accent-color: var(--teal); }

/* growing the path */
.lp-add { margin-top: 34px; }
.lp-add__h { font-size: 17px; margin: 0 0 4px; }
.lp-add__p { font-size: 13px; color: var(--faint); margin: 4px 0 0; max-width: 60ch; }
.lp-add__form { display: flex; flex-direction: column; gap: 10px; margin-top: 12px;
                align-items: flex-start; }
.lp-add__field { width: 100%; max-width: 480px; }
.lp-step__action{ flex: 0 0 auto; white-space: nowrap; font-family: var(--f-display);
                  font-weight: 600; font-size: 12.5px; color: var(--muted); }
.lp-step--current .lp-step__action { color: var(--coral); }
.lp-foot { text-align: center; margin-top: 6px; font-size: 12.5px; color: var(--faint); }

@media (max-width: 859px) {
  .lp { padding: 20px var(--page-pad-m) 40px; }
  .lp-hero { padding: 24px; }
  .lp-hero h1 { font-size: 26px; }
  .lp-hero__prog .bar { width: 120px; }
  .lp-step { gap: 14px; }
  .lp-step__card { flex-wrap: wrap; }
}

/* ==========================================================================
   26. READER — shell, metrics, reading surface
       <div class="reader" data-reading-theme=… data-format=… data-overlay=…
            data-revealed=… data-font=… data-space=… data-margin=… data-size=…>
       Derived (server-side): revealed is FORCED true by any panel overlay;
       selection / tts / immersion deliberately do NOT reveal chrome.
   ========================================================================== */

/* `.reader` is the design system's own frame; `.rd` is the LIVE reader page's
   root element, and it was never given these sizes — so on the real reader
   every one of them fell back to nothing and the designer's phone block below
   applied to no page at all. `.rd-card` was the visible casualty: `width:
   var(--card-w)` with no fallback resolved to `auto`, so the About-this-book
   sheet shrink-wrapped to about 204px on a phone and set its title one word
   per line (Alex, 2026-09-08). Both roots carry the tokens now. */
.reader, .rd {
  --top-h: 56px; --bot-h: 62px; --chrome-pad: 22px; --icon-gap: 20px;
  --clock-w: 120px; --sheet-w: 380px; --card-w: 564px;
  --sel-top: 190px; --dict-bottom: 150px; --tts-w: 560px; --tts-bottom: 96px;
  --read-pad: 96px 40px 88px; --col-w: 640px; --read-size: 20px;
  --audio-art: 236px; --audio-title: 23px; --audio-gap: 18px;
  --audio-ctrl-gap: 38px; --play-btn: 66px; --audio-pad: 64px 40px;
  --pdf-pad: 86px 40px; --pdf-page-w: 560px;
}
/* A phone in landscape is 812x375 — wider than 700 — so a width-only query
   handed it the DESKTOP sizes: a 236px jacket plus 128px of padding inside a
   ~320px box. Height and pointer describe a phone better, exactly as the
   chrome's own query already says. */
@media (max-width: 700px), (max-height: 480px) and (pointer: coarse) {
  .reader, .rd {
    --top-h: 54px; --bot-h: 58px; --chrome-pad: 16px; --icon-gap: 16px;
    --clock-w: 52px; --sheet-w: 100%; --card-w: 344px;
    --sel-top: 150px; --dict-bottom: 120px; --tts-bottom: 80px;
    --read-pad: 78px 22px 70px; --col-w: 100%; --read-size: 18px;
    --audio-art: 204px; --audio-title: 20px; --audio-gap: 16px;
    --audio-ctrl-gap: 28px; --play-btn: 60px; --audio-pad: 64px 20px;
    --pdf-pad: 70px 16px; --pdf-page-w: 320px;
  }
}

.reader {
  position: relative; width: 100%; height: 100%; overflow: hidden;
  background: var(--rbg); color: var(--rtext);
  font-family: var(--f-read);
  -webkit-font-smoothing: antialiased;
}
.reader * { box-sizing: border-box; }

@keyframes rdFade { from { opacity: 0 } to { opacity: 1 } }
@keyframes rdUp   { from { opacity: 0; transform: translateY(14px) } to { opacity: 1; transform: translateY(0) } }
@keyframes rdBar  { 0% { opacity: .5 } 50% { opacity: 1 } 100% { opacity: .5 } }

.reader :focus-visible {
  outline: 2px solid var(--raccent); outline-offset: 2px;
  border-radius: 6px; box-shadow: none;
}
@media (hover: hover) {
  .reader .rd-tool:hover, .reader .rd-arrow:hover, .reader .rd-exit:hover { color: var(--rtext); }
  .reader .rd-pill:hover, .reader .rd-audio__pill:hover { background: var(--rbg); }
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .rd-topbar, .rd-botbar { background: var(--rsheet); }
}

/* ---- reading surface ---- */
.rd-surface { position: absolute; inset: 0; overflow: auto; padding: var(--read-pad); }
.rd-col     { max-width: var(--col-w); margin: 0 auto; }
.rd-chapter-eyebrow {
  font-family: var(--f-display); font-weight: 600; font-size: 12px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--rfaint); margin: 0 0 26px;
}
.rd-p {
  margin: 0 0 22px;
  font-family: var(--read-font, var(--f-read));
  font-size: var(--read-size);
  line-height: var(--read-lh, 1.6);   /* Cozy is the specified default */
  color: var(--rtext);
}

/* Settings-driven modifiers. The Aa panel's 16 values are specified as of V3
   and map 1:1 onto Readium CSS user properties: size a %, spacing a unitless
   multiplier, margins a multiplier. Each --USER__* below is the value Readium
   takes verbatim; the --read-size / --read-lh / --col-w twins next to it are
   what this sheet's own rules consume, so nothing downstream had to change. */
.reader[data-font="literata"] { --read-font: 'Literata', Georgia, serif; }
.reader[data-font="hanken"]   { --read-font: 'Hanken Grotesk', system-ui, sans-serif; }
.reader[data-font="atkinson"] { --read-font: 'Atkinson Hyperlegible', sans-serif; }
.reader[data-font="lexend"]   { --read-font: 'Lexend', sans-serif; }

/* line spacing — 3 steps, --USER__lineHeight, unitless. Cozy is the default.
   Was 1.45 / 1.72 / 2.00; the first two are corrected to the spec. */
.reader[data-space="compact"] { --USER__lineHeight: 1.4; --read-lh: 1.4; }
.reader[data-space="cozy"]    { --USER__lineHeight: 1.6; --read-lh: 1.6; }
.reader[data-space="loose"]   { --USER__lineHeight: 2.0; --read-lh: 2.0; }

/* page margins — 3 steps, --USER__pageMargins, a multiplier. Medium default.
   MECHANISM GAP, left as-is on purpose: this sheet varies the column width,
   V3 varies a margin multiplier, and the spec supplies no base gutter to
   multiply. Same intent, same direction (0.5 = less margin = wider column).
   The multiplier is recorded here so a Readium-backed reader can consume it;
   swap --col-w out for gutter arithmetic once design gives the base. */
.reader[data-margin="narrow"] { --USER__pageMargins: 0.5; --col-w: 760px; }
.reader[data-margin="medium"] { --USER__pageMargins: 1.0; --col-w: 640px; }
.reader[data-margin="wide"]   { --USER__pageMargins: 1.5; --col-w: 520px; }

/* font size — 10 steps, --USER__fontSize, a percentage of a 20px base.
   Endpoints are anchored on access, not taste: 250% is the low-vision ceiling.
   Was 9 absolute steps topping out at 30px, well short of that ceiling. */
.reader[data-size="1"]  { --USER__fontSize:  80%; --read-size: 16px; }
.reader[data-size="2"]  { --USER__fontSize:  90%; --read-size: 18px; }
.reader[data-size="3"]  { --USER__fontSize: 100%; --read-size: 20px; }
.reader[data-size="4"]  { --USER__fontSize: 115%; --read-size: 23px; }
.reader[data-size="5"]  { --USER__fontSize: 130%; --read-size: 26px; }
.reader[data-size="6"]  { --USER__fontSize: 150%; --read-size: 30px; }
.reader[data-size="7"]  { --USER__fontSize: 175%; --read-size: 35px; }
.reader[data-size="8"]  { --USER__fontSize: 200%; --read-size: 40px; }
.reader[data-size="9"]  { --USER__fontSize: 225%; --read-size: 45px; }
.reader[data-size="10"] { --USER__fontSize: 250%; --read-size: 50px; }
@media (max-width: 700px) {
  .reader[data-margin="narrow"], .reader[data-margin="medium"],
  .reader[data-margin="wide"] { --col-w: 100%; }
  /* local addition, no spec counterpart — never below 18px on mobile. Now
     steps 1-2, since the scale re-based (step 3 is already 20px). */
  .reader[data-size="1"],
  .reader[data-size="2"] { --USER__fontSize: 90%; --read-size: 18px; }
}

/* text decorations — four variants of the same paragraph */
.rd-sel      { background: var(--rsel); border-radius: 2px; box-shadow: 0 0 0 1px var(--raccent); }
.rd-tts-word { background: var(--rhl); border-radius: 3px;
               box-shadow: 0 1px 0 var(--raccent); color: var(--rtext); }
.rd-said     { color: var(--rmuted); }
.rd-now      { background: var(--raccent); color: var(--rbg); border-radius: 3px; padding: 0 3px; }
.rd-hl-mark  { background: var(--hl, var(--rhl)); border-radius: 2px; }

/* reading ruler — --ruler-line is set by JS from the live line box */
.rd-p--ruled { position: relative; }
.rd-ruler {
  position: absolute; left: -24px; right: -24px;
  top: calc(var(--read-lh, 1.6) * var(--ruler-line, 2) * 1em - .15em);
  height: 1.5em; background: var(--rband); border-radius: var(--r-cover);
  pointer-events: none;
}
.reader[style*="--ruler-color"] {
  --rband: color-mix(in srgb, var(--ruler-color) 30%, transparent);
}

/* ---- immersive state ---- */
.rd-whisper {
  position: absolute; left: 0; right: 0; bottom: 18px; margin: 0; text-align: center;
  font-family: var(--f-display); font-size: 11.5px; letter-spacing: .03em;
  color: var(--rfaint); animation: rdFade .6s var(--ease);
}
.rd-reveal-zone {
  position: absolute; top: 0; left: 0; right: 0; height: 64px;
  z-index: 10; cursor: pointer; background: none; border: 0; padding: 0;
}

/* ---- top bar ---- */
.rd-topbar {
  position: absolute; top: 0; left: 0; right: 0; height: var(--top-h);
  background: var(--rchrome);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--rline);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--chrome-pad); z-index: 20; animation: rdFade .3s var(--ease);
}
.rd-topbar__left { display: flex; align-items: center; gap: 12px; min-width: 0; }
.rd-exit {
  display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto;
  color: var(--ricon); cursor: pointer; text-decoration: none;
  font-family: var(--f-ui); font-size: 13px; font-weight: 600;
}
.rd-exit__label { opacity: .9; }
.rd-topbar__rule { width: 1px; height: 18px; background: var(--rline); flex: 0 0 auto; }
.rd-booktitle {
  margin: 0; font-family: var(--f-display); font-weight: 600; font-size: 13.5px;
  color: var(--rtext); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rd-tools { display: flex; align-items: center; gap: var(--icon-gap);
            color: var(--ricon); flex: 0 0 auto; }
.rd-tool  { display: inline-flex; cursor: pointer; color: inherit; text-decoration: none;
            background: none; border: 0; padding: 0; }
.rd-tool--accent { color: var(--raccent); }
.rd-tool--aa { font-family: var(--f-display); font-weight: 700; font-size: 16px;
               line-height: 1; letter-spacing: var(--ls-heading); }
.rd-tool--aa span { font-size: 11px; }

/* PDF top-bar extras */
.rd-zoom {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--rline); border-radius: var(--r-ctl); padding: 4px 9px;
  font-family: var(--f-ui); font-size: 12px; color: var(--rmuted);
}
.rd-zoom button { cursor: pointer; font-size: 15px; background: none; border: 0;
                  color: inherit; padding: 0 4px; }
.rd-download {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--rtext); color: var(--rbg); border-radius: var(--r-sm);
  padding: 7px 13px; text-decoration: none;
  font-family: var(--f-display); font-weight: 600; font-size: 12.5px;
}
.rd-viewonly {
  display: inline-flex; align-items: center; gap: 6px; color: var(--rfaint);
  font-family: var(--f-ui); font-size: 11.5px;
  border: 1px solid var(--rline); border-radius: var(--r-pill); padding: 5px 11px;
}

/* ---- bottom bar ---- */
.rd-botbar {
  position: absolute; bottom: 0; left: 0; right: 0; height: var(--bot-h);
  background: var(--rchrome);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  border-top: 1px solid var(--rline);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--chrome-pad); z-index: 20;
  font-family: var(--f-ui); animation: rdFade .3s var(--ease);
}
.rd-clock { width: var(--clock-w); font-family: var(--f-display);
            font-size: 12px; color: var(--rfaint); }
.rd-progress { flex: 1; text-align: center; min-width: 0; }
.rd-progress__line { margin: 0; font-size: 12px; color: var(--rmuted);
                     white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rd-progress__track { height: 3px; width: min(420px, 60%); margin: 6px auto 0;
                      background: var(--rline); border-radius: var(--r-sm); overflow: hidden; }
.rd-progress__fill  { height: 100%; background: var(--raccent); }
.rd-pageturn { width: var(--clock-w); display: flex; justify-content: flex-end;
               gap: 14px; color: var(--ricon); }
.rd-arrow { cursor: pointer; display: inline-flex; background: none; border: 0;
            color: inherit; padding: 0; }
.rd-botbar__spacer { flex: 1; }
.rd-botbar__spacer--end { display: flex; justify-content: flex-end; }
.rd-pdfnav { display: flex; align-items: center; gap: 16px;
             color: var(--ricon); font-size: 13px; }
.rd-pdfnav__count { font-family: var(--f-display); color: var(--rmuted); }
.rd-pdfnav__count span { color: var(--rfaint); }
.rd-servernote { font-size: 11px; color: var(--rfaint); }

/* ---- overlay shells ---- */
.rd-scrim {
  position: absolute; inset: 0; background: var(--rdim);
  z-index: 30; animation: rdFade .2s var(--ease);
  border: 0; padding: 0; width: 100%; cursor: default;
}
.rd-panel {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: var(--sheet-w); max-width: 100%;
  background: var(--rsheet); z-index: 40;
  box-shadow: -18px 0 44px rgba(0,0,0,.22);
  display: flex; flex-direction: column;
  font-family: var(--f-ui); animation: rdUp .22s var(--ease);
}
.rd-panel--left { right: auto; left: 0; box-shadow: 18px 0 44px rgba(0,0,0,.22); }
.rd-card {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  z-index: 40; width: var(--card-w, min(564px, 92vw)); max-width: 92%;
  max-height: 90%; overflow: auto; overscroll-behavior: contain;
  background: var(--rsheet); border-radius: var(--r-xl);
  box-shadow: 0 30px 70px rgba(0,0,0,.35);
  padding: 30px; font-family: var(--f-ui); animation: rdCardUp .24s var(--ease);
}
/* A centred card needs its OWN entrance: rdUp animates `transform`, which
   replaces translate(-50%,-50%) for the animation's duration — so the card
   rendered with its top-left corner at the viewport centre (down and to the
   right) and snapped into place when the animation ended. Every .rd-card
   overlay did this, not just the note composer. */
@keyframes rdCardUp {
  from { opacity: 0; transform: translate(-50%,-50%) translateY(14px); }
  to   { opacity: 1; transform: translate(-50%,-50%); }
}
.rd-card--scroll { padding: 32px; max-height: 90%; overflow: auto; overscroll-behavior: contain; }
/* The dismissal of last resort, pinned to the card while its body scrolls
   under it. 44px is the smallest square a thumb hits reliably. */
.rd-card__x { position: sticky; top: -8px; float: right; margin: -10px -10px 0 10px;
              width: 44px; height: 44px; border: 0; border-radius: var(--r-pill);
              background: var(--rbg); color: var(--rmuted); font-size: 26px; line-height: 1;
              cursor: pointer; z-index: 2; }
.rd-card__x:hover { color: var(--rtext); }
.rd-floatbar {
  position: absolute; left: 50%; bottom: var(--tts-bottom); transform: translateX(-50%);
  z-index: 40; width: var(--tts-w); max-width: 94%;
  background: var(--rsheet); border: 1px solid var(--rline); border-radius: var(--r-lg);
  box-shadow: 0 20px 50px rgba(0,0,0,.28);
  padding: 14px 18px; font-family: var(--f-ui); animation: rdUp .22s var(--ease);
}
.rd-panel__head {
  padding: 20px 22px 16px; border-bottom: 1px solid var(--rline);
  display: flex; align-items: center; justify-content: space-between; flex: 0 0 auto;
}
.rd-panel__headrow { display: flex; align-items: center; justify-content: space-between; }
.rd-panel__title { font-family: var(--f-display); font-weight: 700; font-size: 17px; color: var(--rtext); }
.rd-panel__body  { flex: 1; overflow: auto; }
.rd-close { cursor: pointer; color: var(--rmuted); background: none; border: 0;
            padding: 0; display: inline-flex; align-items: center; justify-content: center;
            /* the only exit from two of these cards — it needs a thumb's worth
               of room around its 20px glyph */
            min-width: 44px; min-height: 44px; margin: -12px -12px 0 0; }

.rd-tabs { display: flex; gap: 22px; margin-top: 16px; }
.rd-tab  { font-family: var(--f-display); font-weight: 600; font-size: 13px;
           color: var(--rmuted); padding-bottom: 8px; cursor: pointer;
           background: none; border: 0; }
.rd-tab[aria-selected="true"] { color: var(--rtext); box-shadow: inset 0 -2px 0 var(--raccent); }

/* universal switch (settings ×5, notebook ×1) */
.rd-switch { background: none; border: 0; padding: 0; cursor: pointer; display: inline-flex; }
.rd-switch__track {
  width: 38px; height: 22px; border-radius: var(--r-pill);
  background: var(--rline); position: relative; flex: 0 0 auto; transition: .15s;
}
.rd-switch__knob {
  position: absolute; top: 2px; left: 2px; width: 18px; height: 18px;
  border-radius: var(--r-pill); background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,.3); transition: .15s;
}
.rd-switch[aria-checked="true"] .rd-switch__track { background: var(--raccent); }
.rd-switch[aria-checked="true"] .rd-switch__knob  { left: 18px; }

.rd-eyebrow {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--f-display); font-weight: 700; font-size: 11px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--raccent);
}
.rd-pill {
  font-family: var(--f-display); font-size: 12px; font-weight: 600; color: var(--ricon);
  border: 1px solid var(--rline); border-radius: var(--r-pill); padding: 6px 12px;
  background: transparent; cursor: pointer;
}
.rd-beta {
  font-size: 8.5px; font-weight: 700; letter-spacing: var(--ls-tag);
  text-transform: uppercase; color: var(--raccent);
  border: 1px solid var(--raccent); border-radius: var(--r-pill); padding: 1px 6px;
}
.rd-note { font-size: 11px; color: var(--rfaint); margin: 8px 0 0;
           display: flex; align-items: center; gap: 6px; }
.rd-search {
  display: flex; align-items: center; gap: 9px; margin-top: 14px;
  background: var(--rbg); border: 1px solid var(--rline); border-radius: 10px;
  padding: 9px 12px;
}
.rd-search input { flex: 1; border: 0; background: transparent; outline: none;
                   font-family: inherit; font-size: 13px; color: var(--rtext); }
/* iOS zooms the whole page when a focused field is under 16px, and this shell
   is fixed + overflow:hidden, so there is no way to scroll back out of it. */
@media (pointer: coarse) {
  .rd-search input, .rd__notecard-text, .rd__panel input, .rd__panel textarea { font-size: 16px; }
}
.rd-search input::placeholder { color: var(--rfaint); }

/* ==========================================================================
   27. READER — Aa (Reading settings) panel
       Defaults: literata · cozy (1.6) · medium (1.0) · size step 3 (100% =
                 20px) · scroll:false · hc:false · anim:true · ruler:true
                 · tts:false · ruler #ffcf5c (was #ffe08a —
                 the ruler tints now draw from the canonical quartet)
   ========================================================================== */

.rd-set__body  { padding: 20px 22px 30px; flex: 1; overflow: auto; }
.rd-set__label {
  font-family: var(--f-display); font-weight: 700; font-size: 11px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--rfaint);
  margin: 24px 0 11px;
}
.rd-set__label:first-child { margin-top: 0; }

/* theme picker — swatch colours are LITERAL: it previews all three at once */
.rd-themes { display: flex; gap: 10px; }
.rd-theme {
  flex: 1; border: 1px solid var(--rline); border-radius: var(--r-md);
  padding: 14px 0; text-align: center; cursor: pointer;
}
.rd-theme.is-on { border: 2px solid var(--raccent); }
.rd-theme__aa  { display: block; font-family: var(--f-display); font-weight: 700; font-size: 15px; }
.rd-theme__lbl { display: block; font-size: 11px; margin-top: 3px; }
.rd-theme[data-k="light"] { background: #faf9f5; }
.rd-theme[data-k="light"] .rd-theme__aa  { color: #20242c; }
.rd-theme[data-k="light"] .rd-theme__lbl { color: #6b7280; }
.rd-theme[data-k="sepia"] { background: #f3ead4; }
.rd-theme[data-k="sepia"] .rd-theme__aa  { color: #463a28; }
.rd-theme[data-k="sepia"] .rd-theme__lbl { color: #8a7a60; }
.rd-theme[data-k="dark"]  { background: #14161c; }
.rd-theme[data-k="dark"]  .rd-theme__aa  { color: #c9cdd6; }
.rd-theme[data-k="dark"]  .rd-theme__lbl { color: #8b93a1; }

/* bordered toggle row */
.rd-set__row {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 12px; padding: 11px 13px;
  border: 1px solid var(--rline); border-radius: 11px; cursor: pointer;
}
.rd-set__row-label { font-size: 13.5px; font-weight: 600; color: var(--rtext); }

/* text-size slider */
.rd-size { display: flex; align-items: center; gap: 14px; }
.rd-size__min { font-family: var(--f-read); font-size: 15px; color: var(--rmuted); }
.rd-size__max { font-family: var(--f-read); font-size: 26px; color: var(--rtext); }
.rd-size__input { flex: 1; -webkit-appearance: none; appearance: none;
                  background: transparent; height: 20px; }
.rd-size__input::-webkit-slider-runnable-track {
  height: 4px; border-radius: var(--r-sm);
  background: linear-gradient(to right,
    var(--raccent) 0 var(--pct, 52%), var(--rline) var(--pct, 52%) 100%);
}
.rd-size__input::-moz-range-track    { height: 4px; border-radius: var(--r-sm); background: var(--rline); }
.rd-size__input::-moz-range-progress { height: 4px; border-radius: var(--r-sm); background: var(--raccent); }
.rd-size__input::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 20px; height: 20px;
  border-radius: var(--r-pill); background: #fff; border: 2px solid var(--raccent);
  box-shadow: 0 1px 4px rgba(0,0,0,.2); cursor: pointer; margin-top: -8px;
}
.rd-size__input::-moz-range-thumb {
  width: 20px; height: 20px; border-radius: var(--r-pill); box-sizing: border-box;
  background: #fff; border: 2px solid var(--raccent);
  box-shadow: 0 1px 4px rgba(0,0,0,.2); cursor: pointer;
}

/* four reading fonts (the Hanken option is labelled "Sans" — keep it) */
.rd-fonts { display: flex; gap: 8px; margin-top: 16px; }
.rd-font  { flex: 1; border: 1px solid var(--rline); border-radius: 11px;
            padding: 11px 6px; text-align: center; cursor: pointer; background: transparent; }
.rd-font.is-on { border: 1.5px solid var(--raccent); background: var(--rbg); }
.rd-font__ag   { display: block; font-size: 16px; color: var(--rtext); line-height: 1; }
.rd-font__name { display: block; font-family: var(--f-ui); font-size: 9.5px;
                 color: var(--rmuted); margin-top: 6px; line-height: 1.2; }
.rd-font[data-k="literata"] .rd-font__ag { font-family: 'Literata', serif; }
.rd-font[data-k="hanken"]   .rd-font__ag { font-family: 'Hanken Grotesk', sans-serif; }
.rd-font[data-k="atkinson"] .rd-font__ag { font-family: 'Atkinson Hyperlegible', sans-serif; }
.rd-font[data-k="lexend"]   .rd-font__ag { font-family: 'Lexend', sans-serif; }

/* line spacing + margins */
.rd-set__pair { display: flex; gap: 20px; margin-top: 22px; }
.rd-set__col  { flex: 1; }
.rd-set__sublabel { font-size: 12px; font-weight: 600; color: var(--rmuted); margin-bottom: 8px; }
.rd-seg3      { display: flex; gap: 6px; }
.rd-seg3__btn {
  flex: 1; text-align: center; border: 1px solid var(--rline); border-radius: var(--r-sm);
  padding: 8px 0; font-family: var(--f-display); font-size: 12px; font-weight: 600;
  color: var(--rmuted); background: transparent; cursor: pointer;
}
.rd-seg3__btn.is-on { border: 1.5px solid var(--raccent); background: var(--rbg); color: var(--rtext); }

/* layout & motion */
.rd-seg2 { display: flex; gap: 6px; background: var(--rbg);
           border: 1px solid var(--rline); border-radius: 11px; padding: 4px; }
.rd-seg2__btn {
  flex: 1; text-align: center; padding: 9px 0; border-radius: var(--r-ctl); border: 0;
  font-family: var(--f-display); font-size: 12.5px; font-weight: 600;
  background: transparent; color: var(--rmuted); box-shadow: none; cursor: pointer;
}
.rd-seg2__btn.is-on { background: var(--rsheet); color: var(--rtext);
                      box-shadow: 0 1px 3px rgba(0,0,0,.14); }

/* accessibility block — bordered, first-class */
.rd-a11y { margin-top: 26px; border: 1.5px solid var(--raccent);
           border-radius: 15px; overflow: hidden; }
.rd-a11y__head { background: var(--raccent); padding: 11px 15px;
                 display: flex; align-items: center; gap: 9px; }
.rd-a11y__title{ font-family: var(--f-display); font-weight: 700; font-size: 13.5px;
                 color: var(--r-on-accent, #04222a); }
.rd-a11y__body { padding: 6px 15px 14px; }
.rd-a11y__row  { display: flex; align-items: center; justify-content: space-between;
                 gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--rline); cursor: pointer; }
.rd-a11y__row--last { border-bottom: 0; }
.rd-a11y__name { font-size: 13.5px; font-weight: 600; color: var(--rtext); }
.rd-a11y__desc { font-size: 11.5px; color: var(--rmuted); margin-top: 1px; }
.rd-a11y__colors { display: flex; gap: 8px; padding: 12px 0; border-bottom: 1px solid var(--rline); }
.rd-rulercolor { width: 26px; height: 26px; border-radius: var(--r-pill); border: 0;
                 background: var(--c, var(--hl-yellow)); cursor: pointer; box-shadow: none; }
.rd-rulercolor.is-on { box-shadow: 0 0 0 2px var(--rsheet), 0 0 0 4px var(--raccent); }

/* ==========================================================================
   28. READER — read-aloud (TTS)
   ========================================================================== */

.rd-tts__head { display: flex; align-items: center; justify-content: space-between;
                margin-bottom: 11px; }
.rd-tts__controls { display: flex; align-items: center; gap: 16px; }
.rd-transport { display: flex; align-items: center; gap: 14px; color: var(--ricon); }
.rd-transport__skip { background: none; border: 0; padding: 0; color: inherit;
                      cursor: pointer; display: inline-flex; }
.rd-play {
  width: 44px; height: 44px; border-radius: var(--r-pill); border: 0;
  background: var(--rtext);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
/* 7-bar waveform — purely decorative CSS, never driven from audio analysis */
.rd-wave { flex: 1; display: flex; gap: 2px; align-items: flex-end; height: 22px; }
.rd-wave span { flex: 1; border-radius: 2px; background: var(--rline); }
.rd-wave span:nth-child(1) { height: 40%; }
.rd-wave span:nth-child(2) { height: 70%;  background: var(--raccent);
                             animation: rdBar 1s ease-in-out infinite; }
.rd-wave span:nth-child(3) { height: 100%; background: var(--raccent);
                             animation: rdBar 1s ease-in-out infinite .15s; }
.rd-wave span:nth-child(4) { height: 55%;  background: var(--raccent);
                             animation: rdBar 1s ease-in-out infinite .3s; }
.rd-wave span:nth-child(5) { height: 35%; }
.rd-wave span:nth-child(6) { height: 50%; }
.rd-wave span:nth-child(7) { height: 30%; }
.rd-tts__foot { font-size: 11px; color: var(--rfaint); margin: 10px 0 0; }
.rd-tts__foot a { color: var(--raccent); cursor: pointer; text-decoration: none; }

.rd-immersion { padding: 13px 16px; }
.rd-immersion__row { display: flex; align-items: center; gap: 13px; }
.rd-immersion__art { width: 44px; height: 44px; border-radius: var(--r-ctl);
                     object-fit: cover; flex: 0 0 auto; }
.rd-immersion__label    { flex: 0 0 auto; }
.rd-immersion__name     { font-family: var(--f-display); font-weight: 700;
                          font-size: 12px; color: var(--rtext); }
.rd-immersion__narrator { font-size: 11px; color: var(--rmuted); margin-top: 1px; }
.rd-immersion .rd-transport { gap: 11px; }
.rd-immersion .rd-play { width: 40px; height: 40px; flex: 0 0 auto; }
.rd-immersion__track { flex: 1; min-width: 36px; }
.rd-immersion__track > div { height: 4px; background: var(--rline);
                             border-radius: var(--r-sm); overflow: hidden; }
.rd-immersion__track > div > div { height: 100%; background: var(--raccent); }
.rd-immersion__foot { font-size: 10.5px; color: var(--rfaint); margin: 9px 0 0; }

/* ==========================================================================
   29. READER — selection menu · attribution · dictionary
       The selection menu is NOT themed: #1b1e27 in light, sepia and dark.
       Positioning below is canvas placement — in production drive left/top
       from the Range's bounding rect with viewport flipping. Keep the sizes.
   ========================================================================== */

.rd-selmenu {
  position: absolute; left: 50%; top: var(--sel-top); transform: translateX(-50%);
  z-index: 40; animation: rdUp .18s var(--ease);
}
.rd-selmenu__bar {
  display: flex; align-items: stretch; background: #1b1e27; border-radius: var(--r-md);
  box-shadow: 0 16px 40px rgba(0,0,0,.4); overflow: hidden; font-family: var(--f-ui);
}
.rd-selmenu__colors {
  display: flex; align-items: center; gap: 4px; padding: 0 12px; cursor: pointer;
  border-right: 1px solid rgba(255,255,255,.09);
}
.rd-swatch { width: 14px; height: 14px; border-radius: var(--r-pill); border: 0;
             background: var(--c, var(--hl-yellow)); cursor: pointer; box-shadow: none; }
.rd-swatch.is-on { box-shadow: 0 0 0 2px #1b1e27, 0 0 0 3px #fff; }
.rd-selmenu__item {
  display: flex; align-items: center; gap: 7px; padding: 11px 14px; cursor: pointer;
  background: none; border: 0; border-right: 1px solid rgba(255,255,255,.09);
  color: #eef0f4; font-size: 13px; font-weight: 600; font-family: inherit;
}
.rd-selmenu__item:hover { background: rgba(255,255,255,.06); }
.rd-selmenu__item--last { border-right: 0; }
.rd-attrib {
  margin: 8px 0 0; background: #1b1e27; border-radius: var(--r-sm); padding: 8px 12px;
  display: flex; align-items: center; gap: 8px; max-width: 340px;
  font-family: var(--f-ui); font-size: 11.5px; color: #aeb4c0; line-height: 1.4;
}
.rd-attrib svg { flex: 0 0 auto; }

.rd-dict {
  position: absolute; left: var(--chrome-pad); bottom: var(--dict-bottom);
  z-index: 40; width: min(360px, calc(100vw - 24px));
  /* THE CARD IS ANCHORED BY ITS BOTTOM, SO IT GROWS UPWARD — and `.rd` is
     position:fixed with overflow:hidden, so anything past the top edge is not
     merely off-screen, it is CLIPPED and unreachable by any scroll. Our own
     shelf is why there is enough of it to matter: "continuous delivery" carries
     8 senses and "devops" 11, well over a phone's height, so Alex opened
     `continuous delivery' in Industrial DevOps and lost the headword and the
     first six senses off the top (2026-09-09). Cap it and scroll INSIDE it —
     the touch layer already exempts .rd-dict from swipe-to-turn and
     tap-to-reveal, so an internal scroller does not fight the page. The floor
     keeps a short window (a landscape phone) from degrading to a sliver. */
  max-height: max(180px, calc(100% - 24px));
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  background: var(--rsheet); border: 1px solid var(--rline); border-radius: 14px;
  box-shadow: 0 18px 44px rgba(0,0,0,.22); padding: 16px 18px;
  font-family: var(--f-ui); animation: rdUp .2s var(--ease);
}
.rd-dict__close {
  position: sticky; float: right; top: 0; z-index: 3; display: grid; place-items: center;
  width: 28px; height: 28px; margin: -7px -9px 0 8px; padding: 0;
  border: 0; border-radius: 50%; background: var(--rline); color: var(--rmuted);
  font: 22px/1 var(--f-ui); cursor: pointer;
}
.rd-dict__close:hover { background: var(--rline); color: var(--rtext); }
.rd-dict__top  { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.rd-dict__word { font-family: var(--f-display); font-weight: 700; font-size: 16px; color: var(--rtext); }
.rd-dict__pos  { font-size: 11px; color: var(--rfaint); }
.rd-dict__ipa  { font-size: 11.5px; color: var(--rfaint); margin-top: 1px; }
.rd-dict__def  { font-size: 13px; line-height: 1.5; color: var(--rmuted); margin: 9px 0 0; }
/* "In our books" — the half of the card no dictionary could supply. It leads,
   and it is set in the READING face rather than the UI face, because these are
   an author's own sentences lifted out of a book on this shelf. The general
   definition below stays in the UI face and reads as the reference note it is. */
.rd-dict__ours     { margin-top: 10px; }
.rd-dict__ourshead { font-family: var(--f-display); font-size: 10.5px; font-weight: 700;
                     letter-spacing: .09em; text-transform: uppercase;
                     color: var(--raccent); margin: 0 0 6px; }
.rd-dict__sense    { border-left: 2px solid var(--rhair, rgba(128,128,128,.25));
                     padding-left: 10px; margin-bottom: 9px; }
.rd-dict__sense:last-child { margin-bottom: 0; }
.rd-dict__sensedef { font-family: var(--f-read); font-size: 13px; line-height: 1.5;
                     color: var(--rtext); margin: 0; }
.rd-dict__sensecite{ font-size: 11px; color: var(--rfaint); margin: 3px 0 0; }
/* When our books answered, the general definition is a footnote to them. */
.rd-dict__ours:not([hidden]) ~ .rd-dict__def { padding-top: 9px;
                     border-top: 1px solid var(--rhair, rgba(128,128,128,.18)); }
/* The headword and onward links remain visible in long entries. The close
   control is a sticky X in the upper-right, and outside-click is also an exit. */
.rd-dict__top { position: sticky; top: -16px; z-index: 1; background: var(--rsheet);
                padding-top: 16px; margin-top: -16px; }
.rd-dict__links{ position: sticky; bottom: -16px; z-index: 1; background: var(--rsheet);
                 padding-bottom: 16px; margin-bottom: -16px;
                 display: flex; gap: 14px; margin-top: 11px;
                 font-family: var(--f-display); font-size: 12px; font-weight: 600; }
.rd-dict__links a { color: var(--raccent); cursor: pointer; text-decoration: none; }

/* ==========================================================================
   30. READER — notebook · contents
   ========================================================================== */

.rd-notebook__head { padding: 20px 22px 14px; border-bottom: 1px solid var(--rline); flex: 0 0 auto; }
.rd-popularrow {
  padding: 6px 14px; border-bottom: 1px solid var(--rline);
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex: 0 0 auto;
}
.rd-popularrow__label { display: flex; align-items: center; gap: 8px;
                        font-size: 12.5px; color: var(--rmuted); }

.rd-hl-list { flex: 1; overflow: auto; padding: 8px 22px 22px; margin: 0; list-style: none; }
/* position: the delete control is absolute and must anchor to its own row —
   without this it resolves against the panel and lands in the sheet's corner,
   looking like a second close button. */
.rd-hl      { display: flex; gap: 11px; padding: 16px 26px 16px 0;
              border-bottom: 1px solid var(--rline);
              position: relative; cursor: pointer; }
/* the row reserves the delete's width above, so it never sits on the passage */
.rd-hl .rd__note-del { top: 12px; right: -4px; }
.rd-hl__meta { flex-wrap: wrap; }
.rd-hl__rail{ width: 4px; border-radius: var(--r-sm); background: var(--c, var(--hl-yellow)); flex: 0 0 auto; }
.rd-hl__body{ flex: 1; min-width: 0; }
.rd-hl__quote { margin: 0; font-family: 'Literata', serif; font-size: 14px;
                line-height: var(--lh-body); color: var(--rtext); }
.rd-hl__note  { margin-top: 8px; background: var(--rbg); border-radius: var(--r-ctl);
                padding: 8px 11px; font-size: 12.5px; color: var(--rmuted); line-height: 1.45; }
.rd-hl__meta  { display: flex; align-items: center; gap: 10px; margin-top: 8px;
                font-size: 11.5px; color: var(--rfaint); flex-wrap: wrap; }
.rd-hl__popular { display: inline-flex; align-items: center; gap: 4px; color: var(--raccent); }
/* when the popular toggle is OFF: hide community badges + community-only rows */
.rd-notebook[data-popular="off"] .rd-hl__popular { display: none; }
.rd-notebook[data-popular="off"] .rd-hl--community { display: none; }

.rd-toc__body { padding: 8px 12px 22px; }
.rd-toc__item {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px; border-radius: var(--r-sm); margin-bottom: 2px;
  background: transparent; cursor: pointer; text-decoration: none;
}
/* The copyright page is hidden from the reading flow but still named here, so
   the book's own © line, its LCCN and the designers' credits stay one tap
   away. It is apparatus, not a chapter — set under a rule and quieter, so it
   reads as the back of the book rather than a section of it. */
.rd-toc__item--foot { margin-top: 14px; padding-top: 16px;
                      border-top: 1px solid var(--rline); border-radius: 0;
                      font-size: 12.5px; }
.rd-toc__item--foot .rd-toc__title { color: var(--rfaint); }
.rd-toc__title { font-family: var(--f-display); font-weight: 500; font-size: 13.5px; color: var(--rmuted); }
.rd-toc__page  { font-size: 12px; color: var(--rfaint); }
.rd-toc__row { display: flex; align-items: stretch; }
.rd-toc__row .rd-toc__item { flex: 1; min-width: 0; }
.rd-toc__add { display: flex; align-items: center; justify-content: center; width: 34px;
               flex: 0 0 auto; color: var(--rfaint); text-decoration: none; font-size: 18px;
               line-height: 1; opacity: .55; }
.rd-toc__row:hover .rd-toc__add, .rd-toc__add:focus-visible { opacity: 1; color: var(--rtext); }
.rd-toc__item[aria-current="true"] { background: var(--rbg); }
.rd-toc__item[aria-current="true"] .rd-toc__title { font-weight: 700; color: var(--rtext); }

/* ==========================================================================
   31. READER — audiobook player · PDF surfaces
   ========================================================================== */

.rd-audio {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  /* `safe` centring keeps the stack centred when it fits and switches to the
     start when it does not: plain `center` inside a clipped box pushes the
     overflow off BOTH ends, so on a 640px phone viewport the switch pill and
     the status line simply vanished with no way to scroll to them. */
  justify-content: safe center;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: var(--audio-pad); text-align: center;
}
/* HEIGHT FROM THE LAYOUT, WIDTH FROM THE PICTURE. A fixed square box with
   object-fit:cover cut the top and bottom off every cover that is not 1:1 — and
   only 15 of the 35 audiobooks have genuinely square art, so most of them were
   being cropped (measured 2026-09-08; 7 more resolve a PORTRAIT file and 13 have
   none of their own). Sizing to the image needs no flag and cannot guess wrong.
   42vh leaves room for the transport on a short screen. */
.rd-audio__art {
  height: min(var(--audio-art), 42vh); width: auto;
  max-width: min(var(--audio-art), 62vw);
  flex: 0 0 auto; object-fit: contain;
  border-radius: 14px; box-shadow: 0 26px 60px rgba(0,0,0,.4);
}
/* the initial-on-accent stand-in has no picture to size to, so it stays square */
.rd-audio__art--fallback { width: min(var(--audio-art), 42vh); }
.rd-audio__title {
  margin: var(--audio-gap) 0 0; font-family: var(--f-display); font-weight: 700;
  font-size: var(--audio-title); color: var(--rtext); letter-spacing: var(--ls-heading);
}
.rd-audio__byline  { margin: 4px 0 0; font-family: var(--f-ui);
                     font-size: 14px; color: var(--rmuted); }
.rd-audio__chapter { margin: 14px 0 0; font-family: var(--f-display);
                     font-size: 12.5px; color: var(--rfaint); }
.rd-audio__scrub { width: 460px; max-width: 88%; margin-top: 12px; flex: 0 0 auto; }
/* NO `overflow: hidden` here. The transparent native range deliberately bleeds
   9px above and below this 5px track so a finger has something to grab; clipping
   it left a 5px touch target and a slider thumb that could not be caught at all
   (2026-09-08). The fill rounds its own corners instead. */
.rd-audio__track { height: 5px; background: var(--rline); border-radius: var(--r-sm); }
.rd-audio__fill  { height: 100%; background: var(--raccent); border-radius: inherit; }
.rd-audio__times { display: flex; justify-content: space-between; margin-top: 6px;
                   font-family: var(--f-ui); font-size: 11.5px; color: var(--rfaint); }
.rd-audio__transport { display: flex; align-items: center; gap: var(--audio-ctrl-gap); margin-top: 22px; }
/* 44px is the smallest square a thumb hits reliably; these were 26px wide and
   sit either side of the play button, which makes them the easiest to miss. */
.rd-skip { display: flex; flex-direction: column; align-items: center; justify-content: center;
           gap: 3px; min-width: 44px; min-height: 44px;
           color: var(--ricon); cursor: pointer; background: none; border: 0; padding: 0; }
.rd-skip span { font-family: var(--f-ui); font-size: 10.5px; color: var(--rfaint); }
.rd-audio__play {
  width: var(--play-btn); height: var(--play-btn); border-radius: var(--r-pill);
  border: 0; background: var(--rtext);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.rd-audio__secondary { display: flex; align-items: center; gap: 10px; margin-top: 22px;
                       font-family: var(--f-display); flex-wrap: wrap; justify-content: center; }
.rd-audio__pill {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-height: 44px;
  font-size: 12.5px; font-weight: 600; color: var(--ricon);
  border: 1px solid var(--rline); border-radius: var(--r-pill); padding: 7px 14px;
  background: transparent; cursor: pointer; font-family: inherit;
}
.rd-switchpill { min-height: 44px;
  display: inline-flex; align-items: center; gap: 9px; margin-top: 24px;
  background: var(--rsurface); border: 1px solid var(--rline); border-radius: var(--r-pill);
  padding: 9px 16px; cursor: pointer; text-decoration: none;
  font-family: var(--f-ui); box-shadow: 0 4px 14px rgba(0,0,0,.12);
}
.rd-switchpill span { font-size: 12.5px; font-weight: 600; color: var(--rtext); }

/* PDF: the desk colour is a literal, theme-branched, non-token value */
.rd-pdf {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  padding: var(--pdf-pad); overflow: auto; background: #3a3f4a;
}
[data-reading-theme="dark"] .rd-pdf { background: #0c0e13; }
.rd-pdf__page {
  width: var(--pdf-page-w); max-width: 100%; aspect-ratio: 1 / 1.294;
  background: #fff; color: #1a1a22;
  box-shadow: 0 20px 60px rgba(12,12,34,.28); border-radius: 2px;
  padding: 9% 10%; overflow: hidden; font-family: 'Literata', serif;
  container-type: inline-size;      /* the design used vw; cqw survives a real viewport */
}
.rd-pdf__title { font-family: var(--f-display); font-weight: 700;
                 font-size: 3.16cqw; letter-spacing: -.01em; color: #0d0d22; }
.rd-pdf__rule  { height: 3px; width: 54px; margin: 2.4% 0;
                 background: linear-gradient(90deg,#0cabca,#38c89b); }
.rd-pdf__body  { font-size: 2.15cqw; line-height: 1.6; color: #2b2f3a; }
.rd-pdf__body p{ margin: 0 0 1.1em; }
@supports not (container-type: inline-size) {
  .rd-pdf__title { font-size: 17.7px; }
  .rd-pdf__body  { font-size: 12px; }
}

/* ==========================================================================
   32. READER — read & listen · about this book · assistant panel
   ========================================================================== */

.rd-ws__h    { font-family: var(--f-display); font-weight: 700; font-size: 21px;
               margin-top: 14px; line-height: 1.2; letter-spacing: var(--ls-heading);
               color: var(--rtext); }
.rd-ws__sub  { font-size: 13.5px; color: var(--rmuted); line-height: 1.5; margin-top: 6px; }
.rd-ws__opts { display: flex; gap: 12px; margin-top: 24px; }
/* the Read tile is fed a real section name by the script, so on a phone
   the tiles stack rather than squeeze */
@media (max-width: 560px) { .rd-ws__opts { flex-direction: column; } }
#rd-ws-readpos { overflow-wrap: anywhere; }
.rd-ws__opt  { position: relative; flex: 1; border: 1px solid var(--rline);
               border-radius: 14px; padding: 16px 10px; text-align: center; cursor: pointer;
               display: flex; flex-direction: column; align-items: center; }
.rd-ws__label { font-family: var(--f-display); font-weight: 700; font-size: 13.5px;
                margin-top: 9px; color: var(--rtext); }
.rd-ws__sublabel { font-size: 11.5px; color: var(--rmuted); margin-top: 2px; }
.rd-ws__now { position: absolute; top: 8px; right: 9px; font-size: 8.5px; font-weight: 700;
              letter-spacing: .05em; text-transform: uppercase; color: var(--rfaint); }
.rd-ws__foot { font-size: 12px; color: var(--rfaint); text-align: center; margin-top: 16px; }

/* align-items MATTERS here: a flex row stretches its children by default, so
   the cover — width 104, height unset — was pulled to the height of the column
   beside it. On a phone that column is tall and narrow, so the jacket rendered
   about 390px tall and grotesquely distorted (Alex, 2026-09-08). */
.rd-about__top   { display: flex; gap: 22px; align-items: flex-start; }
.rd-about__cover { width: 104px; height: auto; object-fit: contain;
                   border-radius: var(--r-cover); flex: 0 0 auto;
                   box-shadow: 0 14px 30px rgba(0,0,0,.3); }
.rd-about__title { font-family: var(--f-display); font-weight: 700; font-size: 24px;
                   line-height: 1.1; letter-spacing: var(--ls-heading); color: var(--rtext);
                   overflow-wrap: break-word; }
.rd-about__author{ font-size: 14px; color: var(--rmuted); margin-top: 6px; }
.rd-about__chips { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.rd-about__chip  { font-family: var(--f-display); font-weight: 600; font-size: 11px;
                   color: var(--rmuted); border: 1px solid var(--rline);
                   border-radius: var(--r-pill); padding: 4px 10px; }
.rd-about__blurb { font-family: 'Literata', serif; font-size: 14.5px; line-height: 1.62;
                   color: var(--rtext); margin-top: 20px; }
.rd-about__where { font-family: var(--f-display); font-weight: 700; font-size: 13px;
                   color: var(--rtext); margin: 20px 0 10px; }
.rd-about__pos   { background: var(--rbg); border-radius: 11px; padding: 13px 15px; }
.rd-about__acts  { display: flex; gap: 10px; margin-top: 16px; }
.rd-about__primary {
  flex: 1; background: var(--rtext); color: var(--rbg); border: 0;
  font-family: var(--f-display); font-weight: 600; font-size: 15px;
  padding: 14px; border-radius: var(--r-md); cursor: pointer;
}
.rd-about__secondary {
  background: transparent; border: 1.5px solid var(--rline); color: var(--rtext);
  font-family: var(--f-display); font-weight: 600; font-size: 14px;
  padding: 14px 18px; border-radius: var(--r-md); cursor: pointer;
}
.rd-about__dismiss { font-size: 12px; color: var(--rfaint); text-align: center; margin-top: 6px; }
.rd-about__dismiss button { padding: 14px 16px; }
/* The note composer asks for .btn-quiet and the sheet never defined one, so
   Cancel — the composer's own dismissal — rendered as unstyled text beside a
   fully drawn Save (2026-09-08). */
.btn-quiet { padding: 13px 18px; min-height: 44px; border: 0; background: none;
             color: var(--rmuted); border-radius: var(--r-md); cursor: pointer;
             font-family: var(--f-display); font-weight: 600; font-size: 14px; }
@media (hover: hover) { .btn-quiet:hover { color: var(--rtext); } }

.rd-ai__head { padding: 20px 22px 0; }
.rd-ai .rd-tabs { gap: 20px; }
.rd-ai .rd-tab  { padding-bottom: 10px; }
.rd-ai__body { padding: 20px 22px; display: flex; flex-direction: column; gap: 16px;
               flex: 1; overflow: auto; }
.rd-bubble--user {
  align-self: flex-end; max-width: 80%;
  background: var(--raccent); color: var(--r-on-accent, #04222a);
  border-radius: 14px 14px 3px 14px; padding: 11px 14px;
  font-size: 13.5px; line-height: 1.45;
}
.rd-bubble--ai {
  align-self: flex-start; max-width: 88%;
  background: var(--rbg); border: 1px solid var(--rline);
  border-radius: 14px 14px 14px 3px; padding: 13px 15px;
  font-size: 13.5px; line-height: var(--lh-body);
}
.rd-citechips { display: flex; gap: 6px; margin-top: 9px; flex-wrap: wrap; }
.rd-citechip  { font-size: 11px; color: var(--raccent); border: 1px solid var(--rline);
                border-radius: var(--r-pill); padding: 3px 9px; }
.rd-composer  { padding: 14px 18px; border-top: 1px solid var(--rline); flex: 0 0 auto; }
.rd-composer__field {
  display: flex; align-items: center; gap: 10px;
  background: var(--rbg); border: 1px solid var(--rline);
  border-radius: var(--r-md); padding: 11px 14px;
}
.rd-composer__field input { flex: 1; border: 0; background: transparent; outline: none;
                            font-family: inherit; font-size: 13.5px; color: var(--rtext); }
.rd-disclaimer { font-size: 11px; color: var(--rfaint); margin-top: 9px;
                 text-align: center; line-height: 1.4; }

/* ==========================================================================
   33. UTILITIES
   ========================================================================== */

.hide       { display: none !important; }
.tap-min    { min-width: var(--tap); min-height: var(--tap); }
.nowrap     { white-space: nowrap; }
.truncate   { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.clamp-2    { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2;
              -webkit-box-orient: vertical; overflow: hidden; }
.measure    { max-width: var(--measure); }
.center     { text-align: center; }

@media print {
  .gnav, .foot, .cta-band, .rd-topbar, .rd-botbar, .rd-panel, .rd-scrim,
  .rd-floatbar, .rd-selmenu { display: none !important; }
  .rd-surface { position: static; padding: 0; }
  body, .reader { background: #fff; color: #000; }
}

/* clear-search control inside the field */
.filterbar__clear {
  flex: 0 0 auto; font: 600 12.5px/1 var(--f-display); text-decoration: none;
  color: var(--faint); padding: 9px 10px; border-radius: 999px;
}
.filterbar__clear:hover { color: var(--coral); }

/* author headshots reuse the .avatar frame the initials fallback occupies */
img.avatar { object-fit: cover; background: var(--field); }

/* bullet lists inside a work description (About tab) */
.prose-list { margin: 0 0 18px; padding-left: 20px; }
.prose-list li { font-size: 15px; line-height: 1.65; color: var(--text2); margin: 0 0 7px; }

/* ==========================================================================
   READER — screen 4 of the V3 design bundle (Reader Frame / Reader /
   Reader Settings sheets).

   The reader carries its OWN token set (--r*) rather than the site tokens.
   That is the design's decision, not a divergence: a reading theme is not a UI
   theme. Sepia and dark here are page colours chosen for long sessions, and
   high-contrast is a SEPARATE axis (data-hc) that can combine with any of
   them — which is why there is a [data-theme="dark"][data-hc="on"] block
   rather than four flat themes.

   Tokens copied verbatim from Reader Frame.dc.html.
   ========================================================================== */

.rd { --rbg:#faf9f5; --rsurface:#ffffff; --rtext:#20242c; --rmuted:#6b7280;
      --rfaint:#6f7681; --rline:#e7e4dc; --rchrome:rgba(250,249,245,.92);
      --ricon:#3a3f48; --raccent:#0f9fbe; --rcoral:#ee5d74;
      --rhl:rgba(255,206,84,.42); --rsel:rgba(15,159,190,.20); --rsheet:#ffffff;
      --rdim:rgba(20,20,34,.34); --rband:rgba(255,214,110,.30); }
.rd[data-theme="sepia"] { --rbg:#f3ead4; --rsurface:#faf3e1; --rtext:#463a28;
      --rmuted:#6d5f47; --rfaint:#8a7856; --rline:#e2d5b8;
      --rchrome:rgba(243,234,212,.93); --ricon:#5b4c37; --raccent:#2f9c8b;
      --rcoral:#c96a52; --rhl:rgba(210,150,40,.34); --rsel:rgba(47,156,139,.22);
      --rsheet:#faf3e1; --rdim:rgba(75,63,47,.32); --rband:rgba(210,160,60,.28); }
.rd[data-theme="dark"] { --rbg:#14161c; --rsurface:#1c1f28; --rtext:#c9cdd6;
      --rmuted:#8b93a1; --rfaint:#8d95a2; --rline:#2a2e38;
      --rchrome:rgba(18,20,26,.92); --ricon:#aeb4bf; --raccent:#3fc3dd;
      --rcoral:#ff6f84; --rhl:rgba(255,214,110,.20); --rsel:rgba(63,195,221,.22);
      --rsheet:#1c1f28; --rdim:rgba(0,0,0,.58); --rband:rgba(255,214,110,.14); }
.rd[data-hc="on"] { --rbg:#ffffff; --rsurface:#ffffff; --rtext:#000000;
      --rmuted:#26313d; --rfaint:#3a4551; --rline:#000000;
      --rchrome:rgba(255,255,255,.98); --ricon:#000000; --raccent:#0a5e73;
      --rcoral:#a5122b; --rhl:rgba(10,94,115,.30); --rsel:rgba(10,94,115,.28);
      --rsheet:#ffffff; --rdim:rgba(0,0,0,.55); --rband:rgba(10,94,115,.20); }
.rd[data-theme="dark"][data-hc="on"] { --rbg:#000000; --rsurface:#000000;
      --rtext:#ffffff; --rmuted:#d7dde6; --rfaint:#b9c0cc; --rline:#ffffff;
      --rchrome:rgba(0,0,0,.98); --ricon:#ffffff; --raccent:#7fe3ff;
      --rcoral:#ff9db0; --rhl:rgba(127,227,255,.32); --rsel:rgba(127,227,255,.30);
      --rsheet:#000000; --rdim:rgba(0,0,0,.7); --rband:rgba(127,227,255,.22); }
.rd[data-hc="on"] * { text-shadow: none !important; }

@keyframes rdFade { from { opacity: 0 } to { opacity: 1 } }
@keyframes rdUp   { from { opacity: 0; transform: translateY(14px) }
                    to   { opacity: 1; transform: translateY(0) } }

/* ---- the shell ---- */
.rd {
  position: fixed; inset: 0; overflow: hidden;
  background: var(--rbg); color: var(--rtext);
  font-family: 'Literata', Georgia, serif;
  /* ONE number for the bottom bar's height AND the scroller's inset below it.
     They used to be written twice, and the phone block changed only one. */
  --rd-chrome-b: calc(62px + env(safe-area-inset-bottom));
  --rd-mini-b: calc(28px + env(safe-area-inset-bottom));
}
/* Immersive by DEFAULT — the governing principle of the sheet. Reading is the
   product, so the chrome is absent until asked for, not merely faded. */
/* visibility, not just opacity: with opacity alone all seven chrome controls
   stayed in the tab order and operable while completely invisible. */
.rd__bar { opacity: 0; visibility: hidden; pointer-events: none;
           transition: opacity .22s ease, visibility .22s; }
/* ONE thing animates the opacity. The revealed rule also ran `animation: rdFade`
   over the top of the .22s transition declared just above, so two engines drove
   the same property and interrupting a reveal — tapping again while it fades —
   handed the element to whichever finished last. That is a flicker on the tap
   that summons the bars (Alex, 2026-09-09). The transition alone does the fade. */
.rd.is-revealed .rd__bar { opacity: 1; visibility: visible; pointer-events: auto; }
.rd__mini {
  position: absolute; inset: auto 0 0; z-index: 19;
  height: var(--rd-mini-b); padding: 0 12px env(safe-area-inset-bottom);
  display: flex; align-items: center; justify-content: center; gap: 14px;
  border: 0; background: var(--rbg); color: var(--rmuted); cursor: pointer;
  font: 11px 'Hanken Grotesk', system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
}
.rd__mini:focus-visible { outline: 2px solid var(--raccent); outline-offset: -2px; }
.rd.is-revealed .rd__mini { visibility: hidden; pointer-events: none; }

.rd__top, .rd__bot {
  position: absolute; left: 0; right: 0; z-index: 20;
  background: var(--rchrome); backdrop-filter: blur(14px);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 28px; font-family: 'Hanken Grotesk', system-ui, sans-serif;
}
.rd__top { top: 0; height: 56px; border-bottom: 1px solid var(--rline); }
.rd__bot { bottom: 0; height: 62px; border-top: 1px solid var(--rline); }
/* The page declares viewport-fit=cover, so the bars run under the notch and the
   home indicator unless they say otherwise. env() is 0 everywhere else, so
   these are inert off a notched phone. */
.rd__bot { height: calc(62px + env(safe-area-inset-bottom));
           padding-bottom: env(safe-area-inset-bottom); }
.rd__top { padding-top: env(safe-area-inset-top);
           height: calc(56px + env(safe-area-inset-top)); }
.rd__top, .rd__bot { padding-left: max(var(--chrome-pad, 22px), env(safe-area-inset-left));
                     padding-right: max(var(--chrome-pad, 22px), env(safe-area-inset-right)); }

.rd__back {
  display: inline-flex; align-items: center; gap: 6px; color: var(--ricon);
  cursor: pointer; font-size: 13px; font-weight: 600; text-decoration: none;
  /* shrinkable: back-label is an arbitrary learning-path title, and an
     unshrinkable one pushed the five tool buttons off a 375px screen */
  flex: 0 1 auto; min-width: 0;
}
.rd__back span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rd__rule { width: 1px; height: 18px; background: var(--rline); flex: 0 0 auto; }
.rd__title {
  font-family: 'Sora', system-ui, sans-serif; font-weight: 600; font-size: 13.5px;
  color: var(--rtext); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rd__tools { display: flex; align-items: center; gap: 18px; color: var(--ricon); flex: 0 0 auto; }
.rd__tool {
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 0; padding: 0; color: inherit; font: inherit;
  /* The icons are 19-20px. A thumb needs 40+, so the BOX grows while the glyph
     stays put — Contents, Notebook, Bookmark and the page arrows were all half
     the size of the finger aiming at them (2026-09-08). */
  min-width: 40px; min-height: 40px;
}
.rd__tool--aa {
  font-family: 'Sora', system-ui, sans-serif; font-weight: 700; font-size: 16px;
  line-height: 1; letter-spacing: -.02em;
}
.rd__tool--aa span { font-size: 11px; }
.rd__tool[aria-pressed="true"] { color: var(--raccent); }

.rd__clock { width: 92px; font-family: 'Sora', system-ui, sans-serif; font-size: 12px;
             color: var(--rfaint); white-space: nowrap; }
.rd__prog  { flex: 1; text-align: center; min-width: 0; }
.rd__progtext { font-size: 12px; color: var(--rmuted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The book's own name, on the line above the chapter. Only a phone shows it —
   on a pointer the top bar has room for it and two of them would be noise. */
.rd__booktitle { display: none; font-family: 'Sora', system-ui, sans-serif;
                 font-weight: 600; font-size: 12px; color: var(--rtext);
                 white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
                 line-height: 1.25; }
.rd__bar-track {
  height: 3px; width: min(420px, 60%); margin: 6px auto 0;
  background: var(--rline); border-radius: 9px; overflow: hidden;
}
.rd__bar-fill { height: 100%; background: var(--raccent); width: 0; }
/* PAGE CHEVRONS AT BOTH ENDS OF THE BOTTOM BAR, ON EVERY DEVICE (2026-09-17,
   matching the paged PDF reader's own fix — pdf_reader.clj, PRs
   #713/#715/#716). `#rd-prev`/`#rd-nxt` used to share one `.rd__page` box,
   right-aligned in `.rd__bot`, which THE RULE THIS COMMENT USED TO SIT ABOVE
   hid entirely under `(hover: none) and (pointer: coarse)` — every
   touch-only device, i.e. exactly the ones with no other way to reach a
   chevron: a mouse has no click zones so the chevrons were its only way to
   turn, but a touch screen was assumed to be covered by the swipe gesture
   and the edge tap zones instead. Alex's real-iPhone report says the
   chevrons are a real, wanted control on touch too — so `.rd__page` is gone
   from reader.clj's markup (see `bottom-bar`): `#rd-prev`, `.rd__prog` and
   `#rd-nxt` are now plain siblings of `.rd__bot`, prev first, next last —
   so `.rd__bot`'s own `justify-content: space-between` plus `.rd__prog`'s
   `flex: 1` (which soaks up every pixel of free space itself, leaving
   nothing for space-between to distribute elsewhere) puts one chevron
   flush at each end with the centred title/counter/track column between
   them, on every device, with no coarse-pointer rule left to hide anything.
   `#rd-clock` keeps its old spot immediately before `#rd-prev` — its
   92px-on-the-left/92px-of-chevrons-on-the-right balancing act is moot now
   that the chevrons are real, un-hidden flex siblings holding their own
   space rather than a box that either existed at full width or vanished
   under `display: none`. The one place clock and the now-flush-left prev
   button collide for room is the narrow-portrait-touch breakpoint below,
   where the clock is hidden instead of either chevron. */
.rd__bot .rd__tool { flex: 0 0 auto; }

/* ---- the reading surface ---- */
.rd__surface { position: absolute; inset: 0; overflow: hidden; }
/* THE BOTTOM BAR IS AN INSET, NOT AN OVERLAY. This was inset:0 with vertical
   padding "to clear the two chrome bars" — but padding on a SCROLL CONTAINER is
   leading and trailing space, not a standing safe strip, so in continuous scroll
   live text ran under the bottom bar and the page looked cut off. Worse, turn()
   steps by sc.clientHeight (reader.clj), so every step ALSO skipped the ~60px
   the bar was sitting on — about two lines — and the chevron that does the
   turning is only reachable while that same bar is up (testers 15 and 16,
   2026-09-08). Insetting the scroll box fixes both at once: clientHeight becomes
   the height a reader can actually see, so the step is honest.
   The TOP stays full-bleed on purpose — "immersive by default" is the sheet's
   governing principle, the top bar auto-hides, and the bottom is the half the
   testers complained about. */
.rd__scroller {
  position: absolute; left: 0; right: 0; top: 0;
  /* THE RESERVATION FOLLOWS THE CHROME. Insetting unconditionally stopped the
     bar covering the text, but it left a 58px strip at the foot of the screen
     that is there whether or not the bar is — and a strip where the words stop,
     closed by the bar's own 1px border-top, IS the box a reader points at. That
     is why the same complaint came back a third time (Alex, 2026-09-09).
     Immersive by default is the sheet's governing principle: with the chrome
     hidden the text now runs to the bottom of the screen, and the space is
     taken only while the bar is actually up. Nothing shifts when it toggles —
     the box only loses room at the BOTTOM, so the text above it does not move. */
  bottom: var(--rd-mini-b);
  overflow-y: auto; overflow-x: hidden;
  padding: var(--rd-pad, 88px 7vw);
  scroll-behavior: auto;
  /* the reader compensates for chapters growing or appearing above the
     viewport itself (fit() + the restore hold); the browser's own anchoring
     did the same job a second time, the hold read the double move as a human
     scroll and let go, and a cold open drifted from the preface to the
     dedication (2026-09-07) */
  overflow-anchor: none;
}
.rd.is-revealed .rd__scroller { bottom: var(--rd-chrome-b); }
.rd.is-paged .rd__scroller { overflow: hidden; bottom: 0; }
/* THE PAGE BOX IS ONE SIZE, ALWAYS. In continuous scroll the inset above is
   right: the box loses room only at the BOTTOM, so the text already on screen
   does not move. In PAGED mode that reasoning is false, because the box height
   IS the page — boxH() is written into the chapter document as the column
   height — so giving the strip back when the chrome hides re-breaks every
   column, the scroller's ResizeObserver fires, and relayout() re-anchors the
   reader under his own thumb. On a 375x812 phone that is 14 lines a page
   becoming 11 and back again, twice per chrome cycle: "once the screen with
   the progress and the little buttons goes away it like moves the page"
   (Alex, 2026-09-09).
   The cure is to hold `bottom` still rather than to reserve the strip twice.
   Paged mode already carries the bar's height as padding-bottom (below), which
   boxH() subtracts either way — so the bar overlays the page's bottom MARGIN
   instead of eating a second one, the page keeps all 14 of its lines, and no
   dead strip appears in either mode. Specificity 0,4,0 beats the 0,3,0 rule
   above, so this wins in both directions. */
.rd.is-paged.is-revealed .rd__scroller { bottom: 0; }
.rd__col { max-width: var(--rd-colw, 34rem); margin: 0 auto; }
.rd__eyebrow {
  font-family: 'Sora', system-ui, sans-serif; font-weight: 600; font-size: 12px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--rfaint);
  margin-bottom: 26px;
}
/* The reader's own typography knobs — these are the Aa panel, expressed as
   custom properties so the panel only has to set a variable. Readium CSS user
   properties cover the same ground inside the chapter iframe. */
.rd__doc, .rd__doc * {
  font-family: var(--rd-font, 'Literata', Georgia, serif) !important;
}
.rd__doc {
  font-size: var(--rd-size, 19px);
  line-height: var(--rd-lh, 1.62);
  color: var(--rtext);
}
.rd__doc p { margin: 0 0 22px; }
.rd__doc h1, .rd__doc h2, .rd__doc h3 {
  font-family: 'Sora', system-ui, sans-serif !important; color: var(--rtext);
  line-height: 1.25; margin: 34px 0 14px;
}
.rd__doc img { max-width: 100%; height: auto; }
.rd__doc a { color: var(--raccent); }
.rd__doc ::selection { background: var(--rsel); }

/* reading ruler — a band that follows the pointer line */
.rd__ruler {
  position: absolute; left: 0; right: 0; height: 2.2em; z-index: 5;
  background: var(--rband); pointer-events: none; display: none;
}
.rd.is-ruler .rd__ruler { display: block; }
/* Honest handoff status. An unmatched audiobook chapter must never look like
   an exact sync or silently restore an older reading bookmark. The notice is
   pointer-inert and short-lived so it cannot become another chrome panel. */
.rd__handoff-note {
  position: fixed; z-index: 46; top: calc(env(safe-area-inset-top, 0px) + 16px);
  left: 50%; transform: translateX(-50%);
  width: min(calc(100vw - 32px), 520px); box-sizing: border-box;
  padding: 11px 15px; border: 1px solid var(--rline); border-radius: 12px;
  background: var(--rsheet); color: var(--rtext);
  box-shadow: 0 6px 20px rgba(0,0,0,.20);
  font-family: var(--f-display); font-size: 13px; line-height: 1.4;
  pointer-events: none;
  animation: rdHandoffNote 8s both;
}
@keyframes rdHandoffNote {
  0%, 85% { opacity: 1; visibility: visible; }
  100% { opacity: 0; visibility: hidden; }
}
/* THE WAY BACK FROM A JUMP. A note reference throws you into the endnotes and
   the book's own return is the note's number — punctuation-sized. This sits
   above the bottom bar, out of both page-turn zones, and only exists after a
   jump has actually been made. It rides above the chrome so it survives the
   bars hiding, which is how the reader actually reads. */
.rd__backto {
  position: fixed; z-index: 45;
  left: 50%; transform: translateX(-50%);
  bottom: calc(var(--rd-chrome-b) + 14px);
  display: inline-flex; align-items: stretch;
  max-width: min(88vw, 390px);
  padding: 0; border: 1px solid var(--rline); border-radius: 999px;
  background: var(--rsheet); color: var(--rtext);
  box-shadow: 0 6px 20px rgba(0,0,0,.20);
  font-family: var(--f-display); font-size: 13px; font-weight: 600;
  overflow: hidden; animation: rdUp .18s var(--ease);
}
.rd__backto[hidden] { display: none; }
.rd__backto-go, .rd__backto-close {
  min-height: 44px; border: 0; background: transparent; color: inherit;
  font: inherit; cursor: pointer;
}
.rd__backto-go {
  display: inline-flex; align-items: center; gap: 7px; min-width: 0;
  padding: 9px 10px 9px 16px;
}
.rd__backto-close {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; flex: 0 0 44px; padding: 0 4px 1px 0;
  color: var(--rmuted); font-size: 22px; font-weight: 400;
}
.rd__backto-ico { display: inline-flex; color: var(--raccent); flex: 0 0 auto; }
.rd__backto-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rd__backto-go:focus-visible, .rd__backto-close:focus-visible {
  outline: 3px solid var(--raccent); outline-offset: -3px;
}
@media (hover:hover) {
  .rd__backto-go:hover, .rd__backto-close:hover { background: var(--rline); }
}
/* THE BAND IS ONE LINE TALL WHERE IT STEPS BY LINES. `2.2em` resolves against
   `.rd`, which sets no font-size, so it is a fixed ~35px while the reader's own
   line runs from 21px to 71px — at the smallest text the band covers 1.7 lines,
   and a step shorter than the band never brackets anything. apply() writes
   --rd-line from the same size x line-height styleFrame gives the chapter.
   Continuous scroll keeps 2.2em: there the band is a place you park, not a
   thing that counts lines. */
.rd.is-paged .rd__ruler { height: var(--rd-line, 2.2em);
                          transition: top .09s cubic-bezier(.4,0,.2,1); }
.rd__ruler.is-dragging { transition: none; }
/* THE HANDLE. Only this is hit-testable: the band spans the full width over
   live text, so it stays pointer-events:none and selection, links and glossary
   marks under it keep working — but a child with pointer-events:auto is still a
   hit target. It rides the band, so the target has already moved to where the
   thumb is going. 44x56 of touch area around a 26x42 pill, in the band's own
   colour so it reads as part of the stripe rather than as chrome. */
.rd__grip {
  position: absolute; top: 50%; right: 0; transform: translateY(-50%);
  width: 44px; height: 56px; min-width: 44px;
  display: none; align-items: center; justify-content: center;
  padding: 0; border: 0; background: transparent; cursor: pointer;
  pointer-events: auto; touch-action: none; -webkit-tap-highlight-color: transparent;
}
/* PAGED, ON A FINGER, WITH THE RULER ON — and nowhere else. On a mouse the band
   already follows the pointer, so a handle there would be an inert control on
   the one platform that does not need it. `is-finger` is set by the first real
   touchstart, so a touchscreen laptop earns it by touching rather than by
   existing. */
.rd.is-ruler.is-paged.is-finger .rd__grip { display: flex; }
.rd__grip-tab {
  width: 26px; height: 42px; border-radius: 8px;
  background: var(--rd-ruler, var(--rband));
  box-shadow: 0 1px 4px rgba(0,0,0,.28), inset 0 0 0 1px rgba(0,0,0,.10);
  position: relative;
}
/* two etched lines: the grip glyph every phone reader has taken hold of before */
.rd__grip-tab::before, .rd__grip-tab::after {
  content: ""; position: absolute; left: 8px; right: 8px; height: 1.5px;
  border-radius: 2px; background: var(--rtext); opacity: .34;
}
.rd__grip-tab::before { top: 18px; } .rd__grip-tab::after { top: 23px; }
/* the top third goes BACK a line, and says so with a chevron */
.rd__grip-up {
  position: absolute; top: 4px; left: 50%; margin-left: -5px;
  width: 10px; height: 6px; opacity: .55;
  background: var(--rtext);
  -webkit-clip-path: polygon(50% 0, 100% 100%, 0 100%);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
.rd__grip:focus-visible { outline: 3px solid var(--raccent); outline-offset: 2px; border-radius: 10px; }
@media (prefers-reduced-motion: reduce) {
  .rd__ruler { transition: none; }
}

/* ---- panels: Aa, contents, notebook ---- */
.rd__scrim {
  position: absolute; inset: 0; background: var(--rdim); z-index: 30;
  display: none; animation: rdFade .2s ease;
}
.rd.is-panel .rd__scrim, .rd.is-card .rd__scrim { display: block; }
.rd__panel {
  position: absolute; z-index: 31; background: var(--rsheet); color: var(--rtext);
  font-family: 'Hanken Grotesk', system-ui, sans-serif;
  display: none; animation: rdUp .22s ease;
}
.rd__panel.is-open { display: flex; flex-direction: column; }
/* The Aa panel is a full-height RIGHT-HAND SHEET, not a popover — that is what
   gives the accessibility block room to be a real card rather than a cramped
   afterthought at the bottom of a dropdown. */
.rd__panel--aa {
  top: 0; bottom: 0; right: 0; width: min(392px, 100%);
  box-shadow: -18px 0 44px rgba(0,0,0,.22); border-left: 1px solid var(--rline);
}
/* Contents is screen 4J: a full-height LEFT sheet, not a floating popover.
   The side matters — Contents opens from the left, every other sheet from the
   right, so the two never look like the same drawer showing different things,
   and on a phone the panel is the whole screen either way. Geometry is
   .rd-panel--left's; the .rd__panel/.is-open machinery still does the toggling. */
.rd__panel--toc {
  top: 0; bottom: 0; left: 0; width: var(--sheet-w, 380px); max-width: 100%;
  box-shadow: 18px 0 44px rgba(0,0,0,.22); border-right: 1px solid var(--rline);
}
/* The notebook is screen 4I: a full-height RIGHT sheet. As a floating card it
   could not hold a head (title + search + three tabs) and a scrolling list
   without the list becoming a slot two rows tall. */
.rd__panel--note {
  top: 0; bottom: 0; right: 0; width: var(--sheet-w, 380px); max-width: 100%;
  box-shadow: -18px 0 44px rgba(0,0,0,.22); border-left: 1px solid var(--rline);
}
.rd__phead {
  padding: 20px 22px 16px; border-bottom: 1px solid var(--rline);
  display: flex; align-items: center; justify-content: space-between; flex: 0 0 auto;
}
.rd__ptitle { font-family: 'Sora', system-ui, sans-serif; font-weight: 700; font-size: 17px; }
.rd__pclose { background: none; border: 0; color: var(--rmuted); cursor: pointer; display: inline-flex; }
.rd__pbody { flex: 1; overflow-y: auto; padding: 20px 22px 30px; }

.rd__pgroup {
  font-family: 'Sora', system-ui, sans-serif; font-weight: 700; font-size: 11px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--rfaint);
  margin: 24px 0 11px;
}
.rd__pbody > .rd__pgroup:first-child { margin-top: 0; }
.rd__plabel { font-size: 12px; font-weight: 600; color: var(--rmuted); margin: 0 0 8px; }

/* theme cards — painted in the theme they select */
.rd__themes { display: flex; gap: 10px; }
.rd__theme {
  flex: 1; border: 1.5px solid var(--rline); border-radius: 12px; padding: 14px 0;
  text-align: center; cursor: pointer; font: inherit;
}
.rd__theme[aria-pressed="true"] { border-color: var(--raccent); border-width: 2px; }
.rd__theme-aa { display: block; font-family: 'Sora', system-ui, sans-serif;
                font-weight: 700; font-size: 15px; }
.rd__theme-label { display: block; font-size: 11px; margin-top: 3px; }
.rd__theme--light { background: #faf9f5; }
.rd__theme--light .rd__theme-aa { color: #20242c } .rd__theme--light .rd__theme-label { color: #6b7280 }
.rd__theme--sepia { background: #f3ead4; }
.rd__theme--sepia .rd__theme-aa { color: #463a28 } .rd__theme--sepia .rd__theme-label { color: #8a7a60 }
.rd__theme--dark  { background: #14161c; }
.rd__theme--dark .rd__theme-aa { color: #c9cdd6 } .rd__theme--dark .rd__theme-label { color: #8b93a1 }

/* the sheet's switch — one control for every boolean in the panel */
.rd__toggle-row, .rd__a11y-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  cursor: pointer;
}
.rd__toggle-row {
  margin-top: 12px; padding: 11px 13px; border: 1px solid var(--rline);
  border-radius: 11px; font-size: 13.5px; font-weight: 600;
}
.rd__sw {
  width: 38px; height: 22px; border-radius: 999px; background: var(--rline);
  position: relative; flex: 0 0 auto; transition: background .15s;
  border: 0; padding: 0; cursor: pointer; display: inline-block;
}
/* --rline is a BORDER token, and high contrast flips it to pure black or pure
   white — the same colour as the knob, so in dark+HC the off state was 1.00:1
   and the switch simply vanished. Give the track its own value there. */
/* AND HIGH CONTRAST MUST NOT MOVE THE KNOB. `[data-hc="on"] button` gives
   EVERY button a 2px border and an 8px radius, and .rd__sw IS the switch's
   track, not a wrapper round one — so with border-box sizing the 38x22 track
   keeps its outer size while its padding box shrinks to 34x18 and moves 2px
   in. .rd__knob is absolutely positioned, and top/left resolve against that
   PADDING edge: the ON knob lands flush with the outer right edge, drawn over
   the border, 4px down from the top and 0 from the bottom, in an 8px
   rectangle rather than a pill. That is "the toggle button is not centered in
   a little box" (Alex, 2026-09-09). A border cannot apply to a track whose
   knob travel is measured from its own edges; the visible boundary high
   contrast needs is the OUTLINE, which is drawn outside the border box and
   costs no layout. Widened to 2px so the control still reads as strongly as
   every other one the shell rule borders. */
.rd[data-hc="on"] .rd__sw { background: #767676; outline: 2px solid var(--rline);
                            border: 0; border-radius: 999px; }
.rd[data-hc="on"] .rd__sw[aria-checked="true"] { background: var(--raccent); }
/* (0,3,0) above out-specifies .rd__sw:focus-visible (0,2,0), so without this
   keyboard focus was invisible in high contrast — of all places. */
.rd[data-hc="on"] .rd__sw:focus-visible { outline: 3px solid var(--raccent);
                                          outline-offset: 2px; }
.rd__sw:focus-visible { outline: 3px solid var(--raccent); outline-offset: 2px; }
.rd__sw[aria-checked="true"] { background: var(--raccent); }
.rd__knob {
  position: absolute; top: 2px; left: 2px; width: 18px; height: 18px;
  border-radius: 999px; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.3);
  transition: left .15s;
}
.rd__sw[aria-checked="true"] .rd__knob { left: 18px; }

/* text size — a slider, per the sheet, not four buttons */
.rd__slider-row { display: flex; align-items: center; gap: 14px; }
.rd__size-a { background: none; border: 0; cursor: pointer;
              font-family: 'Literata', Georgia, serif; color: var(--rmuted); }
.rd__size-a--sm { font-size: 15px; } .rd__size-a--lg { font-size: 26px; color: var(--rtext); }
.rd__slider { flex: 1; -webkit-appearance: none; appearance: none; height: 4px;
              background: var(--rline); border-radius: 9px; outline: none; }
.rd__slider::-webkit-slider-thumb {
  -webkit-appearance: none; width: 20px; height: 20px; border-radius: 999px;
  background: #fff; border: 2px solid var(--raccent);
  box-shadow: 0 1px 4px rgba(0,0,0,.2); cursor: pointer;
}
.rd__slider::-moz-range-thumb {
  width: 20px; height: 20px; border-radius: 999px; background: #fff;
  border: 2px solid var(--raccent); cursor: pointer;
}
.rd__sizelabel { font-size: 11px; color: var(--rfaint); margin: 7px 0 0; text-align: center; }

/* typeface specimens, each set in its own face */
.rd__fonts { display: flex; gap: 8px; margin-top: 16px; }
.rd__font { flex: 1; border: 1.5px solid var(--rline); border-radius: 11px;
            padding: 11px 6px; text-align: center; cursor: pointer;
            background: transparent; font: inherit; }
.rd__font[aria-pressed="true"] { border-color: var(--raccent); border-width: 2px; }
.rd__font-ag { display: block; font-size: 16px; color: var(--rtext); line-height: 1; }
.rd__font-name { display: block; font-family: 'Hanken Grotesk', system-ui, sans-serif;
                 font-size: 9.5px; color: var(--rmuted); margin-top: 6px; line-height: 1.2; }

.rd__hint { font-size: 11px; color: var(--rfaint); margin: 8px 0 0;
            display: flex; align-items: flex-start; gap: 6px; line-height: 1.45; }
.rd__hint svg { stroke: var(--raccent); flex: 0 0 auto; margin-top: 1px; }

/* The segmented control. These base rules were lost when the panel block was
   rewritten, which left Line spacing and Margins as unstyled browser buttons —
   no flex, no border, no radius, wrong face. Restored to the sheet: flex:1
   pills, Sora 600, accent when chosen. */
.rd__seg { display: flex; gap: 6px; }
.rd__seg button {
  flex: 1 1 0; min-width: 0; text-align: center; white-space: nowrap;
  border: 1.5px solid var(--rline); border-radius: 9px; padding: 8px 2px;
  font-family: 'Sora', system-ui, sans-serif; font-size: 11.5px; font-weight: 600;
  color: var(--rmuted); background: transparent; cursor: pointer;
}
.rd__seg button[aria-pressed="true"] { border-color: var(--raccent); color: var(--raccent); }

.rd__pair { display: flex; gap: 14px; margin-top: 22px; }
/* stacked on a phone: side by side gives each segment ~42px of content box and
   "Normal" paints straight through its own pill border */
@media (max-width: 700px) { .rd__pair { flex-direction: column; gap: 16px; } }
.rd__pair > div { flex: 1; min-width: 0; }

/* the paged/scroll switcher — an inset track, per the sheet */
.rd__switcher { display: flex; gap: 6px; background: var(--rbg);
                border: 1px solid var(--rline); border-radius: 11px; padding: 4px; }
.rd__switcher button {
  flex: 1; text-align: center; padding: 9px 0; border: 0; border-radius: 8px;
  font-family: 'Sora', system-ui, sans-serif; font-size: 12.5px; font-weight: 600;
  cursor: pointer; background: transparent; color: var(--rmuted);
}
.rd__switcher button[aria-pressed="true"] {
  background: var(--rsheet); color: var(--rtext); box-shadow: 0 1px 3px rgba(0,0,0,.16);
}

/* ACCESSIBILITY — a first-class block, not a buried sub-menu */
.rd__a11y { margin-top: 26px; border: 1.5px solid var(--raccent);
            border-radius: 15px; overflow: hidden; }
.rd__a11y-head {
  background: var(--raccent); padding: 11px 15px; display: flex;
  align-items: center; gap: 9px; color: #04222a;
  font-family: 'Sora', system-ui, sans-serif; font-weight: 700; font-size: 13.5px;
}
.rd__a11y-head svg { stroke: #04222a; }
.rd[data-theme="dark"] .rd__a11y-head { color: #04222a; }
/* In high contrast the accent darkens to #0a5e73, and the card header's ink
   (#04222a on it) fell to 2.26:1 — the one card that exists for legibility was
   the least legible thing in the panel. */
.rd[data-hc="on"] .rd__a11y-head { color: #ffffff; }
.rd[data-hc="on"] .rd__a11y-head svg { stroke: #ffffff; }
.rd__a11y-body { padding: 6px 15px 14px; }
.rd__a11y-row { padding: 12px 0; border-bottom: 1px solid var(--rline); }
.rd__a11y-row:last-child { border-bottom: 0; }
.rd__a11y-t { font-size: 13.5px; font-weight: 600; color: var(--rtext); margin: 0; }
.rd__a11y-d { font-size: 11.5px; color: var(--rmuted); margin: 1px 0 0; }
/* THE VOICE PICKER. A stacked row, because a <select> holding forty voices
   needs the width and the accessibility rows are built for a label beside a
   22px switch. Native on purpose: on a phone this is the system wheel picker,
   which is better than anything hand-built for a list this long. */
.rd__a11y-row--stack { display: block; }
.rd__voicepick { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.rd__voicesel {
  flex: 1 1 auto; min-width: 0;
  font-family: var(--f-ui); font-size: 13.5px; color: var(--rtext);
  background: var(--rbg); border: 1px solid var(--rline); border-radius: 9px;
  padding: 9px 10px; cursor: pointer;
}
.rd__voicesel:disabled { color: var(--rfaint); cursor: default; }
.rd__voicesel:focus-visible { outline: 3px solid var(--raccent); outline-offset: 2px; }
/* the sample button: names mean nothing, so hearing it is the whole point */
.rd__voicetry {
  flex: 0 0 auto; width: 40px; height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--rline); border-radius: 999px;
  background: transparent; color: var(--raccent); cursor: pointer;
}
.rd__voicetry:hover { background: var(--rline); }
.rd__voicetry:focus-visible { outline: 3px solid var(--raccent); outline-offset: 2px; }
.rd__voicehint { margin: 8px 0 0; font-size: 11.5px; line-height: 1.45; color: var(--rfaint); }
.rd__a11y-row--stack[hidden] { display: none; }

.rd__rulercolors { display: none; gap: 8px; padding: 12px 0;
                   border-bottom: 1px solid var(--rline); }
.rd.is-ruler .rd__rulercolors { display: flex; }
.rd__rc { width: 26px; height: 26px; border-radius: 999px; border: 0; cursor: pointer;
         padding: 7px; background-clip: content-box; box-sizing: content-box; }
.rd__rc[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--rsheet), 0 0 0 4px var(--raccent); }
/* The ruler used a hard-coded 55%-opacity amber in every theme, which dropped
   the text under it from 14.76:1 to 2.90:1 — the band made its own target line
   the least legible line on the page. --rband is the design's per-theme value
   and lands at ~6:1. The colour swatches tint it, they do not replace it. */
.rd__ruler { background: var(--rd-ruler, var(--rband)); }

/* ---- the read-aloud bar (Reader Frame's immersion bar) ---- */
.rd__ttsbar {
  position: absolute; left: 50%; transform: translateX(-50%);
  /* the bar's own height, not a fourth copy of the number: at a flat 84px the
     transport sat 4px inside a 74px bottom bar, and 38px inside a notched one —
     on top of the book title. env() comes along for free on desktop too. */
  bottom: calc(var(--rd-chrome-b) + 22px);
  z-index: 40; width: 560px; max-width: 94%;
  background: var(--rsheet); border: 1px solid var(--rline); border-radius: 16px;
  box-shadow: 0 20px 50px rgba(0,0,0,.28); padding: 13px 16px;
  font-family: 'Hanken Grotesk', system-ui, sans-serif;
  display: none; align-items: center; gap: 13px; animation: rdUp .22s ease;
}
.rd__ttsbar.is-open { display: flex; }
.rd__tts-id { display: flex; align-items: center; gap: 7px; flex: 0 0 auto; }
.rd__tts-name { font-family: 'Sora', system-ui, sans-serif; font-weight: 700;
                font-size: 12px; color: var(--rtext); }
.rd__tts-beta {
  font-size: 8.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--raccent); border: 1px solid var(--raccent); border-radius: 999px;
  padding: 1px 6px;
}
.rd__tts-ctl { display: flex; align-items: center; gap: 11px; color: var(--ricon); flex: 0 0 auto; }
.rd__tts-play {
  width: 40px; height: 40px; border-radius: 999px; background: var(--rtext);
  border: 0; display: flex; align-items: center; justify-content: center;
  cursor: pointer; flex: 0 0 auto;
}
.rd__tts-play svg { fill: var(--rbg); }
.rd__tts-play .rd__play { display: none; }
.rd__tts-play[data-paused="true"] .rd__pause { display: none; }
.rd__tts-play[data-paused="true"] .rd__play { display: block; }
.rd__tts-track { flex: 1; min-width: 36px; height: 4px; background: var(--rline);
                 border-radius: 9px; overflow: hidden; }
.rd__tts-fill { width: 0; height: 100%; background: var(--raccent); }
.rd__tts-pos { font-family: 'Sora', system-ui, sans-serif; font-size: 11px;
               color: var(--rmuted); flex: 0 0 auto; font-variant-numeric: tabular-nums; }
.rd__tts-rate {
  font-family: 'Sora', system-ui, sans-serif; font-size: 12px; font-weight: 600;
  color: var(--ricon); background: none; border: 1px solid var(--rline);
  border-radius: 999px; padding: 6px 12px; cursor: pointer; flex: 0 0 auto;
}
@media (max-width: 700px) {
  .rd__ttsbar { padding: 11px 12px; gap: 9px; }
  .rd__tts-id, .rd__tts-pos { display: none; }
}

.rd__toclist, .rd__notelist { list-style: none; margin: 0; padding: 0; }
.rd__toclist a {
  display: block; padding: 9px 20px; color: var(--rtext); text-decoration: none;
  font-size: 13.5px; border-left: 3px solid transparent;
}
@media (hover: hover) { .rd__toclist a:hover { background: var(--rline); } }
.rd__toclist a[aria-current="true"] { border-left-color: var(--raccent); color: var(--raccent); font-weight: 600; }
.rd__note { padding: 12px 20px; border-bottom: 1px solid var(--rline); }
.rd__note q { display: block; font-family: 'Literata', Georgia, serif; font-size: 13.5px;
              background: var(--rhl); padding: 6px 8px; border-radius: 4px; quotes: none; }
.rd__note { position: relative; }
.rd__note p { font-size: 12.5px; color: var(--rmuted); margin: 8px 0 0; }
.rd__note q { display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
              overflow: hidden; }
.rd__note-meta { font-size: 11px; color: var(--rfaint) !important; }
.rd__note-del {
  /* 40px, and visible without hover: on a phone its only affordance was a
     :hover background, so it read as a stray glyph on top of the note */
  position: absolute; top: 6px; right: 8px; width: 40px; height: 40px;
  border: 0; border-radius: 999px; background: transparent; color: var(--rmuted);
  font-size: 17px; line-height: 1; cursor: pointer;
}
@media (hover: hover) { .rd__note-del:hover { background: var(--rline); color: var(--rtext); } }
@media (hover: none) { .rd__note-del { color: var(--rfaint); background: var(--rline); } }
.rd__empty { padding: 26px 20px; color: var(--rfaint); font-size: 13px; text-align: center; }

/* ---- the selection menu ---- */
.rd__selmenu {
  position: absolute; z-index: 40; display: none; gap: 2px;
  /* eight controls in one nowrap row measure 470-630px; on a phone the JS
     clamp then pinned it to left:12 and Copy/Share sat past the right edge */
  max-width: calc(100vw - 24px);
  background: var(--rsheet); border: 1px solid var(--rline); border-radius: 11px;
  box-shadow: 0 10px 34px rgba(0,0,0,.24); padding: 4px;
  font-family: 'Hanken Grotesk', system-ui, sans-serif;
}
/* nowrap on the row AND on the items: without it the flex children shrink when
   the menu is near an edge and "Read from here" breaks across three lines,
   which makes the menu tall enough to cover the passage it belongs to. */
.rd__selmenu.is-open { display: flex; flex-wrap: nowrap; align-items: center; }
/* On a phone the row WRAPS instead — a menu two rows tall beats one whose
   right-hand half is off the screen. */
@media (max-width: 700px), (pointer: coarse) {
  .rd__selmenu.is-open { flex-wrap: wrap; justify-content: center; }
  .rd__selmenu button { flex: 0 1 auto; }
}
.rd__selmenu button {
  cursor: pointer; background: none; border: 0; color: var(--rtext);
  font: inherit; font-size: 12.5px; padding: 7px 11px; border-radius: 8px;
  white-space: nowrap; flex: 0 0 auto;
}
@media (hover: hover) { .rd__selmenu button:hover { background: var(--rline); } }
.rd__hlmark { background: var(--rhl); border-radius: 2px; }

/* ---- mobile (4P–4U) ---- */
/* A phone in landscape is 812x375 — wider than 700, so every mobile rule
   switched off and the bars grew back to 30% of the viewport height. Height and
   pointer type describe a phone better than width alone does. */
@media (max-width: 700px), (max-height: 480px) and (pointer: coarse) {
  /* LONGHANDS, never the `padding` shorthand: the shorthand reset the very
     safe-area padding granted above, and the flat heights dropped the env()
     term — on exactly the notched phones those rules were written for. */
  .rd { --rd-chrome-b: calc(58px + env(safe-area-inset-bottom)); }
  .rd__top { height: calc(52px + env(safe-area-inset-top)); }
  .rd__bot { height: var(--rd-chrome-b); }
  .rd__top, .rd__bot { padding-left: max(16px, env(safe-area-inset-left));
                       padding-right: max(16px, env(safe-area-inset-right)); }
  .rd__clock { width: 64px; }
  .rd__scroller { padding: var(--rd-pad-m, 74px 6vw); }
  /* closer together: with the title and the back label gone the row has room,
     and five icons spread across a phone read as clutter (Alex, 2026-09-09) */
  .rd__tools { gap: 9px; }
  /* the Aa panel becomes a bottom sheet, per 4R */
  .rd__panel { top: auto; bottom: 0; left: 0; right: 0; width: auto;
               max-height: 78%; border-radius: 18px 18px 0 0; }
  /* Overlay cards on a phone: a jacket the size of a thumbnail, a title that
     fits beside it, and actions that stack rather than squeeze. */
  .rd-card--scroll { padding: 20px 18px 22px; max-height: 86%; }
  .rd-about__top   { gap: 14px; }
  .rd-about__cover { width: 68px; }
  .rd-about__title { font-size: 19px; }
  .rd-about__author{ font-size: 13px; }
  .rd-about__blurb { margin-top: 16px; }
  .rd-about__acts  { flex-wrap: wrap; }
  .rd-about__acts > * { flex: 1 1 100%; }
}
/* A NARROW TOUCH SCREEN — a phone held upright. This is the only shape with no
   room for the book's name in the top bar, so it is the only shape that moves
   it down; a tablet, and a phone turned sideways, keep the title where it is
   and keep the shorter bar. Gating this on pointer type alone would have taken
   the title off an iPad with 700px of empty bar, and grown a landscape phone's
   chrome to 37% of its height to carry a line it did not need. */
@media (max-width: 700px) and (pointer: coarse) {
  /* one line taller: the bar now carries the book's name above the chapter */
  .rd { --rd-chrome-b: calc(74px + env(safe-area-inset-bottom)); }
  /* THE CLOCK LOSES TO THE CHEVRON HERE. It used to float as a
     pointer-events:none overlay at the bar's own left edge (with
     `.rd__prog` padded 52px on both sides to keep the centred column clear
     of it, back when the chevrons were `display:none` on every touch
     device and there was nothing else in that corner to collide with — see
     the long comment above `.rd__bot .rd__tool` in this file). Now that
     `#rd-prev` is a real, visible flex sibling claiming that same left
     corner (2026-09-17), there is no room left for both at this width —
     Alex's call is that the page-turn chevron wins and the clock goes,
     rather than overlaying a live tap target or shrinking either below its
     44px floor. `.rd__prog`'s old 52px padding trick goes with it: it was
     only ever compensating for the clock's overlay and the chevrons'
     absence, and `#rd-prev`/`#rd-nxt` now hold their own space as ordinary
     flex siblings (see `.rd__bot .rd__tool { flex: 0 0 auto; }` above) with
     nothing left for a manual padding to make room for. */
  .rd__clock { display: none; }
  .rd__booktitle { display: block; }
  .rd__back-label, .rd__rule, .rd__title { display: none; }
  /* THE BACK LINK IS THE READER'S ONLY WAY OUT, and its box was made entirely
     of the word "Library" — hiding the word left a 19px glyph, half of what a
     thumb can hit and under the 24px floor the guidelines set. The box grows,
     the arrow stays put, and the negative margin keeps it optically on the
     bar's own padding rather than pushing it inward. */
  .rd__back { min-width: 44px; min-height: 44px; justify-content: center;
              margin-left: -12px; }
  /* Keep the icons visually quiet while giving every reader action a full
     thumb-sized hit box. Several controls otherwise measured only 22-40px. */
  .rd__tool { min-width: 44px; min-height: 44px; }
  .rd__pclose { min-width: 44px; min-height: 44px; align-items: center;
                justify-content: center; margin: -11px; }
  .rd__size-a { min-width: 44px; min-height: 44px; padding: 0; }
  .rd__seg button, .rd__switcher button, .rd-tab { min-height: 44px; }
  .rd-toc__add { width: 44px; }
  .rd-exit { min-width: 44px; min-height: 44px; justify-content: center; }
  /* The thumb already looks correct; enlarge the native input around it
     without painting a 44px-thick track. */
  .rd__slider {
    height: 44px; background: linear-gradient(to bottom,
      transparent 20px, var(--rline) 20px, var(--rline) 24px, transparent 24px);
  }
  /* PAGED MODE PAYS FOR THE BAR IN PADDING, NOT IN BOX HEIGHT. The page box is
     pinned to one size (see .rd.is-paged.is-revealed above) so a chrome toggle
     cannot re-break the columns — which means the bar now overlays the foot of
     the page, and the page's bottom margin is what keeps the last line clear of
     it. --rd-pad-m's own 74px matches the bar on a phone with its toolbar up,
     but NOT on the Home Screen, where env(safe-area-inset-bottom) grows the bar
     to 108px and the home indicator would sit on the text. One token, so the
     margin cannot drift from the thing it is clearing. */
  .rd.is-paged .rd__scroller { padding-bottom: var(--rd-chrome-b); }
}

/* Chapter BODY owns the reading measure. Host gutters used to charge for
   margins a second time (and, without ReadiumCSS, a third time). */
.rd .rd__scroller { padding-left: env(safe-area-inset-left);
                    padding-right: env(safe-area-inset-right); }

/* --- audiobook player: the parts a static mock didn't need -----------------
   Section 31 draws the player; these four make it work. Everything else the
   audio surface uses is the sheet's own .rd-audio__* / .rd-skip / .rd-switchpill. */

/* The sheet's .reader is 100%/100% inside a device frame; on a real page it
   needs a host that is the viewport. */
.rd-audio-surface { position: fixed; inset: 0; }

/* Seeking. A native range keeps keyboard, screen-reader and touch behaviour
   that a styled div cannot fake, so it sits transparent on top of the drawn
   track rather than replacing it. */
.rd-audio__track { position: relative; }
.rd-audio__range {
  position: absolute; inset: -9px 0; width: 100%; height: 23px; margin: 0;
  opacity: 0; cursor: pointer; background: transparent;
  -webkit-appearance: none; appearance: none;
}
.rd-audio__range::-webkit-slider-thumb { -webkit-appearance: none; width: 23px; height: 23px; }
.rd-audio__track:focus-within { box-shadow: 0 0 0 2px var(--rbg), 0 0 0 4px var(--raccent); }
.rd-audio__times { font-variant-numeric: tabular-nums; }

/* No cover in the index: the hero still has to hold the layout, so it carries
   the title's initial rather than a broken image or an empty grey square. */
.rd-audio__art--fallback {
  display: flex; align-items: center; justify-content: center;
  background: var(--raccent); color: var(--r-on-accent);
  font-family: var(--f-display); font-weight: 700; font-size: 84px;
  line-height: 1; letter-spacing: var(--ls-heading);
}
@media (max-width: 640px) { .rd-audio__art--fallback { font-size: 72px; } }

/* A phone held sideways has ~375px of height for a column that wants 674.
   It scrolls now rather than clipping, but it should not have to: the jacket
   and the breathing room shrink so the transport is in reach without one. */
@media (max-height: 480px) and (pointer: coarse) {
  .reader, .rd { --audio-pad: 16px 20px; --audio-art: 150px; --audio-gap: 10px; }
  .rd-audio__transport, .rd-audio__secondary { margin-top: 14px; }
  .rd-audio__msg { margin-top: 10px; }
}

/* The chapter list the Chapters pill opens — a bottom sheet on a phone, a
   centred card on a desk. Until 2026-09-08 the pill opened NOTHING: the
   markup rendered a button and the script's chapter branch was an empty
   string, which is exactly the control-that-opens-nothing this file's own
   header warns against. */
.rd-chaps {
  position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
  z-index: 45; width: min(460px, 100%); max-height: 72%;
  display: flex; flex-direction: column;
  background: var(--rsheet); color: var(--rtext);
  border-radius: 18px 18px 0 0; box-shadow: 0 -18px 50px rgba(0,0,0,.4);
  text-align: left; animation: rdUp .2s var(--ease, ease);
}
.rd-chaps__head { display: flex; align-items: center; justify-content: space-between;
                  gap: 12px; padding: 16px 8px 12px 20px; border-bottom: 1px solid var(--rline);
                  flex: 0 0 auto; }
.rd-chaps__h { margin: 0; font-family: var(--f-display); font-weight: 700; font-size: 15px; }
.rd-chaps__list { list-style: none; margin: 0; padding: 8px 12px 20px; overflow-y: auto;
                  -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
.rd-chaps__btn {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%;
  min-height: 44px; padding: 11px 12px; border: 0; border-radius: var(--r-sm);
  background: transparent; color: var(--rmuted); cursor: pointer; text-align: left;
  font-family: var(--f-display); font-weight: 500; font-size: 13.5px;
}
.rd-chaps__btn[aria-current="true"] { background: var(--rbg); color: var(--rtext); font-weight: 700; }
.rd-chaps__t { min-width: 0; overflow-wrap: break-word; }
/* a timestamp must never wrap mid-value */
.rd-chaps__at { flex: 0 0 auto; white-space: nowrap; font-family: var(--f-ui);
                font-size: 12px; color: var(--rfaint); font-variant-numeric: tabular-nums; }
.rd-chaps__x { width: 44px; height: 44px; flex: 0 0 auto; border: 0; border-radius: var(--r-pill);
               background: transparent; color: var(--rmuted); font-size: 24px; line-height: 1;
               cursor: pointer; }
@media (min-width: 701px) {
  .rd-chaps { bottom: 50%; transform: translate(-50%, 50%); border-radius: 18px;
              box-shadow: 0 30px 70px rgba(0,0,0,.4); }
}
/* Touch has no hover, so anything a hover rule alone reveals is invisible on a
   phone — the notebook's add control and the contents rows both leaned on it. */
@media (hover: none) {
  .rd-toc__add { opacity: 1; }
}

/* Status line — resume confirmations and playback errors. */
.rd-audio__msg {
  /* two lines reserved: "Picked up where you left off — 1:23:45." wraps on a
     phone, and growing the last child of a centred column shoved the play
     button upward under the reader's thumb */
  margin: 16px 0 0; min-height: 2.6em;
  font-family: var(--f-ui); font-size: 11.5px; color: var(--rfaint);
}

/* ---- the note composer ---------------------------------------------------
   The sheet has no note-writing surface (its Note button is a menu item), so
   this is built in the .rd-card idiom the other reader cards use. */
.rd__notecard {
  z-index: 45; width: min(560px, 92%);
  /* the card is a column that never outgrows the viewport: the passage
     scrolls inside it, so the field and the buttons are always reachable
     however much text was selected */
  max-height: min(80dvh, 88%); display: flex; flex-direction: column;
}
.rd__notecard[hidden] { display: none; }
.rd__notecard-eyebrow {
  margin: 0 0 10px; font-family: var(--f-display); font-weight: 700;
  font-size: 12px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--raccent);
}
.rd__notecard-quote {
  margin: 0 0 14px; padding: 10px 14px; border-left: 3px solid var(--rline);
  background: var(--rbg); border-radius: 0 var(--r-ctl) var(--r-ctl) 0;
  font-family: 'Literata', Georgia, serif; font-size: 13.5px; line-height: 1.5;
  color: var(--rmuted);
  /* line-clamp cut a long passage mid-sentence with no way to read the rest.
     Scroll it instead — the reader can check what they selected. */
  flex: 0 1 auto; min-height: 3em; max-height: 34vh; overflow-y: auto;
  overscroll-behavior: contain;
  /* a visible track, so a clipped last line reads as "there is more, scroll"
     rather than as the passage having been truncated */
  scrollbar-width: thin; scrollbar-color: var(--rline) transparent;
}
.rd__notecard-quote::-webkit-scrollbar { width: 8px; }
.rd__notecard-quote::-webkit-scrollbar-thumb {
  background: var(--rline); border-radius: 999px;
}
.rd__notecard-text {
  width: 100%; resize: vertical; box-sizing: border-box; flex: 1 1 auto; min-height: 96px;
  border: 1px solid var(--rline); border-radius: var(--r-ctl);
  background: var(--rsheet); color: var(--rtext);
  font-family: var(--f-ui); font-size: 14px; line-height: 1.5; padding: 11px 13px;
}
.rd__notecard-text:focus-visible { outline: 2px solid var(--raccent); outline-offset: 1px; }
.rd__notecard-actions {
  display: flex; justify-content: flex-end; gap: 10px; margin-top: 14px;
  flex: 0 0 auto;
}
.rd__notecard-spacer { flex: 1 1 auto; }
.rd__notecard-del { color: var(--rcoral); }
.rd__notecard-del[hidden] { display: none; }

/* ---- highlight swatches (selection menu + note composer) ----------------
   4H leads its menu with the palette. The ring uses the surface behind it as
   a spacer so the selected swatch reads as chosen on both the dark selection
   menu and the light card. */
.rd__swatches { display: inline-flex; align-items: center; gap: 6px; }
/* SPECIFICITY, not source order: `.rd__selmenu button` is (0,1,1) and would
   otherwise beat a bare `.rd__swatch` (0,1,0) — it set background:none and
   button padding, so the swatches rendered as invisible circles inside
   menu-sized ovals. Each context is named so the pair is (0,2,0) and wins. */
.rd__swatch,
.rd__selmenu .rd__swatch,
.rd__notecard .rd__swatch { padding: 13px; background-clip: content-box; box-sizing: content-box;
  width: 16px; height: 16px; border-radius: 999px; border: 0; padding: 0;
  background: var(--c, var(--hl-yellow)); cursor: pointer; flex: 0 0 auto;
}
.rd__selmenu .rd__swatches { padding: 0 10px 0 12px; margin-right: 2px;
  border-right: 1px solid rgba(255,255,255,.14); align-self: stretch; }
.rd__selmenu .rd__swatch[aria-selected="true"] {
  box-shadow: 0 0 0 2px #1b1e27, 0 0 0 3px #fff;
}
.rd__notecard .rd__swatch[aria-selected="true"] {
  box-shadow: 0 0 0 2px var(--rsheet), 0 0 0 3px var(--rtext);
}
.rd__swatch:focus-visible { outline: 2px solid var(--raccent); outline-offset: 3px; }
.rd__notecard-top {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.rd__notecard-top .rd__notecard-eyebrow { margin-bottom: 0; }

/* ============================================================================
   AUTHOR PAGE — /library/authors/<slug>, per Design's "Author Page Flow"
   (states 9A rich / 9B book / 9C thin). Hero on --surface with the bio next
   to the face; the newest work carries the page's only ink button; talks sit
   in a fixed dark band (video is a different app — theme-invariant, like
   .cta-band); the Track record is a year rail whose filter chips and earlier
   fold are radios + a checkbox, revealed by sibling rules — zero JS.
   ========================================================================== */
/* the index page header reuses these two */
.apage { max-width: 980px; margin: 0 auto; padding: 26px 24px 64px; }
.apage__name {
  font-size: 38px; line-height: 1.05; margin: 0;
  color: var(--text); letter-spacing: var(--ls-display);
}

/* ---- hero ---- */
.ap-hero { background: var(--surface); border-bottom: 1px solid var(--hair); }
.ap-hero__inner { max-width: 1180px; margin: 0 auto; padding: 4px 40px 44px; }
.ap-hero__id { display: flex; align-items: center; gap: 20px; margin-top: 14px; }
.ap-hero__photo {
  width: 92px; height: 92px; border-radius: 999px; object-fit: cover;
  object-position: center 18%; filter: grayscale(1);
  border: 1px solid var(--hair); flex: 0 0 auto;
}
.ap-hero__initials {
  width: 92px; height: 92px; border-radius: 999px; background: var(--grad);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--f-display); font-weight: 800; font-size: 28px;
  color: #07141b; flex: 0 0 auto;
}
.ap-hero__eyebrow {
  font-family: var(--f-display); font-weight: 700; font-size: 11px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--faint);
  margin: 0 0 9px;
}
.ap-hero__name {
  font-family: var(--f-display); font-weight: 800; font-size: 40px;
  line-height: 1.05; margin: 0; color: var(--text);
  letter-spacing: var(--ls-display);
}
.ap-hero__role { font-size: 16px; color: var(--text2); margin: 8px 0 0; font-weight: 500; }
.ap-hero__linkedin {
  display: inline-flex; align-items: center; gap: 8px; margin-top: 14px;
  border: 1px solid var(--hair); background: var(--paper, var(--bg));
  border-radius: 999px; padding: 8px 16px;
  font-family: var(--f-display); font-weight: 600; font-size: 12.5px;
  color: var(--text);
}
.ap-hero__linkedin:hover { border-color: var(--text); }
/* the follow row holds LinkedIn + any phase-4 link pills on one wrapping line */
.ap-hero__follow { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0; }
.ap-hero__link {
  display: inline-flex; align-items: center; margin-top: 14px;
  border: 1px solid var(--hair); background: var(--paper, var(--bg));
  border-radius: 999px; padding: 8px 14px;
  font-family: var(--f-display); font-weight: 600; font-size: 12.5px;
  color: var(--muted);
}
.ap-hero__link:hover { border-color: var(--text); color: var(--text); }
.ap-hero__in {
  width: 16px; height: 16px; border-radius: 3px; background: #0a66c2;
  color: #fff; font-size: 8.5px; font-weight: 700; display: flex;
  align-items: center; justify-content: center; font-family: var(--f-display);
}
.ap-hero__bio {
  font-size: 16.5px; line-height: 1.62; color: var(--text2);
  margin: 24px 0 0; max-width: 760px; text-wrap: pretty;
}
.ap-hero__bio-src {
  font-size: 13px; line-height: 1.5; color: var(--faint);
  margin: 7px 0 0; max-width: 760px;
}
.ap-hero__stats {
  display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 22px;
}
.ap-hero__stat {
  font-family: var(--f-display); font-weight: 600; font-size: 13.5px;
  color: var(--text); border-bottom: 1px solid var(--hair); padding-bottom: 2px;
}
a.ap-hero__stat:hover { color: var(--teal); border-color: var(--teal); }
.ap-hero__topics { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.ap-hero__topic {
  font-size: 12.5px; font-weight: 600; color: var(--muted);
  border: 1px solid var(--hair); border-radius: 999px; padding: 6px 13px;
}
.ap-hero__topic:hover { color: var(--text); border-color: var(--teal); }

/* ---- shared section furniture ---- */
.ap-feat, .ap-works, .ap-collabs, .ap-track, .ap-cta {
  max-width: 1180px; margin: 0 auto; padding: 48px 40px 0;
}
.ap-sect__heading { font-size: 23px; font-weight: 700; margin: 0; color: var(--text); }

/* ---- start here: the featured newest work ---- */
.ap-feat {
  display: grid; grid-template-columns: 132px 1fr auto; gap: 30px;
  align-items: center; border: 1px solid var(--hair); border-radius: 16px;
  padding: 26px 30px; background: var(--bg); box-shadow: var(--shadow-card, 0 12px 34px rgba(12,12,34,.12));
  max-width: 1100px; margin: 52px auto 0;
}
.ap-feat__cover {
  width: 132px; border-radius: 4px; display: block;
  box-shadow: 0 10px 26px rgba(12,12,34,.28);
}
.ap-feat__cover--none {
  height: 190px; background: var(--surface); border: 1px solid var(--hair);
}
.ap-feat__eyebrow {
  display: flex; align-items: center; gap: 8px; margin: 0;
  font-family: var(--f-display); font-weight: 700; font-size: 11px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--text);
}
.ap-feat__title { font-size: 24px; font-weight: 800; margin: 10px 0 0; color: var(--text); }
.ap-feat__blurb {
  font-size: 14.5px; line-height: 1.55; color: var(--text2);
  margin: 9px 0 0; max-width: 560px;
}
.ap-feat__access {
  display: flex; gap: 7px; align-items: center; margin: 13px 0 0;
  font-size: 12.5px; color: var(--text);
}
.ap-feat__access b { font-weight: 600; }
.ap-feat__meta { color: var(--muted); margin-left: 9px; }
.ap-feat__actions { display: flex; flex-direction: column; gap: 10px; align-items: stretch; }
/* `.btn-primary`/`.btn-secondary` are styled only inside the detail rail's
   `.action` panel — restate the same buttons here (the comp's ink pair,
   tighter padding for the card context) or they render as bare text links */
.ap-feat__actions .btn-primary {
  background: var(--btn); color: var(--btn-t); border: none;
  font-family: var(--f-display); font-weight: 600; font-size: 14px;
  padding: 13px 24px; border-radius: var(--r-md); cursor: pointer;
  text-align: center; white-space: nowrap; display: block;
}
.ap-feat__actions .btn-primary:hover { background: var(--btn-hover); }
.ap-feat__actions .btn-secondary {
  background: transparent; border: 1.5px solid var(--hair); color: var(--text);
  font-family: var(--f-display); font-weight: 600; font-size: 13px;
  padding: 11px 24px; border-radius: var(--r-md); cursor: pointer;
  text-align: center; white-space: nowrap; display: block;
}
.ap-feat__actions .btn-secondary:hover { border-color: var(--btn); }

/* ---- in the library ---- */
.ap-works__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 20px; margin-bottom: 22px;
}
.ap-works__count { color: var(--faint); font-weight: 500; font-size: 17px; }

/* ---- writes with ---- */
.ap-collabs { padding-top: 44px; }
.ap-collabs {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  border-top: 1px solid var(--hair); margin-top: 44px; padding-top: 26px;
  max-width: 1100px;
}
.ap-collabs__label {
  font-family: var(--f-display); font-weight: 700; font-size: 11px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--faint);
}
.ap-collabs__chips { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; }
.ap-collab {
  display: flex; align-items: center; gap: 9px; padding: 6px 14px 6px 6px;
  border-radius: 999px; border: 1px solid var(--hair); background: var(--surface);
}
.ap-collab:hover { border-color: var(--teal); }
.ap-collab__avatar {
  width: 26px; height: 26px; border-radius: 999px; background: var(--grad);
  color: #07141b; font-family: var(--f-display); font-weight: 800;
  font-size: 10px; display: flex; align-items: center; justify-content: center;
}
.ap-collab__name {
  font-family: var(--f-display); font-weight: 600; font-size: 12.5px;
  color: var(--text); white-space: nowrap;
}
.ap-collab__n { font-size: 11.5px; color: var(--faint); white-space: nowrap; }
.ap-collab__more { font-size: 12.5px; font-weight: 600; color: var(--muted); padding: 6px 8px; }

/* ---- talks: the dark band (theme-invariant, like .cta-band) ---- */
.ap-talks { max-width: none; padding: 0; background: #0c0c22; margin-top: 52px; }
.ap-talks__inner { max-width: 1180px; margin: 0 auto; padding: 46px 40px; }
.ap-talks__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 20px; margin-bottom: 22px;
}
.ap-talks__eyebrow {
  font-family: var(--f-display); font-weight: 700; font-size: 11px;
  letter-spacing: .14em; text-transform: uppercase; color: #3fc3dd; margin: 0;
}
.ap-talks__heading { font-size: 23px; font-weight: 700; color: #fff; margin: 9px 0 0; }
.ap-talks__all { color: #3fc3dd; font-weight: 600; font-size: 13.5px; }
.ap-talks__all:hover { color: #fff; }
.ap-talks__grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 24px; max-width: 100%;
}
.ap-talk { display: block; min-width: 0; }
.ap-talk__thumb {
  position: relative; aspect-ratio: 16/9; border-radius: 12px; overflow: hidden;
  background: #17173a; display: flex; align-items: center; justify-content: center;
}
.ap-talk__thumb img { width: 100%; height: 100%; object-fit: cover; }
.ap-talk__play {
  position: absolute; width: 46px; height: 46px; border-radius: 999px;
  background: rgba(10,10,20,.55);
}
.ap-talk__play::after {
  content: ""; position: absolute; left: 18px; top: 15px;
  border-left: 13px solid #fff; border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
}
.ap-talk__dur {
  position: absolute; bottom: 9px; right: 9px; background: rgba(10,10,20,.8);
  color: #fff; font-size: 11px; font-weight: 600; padding: 2px 7px;
  border-radius: 5px; font-family: var(--f-display);
}
.ap-talk__title {
  font-family: var(--f-display); font-weight: 700; font-size: 14.5px;
  color: #fff; margin: 12px 0 0; line-height: 1.3;
}
.ap-talk__event { font-size: 12.5px; color: #9aa2b4; margin: 4px 0 0; }
.ap-talk__thumb--stack {
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.12);
  gap: 0;
}
.ap-talk--more:hover .ap-talk__thumb--stack { border-color: #3fc3dd; }
.ap-talk__mini {
  width: 74px !important; height: 42px !important; object-fit: cover;
  border-radius: 6px; box-shadow: 0 6px 16px rgba(0,0,0,.35);
  border: 1px solid rgba(255,255,255,.14); flex: 0 0 auto;
}
.ap-talk__mini + .ap-talk__mini { margin-left: -26px; }
.ap-talk__rest {
  position: absolute; right: 12px; bottom: 10px;
  font-family: var(--f-display); font-weight: 800; font-size: 15px; color: #fff;
}

/* ---- track record ---- */
.ap-track { padding-top: 52px; }
.ap-track__radio, .ap-track__earlier { position: absolute; opacity: 0; pointer-events: none; }
.ap-track__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 20px; margin-bottom: 8px; flex-wrap: wrap;
}
.ap-track__sub { font-size: 14px; color: var(--muted); margin: 7px 0 0; max-width: 560px; }
.ap-track__filters { display: flex; gap: 7px; flex-wrap: wrap; }
.ap-track__chip {
  font-family: var(--f-display); font-weight: 600; font-size: 12.5px;
  color: var(--muted); border: 1px solid var(--hair); border-radius: 999px;
  padding: 7px 15px; cursor: pointer;
}
.ap-track__chip:hover { color: var(--text); border-color: var(--faint); }
/* the checked filter's chip flips to ink */
#trf-all:checked   ~ .ap-track__head label[for="trf-all"],
#trf-pubs:checked  ~ .ap-track__head label[for="trf-pubs"],
#trf-talks:checked ~ .ap-track__head label[for="trf-talks"],
#trf-roles:checked ~ .ap-track__head label[for="trf-roles"] {
  color: var(--on-ink); background: var(--ink); border-color: var(--ink);
}
.ap-track__rows { margin-top: 22px; }
.ap-tr { display: grid; grid-template-columns: 56px 20px 1fr; align-items: stretch; }
.ap-tr__year {
  font-family: var(--f-display); font-weight: 700; font-size: 13px;
  color: var(--faint); padding-top: 16px; font-variant-numeric: tabular-nums;
}
.ap-tr__rail { position: relative; display: flex; justify-content: center; }
.ap-tr__rail::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: 50%;
  width: 1px; background: var(--hair);
}
.ap-tr__dot {
  position: absolute; top: 19px; width: 9px; height: 9px; border-radius: 999px;
  box-shadow: 0 0 0 4px var(--bg);
}
.ap-tr--paper .ap-tr__dot, .ap-tr--book .ap-tr__dot { background: var(--teal); }
.ap-tr--talk .ap-tr__dot { background: var(--coral); }
.ap-tr--role .ap-tr__dot { background: var(--faint); }
.ap-tr__body { padding: 13px 0 15px 16px; }
.ap-tr__head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin: 0; }
.ap-tr__kind {
  font-family: var(--f-display); font-weight: 700; font-size: 9.5px;
  letter-spacing: .11em; text-transform: uppercase;
}
.ap-tr--paper .ap-tr__kind, .ap-tr--book .ap-tr__kind { color: var(--teal); }
.ap-tr--talk .ap-tr__kind { color: var(--coral); }
.ap-tr--role .ap-tr__kind { color: var(--faint); }
.ap-tr__title {
  font-family: var(--f-display); font-weight: 600; font-size: 14.5px;
  color: var(--text); line-height: 1.3;
}
a.ap-tr__title:hover { color: var(--teal); text-decoration: underline; }
.ap-tr__meta { font-size: 12.5px; color: var(--muted); margin: 3px 0 0; }
/* filter: hide the kinds the checked radio excludes */
#trf-pubs:checked  ~ .ap-track__rows .ap-tr--talk,
#trf-pubs:checked  ~ .ap-track__rows .ap-tr--role,
#trf-talks:checked ~ .ap-track__rows .ap-tr--paper,
#trf-talks:checked ~ .ap-track__rows .ap-tr--book,
#trf-talks:checked ~ .ap-track__rows .ap-tr--role,
#trf-roles:checked ~ .ap-track__rows .ap-tr--paper,
#trf-roles:checked ~ .ap-track__rows .ap-tr--book,
#trf-roles:checked ~ .ap-track__rows .ap-tr--talk { display: none; }
/* the earlier fold */
.ap-tr--early { display: none; }
#tr-earlier:checked ~ .ap-track__rows .ap-tr--early { display: grid; }
#trf-pubs:checked  ~ .ap-track__rows .ap-tr--early.ap-tr--talk,
#trf-pubs:checked  ~ .ap-track__rows .ap-tr--early.ap-tr--role,
#trf-talks:checked ~ .ap-track__rows .ap-tr--early.ap-tr--paper,
#trf-talks:checked ~ .ap-track__rows .ap-tr--early.ap-tr--book,
#trf-talks:checked ~ .ap-track__rows .ap-tr--early.ap-tr--role,
#trf-roles:checked ~ .ap-track__rows .ap-tr--early.ap-tr--paper,
#trf-roles:checked ~ .ap-track__rows .ap-tr--early.ap-tr--book,
#trf-roles:checked ~ .ap-track__rows .ap-tr--early.ap-tr--talk { display: none; }
.ap-track__more { display: grid; grid-template-columns: 56px 20px 1fr; }
.ap-track__more > :first-child { grid-column: 3; }
.ap-track__toggle {
  grid-column: 3; justify-self: start; margin: 6px 0 0 16px;
  background: var(--surface); border: 1px solid var(--hair); color: var(--text);
  font-family: var(--f-display); font-weight: 600; font-size: 12.5px;
  padding: 9px 16px; border-radius: 10px; cursor: pointer;
}
.ap-track__toggle:hover { border-color: var(--faint); }
.ap-track__hide { display: none; }
#tr-earlier:checked ~ .ap-track__more .ap-track__show { display: none; }
#tr-earlier:checked ~ .ap-track__more .ap-track__hide { display: inline; }

/* the page breathes before the footer whether or not the membership band
   (hidden for members) is the last section */
main.ap { padding-bottom: 64px; }

/* ---- the membership band ---- */
.ap-cta { padding-top: 56px; padding-bottom: 0; }
.ap-cta__panel {
  background: #0c0c22; border-radius: 18px; padding: 42px 44px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 40px; flex-wrap: wrap;
}
.ap-cta__copy { max-width: 660px; }
.ap-cta__title {
  font-size: 26px; font-weight: 800; color: #fff;
  letter-spacing: -.025em; margin: 0;
}
.ap-cta__body { font-size: 15px; line-height: 1.6; color: #c7ccda; margin: 12px 0 0; }
.ap-cta__actions { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
.ap-cta__btn {
  background: var(--grad); border: none; color: #06121a;
  font-family: var(--f-display); font-weight: 700; font-size: 14px;
  padding: 13px 24px; border-radius: 999px; white-space: nowrap;
}
.ap-cta__link { font-size: 13px; font-weight: 600; color: #9aa2b4; }
.ap-cta__link:hover { color: #fff; }

/* ---- mobile: hero stacks, featured stacks, rail persists ---- */
@media (max-width: 760px) {
  .ap-hero__inner, .ap-feat, .ap-works, .ap-collabs, .ap-track, .ap-cta,
  .ap-talks__inner { padding-left: 20px; padding-right: 20px; }
  .ap-hero__name { font-size: 30px; }
  .ap-feat { grid-template-columns: 1fr; }
  .ap-feat__cover { width: 110px; }
  .ap-talks__grid { grid-template-columns: 1fr; }
}

/* author-name links back into the author page from a work's author block */
.author-name-link { color: inherit; }
.author-name-link:hover { color: var(--teal); text-decoration: underline; }
.author-more { font-size: 13.5px; margin: 10px 0 0; }

/* searchable contributor directory at /library/authors */
.adir__hero { max-width: 700px; margin-top: 24px; }
.adir__lede { max-width: 58ch; margin: 10px 0 0; color: var(--muted); font-size: 17px; line-height: 1.55; }
.adir__search { max-width: 760px; margin-top: 28px; }
.adir__controls { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-top: 20px; }
.adir__filters { display: flex; gap: 8px; flex-wrap: wrap; }
.adir__sort { display: flex; align-items: center; gap: 4px; white-space: nowrap; color: var(--faint); font-size: 13px; }
.adir__sort span { margin-right: 4px; }
.adir__sort a { color: var(--muted); padding: 7px 9px; border-radius: 7px; font-weight: 600; }
.adir__sort a:hover, .adir__sort a.is-on { color: var(--text); background: var(--wash); }
.adir__count { font-size: 14px; color: var(--muted); margin: 24px 0 10px; }
.adir__grid { list-style: none; margin: 0 0 64px; padding: 0; display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 14px; }
.adir-card {
  min-width: 0; position: relative; border: 1px solid var(--hair); border-radius: 14px;
  background: var(--paper); padding: 20px; transition: border-color .16s ease, transform .16s ease;
}
.adir-card:hover { border-color: color-mix(in srgb,var(--teal) 42%,var(--hair)); transform: translateY(-1px); }
.adir-card__person { display: grid; grid-template-columns: 54px minmax(0,1fr); align-items: center; gap: 13px; padding-right: 58px; color: var(--text); }
.adir-card__portrait, .adir-card__initials { width: 54px; height: 54px; border-radius: 50%; }
.adir-card__portrait { display: block; object-fit: cover; background: var(--wash); }
.adir-card__initials { display: grid; place-items: center; background: var(--wash); color: var(--teal); font-weight: 700; font-size: 15px; }
.adir-card__identity { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.adir-card__name { font-size: 17px; line-height: 1.25; font-weight: 700; }
.adir-card__affiliation { color: var(--muted); font-size: 13px; line-height: 1.35; }
.adir-card__count { position: absolute; right: 20px; top: 23px; color: var(--faint); font-size: 12px; }
.adir-card__works { list-style: none; margin: 16px 0 0 67px; padding: 13px 0 0; border-top: 1px solid var(--hair); }
.adir-card__works li + li { margin-top: 6px; }
.adir-card__works a {
  display: flex; align-items: baseline; gap: 8px; color: var(--muted);
  font-size: 13px; line-height: 1.35;
}
.adir-card__works .adir-card__work--book + li { margin-top: 7px; }
.adir-card__work--book a { align-items: center; color: var(--text); font-weight: 600; }
.adir-card__work-title { min-width: 0; flex: 1; }
.adir-card__work-year {
  flex: 0 0 auto; margin-left: auto; color: var(--faint); font-size: 11px;
  font-weight: 500; font-variant-numeric: tabular-nums;
}
.adir-card__work-cover {
  width: 18px; height: 26px; flex: 0 0 18px; display: block; object-fit: cover;
  border-radius: 2px; box-shadow: 0 2px 5px rgba(11,12,32,.16);
}
.adir-card__work-cover--blank {
  position: relative; border: 1px solid var(--hair); background: var(--wash); box-shadow: none;
}
.adir-card__work-cover--blank::after {
  content: ""; position: absolute; left: 4px; right: 4px; top: 7px; height: 1px;
  background: var(--teal); box-shadow: 0 4px 0 var(--teal);
}
.adir-card__works a:hover { color: var(--teal); text-decoration: underline; }
.adir-card__more {
  margin-top: 8px; color: var(--faint); font-size: 12.5px; font-weight: 600;
}
@media (max-width: 700px) {
  .adir__controls { align-items: flex-start; flex-direction: column; gap: 12px; }
  .adir__grid { grid-template-columns: 1fr; }
  .adir__search .filterbar__go { padding-inline: 16px; }
  .adir-card { padding: 17px; }
  .adir-card__count { right: 17px; top: 20px; }
}

/* presale cards + panel: the date IS the access line */
.cover-card__access--coming { font-size: 12px; color: var(--coming); }
.action__eyebrow--coming { color: var(--coming); }

/* ---- /glossary — the public term pages (mirrors .adir) ------------------- */
.gdir{min-width:0;overflow-x:hidden}
.gdir .adir__group{margin:1.75rem 0 0}
.gdir .adir__letter{margin:0 0 .45rem;font-family:var(--f-display);font-size:1.35rem;
  line-height:1;color:var(--text)}
.gdir .adir__list{list-style:none;margin:0;padding:0;border-top:1px solid var(--hair)}
.gdir .adir__row{display:flex;align-items:baseline;gap:1.25rem;min-width:0;
  padding:.72rem 0;border-bottom:1px solid var(--hair)}
.gdir .adir__name{flex:0 1 38%;min-width:10rem;color:var(--text);
  font-family:var(--f-display);font-weight:650;line-height:1.35;text-decoration:none}
.gdir .adir__name:hover{color:var(--teal)}
.gdir .adir__n{flex:1 1 0;min-width:0;color:var(--muted);font-size:.86rem;
  line-height:1.4;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gterm__lede{color:var(--text-2,inherit);max-width:62ch;margin:0 0 1.4rem;
  font-size:1.02rem}
.gterm__senses{display:flex;flex-direction:column;gap:1.1rem;max-width:68ch}
.gterm__sense{border:1px solid var(--line,rgba(12,12,34,.12));border-radius:12px;
  background:var(--paper);padding:1.1rem 1.25rem}
.gterm__def{margin:0 0 .65rem;font-size:1.04rem;line-height:1.65}
.gterm__src{margin:0;font-size:.88rem;color:var(--text-2,inherit)}
.gterm__book{font-weight:600}
/* the chapter link on a first-use sense: dotted, like a glossary mark in the
   reader's prose — the same "this goes somewhere" affordance, pointed back */
.gterm__loc{color:inherit;text-decoration:underline;
  text-decoration-style:dotted;text-underline-offset:3px}
.gterm__as{font-style:italic}
.gterm__foot{margin-top:2rem;font-size:.9rem}
.gterm__origin{font-style:italic}
/* where a term came from — a quieter card than a sense, because it answers a
   different question than "what does it mean" */
.gterm__origin-block{max-width:68ch;margin:1.4rem 0 0;padding:.9rem 1.1rem;
  border-left:3px solid var(--hair,rgba(12,12,34,.18));
  background:var(--paper-2,transparent)}
.gterm__coined{margin:0 0 .5rem;font-size:.95rem}
.gterm__coined-span{margin:0 0 .5rem;font-size:1rem;line-height:1.6;
  font-style:italic;color:var(--text-2,inherit)}
.gterm__also{color:var(--text-2,inherit);font-size:.92rem;margin:-.4rem 0 1rem}
/* the explainer above the shelf: what field these terms belong to and who
   defines them — reading copy, so it gets the reading measure */
.gdir__about{color:var(--text-2,inherit);max-width:64ch;font-size:1.02rem;
  line-height:1.62;margin:0 0 1.2rem}
/* Glossary rows carry arbitrary headwords and full source titles. The author
   directory's useful nowrap treatment cannot safely contain those on a phone. */
@media (max-width:560px){
  .gdir{overflow-x:clip}
  .gdir .adir__row{align-items:flex-start;flex-direction:column;gap:2px}
  .gdir .adir__row>*{min-width:0;max-width:100%}
  .gdir .adir__name,.gdir .adir__n{white-space:normal;overflow-wrap:anywhere}
  .gdir .adir__name{flex:auto}
  .gdir .adir__n{margin-left:0;text-align:left}
}
/* browse-by-topic chips: the by-subject doors into the dictionary */
.gdir__topics{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 1.4rem}
.gdir__topic{font-family:var(--f-display);font-weight:600;font-size:12.5px;
  color:var(--text);text-decoration:none;border:1.5px solid var(--hair);
  border-radius:999px;padding:5px 13px;white-space:nowrap}
.gdir__topic:hover{border-color:var(--teal);color:var(--teal)}
.gdir__topic:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
/* a term page's way back out by subject */
.gterm__seealso{margin-top:1.6rem;font-size:.9rem;color:var(--muted,#5b6470)}
.gterm__seealso+.gterm__filed{margin-top:.35rem}
.gterm__filed{margin-top:1.6rem;font-size:.9rem;color:var(--muted,#5b6470)}
.gterm__filed-link{color:inherit;text-decoration:underline;
  text-decoration-style:dotted;text-underline-offset:3px}
.gterm__filed-link:hover{color:var(--teal)}
/* the glossary filter bar: quiet, roomy, icon inside the field */
.gdir__bar{position:relative;max-width:24rem;margin:1.1rem 0 .8rem}
.gdir__mag{position:absolute;left:.85rem;top:50%;transform:translateY(-50%);
  color:var(--text-2,#667085);pointer-events:none}
.gdir__filter{width:100%;padding:.6rem .9rem .6rem 2.35rem;font:inherit;
  font-size:.95rem;border:1px solid var(--line,rgba(12,12,34,.16));
  border-radius:999px;background:var(--paper);color:inherit;
  transition:border-color .12s ease}
.gdir__filter:focus{outline:none;border-color:currentColor}
.gdir__filter::-webkit-search-cancel-button{-webkit-appearance:none}
.gdir__none{color:var(--text-2,inherit);font-style:italic;margin-top:1.2rem}
/* class-based hiding: an author display rule on the rows would defeat the
   [hidden] attribute (it did — the filter's first bug in production) */
.adir__row.is-hid,.adir__group.is-hid{display:none}
#gcount{font-size:.88rem}

/* ---- beta: first-session welcome + feedback (2026-09-05) ---- */
.ob{padding:1.4rem 1.6rem}
.ob__steps{margin:.6rem 0 1.2rem;padding-left:1.2rem;display:grid;gap:.55rem;max-width:64ch}
.ob__steps li{line-height:1.5}
.ob__actions{display:flex;gap:.75rem;flex-wrap:wrap;align-items:center}
.fb__kinds{border:0;padding:0;margin:0 0 1rem;display:grid;gap:.4rem}
.fb__kinds legend{margin-bottom:.4rem}
.fb__kind{display:flex;gap:.5rem;align-items:center}
.fb__contact{display:flex;gap:.5rem;align-items:center;margin:.8rem 0 1.1rem}

/* PHONE (Alex, 2026-09-07): one column already under 880px; here the shell
   loses its side padding, the card's two actions and the search box each
   stay on ONE line, the list head wraps its count under the title, and a
   row is number · media · body with the actions on a second line. */
@media (max-width: 560px) {
  .lp-shell { padding: 16px 16px 40px; }
  .lp-crumbs { margin-bottom: 14px; }
  .lp-crumbs__cur { max-width: 22ch; }
  .lp-panel { gap: 12px; }
  .lp-hero { padding: 18px 18px 20px; }
  .lp-hero h1 { font-size: 22px; }
  .lp-hero__go { font-size: 13.5px; padding: 11px 14px; white-space: nowrap; }
  .lp-hero__delbtn { font-size: 12.5px; padding: 11px 11px; }
  .lp-hero__confirm { width: min(280px, calc(100vw - 48px)); }
  .pb { padding: 14px 14px 16px; }
  .pb__form { flex-wrap: nowrap; }
  .pb__field { flex: 1 1 auto; min-width: 0; }
  .pb__field input { font-size: 13.5px; }
  /* Results are in-flow now, so viewport math would add the builder's own
     padding a second time and force the whole path 30px wider than a phone. */
  .pb-results--open { width: 100%; }
  .lp-listhead { flex-wrap: wrap; row-gap: 2px; margin-top: 4px; }
  .lp-listhead h2 { font-size: 17px; }
  .lp-listhead__meta { margin-left: 0; flex-basis: 100%; }
  .lp-step { grid-template-columns: 22px 72px minmax(0, 1fr); gap: 10px 12px; padding: 10px 6px; }
  .lp-step__media { width: 72px; height: 60px; }
  .lp-step__title { font-size: 14px; }
  .lp-step__acts { grid-column: 2 / -1; flex-direction: row; align-items: center;
                   justify-content: flex-end; gap: 12px; }
  .lp-step__acts .btn { min-width: 0; }
}

/* ============================================================================
   Member home — /members/<handle> (Option B, 2026-09-07). The card grammar is
   .acct__card's (18px radius, 26px padding, --card on --bg-app); what is new
   is the hero and the three private sections with their own switches.
   ========================================================================= */
.mh-app { background: var(--bg-app); }
.mh { max-width: 1120px; margin: 0 auto; padding: 44px var(--page-pad) 80px;
      display: flex; flex-direction: column; gap: 28px; }
.mh-hero { display: flex; gap: 28px; align-items: flex-start; }
.mh-avatar { width: 116px; height: 116px; border-radius: var(--r-pill); object-fit: cover; flex: 0 0 auto; }
.mh-avatar--initials { background: var(--grad-chip); color: var(--on-grad);
             display: inline-flex; align-items: center; justify-content: center;
             font-family: var(--f-display); font-size: 40px; font-weight: 700; }
.mh-id { display: flex; flex-direction: column; gap: 8px; flex: 1; min-width: 0; }
.mh-id__row { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.mh-name { margin: 0; font-size: 34px; font-weight: 800; letter-spacing: -.01em; color: var(--text); }
.mh-since { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--faint); }
.mh-role { margin: 0; font-size: 17px; color: var(--text2); }
.mh-org { color: var(--muted); }
.mh-pills { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 4px; }
.mh-pill { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 600;
           color: var(--text); border: 1.5px solid var(--hair); border-radius: var(--r-pill);
           padding: 7px 13px; text-decoration: none; }
.mh-pill:hover { border-color: var(--text); }
.mh-own { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; flex: 0 0 auto; }
.mh-two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.mh-card { background: var(--card); border: 1px solid var(--hair); border-radius: 18px; padding: 22px 26px;
           display: flex; flex-direction: column; gap: 14px; }
.mh-card__head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.mh-card__h { margin: 0; font-family: var(--f-display); font-size: 15px; font-weight: 700; color: var(--text); }
.mh-eyebrow { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--faint); }
.mh-para { margin: 0; color: var(--text2); }
.mh-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.mh-chip { font-family: var(--f-display); font-size: 12.5px; font-weight: 600; color: var(--text2);
           border: 1px solid var(--hair); border-radius: var(--r-pill); padding: 6px 12px; }
.mh-card__lead { display: flex; align-items: center; gap: 12px; }
.mh-card__meta { display: flex; align-items: center; gap: 14px; margin-left: auto; }
.mh-tag { font-size: 11.5px; font-weight: 600; color: var(--faint); white-space: nowrap;
          border: 1px solid var(--hair); border-radius: var(--r-pill); padding: 4px 10px; }
.mh-tag.is-on { color: var(--green); border-color: rgba(34,176,131,.35); }
.mh-go { margin: 0; }
.mh-vis { position: relative; }
.mh-vis__sum { display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
               font-size: 12.5px; color: var(--muted); list-style: none; }
.mh-vis__sum::-webkit-details-marker { display: none; }
.mh-vis__dot { width: 8px; height: 8px; border-radius: var(--r-pill); flex: 0 0 auto;
               background: var(--green); box-shadow: 0 0 0 3px rgba(34,176,131,.18); }
.mh-vis.is-off .mh-vis__dot { background: var(--faint); box-shadow: none; }
.mh-vis.is-off .mh-vis__state { color: var(--text2); font-weight: 600; }
.mh-vis__link { color: var(--teal); font-weight: 600; }
.mh-vis__state::after { content: "\00b7"; margin: 0 7px; color: var(--faint); font-weight: 400; }
.mh-vis__sum:hover .mh-vis__link { color: var(--teal-ink, var(--teal)); text-decoration: underline; }
.mh-vis__panel { position: absolute; top: calc(100% + 12px); right: 0; z-index: 40; width: 400px;
                 text-align: left; background: var(--card); border: 1px solid var(--hair);
                 border-radius: 16px; padding: 20px; display: flex; flex-direction: column; gap: 14px;
                 box-shadow: 0 18px 44px rgba(12,12,34,.18); }
.mh-vis__intro, .mh-vis__note { margin: 0; font-size: 12px; color: var(--faint); line-height: 1.45; }
.mh-vis__row { display: grid; grid-template-columns: 17px minmax(0, 1fr); gap: 11px;
               align-items: start; cursor: pointer; }
.mh-vis__cb { width: 16px; height: 16px; margin: 2px 0 0; accent-color: var(--teal); cursor: pointer; }
.mh-vis__l { display: block; font-family: var(--f-display); font-size: 13.5px; font-weight: 600; color: var(--text); }
.mh-vis__d { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; line-height: 1.4; }
.mh-vis__acts { display: flex; justify-content: flex-end; border-top: 1px solid var(--hair); padding-top: 14px; }
.mh-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.mh-stat { background: var(--surface); border: 1px solid var(--hair); border-radius: 12px; padding: 16px 18px;
           display: flex; flex-direction: column; gap: 4px; }
.mh-stat__n { font-family: var(--f-display); font-size: 30px; font-weight: 800; color: var(--text);
              font-variant-numeric: tabular-nums; }
.mh-stat__u { font-size: 16px; color: var(--muted); }
.mh-stat__l { font-size: 12.5px; color: var(--muted); }
.mh-chart { display: flex; flex-direction: column; gap: 8px; }
.mh-chart__cap { display: flex; justify-content: space-between; font-size: 12px; color: var(--faint); }
.mh-bars { display: block; }
.mh-bars__m { font-family: var(--f-ui); }
.mh-finished .ml-grid { margin-top: 0; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); }
.mh-finished .ml-tile__title { font-size: 14px; text-wrap: pretty; }
.mh-more { font-size: 12.5px; font-weight: 600; align-self: flex-end; }
.mh-empty { margin: 0; color: var(--muted); font-size: 14px; }
.mh-note { font-size: 12.5px; color: var(--faint); }
.mh-creds { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.mh-cred { border: 1px solid var(--hair); border-radius: 12px; padding: 18px; display: flex; gap: 14px;
           align-items: flex-start; text-decoration: none; color: inherit; }
.mh-cred__ic { width: 40px; height: 40px; border-radius: 10px; display: inline-flex; align-items: center;
               justify-content: center; flex: 0 0 auto; }
.mh-cred__ic.is-cert { background: var(--teal-soft); color: var(--teal); }
.mh-cred__ic.is-quiz { background: rgba(34,176,131,.12); color: var(--green); }
.mh-cred__t { display: block; font-family: var(--f-display); font-size: 13.5px; font-weight: 600; color: var(--text); }
.mh-cred__d { display: block; font-size: 12px; color: var(--muted); margin-top: 3px; }
@media (max-width: 860px) {
  .mh-hero { flex-direction: column; }
  .mh-own { align-items: flex-start; }
  .mh-two, .mh-stats, .mh-creds { grid-template-columns: 1fr 1fr; }
  /* a popover anchored to a right-aligned hero has nowhere to go on a phone */
  .mh-vis__panel { position: static; width: auto; box-shadow: none; margin-top: 12px; }
  .mh-finished .ml-grid { grid-template-columns: repeat(auto-fill, minmax(138px, 1fr)); }
}

/* beta ops: the grant / end / invite screen (2026-09-08) */
.ops-action{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:10px 0}
.ops-note-input{font:inherit;font-size:14px;padding:9px 12px;border:1px solid var(--hair, #d5dde2);border-radius:10px;min-width:18rem;background:var(--paper, #fff);color:inherit}
.ops-flash{margin:0 0 14px;padding:10px 14px;border-radius:10px;background:var(--tealsoft, #e6f4ef);color:var(--teal, #0d8a6a);font-weight:500}
.ops-ta{font:inherit;font-size:14px;width:100%;max-width:40rem;padding:10px 12px;border:1px solid var(--hair, #d5dde2);border-radius:10px;background:var(--paper, #fff);color:inherit;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.ops-until{display:inline-flex;align-items:center;gap:6px;font-size:14px}
.ops-check{display:block;margin:8px 0;font-size:14px}

/* ==========================================================================
   34. READER — figure viewer (.rd-fig): a picture at its own size
   ========================================================================== */

/* Testers 4 and 5 (2026-09-08) reported one missing feature from two devices:
   "In mobile, I can't click an image and make it zoom in or open in a pop up
   window. I have to pinch zoom into the page instead" and "Same regarding image
   on desktop." The paged sheet is why it matters: styleFrame clamps every
   picture to `img,svg{max-width:colW()px}` and to one page's height, so a
   full-page rubric TABLE RENDERED AS AN IMAGE — how the guidance papers ship
   theirs — arrives on a phone about 320px wide. That is not a table, it is a
   photograph of one.

   WHERE THIS LIVES: see the `figure-viewer` docstring. Inside `.rd` for the
   theme tokens, `position:fixed` to escape `.rd`'s overflow:hidden. */
.rd-fig {
  position: fixed; inset: 0; z-index: 60;
  display: flex; flex-direction: column;
  background: var(--rbg); color: var(--rtext);
  padding: calc(6px + env(safe-area-inset-top)) 0 calc(10px + env(safe-area-inset-bottom));
  animation: rdFade .18s ease;
  transition: transform .18s cubic-bezier(.4, 0, .2, 1), opacity .18s ease;
}
/* THE STYLESHEET HAS TO SAY THIS OUT LOUD. `[hidden]{display:none}` is
   UA-origin, and every author `display` here outranks it — which is why
   `.rd__notecard[hidden]` already exists a few hundred lines down, and why the
   global `img{display:block}` at the top of this file would otherwise leave
   `fgImg.hidden=true` doing nothing whatsoever. */
.rd-fig[hidden], .rd-fig__img[hidden], .rd-fig__paint[hidden],
.rd-fig__meta[hidden], .rd-fig__cap[hidden], .rd-fig__desc[hidden] {
  display: none;
}

.rd-fig__stage {
  flex: 1 1 auto; min-height: 0; position: relative;
  display: grid; place-items: center; overflow: hidden;
  /* the browser must not pan, pinch or double-tap-zoom this: each of those is a
     gesture the viewer implements itself, and letting the PAGE zoom instead
     carries the close button off the screen */
  touch-action: none;
  -webkit-user-select: none; user-select: none;
}
.rd-fig__box {
  display: grid; place-items: center;
  transform-origin: center center; will-change: transform;
  transition: transform .18s cubic-bezier(.4, 0, .2, 1);
}
.rd-fig__box.is-dragging { transition: none; }
/* Canvas and image occupy the SAME grid cell with the same intrinsic ratio and
   the same fit, so the full-resolution <img> lands exactly over the instant
   canvas paint and the swap is invisible. */
.rd-fig__img, .rd-fig__paint {
  grid-area: 1 / 1;
  max-width: 100%; max-height: 100%;
  width: auto; height: auto; object-fit: contain;
  /* every InDesign chart is a transparent PNG; without a ground they are black
     line art on a black theme */
  background: #fff; border-radius: 2px;
}
.rd-fig__meta {
  flex: 0 1 auto; width: 100%; max-height: 30%; overflow-y: auto;
  overscroll-behavior: contain; padding: 0 var(--chrome-pad);
  font-family: 'Hanken Grotesk', system-ui, sans-serif;
}
.rd-fig__cap {
  margin: 12px auto 0; max-width: 64ch;
  font-family: 'Hanken Grotesk', system-ui, sans-serif;
  font-size: 13px; line-height: 1.5; color: var(--rmuted); text-align: center;
}
.rd-fig__desc {
  max-width: 64ch; margin: 8px auto 0;
  border-top: 1px solid var(--rhair, rgba(128,128,128,.22));
  color: var(--rmuted); font-size: 13px; line-height: 1.5;
}
.rd-fig__desc > summary {
  display: flex; align-items: center; justify-content: center; min-height: 44px;
  color: var(--raccent); cursor: pointer; font-weight: 600; list-style: none;
}
.rd-fig__desc > summary::-webkit-details-marker { display: none; }
.rd-fig__desc > summary::after { content: "+"; margin-left: 8px; font-size: 17px; }
.rd-fig__desc[open] > summary::after { content: "−"; }
.rd-fig__desc > p { margin: 0 auto 14px; color: var(--rtext); text-align: left; }
/* zoomed in, the caption is sitting on the thing you zoomed in on */
.rd-fig.is-zoomed .rd-fig__meta { display: none; }

.rd-fig__x, .rd-fig__zoom {
  position: absolute; top: calc(6px + env(safe-area-inset-top)); z-index: 2;
  width: 44px; height: 44px; border: 0; border-radius: 999px;
  background: var(--rsheet); color: var(--rmuted);
  line-height: 1; cursor: pointer; box-shadow: 0 2px 10px rgba(0, 0, 0, .18);
}
.rd-fig__x { right: 10px; font-size: 26px; }
.rd-fig__zoom { font-size: 20px; }
.rd-fig__zoom--out { left: 10px; }
.rd-fig__zoom--in  { left: 60px; }
.rd-fig__x:hover, .rd-fig__zoom:hover { color: var(--rtext); }
.rd-fig__zoom[disabled] { opacity: .38; cursor: default; }
.rd-fig__x:focus-visible, .rd-fig__zoom:focus-visible, .rd-fig__done:focus-visible,
.rd-fig__desc > summary:focus-visible {
  outline: 2px solid var(--raccent); outline-offset: 2px;
}
/* THE EXIT A THUMB CAN REACH. This reader hides its chrome by default, so a
   44px target in the top corner of a 6.1" phone is the one control a
   one-handed reader cannot get to — the same reach argument that gave touch its
   own turn zones. Coarse pointers get a second exit down where the thumb
   already is; swipe-down and a tap on the background are the other two. */
.rd-fig__done { display: none; }
@media (pointer: coarse) {
  .rd-fig__done {
    display: block; flex: 0 0 auto; align-self: center;
    margin: 12px auto 0; min-height: 48px; padding: 0 32px;
    border: 0; border-radius: 999px;
    background: var(--rtext); color: var(--rbg);
    font-family: 'Sora', system-ui, sans-serif; font-weight: 600; font-size: 14px;
    cursor: pointer;
  }
}

/* ==========================================================================
   READER HELP — public, readable before sign-in
   ========================================================================== */

.help-page { background: var(--paper); }
.help {
  width: 100%; max-width: 1260px; margin: 0 auto;
  padding: clamp(72px, 9vw, 124px) var(--page-pad) 120px;
}
.help__hero { max-width: 900px; padding-bottom: clamp(64px, 8vw, 104px); }
.help__eyebrow {
  margin-bottom: 18px; color: var(--coral); font-family: var(--f-display);
  font-size: 11px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase;
}
.help__title {
  max-width: 820px; margin: 0; color: var(--text);
  font-size: clamp(42px, 6.2vw, 78px); line-height: .98; letter-spacing: -.055em;
}
.help__intro {
  max-width: 680px; margin: 28px 0 0; color: var(--muted);
  font-size: clamp(17px, 2vw, 20px); line-height: 1.65;
}
.help__intro a {
  color: var(--text); font-weight: 700; text-decoration: underline;
  text-underline-offset: 4px; overflow-wrap: anywhere;
}
.help__layout {
  display: grid; grid-template-columns: 235px minmax(0, 1fr);
  gap: clamp(48px, 8vw, 112px); align-items: start;
}
.help__rail { position: sticky; top: 92px; }
.help__rail-label {
  margin: 0 0 12px; color: var(--faint); font-family: var(--f-display);
  font-size: 10px; font-weight: 800; letter-spacing: .13em; text-transform: uppercase;
}
.help__rail-link {
  display: grid; grid-template-columns: 34px 1fr; gap: 8px; align-items: baseline;
  padding: 11px 0; border-top: 1px solid var(--hair); color: var(--text2);
  font-size: 13px; font-weight: 650;
}
.help__rail-link span { color: var(--coral); font-size: 10px; letter-spacing: .08em; }
.help__rail-link:hover { color: var(--coral); }
.help__feedback {
  display: flex; flex-direction: column; gap: 7px; margin-top: 30px;
  padding: 20px; border-radius: var(--r-md); background: var(--ink); color: var(--on-ink);
}
.help__feedback strong { font-family: var(--f-display); font-size: 13px; }
.help__feedback span { color: #ff8293; font-size: 12px; font-weight: 700; }
.help__group { padding-bottom: 72px; scroll-margin-top: 90px; }
.help__group-head {
  display: grid; grid-template-columns: 64px 1fr; gap: 16px; align-items: baseline;
  padding-bottom: 24px; border-bottom: 2px solid var(--text);
}
.help__number { color: var(--coral); font-family: var(--f-display); font-size: 12px; font-weight: 800; letter-spacing: .08em; }
.help__group-title { margin: 0; color: var(--text); font-size: clamp(27px, 3vw, 38px); letter-spacing: -.035em; }
.help__answer {
  display: grid; grid-template-columns: minmax(190px, .75fr) minmax(300px, 1.25fr);
  gap: clamp(28px, 5vw, 72px); padding: 30px 0; border-bottom: 1px solid var(--hair);
}
.help__answer h3 {
  margin: 0; color: var(--text); font-family: var(--f-display);
  font-size: 15px; line-height: 1.45; letter-spacing: -.01em;
}
.help__answer p { margin: 0; color: var(--muted); font-size: 15px; line-height: 1.7; }
.help__answer-link {
  grid-column: 2; justify-self: start; margin-top: -18px;
  color: var(--coral); font-size: 13px; font-weight: 750;
}
.help :is(a):focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; }

@media (max-width: 860px) {
  .help__layout { grid-template-columns: 1fr; gap: 58px; }
  .help__rail { position: static; display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 20px; }
  .help__rail-label, .help__feedback { grid-column: 1 / -1; }
  .help__feedback { max-width: 340px; }
}
@media (max-width: 620px) {
  .help {
    padding: 58px var(--page-pad-m) 80px;
  }
  .help__hero { padding-bottom: 58px; }
  .help__title { font-size: clamp(40px, 12vw, 52px); }
  .help__rail { grid-template-columns: 1fr; }
  .help__group { padding-bottom: 54px; }
  .help__group-head { grid-template-columns: 44px 1fr; }
  .help__answer { grid-template-columns: 1fr; gap: 12px; padding: 24px 0; }
  .help__answer-link { grid-column: 1; margin-top: 0; }
}
