/* ============================================================================
   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                      */
  --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;

  --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)
  :is(input, textarea, select):focus-visible {
  box-shadow: none;
  outline: none;
}
:is(.field, .hl-search, .filterbar__search, .tut-field, .gnav-sheet-search):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; }
.btn-outline--pill{ font-size: 13.5px; padding: 13px 30px; 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); }

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

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

/* ---- 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-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: with the search box and
   "By Topic" gone the desktop bar wants 911px (125px logo + divider + switcher
   + 4 links at the designer's 20px gap + Log in + CTA + 52px padding), so the
   swap at 940px leaves 29px of honest headroom. The old ladder (1160px puck,
   swap at 859px) began overlapping at 881px and served a bar that was 79%
   empty one pixel later. Panels live inside their bars now, so hiding a bar
   hides its menus — no !important escort required. */
@media (max-width: 939px) {
  .gnav-bar   { display: none; }
  .gnav-bar-m { display: flex; }
}


/* ==========================================================================
   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);
}
.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);
}
.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;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.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; }
  /* 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;
}
.work-rail { align-self: start; position: sticky; top: 20px; }
/* 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; }

/* ---- 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; }
/* 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; }
.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  — hero · pillars · plans · org · returning band · paths
   ========================================================================== */

.hero { background: var(--ink); color: #fff; overflow: hidden; }
.hero__inner {
  max-width: var(--page-max); margin: 0 auto; padding: 80px var(--page-pad) 92px;
  display: grid; grid-template-columns: 1fr .9fr; gap: 36px; align-items: center;
}
.hero__h1 {
  font-size: 62px; font-weight: 800; color: #fff; margin: 16px 0 0;
  line-height: 1.02; letter-spacing: var(--ls-display); max-width: 14ch;
}
.hero__lead { font-size: 18px; color: var(--on-ink-2); max-width: 600px;
              margin: 22px 0 0; line-height: var(--lh-body); }
.hero__cta  { display: flex; gap: 14px; margin-top: 30px; flex-wrap: wrap; align-items: center; }
.hero__meta { font-size: 12.5px; color: var(--on-ink-3); margin-top: 18px; }
.hero__meta a { color: var(--on-ink-accent); cursor: pointer; }

.hero__covers { display: flex; align-items: center; justify-content: flex-end; gap: 14px; }
.hero__cover  { border-radius: 4px; box-shadow: 0 18px 40px rgba(0,0,0,.4); flex: 0 0 auto; }
.hero__cover--1 { height: 250px; transform: translateY(-16px); }
.hero__cover--2 { height: 290px; transform: translateY(18px); }
.hero__cover--3 { height: 240px; transform: translateY(-26px); }

/* ---- five pillars ---- */
.pillars__head { text-align: center; max-width: 640px; margin: 0 auto 40px; }
.pillars__h2   { font-size: 34px; margin: 12px 0 0; line-height: 1.1; }
.pillars__lead { font-size: 16px; color: var(--muted); margin: 14px 0 0; line-height: var(--lh-body); }
.pillars__grid {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: 16px;
  list-style: none; margin: 0; padding: 0;
}
.pillar {
  background: var(--surface); border: 1px solid var(--hair); border-radius: var(--r-lg);
  padding: 22px; display: flex; flex-direction: column; gap: 12px;
}
.pillar__title { font-family: var(--f-display); font-weight: 700; font-size: 15.5px; color: var(--text); }
.pillar__count { font-size: 12.5px; font-weight: 600; color: var(--teal); margin: 2px 0 0; }
.pillar__desc  { font-size: 13.5px; color: var(--muted); line-height: 1.5; margin: 0; }
.pillars__foot { text-align: center; margin-top: 22px; font-size: 13.5px; color: var(--faint); }

/* ---- plans ---- */
.plans {
  background: var(--surface);
  border-top: 1px solid var(--hair); border-bottom: 1px solid var(--hair);
  scroll-margin-top: 70px;
}
.plans__head { text-align: center; margin-bottom: 32px; }
.plans__h2   { font-size: 34px; }
.plans__head .seg { margin-top: 18px; }
.plans__grid {
  display: grid; grid-template-columns: 1.15fr .85fr; gap: 22px;
  max-width: 960px; margin: 0 auto; align-items: start;
}
.plancard {
  background: var(--paper); border: 2px solid var(--ink); border-radius: var(--r-xl);
  padding: 32px; position: relative; box-shadow: 0 20px 50px rgba(12,12,34,.12);
}
.plancard__price { display: flex; align-items: baseline; gap: 8px; margin: 14px 0 0; flex-wrap: wrap; }
.plancard__amount {
  font-family: var(--f-display); font-weight: 800; font-size: 44px;
  color: var(--text); letter-spacing: var(--ls-display);
}
.plancard__unit { font-size: 15px; color: var(--muted); }
.plancard .seg--sm { margin-top: 14px; }
.plancard__cta  { margin-top: 22px; }
.plancard__note { font-size: 12px; color: var(--faint); text-align: center; margin: 10px 0 0; }
.plancard__inclhead {
  font-family: var(--f-display); font-weight: 700; font-size: 12.5px;
  color: var(--text); margin: 0 0 12px;
}

.plans__side { display: flex; flex-direction: column; gap: 16px; }
.freecard__title { font-family: var(--f-display); font-weight: 700; font-size: 16px; color: var(--text); }
.freecard__body  { font-size: 13.5px; color: var(--muted); line-height: 1.5; margin: 8px 0 14px; }
.cccard {
  background: linear-gradient(135deg, rgba(15,159,190,.09), rgba(56,200,155,.09));
  border: 1px solid var(--hair); border-radius: 18px; padding: 24px;
}
.cccard__title { font-family: var(--f-display); font-weight: 700; font-size: 16px;
                 color: var(--text); margin-top: 8px; }
.cccard__body  { font-size: 13.5px; color: var(--muted); line-height: 1.5; margin: 8px 0 14px; }
.cccard__link  { display: inline-flex; align-items: center; gap: 7px;
                 font-family: var(--f-display); font-weight: 600; font-size: 14px;
                 color: var(--coral); cursor: pointer; }

.orgcard {
  max-width: 820px; margin: 0 auto; background: var(--paper);
  border: 1px solid var(--hair); border-radius: var(--r-xl); padding: 34px;
  box-shadow: 0 20px 50px rgba(12,12,34,.10);
}
.orgcard__grid { display: grid; grid-template-columns: 1.2fr .8fr; gap: 28px; align-items: center; }
.orgcard__h3   { font-size: 24px; margin: 12px 0 0; }
.orgcard__body { font-size: 14.5px; color: var(--muted); line-height: var(--lh-body); margin: 12px 0 0; }
.orgcard__cta  { display: flex; gap: 12px; margin-top: 22px; flex-wrap: wrap; }

/* ---- returning-customer band ---- */
.retband {
  background: var(--ink); border-radius: var(--r-xl); padding: 40px; color: #fff;
  display: grid; grid-template-columns: 1.3fr .7fr; gap: 28px; align-items: center;
}
.retband__h2   { font-size: 30px; color: #fff; margin: 12px 0 0; line-height: 1.12; }
.retband__body { font-size: 15px; color: var(--on-ink-2); line-height: var(--lh-body); margin: 14px 0 0; }
.retband .btn-light { margin-top: 20px; }
.retband__covers { display: flex; gap: 12px; justify-content: center; }
.retband__covers img { height: 150px; border-radius: 4px; box-shadow: 0 16px 34px rgba(0,0,0,.4); }

/* ---- secondary paths ---- */
.secondary { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.pathtile {
  border: 1px solid var(--hair); border-radius: var(--r-lg); padding: 22px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.pathtile:hover { box-shadow: var(--sh-sm); }
.pathtile__title { font-family: var(--f-display); font-weight: 700; font-size: 15px; color: var(--text); }
.pathtile__sub   { font-size: 13px; color: var(--muted); margin: 3px 0 0; }
.pathtile__arrow { color: var(--coral); font-weight: 600; font-size: 20px; flex: 0 0 auto; }

@media (max-width: 859px) {
  .hero__inner { padding: 46px 24px 54px; grid-template-columns: 1fr; }
  .hero__h1    { font-size: 40px; }
  .hero__lead  { font-size: 16px; }
  .hero__covers { display: none; }
  .pillars__h2, .plans__h2 { font-size: 26px; }
  .pillars__grid { grid-template-columns: 1fr 1fr; }
  .plans__grid, .orgcard__grid { grid-template-columns: 1fr; }
  .retband { grid-template-columns: 1fr; padding: 28px; }
  .retband__h2 { font-size: 24px; }
  .retband__covers img { height: 120px; }
  .secondary { grid-template-columns: 1fr; }
}
@media (max-width: 1120px) and (min-width: 860px) {
  .pillars__grid { grid-template-columns: repeat(3, 1fr); }
}


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


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

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


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

/* 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;
  background: var(--paper); border: 1px solid var(--hair); border-radius: var(--r-md);
  box-shadow: var(--sh-menu); padding: 6px;
}
.ml-sort__opt {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 12px; 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: flex; flex-direction: column; gap: 12px; }
.ml-row  { display: flex; gap: 16px; align-items: center;
           background: var(--paper); border: 1px solid var(--hair);
           border-radius: 15px; padding: 14px 16px; }
.ml-row__cover {
  height: 64px; object-fit: cover; border-radius: 4px; flex: 0 0 auto;
  box-shadow: 0 5px 14px rgba(12,12,34,.2);
}
.ml-row__cover--portrait { width: 44px; }
.ml-row__cover--square   { width: 64px; }
.ml-row__thumb {
  width: 96px; height: 60px; border-radius: var(--r-ctl); flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg,#123c4a,#1d6b6b);
}
.ml-row__play {
  width: 26px; height: 26px; border-radius: var(--r-pill); background: rgba(10,10,20,.5);
  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 {
  height: 64px; border-radius: 4px; flex: 0 0 auto;
  box-shadow: 0 5px 14px rgba(12,12,34,.12);
}
.ml-row__ph::before { left: 5px; top: 0; bottom: 0; width: 1.5px; }
.ml-row__ph--portrait { width: 44px; }
.ml-row__ph--square   { width: 64px; }
.ml-row__body  { flex: 1; min-width: 0; }
.ml-row__tags  { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ml-row__title {
  font-family: var(--f-display); font-weight: 700; font-size: 15px; color: var(--text);
  margin: 7px 0 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ml-row__by   { font-size: 12.5px; color: var(--muted); margin: 1px 0 0; }
.ml-row__prog { display: flex; align-items: center; gap: 11px; margin-top: 9px; }
.ml-row__prog .bar { flex: 1; max-width: 280px; }
.ml-row__pos  { font-size: 12px; color: var(--muted); white-space: nowrap; }
.ml-row__aside{ display: flex; flex-direction: column; align-items: flex-end;
                gap: 9px; flex: 0 0 auto; }
/* format pills: filled = format you use / can access, outline = present but unused */
.ml-fmts { display: flex; gap: 5px; }
.ml-fmt  {
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted); background: transparent;
  border: 1px solid var(--hair); border-radius: var(--r-cover); padding: 2px 7px;
}
.ml-fmt.is-used { color: #fff; background: var(--teal); border-color: var(--teal); }

/* ---- 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; cursor: pointer; }
.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;
}
.ml-tile__well--square { aspect-ratio: 1/1; }
.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; }

/* ---- 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-row { flex-wrap: wrap; }
  .ml-row__aside { flex-direction: row; align-items: center; width: 100%;
                   justify-content: space-between; }
}
/* 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.
   ========================================================================== */

.lp { max-width: 860px; margin: 0 auto; padding: 40px var(--page-pad) 60px; background: var(--bg-app); }

.lp-hero { background: var(--ink); border-radius: var(--r-xl); padding: 34px;
           color: #fff; position: relative; overflow: hidden; }
.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: 34px; color: #fff; margin: 14px 0 0; line-height: 1.08; max-width: 16ch; }
.lp-hero p  { font-size: 15px; color: #c7ccda; max-width: 560px; margin: 14px 0 0;
              line-height: var(--lh-body); }
.lp-hero__actions { display: flex; align-items: center; gap: 20px; margin-top: 22px; flex-wrap: wrap; }
.lp-hero__prog { display: flex; align-items: center; gap: 12px; }
.lp-hero__prog .bar { width: 180px; flex: 0 0 auto; }
.lp-hero__meta { font-family: var(--f-display); font-weight: 600; font-size: 13px; 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-steps { list-style: none; margin: 30px 0 0; padding: 0; }
.lp-step  { display: flex; gap: 18px; }
.lp-step__rail { display: flex; flex-direction: column; align-items: center; flex: 0 0 auto; }
.lp-step__dot {
  width: 34px; height: 34px; border-radius: var(--r-pill); flex: 0 0 auto; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--f-display); font-weight: 700; font-size: 13px;
  background: var(--paper); border: 2px solid var(--hair); color: var(--muted);
}
.lp-step__dot.is-done    { background: var(--green); border-color: var(--green); color: #fff; }
.lp-step__dot.is-current { background: var(--grad); border-color: transparent; color: var(--on-grad); }
.lp-step__line { width: 2px; flex: 1; min-height: 26px; background: var(--hair); }
.lp-step:last-child .lp-step__line { display: none; }

.lp-step__wrap { flex: 1; min-width: 0; padding-bottom: 16px; }
.lp-step__card { display: flex; align-items: center; gap: 15px;
                 background: var(--paper); border: 1px solid var(--hair);
                 border-radius: 15px; padding: 16px 18px; }
.lp-step--current .lp-step__card {
  border: 2px solid var(--teal); box-shadow: 0 12px 30px rgba(15,159,190,.16);
}
.lp-step__card img { width: 44px; height: 64px; object-fit: cover; border-radius: 4px;
                     flex: 0 0 auto; box-shadow: 0 4px 12px rgba(12,12,34,.2); }
.lp-step__thumb { width: 80px; height: 52px; border-radius: 7px; flex: 0 0 auto;
                  display: flex; align-items: center; justify-content: center;
                  background: linear-gradient(135deg,#123c4a,#1d6b6b); }
.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  { flex: 1; 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: 700; font-size: 14.5px;
                  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__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 {
  position: relative; width: 100%; height: 100%; overflow: hidden;
  background: var(--rbg); color: var(--rtext);
  font-family: var(--f-read);
  -webkit-font-smoothing: antialiased;

  --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;
}
.reader * { box-sizing: border-box; }

@media (max-width: 700px) {
  .reader {
    --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;
  }
}

@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); max-width: 92%;
  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; }
.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; }

.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); }
.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 · orient: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) · read-along (immersion)
   ========================================================================== */

.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: 290px;
  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__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; }
.rd-dict__links{ 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;
}
.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__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;
  padding: var(--audio-pad); text-align: center;
}
.rd-audio__art {
  width: var(--audio-art); height: var(--audio-art);
  border-radius: 14px; object-fit: cover; box-shadow: 0 26px 60px rgba(0,0,0,.4);
}
.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; }
.rd-audio__track { height: 5px; background: var(--rline); border-radius: var(--r-sm); overflow: hidden; }
.rd-audio__fill  { height: 100%; background: var(--raccent); }
.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; }
.rd-skip { display: flex; flex-direction: column; align-items: center; gap: 3px;
           color: var(--ricon); cursor: pointer; background: none; border: 0; padding: 0; }
.rd-skip span { font-family: var(--f-ui); font-size: 9px; 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; gap: 7px;
  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 {
  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 — whispersync · 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; }
.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__opt.is-rec { border: 1.5px solid var(--raccent); background: var(--rbg); }
.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__rec { position: absolute; top: -9px; left: 50%; transform: translateX(-50%);
              background: var(--raccent); color: var(--r-on-accent, #04222a);
              font-size: 8.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
              padding: 2px 9px; border-radius: var(--r-pill); white-space: nowrap; }
.rd-ws__foot { font-size: 12px; color: var(--rfaint); text-align: center; margin-top: 16px; }

.rd-about__top   { display: flex; gap: 22px; }
.rd-about__cover { width: 104px; 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); }
.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: 14px; }

.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;
}
/* 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; }
.rd.is-revealed .rd__bar { opacity: 1; visibility: visible; pointer-events: auto;
                           animation: rdFade .3s ease; }

.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); }

.rd__back {
  display: inline-flex; align-items: center; gap: 6px; color: var(--ricon);
  cursor: pointer; font-size: 13px; font-weight: 600; text-decoration: none;
  flex: 0 0 auto;
}
.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; background: none; border: 0; padding: 0;
  color: inherit; font: inherit;
}
.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; }
.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; }
.rd__page { width: 92px; display: flex; justify-content: flex-end; gap: 14px; color: var(--ricon); }

/* ---- the reading surface ---- */
.rd__surface { position: absolute; inset: 0; overflow: hidden; }
.rd__scroller {
  position: absolute; inset: 0; overflow-y: auto; overflow-x: hidden;
  padding: var(--rd-pad, 88px 7vw);
  scroll-behavior: auto;
}
.rd.is-paged .rd__scroller { overflow: hidden; }
.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; }

/* ---- 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 { 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. */
.rd[data-hc="on"] .rd__sw { background: #767676; outline: 1px solid var(--rline); }
.rd[data-hc="on"] .rd__sw[aria-checked="true"] { background: var(--raccent); }
.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; }
.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; }
.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; }
.rd__rc[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--rsheet), 0 0 0 4px var(--raccent); }
/* orientation lock is a mobile affordance; the sheet only shows it there */
.rd__a11y-row--mobile { display: none; }
@media (max-width: 700px) { .rd__a11y-row--mobile { display: flex; } }

/* 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-along bar (Reader Frame's immersion bar) ---- */
.rd__ttsbar {
  position: absolute; left: 50%; bottom: 84px; transform: translateX(-50%);
  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 { bottom: 70px; 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;
}
.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 {
  position: absolute; top: 10px; right: 12px; width: 26px; height: 26px;
  border: 0; border-radius: 999px; background: transparent; color: var(--rmuted);
  font-size: 17px; line-height: 1; cursor: pointer;
}
.rd__note-del:hover { background: var(--rline); color: var(--rtext); }
.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;
  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;
}
.rd__selmenu.is-open { display: flex; }
.rd__selmenu button {
  cursor: pointer; background: none; border: 0; color: var(--rtext);
  font: inherit; font-size: 12.5px; padding: 7px 11px; border-radius: 8px;
}
.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) {
  .rd__top, .rd__bot { padding: 0 16px; }
  .rd__top { height: 52px; }
  .rd__bot { height: 58px; }
  .rd__clock, .rd__page { width: 64px; }
  .rd__scroller { padding: var(--rd-pad-m, 74px 6vw); }
  .rd__tools { gap: 14px; }
  /* 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; }
}

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

/* Status line — resume confirmations and playback errors. */
.rd-audio__msg {
  margin: 16px 0 0; min-height: 1em;
  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(80vh, 720px); 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 {
  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); }
.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__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; }

/* the A-Z author directory at /library/authors */
.adir__count { font-size: 14px; color: var(--muted); margin: 8px 0 0; }
.adir__group { margin-top: 26px; }
.adir__letter {
  font-size: 13px; font-weight: 700; color: var(--faint);
  letter-spacing: var(--ls-tag); margin: 0 0 6px;
  border-bottom: 1px solid var(--hair); padding-bottom: 6px;
}
.adir__list { list-style: none; margin: 0; padding: 0; }
.adir__row {
  display: flex; align-items: baseline; gap: 12px; padding: 7px 0;
  font-size: 14.5px;
}
.adir__name { font-weight: 600; color: var(--text); white-space: nowrap; }
.adir__name:hover { color: var(--teal); text-decoration: underline; }
.adir__org {
  color: var(--muted); font-size: 13px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.adir__n { margin-left: auto; color: var(--faint); font-size: 12.5px; white-space: nowrap; }
