/* ============================================================================
 * MYSTRIX READER — the web reader's design system.
 *
 * IMP-0619. Built from docs/design/MYSTRIX_DESIGN_LANGUAGE.md; the palette, the
 * three type roles, the 12/16px radius and the forking-rule signature below are
 * that brief's decisions, not new ones. The component shapes ARE new — the
 * brief explicitly leaves them to each dependent improvement ("Concrete
 * component shapes ... are each dependent improvement's own job to design using
 * these tokens").
 *
 * WHY THIS FILE EXISTS
 * IMP-0619's complaint, in the code: welcome introduced a bespoke serif hero,
 * glass surfaces and 20 gradients; discovery drew cards one way and worlds drew
 * them another off legacy fallback token names; the player alone carried five
 * font-family stacks and its own colour literals; pages.css and
 * creator-profile.css each defined an overlapping profile-card system. Four
 * routes, four products. root.css named `--text-muted` and gave it a pink, and
 * carried five "accent" colours whose only job was that a default was needed.
 * This file is the one place those decisions now live.
 *
 * DESIGN DIRECTION — AND HOW IT DIFFERS FROM THE STUDIO
 * The governing metaphor is an illuminated manuscript read in low light. The
 * creator studio (IMP-0626, creator/app/static/css/studio.css) is where that
 * manuscript is AUTHORED: it is dense (13px base, 32px controls), it is a
 * multi-pane workspace, and its signature is the UNFORKED margin rule down each
 * panel edge. This file is where the manuscript is READ, and the brief is
 * explicit that these are "deliberately DIFFERENT densities for different jobs":
 *
 *   - Density is generous. Base UI size is 16px, the canonical control is 40px
 *     tall, and the page is a single focal column, not a workspace.
 *   - The READING SERIF is the lead role here, not a borrowed preview font.
 *     Source Serif 4 sets every word of story prose; Inter is demoted to chrome.
 *   - The signature is the FORKING RULE (§8): the trunk line that splits at a
 *     choice. The studio's margin rule deliberately never forks; this is where
 *     it does. It is the one place the product spends motion, so every state
 *     component here (§7) is quiet by construction.
 *
 * SECTIONS
 *   1. Fonts (self-hosted)      6. Controls: buttons, fields, chips, badges
 *   2. Tokens                   7. State: empty, loading, skeleton
 *   3. Base / type roles        8. THE FORKING RULE — the signature
 *   4. Page + stage layout      9. Prose: narration, dialogue, recap
 *   5. Cards, panels, hero     10. Utilities
 * ==========================================================================*/


/* ---------------------------------------------------------------------------
 * 1. FONTS — self-hosted variable woff2, script-subsetted.
 *
 * Per the brief these are self-hosted rather than pulled from a third-party
 * CDN, following the precedent BUG-1627 set on this very service (the session
 * player is the authenticated reader and used to load an unpinned CDN script).
 *
 * These files are a COPY of the ones creator/app/static/fonts/ carries for
 * IMP-0626, not a second download of a different cut. main and creator are
 * separate origins — mystrix.ink and creator.mystrix.ink — so a font referenced
 * across them would need CORS on the other vhost and would still be a second
 * connection and a second cache entry for the reader. A copy inside this
 * service's own static tree is the cheaper and simpler answer.
 *
 * Source Serif 4 is new here: the studio only ever needed a fallback stack for
 * its preview pane, because the reading-serif role belongs to this surface.
 * Its italic is shipped too — story prose uses emphasis, and a synthesised
 * oblique of a reading serif is exactly the tell the brief is trying to avoid.
 *
 * Each face is split by unicode-range, so a reader in a Latin locale downloads
 * only the Latin subset. Scripts these faces do not cover (Arabic, Bengali,
 * Hindi, Marathi, Urdu, Chinese, Japanese — 7 of the product's 22 UI locales)
 * fall through to the system stack, which is correct: no glyph is faked.
 * Licence text for all three ships alongside them (OFL-*.txt).
 * ------------------------------------------------------------------------ */

/* --- Source Serif 4: THE READING FACE. Story prose, and nothing else. --- */
@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('../fonts/source-serif-4-var-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('../fonts/source-serif-4-var-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('../fonts/source-serif-4-var-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('../fonts/source-serif-4-var-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F,
    U+FE2E-FE2F;
}
@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('../fonts/source-serif-4-var-greek.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1,
    U+03A3-03FF;
}
@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('../fonts/source-serif-4-var-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
    U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329,
    U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Source Serif 4';
  font-style: italic;
  font-weight: 200 900;
  font-display: swap;
  src: url('../fonts/source-serif-4-var-latin-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Source Serif 4';
  font-style: italic;
  font-weight: 200 900;
  font-display: swap;
  src: url('../fonts/source-serif-4-var-latin-ext-italic.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- Fraunces: the display face. Titles and choice labels, used with
   restraint — large sizes and generous tracking, never body copy. --- */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/fraunces-var-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/fraunces-var-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/fraunces-var-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
    U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329,
    U+1EA0-1EF9, U+20AB;
}

/* --- Inter: the UI/utility face. Chrome, controls, data, timestamps. --- */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/inter-var-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/inter-var-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/inter-var-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/inter-var-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F,
    U+FE2E-FE2F;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/inter-var-greek.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1,
    U+03A3-03FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/inter-var-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
    U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329,
    U+1EA0-1EF9, U+20AB;
}


/* ---------------------------------------------------------------------------
 * 2. TOKENS
 *
 * The brief's seven colours are declared in root.css under the brief's own
 * names (--ink, --parchment, --amethyst, --amethyst-deep, --ember, --verdigris,
 * --error) because root.css is this service's declared single source of truth
 * and ~29k lines of not-yet-converted reader CSS read its legacy names. Those
 * legacy names are now aliases of the seven, so an unconverted page is already
 * disciplined even before it is redrawn. Everything derived — surfaces, rules,
 * type scale, space, motion — lives here under --rd-*.
 * ------------------------------------------------------------------------ */

:root {
  /* --- Surfaces. Every step is a violet-cast lift off --ink, never a neutral
     gray: the brief calls for "near-black with a violet cast". The reader gets
     a shallower stack than the studio because it has far fewer simultaneous
     panes to separate — depth here would be noise at reading distance. */
  --rd-surface: #141119;         /* the leaf: cards, panels */
  --rd-surface-raised: #1b1725;  /* hover, nested, sticky chrome */
  --rd-veil: #0e0c14;            /* recessed: inputs, cover wells */

  /* Rules (borders). "Rule" is the manuscript word for a ruled line, and the
     forking rule is this surface's signature — so borders share its vocabulary
     rather than being called "border-color-2". */
  --rd-rule: #272033;
  --rd-rule-soft: #1c1826;
  --rd-rule-strong: #372e4c;

  /* Text. Contrast floors verified against every surface above:
     text 14.9:1, muted 8.0:1, dim 5.8:1, faint 4.9:1. */
  --rd-text: #efeaf7;
  --rd-text-muted: #b3abc7;
  --rd-text-dim: #9990b0;
  --rd-text-faint: #8b82a4;
  --rd-on-accent: var(--ink);    /* type sitting ON amethyst/ember/verdigris */

  /* Accent channels. Declared once in root.css beside the seven hexes they
     belong to; named here so a --rd-* tint never has to reach across files
     for a literal. root.css's 130 --tint-* aliases resolve through the same
     channel tokens, which is what keeps a tint from drifting off its base. */
  --rd-amethyst-rgb: var(--amethyst-rgb);
  --rd-ember-rgb: var(--ember-rgb);
  --rd-verdigris-rgb: var(--verdigris-rgb);
  --rd-error-rgb: var(--error-rgb);
  --rd-ink-rgb: var(--ink-rgb);
  --rd-parchment-rgb: var(--parchment-rgb);

  /* Two alphas per accent — a wash for surfaces, a line for borders — plus a
     glow for focus. Nothing else. This is what stops the grab-bag reappearing:
     there is no third value to reach for. */
  --rd-amethyst-wash: rgba(var(--rd-amethyst-rgb), 0.10);
  --rd-amethyst-wash-strong: rgba(var(--rd-amethyst-rgb), 0.18);
  --rd-amethyst-line: rgba(var(--rd-amethyst-rgb), 0.32);
  --rd-amethyst-glow: rgba(var(--rd-amethyst-rgb), 0.22);
  --rd-ember-wash: rgba(var(--rd-ember-rgb), 0.10);
  --rd-ember-line: rgba(var(--rd-ember-rgb), 0.30);
  --rd-verdigris-wash: rgba(var(--rd-verdigris-rgb), 0.10);
  --rd-verdigris-line: rgba(var(--rd-verdigris-rgb), 0.30);
  --rd-error-wash: rgba(var(--rd-error-rgb), 0.10);
  --rd-error-line: rgba(var(--rd-error-rgb), 0.32);
  --rd-scrim: rgba(var(--rd-ink-rgb), 0.72);
  --rd-scrim-strong: rgba(var(--rd-ink-rgb), 0.92);

  /* --- Type -------------------------------------------------------------- */
  --rd-font-display: 'Fraunces', 'Iowan Old Style', Georgia, serif;
  --rd-font-reading: 'Source Serif 4', 'Iowan Old Style', Georgia, serif;
  --rd-font-ui: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    'Helvetica Neue', sans-serif;
  --rd-font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas,
    monospace;

  /* Type scale. The base is 16px, not the studio's 13px: this is read, not
     operated. Display sizes are fluid because a story title is the page's
     one hero moment and has to hold a 400px phone and a 1600px desktop. */
  --rd-text-xs: 0.75rem;      /* 12px — timestamps, counts */
  --rd-text-sm: 0.8125rem;    /* 13px — captions, meta */
  --rd-text-md: 0.875rem;     /* 14px — dense labels */
  --rd-text-base: 1rem;       /* 16px — the reader's workhorse UI size */
  --rd-text-lg: 1.0625rem;    /* 17px — lead UI copy */

  /* Reading role. --rd-prose is the size a scene is set at; the reader can
     scale it from the session's text-size setting by overriding this one
     custom property rather than by re-declaring font sizes per block. */
  --rd-prose: 1.125rem;       /* 18px */
  --rd-prose-sm: 1.0625rem;
  --rd-prose-lg: 1.25rem;

  --rd-display-xs: 1.0625rem; /* Fraunces: choice labels, card titles */
  --rd-display-sm: 1.25rem;   /* Fraunces: panel + section titles */
  --rd-display-md: clamp(1.5rem, 1.15rem + 1.4dvw, 2rem);  /* page titles */
  --rd-display-lg: clamp(2rem, 1.3rem + 3dvw, 3.25rem);    /* story hero */

  --rd-leading-tight: 1.15;
  --rd-leading-ui: 1.5;
  --rd-leading-prose: 1.75;   /* a page of narrative, not a paragraph of UI */
  --rd-tracking-display: -0.02em;
  --rd-tracking-ui: -0.006em;
  --rd-tracking-eyebrow: 0.08em;

  --rd-weight-normal: 400;
  --rd-weight-medium: 500;
  --rd-weight-semi: 600;
  --rd-weight-bold: 700;

  /* --- Space. 4px grid. The reader starts where the studio ends: its
     smallest routine gap is the studio's mid step, which IS the "generous
     whitespace" the brief asks the reader-facing product for. */
  --rd-space-1: 4px;
  --rd-space-2: 8px;
  --rd-space-3: 12px;
  --rd-space-4: 16px;
  --rd-space-5: 24px;
  --rd-space-6: 32px;
  --rd-space-7: 48px;
  --rd-space-8: 64px;
  --rd-space-9: 96px;

  /* --- Controls. 40px is the reader's canonical target: comfortable with a
     thumb, and 8px taller than the studio's, which is the density difference
     made concrete. */
  --rd-control-h-sm: 32px;
  --rd-control-h: 40px;
  --rd-control-h-lg: 48px;
  --rd-control-pad-x: var(--rd-space-4);

  /* --- Radius. The brief keeps the product's existing 12/16 and says not to
     relitigate them. The smaller steps are for controls nested inside. */
  --rd-radius-xs: 6px;
  --rd-radius-sm: 8px;
  --rd-radius: 12px;
  --rd-radius-lg: 16px;
  --rd-radius-pill: 999px;

  /* --- Composition. One focal column, per the brief's layout principles. */
  --rd-measure: 66ch;         /* prose line length */
  --rd-column: 720px;         /* the reading column */
  --rd-page: 1180px;          /* the widest a reader page ever gets */

  /* --- The forking rule: the reader's signature dimensions (see §8). */
  --rd-rule-w: 2px;           /* the trunk's stroke */
  --rd-fork-gutter: 28px;     /* the margin the trunk runs down */
  --rd-fork-reach: 18px;      /* how far a branch travels off the trunk */
  --rd-fork-radius: 12px;     /* the bend where a branch leaves the trunk */

  /* --- Motion. Everything is fast and small EXCEPT --rd-dur-fork, which is
     the one place the product spends its motion budget. */
  --rd-ease: cubic-bezier(0.2, 0, 0, 1);
  --rd-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --rd-dur-fast: 120ms;
  --rd-dur: 200ms;
  --rd-dur-slow: 340ms;
  --rd-dur-fork: 520ms;

  /* --- Elevation. Low light: shadows are deep and soft, never gray. */
  --rd-shadow-sm: 0 1px 2px rgba(var(--rd-ink-rgb), 0.5);
  --rd-shadow: 0 8px 28px rgba(var(--rd-ink-rgb), 0.55);
  --rd-shadow-lg: 0 24px 64px rgba(var(--rd-ink-rgb), 0.65);
  --rd-focus-ring: 0 0 0 3px var(--rd-amethyst-glow);
}


/* ---------------------------------------------------------------------------
 * 3. BASE / TYPE ROLES
 *
 * main.css:18 and session-runtime.css:5 both set the body font to the system UI
 * stack — the exact stack the brief names as the "tiny system UI" problem.
 * reader.css loads after both and installs the three real roles.
 * ------------------------------------------------------------------------ */

body {
  font-family: var(--rd-font-ui);
  font-size: var(--rd-text-base);
  line-height: var(--rd-leading-ui);
  letter-spacing: var(--rd-tracking-ui);
  font-feature-settings: 'cv05' 1, 'cv08' 1;
  -webkit-font-smoothing: antialiased;
}

/* Display role. Restraint is enforced by scope: Fraunces is reachable only
   through .reader-display and the components below that opt into it. */
.reader-display {
  font-family: var(--rd-font-display);
  font-optical-sizing: auto;
  font-weight: var(--rd-weight-semi);
  letter-spacing: var(--rd-tracking-display);
  line-height: var(--rd-leading-tight);
  color: var(--rd-text);
  margin: 0;
}

/* READING ROLE — the one this surface exists for. Everything a reader is
   actually reading (scene text, dialogue, recap, synopsis, excerpt) is set
   here; nothing else is. */
.reader-prose {
  font-family: var(--rd-font-reading);
  font-size: var(--rd-prose);
  line-height: var(--rd-leading-prose);
  letter-spacing: 0;
  color: var(--rd-text);
  max-width: var(--rd-measure);
  font-variant-numeric: oldstyle-nums;
}
.reader-prose p { margin: 0 0 1em; }
.reader-prose p:last-child { margin-bottom: 0; }
.reader-prose em,
.reader-prose i { font-style: italic; }
.reader-prose strong,
.reader-prose b { font-weight: var(--rd-weight-semi); }
/* Wide variant for a hero synopsis that is not inside the reading column. */
.reader-prose--wide { max-width: 76ch; }
.reader-prose--sm { font-size: var(--rd-prose-sm); }
.reader-prose--muted { color: var(--rd-text-muted); }

/* An eyebrow: the small tracked-out label above a title. Inter, never Fraunces
   — the brief reserves the display face for large sizes. */
.reader-eyebrow {
  font-family: var(--rd-font-ui);
  font-size: var(--rd-text-xs);
  font-weight: var(--rd-weight-semi);
  letter-spacing: var(--rd-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--rd-text-faint);
  margin: 0;
}

.reader-num { font-variant-numeric: tabular-nums; }
.reader-mono { font-family: var(--rd-font-mono); font-size: var(--rd-text-sm); }


/* ---------------------------------------------------------------------------
 * 4. PAGE + STAGE LAYOUT
 *
 * "Generous whitespace and a single clear focal column" (brief, Density). A
 * reader page is one column with an optional aside; it is never a workspace.
 * ------------------------------------------------------------------------ */

.reader-page {
  max-width: var(--rd-page);
  margin-inline: auto;
  padding-inline: var(--rd-space-4);
  padding-block-end: var(--rd-space-8);
}
.reader-page--narrow { max-width: 860px; }

/* Vertical rhythm between page sections. One value, so a reader moving between
   routes never meets a different spacing system. */
.reader-stack { display: flex; flex-direction: column; gap: var(--rd-space-5); }
.reader-stack--roomy { gap: var(--rd-space-6); }
.reader-stack--tight { gap: var(--rd-space-3); }

/* Two-up: main column plus a sticky aside (story detail's CTA rail). */
.reader-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: var(--rd-space-6);
  align-items: start;
}
.reader-split__main { min-width: 0; }
.reader-split__aside {
  display: flex;
  flex-direction: column;
  gap: var(--rd-space-4);
  position: sticky;
  top: var(--rd-space-5);
  min-width: 0;
}
@media (max-width: 900px) {
  .reader-split { grid-template-columns: minmax(0, 1fr); }
  .reader-split__aside { position: static; }
}

/* --- Page header. One system, replacing .browse-intro / .page-header /
   .section-header / .detail-header and the four title sizes between them.

   The short amethyst rule at the inline-start of the underline is where the
   trunk line starts on a reader screen — the same line that forks at a choice
   and that the studio carries, unforked, down every panel edge. -------------*/
.reader-page-header {
  display: flex;
  align-items: flex-end;
  gap: var(--rd-space-5);
  flex-wrap: wrap;
  padding-block: var(--rd-space-6) var(--rd-space-4);
  margin-block-end: var(--rd-space-5);
  border-block-end: 1px solid var(--rd-rule-soft);
  position: relative;
}
.reader-page-header::after {
  content: '';
  position: absolute;
  inset-block-end: -1px;
  inset-inline-start: 0;
  width: 56px;
  height: var(--rd-rule-w);
  background: var(--amethyst);
  border-radius: var(--rd-radius-pill);
}
.reader-page-header__content { flex: 1 1 360px; min-width: 0; }
.reader-page-header__title {
  font-family: var(--rd-font-display);
  font-optical-sizing: auto;
  font-size: var(--rd-display-md);
  font-weight: var(--rd-weight-semi);
  letter-spacing: var(--rd-tracking-display);
  line-height: var(--rd-leading-tight);
  color: var(--rd-text);
  margin: 0;
}
.reader-page-header__subtitle {
  margin: var(--rd-space-2) 0 0;
  font-size: var(--rd-text-lg);
  line-height: var(--rd-leading-ui);
  color: var(--rd-text-muted);
  max-width: 68ch;
}
.reader-page-header__actions {
  display: flex;
  align-items: center;
  gap: var(--rd-space-3);
  flex-wrap: wrap;
}

/* --- Section heading inside a page. --------------------------------------*/
.reader-section-header {
  display: flex;
  align-items: baseline;
  gap: var(--rd-space-3);
  margin-block-end: var(--rd-space-4);
}
.reader-section-header__title {
  font-family: var(--rd-font-display);
  font-optical-sizing: auto;
  font-size: var(--rd-display-sm);
  font-weight: var(--rd-weight-semi);
  letter-spacing: var(--rd-tracking-display);
  line-height: var(--rd-leading-tight);
  color: var(--rd-text);
  margin: 0;
}
.reader-section-header__rule { flex: 1; height: 1px; background: var(--rd-rule-soft); }

/* --- THE STAGE. The live manuscript column: the transcript being read, or
   any single-column run of prose. It carries the trunk of the forking rule
   down its inline-start edge (§8), which is why it, and not .reader-page, is
   what the session transcript uses. --------------------------------------- */
.reader-stage {
  position: relative;
  max-width: var(--rd-column);
  margin-inline: auto;
  padding-inline-start: var(--rd-fork-gutter);
  padding-inline-end: var(--rd-space-2);
}
.reader-stage::before {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: var(--rd-rule-w);
  border-radius: var(--rd-radius-pill);
  /* The trunk fades in and out at the column's ends rather than butting into
     the chrome — a ruled margin on a leaf, not a table border. */
  background: linear-gradient(
    to bottom,
    rgba(var(--rd-amethyst-rgb), 0) 0%,
    var(--rd-amethyst-line) 6%,
    var(--rd-amethyst-line) 94%,
    rgba(var(--rd-amethyst-rgb), 0) 100%
  );
  pointer-events: none;
}
/* A stage with no live choice pending keeps the trunk dimmer still — the line
   only reaches full amethyst where the story is actually branching. */
.reader-stage--quiet::before { opacity: 0.55; }


/* ---------------------------------------------------------------------------
 * 5. CARDS, PANELS, HERO
 *
 * THE canonical card. Discovery drew one card, worlds drew another off legacy
 * fallback token names, the creator profile drew a third, and welcome drew a
 * fourth in glass. One shape now: an ink leaf with a hairline rule, a 3:4 cover
 * well, a Fraunces title and an Inter meta row.
 *
 * The cover is 3:4 (portrait) rather than the studio's 16:9. A story cover is
 * a book jacket; the studio's is a workspace thumbnail. That is the difference
 * between browsing a shelf and managing assets, and it is deliberate.
 * ------------------------------------------------------------------------ */

.reader-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--rd-space-4);
}
.reader-grid--wide { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
@media (max-width: 520px) {
  .reader-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--rd-space-3); }
}

.reader-card,
.story-card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--rd-surface);
  border: 1px solid var(--rd-rule);
  border-radius: var(--rd-radius);
  overflow: hidden;
  color: inherit;
  text-decoration: none;
  transition: border-color var(--rd-dur) var(--rd-ease),
              background-color var(--rd-dur) var(--rd-ease),
              transform var(--rd-dur) var(--rd-ease);
}
.reader-card:hover,
.story-card:hover {
  background: var(--rd-surface-raised);
  border-color: var(--rd-rule-strong);
}
.reader-card:focus-within,
.story-card:focus-within {
  border-color: var(--amethyst);
  box-shadow: var(--rd-focus-ring);
}
/* Selected / active — the same amethyst wash the studio uses, so a reader who
   also creates never learns two "this one" languages. */
.reader-card--active {
  border-color: var(--rd-amethyst-line);
  background: var(--rd-amethyst-wash);
}
/* Locked: gated by credits, subscription or purchase. Ember, not a new hue. */
.reader-card--locked .reader-card__cover::after,
.story-card.credits-locked .story-card-cover::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(var(--rd-ink-rgb), 0.55);
}

.reader-card__cover,
.story-card-cover {
  position: relative;
  display: block;
  aspect-ratio: 3 / 4;
  background: var(--rd-veil);
  background-size: cover;
  background-position: center;
  overflow: hidden;
}
.reader-card__cover img,
.story-card-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* The cover well when there is no artwork. Undecorated by design (§7). */
.reader-card__cover:empty::before,
.reader-card__cover--empty::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg, var(--rd-surface-raised), var(--rd-veil));
}
.reader-card__badges,
.story-card-badges {
  position: absolute;
  inset-block-start: var(--rd-space-2);
  inset-inline-start: var(--rd-space-2);
  display: flex;
  flex-wrap: wrap;
  gap: var(--rd-space-1);
  z-index: 1;
}
.reader-card__body,
.story-card-body {
  display: flex;
  flex-direction: column;
  gap: var(--rd-space-2);
  padding: var(--rd-space-3) var(--rd-space-4) var(--rd-space-4);
  flex: 1;
  min-width: 0;
}
.reader-card__title,
.story-card-title {
  font-family: var(--rd-font-display);
  font-optical-sizing: auto;
  font-size: var(--rd-display-xs);
  font-weight: var(--rd-weight-semi);
  letter-spacing: var(--rd-tracking-display);
  line-height: var(--rd-leading-tight);
  color: var(--rd-text);
  margin: 0;
}
.reader-card__title a { color: inherit; text-decoration: none; }
.reader-card__title a:hover { color: var(--amethyst); }
.reader-card__byline,
.story-card-creator {
  margin: 0;
  font-size: var(--rd-text-sm);
  color: var(--rd-text-faint);
}
.reader-card__byline a { color: var(--rd-text-muted); text-decoration: none; }
.reader-card__byline a:hover { color: var(--amethyst); }
/* A card's blurb is prose the reader reads, so it is set in the reading serif
   at a small size — this is where the discovery grid stops looking like a
   product catalogue and starts looking like a shelf. */
.reader-card__blurb,
.story-card-tagline {
  margin: 0;
  font-family: var(--rd-font-reading);
  font-size: var(--rd-prose-sm);
  line-height: 1.55;
  color: var(--rd-text-muted);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.reader-card__meta,
.story-card-price,
.story-card-rating {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--rd-space-3);
  margin-block-start: auto;
  padding-block-start: var(--rd-space-2);
  font-size: var(--rd-text-xs);
  color: var(--rd-text-faint);
  font-variant-numeric: tabular-nums;
}
.reader-card__meta i { margin-inline-end: var(--rd-space-1); }
.reader-card__actions,
.story-card-actions {
  display: flex;
  align-items: center;
  gap: var(--rd-space-2);
  padding: var(--rd-space-3) var(--rd-space-4);
  border-block-start: 1px solid var(--rd-rule-soft);
}
.reader-card__actions .reader-btn--grow { flex: 1; }
/* Hover-revealed overlay actions. Hidden from pointerless input by opacity
   only — they remain focusable and are revealed on keyboard focus. */
.reader-card__hover,
.story-card-hover-actions {
  position: absolute;
  inset-block-start: var(--rd-space-2);
  inset-inline-end: var(--rd-space-2);
  display: flex;
  gap: var(--rd-space-1);
  opacity: 0;
  transition: opacity var(--rd-dur) var(--rd-ease);
  z-index: 1;
}
.reader-card:hover .reader-card__hover,
.reader-card:focus-within .reader-card__hover,
.story-card:hover .story-card-hover-actions { opacity: 1; }

/* --- LEGACY BRIDGE: the .story-card family ------------------------------
   The improvement's complaint, stated exactly: "token vocabulary, typography,
   card geometry ... change by route". The `.story-card*` names are emitted by
   creator-profile.js, sessions-list.js and home.html, but the rules behind them
   lived in ONE page's stylesheet (discovery.css) — so the same class rendered
   as a different card depending on which route happened to load which file, and
   a rail on the home page was a different object from the identical rail on the
   creator profile. The converted screens emit `.reader-card*`; the aliases in
   the selector lists above hand every not-yet-converted screen the identical
   component, which is what makes this a consolidation rather than a fourth
   parallel system. Drop an alias when its last emitter is converted. ----- */

/* --- Panel: a card that is not in a grid. The story detail's sections, the
   CTA rail, a settings group. Same leaf, no cover. ------------------------ */
.reader-panel {
  background: var(--rd-surface);
  border: 1px solid var(--rd-rule);
  border-radius: var(--rd-radius);
  padding: var(--rd-space-4);
  min-width: 0;
}
.reader-panel--roomy { padding: var(--rd-space-5); }
.reader-panel--flush { padding: 0; }
.reader-panel--quiet { background: transparent; border-color: var(--rd-rule-soft); }
/* Accent variants — strictly the brief's three roles, no others. */
.reader-panel--warn { border-color: var(--rd-ember-line); background: var(--rd-ember-wash); }
.reader-panel--good { border-color: var(--rd-verdigris-line); background: var(--rd-verdigris-wash); }
.reader-panel--danger { border-color: var(--rd-error-line); background: var(--rd-error-wash); }
.reader-panel__title {
  display: flex;
  align-items: center;
  gap: var(--rd-space-2);
  font-family: var(--rd-font-display);
  font-optical-sizing: auto;
  font-size: var(--rd-display-sm);
  font-weight: var(--rd-weight-semi);
  letter-spacing: var(--rd-tracking-display);
  line-height: var(--rd-leading-tight);
  color: var(--rd-text);
  margin: 0 0 var(--rd-space-3);
}
.reader-panel__title > i { font-size: 0.8em; color: var(--amethyst); flex: none; }
.reader-panel__note {
  margin: 0;
  font-size: var(--rd-text-sm);
  line-height: var(--rd-leading-ui);
  color: var(--rd-text-muted);
}

/* --- Hero: the story-detail cover moment. The one place a reader page is
   allowed to be cinematic, and the only place --rd-display-lg is used. ---- */
.reader-hero {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: flex-end;
  min-height: clamp(280px, 42dvh, 460px);
  padding: var(--rd-space-6) var(--rd-space-5) var(--rd-space-5);
  border-radius: var(--rd-radius-lg);
  overflow: hidden;
  background: var(--rd-veil);
}
.reader-hero__image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -2;
}
/* The scrim. A single vertical ink gradient — not the three stacked radial
   gradients each detail/hero surface used to invent for itself. */
.reader-hero__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    to top,
    var(--rd-scrim-strong) 0%,
    var(--rd-scrim) 45%,
    rgba(var(--rd-ink-rgb), 0.25) 100%
  );
}
.reader-hero__content {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--rd-space-2);
  max-width: 40ch;
  min-width: 0;
}
.reader-hero__title {
  font-family: var(--rd-font-display);
  font-optical-sizing: auto;
  font-size: var(--rd-display-lg);
  font-weight: var(--rd-weight-semi);
  letter-spacing: var(--rd-tracking-display);
  line-height: 1.02;
  color: var(--rd-text);
  margin: 0;
  text-wrap: balance;
}
.reader-hero__tagline {
  font-family: var(--rd-font-reading);
  font-size: var(--rd-prose);
  font-style: italic;
  line-height: 1.45;
  color: var(--rd-text-muted);
  margin: 0;
}
.reader-hero__byline {
  font-size: var(--rd-text-sm);
  color: var(--rd-text-muted);
  margin: 0;
}
.reader-hero__byline a { color: var(--amethyst); text-decoration: none; }
.reader-hero__byline a:hover { text-decoration: underline; }
.reader-hero__badges { display: flex; flex-wrap: wrap; gap: var(--rd-space-1); }
/* No artwork: the hero degrades to a quiet parchment-less well with the
   title's initial, rather than a grey box. */
.reader-hero__fallback {
  position: absolute;
  inset: 0;
  z-index: -2;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--rd-font-display);
  font-size: clamp(4rem, 18dvw, 9rem);
  color: var(--rd-rule-strong);
  background: linear-gradient(160deg, var(--rd-surface-raised), var(--rd-veil));
}


/* ---------------------------------------------------------------------------
 * 6. CONTROLS — buttons, fields, chips, badges, toolbar
 * ------------------------------------------------------------------------ */

.reader-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--rd-space-2);
  height: var(--rd-control-h);
  padding-inline: var(--rd-space-4);
  font-family: var(--rd-font-ui);
  font-size: var(--rd-text-base);
  font-weight: var(--rd-weight-medium);
  letter-spacing: var(--rd-tracking-ui);
  line-height: 1;
  white-space: nowrap;
  border: 1px solid var(--rd-rule);
  border-radius: var(--rd-radius-sm);
  background: var(--rd-surface-raised);
  color: var(--rd-text);
  cursor: pointer;
  text-decoration: none;
  transition: background-color var(--rd-dur-fast) var(--rd-ease),
              border-color var(--rd-dur-fast) var(--rd-ease),
              color var(--rd-dur-fast) var(--rd-ease);
}
.reader-btn:hover { background: var(--rd-rule); border-color: var(--rd-rule-strong); color: var(--rd-text); }
.reader-btn:focus-visible { outline: none; box-shadow: var(--rd-focus-ring); }
.reader-btn:disabled,
.reader-btn[disabled] { opacity: 0.45; cursor: not-allowed; }

.reader-btn--primary {
  background: var(--amethyst);
  border-color: var(--amethyst);
  color: var(--rd-on-accent);
  font-weight: var(--rd-weight-semi);
}
.reader-btn--primary:hover {
  background: var(--amethyst-deep);
  border-color: var(--amethyst-deep);
  color: var(--rd-text);
}
.reader-btn--ghost { background: transparent; color: var(--rd-text-muted); }
.reader-btn--ghost:hover { background: var(--rd-surface-raised); color: var(--rd-text); }
.reader-btn--quiet {
  background: transparent;
  border-color: transparent;
  color: var(--rd-text-muted);
  padding-inline: var(--rd-space-3);
}
.reader-btn--quiet:hover { background: var(--rd-surface-raised); color: var(--rd-text); }
.reader-btn--danger { background: transparent; border-color: var(--rd-error-line); color: var(--error); }
.reader-btn--danger:hover { background: var(--rd-error-wash); }
/* Ember, the brief's warmth accent, for a call to action that is a HIGHLIGHT
   rather than the primary path — "you are out of credits, top up". It is
   outlined, not filled, so it never competes with --rd-btn--primary. */
.reader-btn--warm { background: transparent; border-color: var(--rd-ember-line); color: var(--ember); }
.reader-btn--warm:hover { background: var(--rd-ember-wash); }
.reader-btn--lg { height: var(--rd-control-h-lg); font-size: var(--rd-text-lg); padding-inline: var(--rd-space-5); }
.reader-btn--sm { height: var(--rd-control-h-sm); font-size: var(--rd-text-sm); padding-inline: var(--rd-space-3); }
.reader-btn--icon { padding-inline: 0; width: var(--rd-control-h); flex: none; }
.reader-btn--icon.reader-btn--sm { width: var(--rd-control-h-sm); }
.reader-btn--block { width: 100%; }

/* Fields. One primitive, recessed into the page like a ruled blank. */
.reader-field { display: flex; flex-direction: column; gap: var(--rd-space-2); min-width: 0; }
.reader-field__label {
  font-size: var(--rd-text-md);
  font-weight: var(--rd-weight-medium);
  color: var(--rd-text-muted);
  line-height: var(--rd-leading-tight);
}
.reader-field__hint { margin: 0; font-size: var(--rd-text-sm); color: var(--rd-text-faint); }

.reader-input,
.reader-select,
.reader-textarea {
  width: 100%;
  min-width: 0;
  font-family: var(--rd-font-ui);
  font-size: var(--rd-text-base);
  line-height: var(--rd-leading-ui);
  letter-spacing: var(--rd-tracking-ui);
  color: var(--rd-text);
  background: var(--rd-veil);
  border: 1px solid var(--rd-rule);
  border-radius: var(--rd-radius-sm);
  padding: 0 var(--rd-control-pad-x);
  height: var(--rd-control-h);
  appearance: none;
  transition: border-color var(--rd-dur-fast) var(--rd-ease),
              box-shadow var(--rd-dur-fast) var(--rd-ease);
}
.reader-textarea {
  height: auto;
  min-height: 96px;
  padding: var(--rd-space-3) var(--rd-control-pad-x);
  resize: vertical;
  line-height: var(--rd-leading-prose);
}
.reader-select {
  /* Chevron drawn in the rule colour so the control has no second palette. */
  background-image: linear-gradient(45deg, transparent 50%, var(--rd-text-faint) 50%),
                    linear-gradient(135deg, var(--rd-text-faint) 50%, transparent 50%);
  background-position: calc(100% - 18px) calc(50% + 1px), calc(100% - 13px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-inline-end: var(--rd-space-6);
  cursor: pointer;
}
[dir='rtl'] .reader-select {
  background-position: 18px calc(50% + 1px), 13px calc(50% + 1px);
}
.reader-input::placeholder,
.reader-textarea::placeholder { color: var(--rd-text-faint); }
.reader-input:hover,
.reader-select:hover,
.reader-textarea:hover { border-color: var(--rd-rule-strong); }
.reader-input:focus,
.reader-select:focus,
.reader-textarea:focus {
  outline: none;
  border-color: var(--amethyst);
  box-shadow: var(--rd-focus-ring);
}

/* A search field with its glyph inside the well. */
.reader-search { position: relative; display: flex; align-items: center; min-width: 0; flex: 1 1 260px; }
.reader-search > i {
  position: absolute;
  inset-inline-start: var(--rd-space-3);
  color: var(--rd-text-faint);
  pointer-events: none;
  font-size: var(--rd-text-md);
}
.reader-search .reader-input { padding-inline-start: var(--rd-space-6); }
.reader-search__clear {
  position: absolute;
  inset-inline-end: var(--rd-space-2);
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: var(--rd-radius-pill);
  background: transparent;
  color: var(--rd-text-faint);
  cursor: pointer;
}
.reader-search__clear:hover { background: var(--rd-rule); color: var(--rd-text); }

/* Toolbar: the filter/search bar above a grid. */
.reader-toolbar {
  display: flex;
  align-items: center;
  gap: var(--rd-space-3);
  flex-wrap: wrap;
  padding: var(--rd-space-3);
  background: var(--rd-surface);
  border: 1px solid var(--rd-rule);
  border-radius: var(--rd-radius);
  margin-block-end: var(--rd-space-4);
}
.reader-toolbar__group { display: flex; align-items: center; gap: var(--rd-space-2); flex-wrap: wrap; min-width: 0; }
.reader-toolbar__group--grow { flex: 1 1 260px; }
.reader-toolbar .reader-select { width: auto; min-width: 148px; }

/* Chips: tags, active filters, facets. One control for all three. */
.reader-chips { display: flex; flex-wrap: wrap; gap: var(--rd-space-2); min-width: 0; }
.reader-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--rd-space-2);
  height: var(--rd-control-h-sm);
  padding-inline: var(--rd-space-3);
  font-family: var(--rd-font-ui);
  font-size: var(--rd-text-md);
  line-height: 1;
  color: var(--rd-text-muted);
  background: var(--rd-surface);
  border: 1px solid var(--rd-rule);
  border-radius: var(--rd-radius-pill);
  text-decoration: none;
  cursor: pointer;
  max-width: 100%;
  transition: border-color var(--rd-dur-fast) var(--rd-ease),
              color var(--rd-dur-fast) var(--rd-ease),
              background-color var(--rd-dur-fast) var(--rd-ease);
}
.reader-chip:hover { border-color: var(--rd-rule-strong); color: var(--rd-text); }
.reader-chip.is-active,
.reader-chip--active {
  background: var(--rd-amethyst-wash);
  border-color: var(--rd-amethyst-line);
  color: var(--rd-text);
}
.reader-chip button {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: none;
  border-radius: var(--rd-radius-pill);
  background: transparent;
  color: var(--rd-text-faint);
  font-size: var(--rd-text-sm);
  cursor: pointer;
}
.reader-chip button:hover { background: var(--rd-amethyst-wash-strong); color: var(--rd-text); }

/* Badges: rating, access, language, "new". Read-only, never clickable.

   LEGACY BRIDGE: `.badge` was declared once, in discovery.css, and emitted from
   nine places across home, saved, discovery, story detail, the creator profile,
   onboarding and the version-update control — so the badge on a rail card and
   the badge on a story hero were the same object only by accident, and
   onboarding (which does not load discovery.css) rendered it unstyled. The name
   is aliased here rather than chased across nine files: every surface now gets
   the component, and the per-tier `.badge-*` hues in discovery.css still layer
   on top of it. */
.reader-badge,
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--rd-space-1);
  height: 22px;
  padding-inline: var(--rd-space-2);
  font-family: var(--rd-font-ui);
  font-size: var(--rd-text-xs);
  font-weight: var(--rd-weight-medium);
  line-height: 1;
  white-space: nowrap;
  border-radius: var(--rd-radius-pill);
  background: rgba(var(--rd-ink-rgb), 0.72);
  border: 1px solid var(--rd-rule);
  color: var(--rd-text-muted);
  backdrop-filter: blur(6px);
}
.reader-badge--brand { background: var(--rd-amethyst-wash); border-color: var(--rd-amethyst-line); color: var(--amethyst); }
.reader-badge--good { background: var(--rd-verdigris-wash); border-color: var(--rd-verdigris-line); color: var(--verdigris); }
/* Ember is "warmth/highlight" per the brief: an active cinematic scene, a
   "new" marker. It is not a warning colour here. */
.reader-badge--warm { background: var(--rd-ember-wash); border-color: var(--rd-ember-line); color: var(--ember); }
.reader-badge--danger { background: var(--rd-error-wash); border-color: var(--rd-error-line); color: var(--error); }

/* A stat pair (players, rating). Tabular so a column of them lines up. */
.reader-stats { display: flex; gap: var(--rd-space-5); flex-wrap: wrap; }
.reader-stat { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.reader-stat__value {
  font-family: var(--rd-font-display);
  font-optical-sizing: auto;
  font-size: var(--rd-display-sm);
  font-weight: var(--rd-weight-semi);
  font-variant-numeric: tabular-nums;
  color: var(--rd-text);
  line-height: 1;
}
.reader-stat__label {
  font-size: var(--rd-text-xs);
  letter-spacing: var(--rd-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--rd-text-faint);
}

/* Progress: a rule that fills. Same primitive as everything else here. */
.reader-progress { display: flex; align-items: center; gap: var(--rd-space-3); font-size: var(--rd-text-xs); color: var(--rd-text-faint); font-variant-numeric: tabular-nums; }
.reader-progress__track { flex: 1; height: var(--rd-rule-w); background: var(--rd-rule); border-radius: var(--rd-radius-pill); overflow: hidden; }
.reader-progress__fill { height: 100%; background: var(--amethyst); border-radius: var(--rd-radius-pill); transition: width var(--rd-dur-slow) var(--rd-ease); }


/* ---------------------------------------------------------------------------
 * 7. STATE COMPONENTS — empty, loading, skeleton
 *
 * The brief is explicit that state screens are "deliberately UNDECORATED
 * relative to the signature moment, not competing with it". The studio drew
 * that conclusion as a dashed blank leaf; the reader draws it differently on
 * purpose, and the difference is the point:
 *
 *   A reader is not looking at an unwritten page they are about to fill in —
 *   they are looking for something to read and there is nothing here. So the
 *   reader's empty state has NO enclosure at all: no dashed border, no box,
 *   no fill. It is a short centred line of type under a single hairline rule.
 *   It reads as a gap in the shelf rather than a blank form, and it is quieter
 *   than the studio's, which is the correct relationship for a surface whose
 *   whole job is to keep the reader's attention on prose.
 *
 * Replaces .browse-empty (48px glyph, own padding), .session-error's icon
 * block, the four hand-rolled skeleton-card copies in stories.html, and the
 * spin keyframe duplicated in mobile.css and session-runtime.css.
 * ------------------------------------------------------------------------ */

.reader-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: var(--rd-space-3);
  padding: var(--rd-space-7) var(--rd-space-4);
  background: transparent;
  border: 0;
  color: var(--rd-text-muted);
}
/* The hairline: the one mark an empty state gets. */
.reader-empty::before {
  content: '';
  width: 56px;
  height: 1px;
  background: var(--rd-rule-strong);
  margin-block-end: var(--rd-space-1);
}
.reader-empty__icon {
  font-size: 20px;
  line-height: 1;
  /* Colour, not opacity: the app previously mixed 0.4/0.5/0.6/none, so the
     same glyph rendered at four weights on adjacent screens. */
  color: var(--rd-text-faint);
  opacity: 1;
}
.reader-empty__title {
  font-family: var(--rd-font-display);
  font-optical-sizing: auto;
  font-size: var(--rd-display-sm);
  font-weight: var(--rd-weight-semi);
  letter-spacing: var(--rd-tracking-display);
  line-height: var(--rd-leading-tight);
  color: var(--rd-text);
  margin: 0;
}
.reader-empty__body {
  margin: 0;
  font-size: var(--rd-text-base);
  line-height: var(--rd-leading-ui);
  color: var(--rd-text-muted);
  max-width: 48ch;
}
.reader-empty__actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--rd-space-3);
  flex-wrap: wrap;
  margin-block-start: var(--rd-space-2);
}
.reader-empty--page { padding-block: var(--rd-space-9); }
.reader-empty--sm { padding: var(--rd-space-5) var(--rd-space-3); }
.reader-empty--sm .reader-empty__title { font-size: var(--rd-text-lg); }
/* Screens toggle these with .hidden or [hidden]; a display rule here would
   otherwise beat the utility and leave them permanently visible. */
.reader-empty[hidden],
.reader-loading[hidden] { display: none; }

/* --- Loading: THE RULING LINE, not a spinner. The same trunk the forking
   rule uses, being drawn. A 2px line cannot out-compete the signature, which
   is exactly why it is the right loading metaphor for this surface. ------- */
.reader-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--rd-space-3);
  padding: var(--rd-space-6) var(--rd-space-4);
  color: var(--rd-text-muted);
  font-size: var(--rd-text-md);
}
.reader-loading::before {
  content: '';
  display: block;
  width: 112px;
  height: var(--rd-rule-w);
  border-radius: var(--rd-radius-pill);
  background: var(--rd-rule);
  background-image: linear-gradient(90deg, transparent, var(--amethyst), transparent);
  background-repeat: no-repeat;
  background-size: 40% 100%;
  animation: reader-rule-draw 1.4s var(--rd-ease) infinite;
}
.reader-loading--sm { padding: var(--rd-space-4); }
.reader-loading--sm::before { width: 72px; }
.reader-loading-inline {
  display: inline-block;
  vertical-align: middle;
  width: 56px;
  height: var(--rd-rule-w);
  border-radius: var(--rd-radius-pill);
  background: var(--rd-rule);
  background-image: linear-gradient(90deg, transparent, var(--amethyst), transparent);
  background-repeat: no-repeat;
  background-size: 40% 100%;
  animation: reader-rule-draw 1.4s var(--rd-ease) infinite;
}
@keyframes reader-rule-draw {
  0%   { background-position: -60% 0; }
  100% { background-position: 160% 0; }
}

/* Skeleton — one system. The four hand-copied skeleton cards in stories.html
   and the shimmer in discovery.css collapse to this. */
.reader-skeleton {
  background: var(--rd-surface);
  background-image: linear-gradient(90deg, transparent, var(--rd-surface-raised), transparent);
  background-repeat: no-repeat;
  background-size: 50% 100%;
  border-radius: var(--rd-radius-xs);
  animation: reader-rule-draw 1.6s var(--rd-ease) infinite;
}
.reader-skeleton--text { height: 12px; width: 60%; }
.reader-skeleton--title { height: 17px; width: 45%; }
.reader-skeleton--chip { height: var(--rd-control-h-sm); width: 84px; border-radius: var(--rd-radius-pill); }
.reader-skeleton--cover { aspect-ratio: 3 / 4; width: 100%; border-radius: 0; }
.reader-skeleton--block { height: 120px; width: 100%; border-radius: var(--rd-radius-sm); }

/* The brief spends the product's motion budget on the forking rule alone. If
   the OS asks for less motion, the state animations stop entirely and the
   line simply sits at rest. root.css zeroes durations globally; this is
   explicit so the intent survives a refactor of that rule. */
@media (prefers-reduced-motion: reduce) {
  .reader-loading::before,
  .reader-loading-inline,
  .reader-skeleton {
    animation: none;
    background-image: none;
  }
  .reader-loading::before,
  .reader-loading-inline { background: var(--amethyst); }
  .reader-skeleton { background: var(--rd-surface-raised); }
}


/* ===========================================================================
 * 8. THE FORKING RULE — the reader surface's signature element.
 *
 * The brief, verbatim: "A thin vertical --amethyst line runs down the left edge
 * of the active scene/manuscript column. At a choice point, the line visibly
 * SPLITS — animates into two (or more) branches, one per choice, each branch
 * leading to its own choice label set in Fraunces at a small size. Selecting a
 * choice collapses the unchosen branches back into the single trunk line as the
 * story continues."
 *
 * HOW IT IS BUILT
 * The trunk is .reader-stage::before (§4) — it runs the full height of the
 * transcript. The choice panel is fixed to the bottom of the player, but it is
 * centred on the SAME reading column, so a trunk stub at the same inline-start
 * offset reads as one continuous line arriving at the fork:
 *
 *      │            ← .reader-stage::before  (the manuscript column's trunk)
 *      │            ← .reader-fork__trunk    (the stub, in the choice panel)
 *      ├──▸ Follow the light        ┐
 *      ├──▸ Turn back               ├ .reader-fork__branch, one per choice
 *      └──▸ Say nothing             ┘
 *
 * Each branch's connector is one box drawing an inline-start edge and a
 * block-end edge with a rounded corner — a line leaving the trunk and bending
 * out to its label. It is REVEALED by clip-path from the top down, so the eye
 * reads it as the trunk growing down and curving outward, staggered per branch.
 * That is the split; nothing is faked with a background image.
 *
 * On selection: the chosen branch's connector and label stay lit while every
 * other connector runs its reveal backwards and its label fades — the unchosen
 * branches collapse back into the trunk, exactly as the brief describes, and
 * the trunk stub extends past the fork so the story continues on one line.
 *
 * This is the ONLY animated ornament in the reader. §7's state components are
 * deliberately undecorated so this is never in competition.
 * ======================================================================== */

.reader-fork {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--rd-space-2);
  max-width: var(--rd-column);
  margin-inline: auto;
  padding-inline-start: var(--rd-fork-gutter);
  padding-block: var(--rd-space-4) var(--rd-space-3);
  min-width: 0;
}

/* THE TRUNK. One continuous amethyst line down the fork's inline-start edge,
   picking up where the stage's trunk left off and running PAST every take-off
   point — so what the eye sees is a single line that branches, not a stack of
   separate ticks. It fades in at the top so it reads as the same line arriving
   rather than a rule that starts here. */
.reader-fork__trunk {
  position: absolute;
  inset-inline-start: 0;
  inset-block: 0;
  width: var(--rd-rule-w);
  border-radius: var(--rd-radius-pill);
  background: linear-gradient(
    to bottom,
    rgba(var(--rd-amethyst-rgb), 0) 0%,
    var(--amethyst) 18%,
    var(--amethyst) 100%
  );
  pointer-events: none;
}

/* The question being branched on. Prose, so it is set in the reading serif —
   a branch question is part of the story, not a form legend. */
.reader-fork__question {
  margin: 0 0 var(--rd-space-1);
  font-family: var(--rd-font-reading);
  font-size: var(--rd-prose-sm);
  line-height: 1.5;
  color: var(--rd-text);
  max-width: var(--rd-measure);
}
.reader-fork__helper {
  margin: 0 0 var(--rd-space-1);
  font-family: var(--rd-font-ui);
  font-size: var(--rd-text-xs);
  letter-spacing: var(--rd-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--rd-text-faint);
}
.reader-fork__note {
  margin: var(--rd-space-1) 0 0;
  font-size: var(--rd-text-sm);
  color: var(--rd-text-faint);
  max-width: var(--rd-measure);
}

.reader-fork__branches {
  display: flex;
  flex-direction: column;
  gap: var(--rd-space-2);
  margin: 0;
  padding: 0;
  list-style: none;
  min-width: 0;
}

/* A BRANCH. Its connector is an L of two 2px edges with a rounded corner: it
   runs down the trunk's own x from the top of this row, bends, and reaches
   --rd-fork-reach out to the label. Because the trunk above is continuous and
   the connector shares its x, the pair reads as ONE line that splits — the
   connector is the part of the line that leaves.

   The reveal is top-down (clip-path), staggered per branch, so the split is
   drawn rather than appearing. */
.reader-fork__branch {
  position: relative;
  padding-inline-start: var(--rd-fork-reach);
  min-width: 0;
}
.reader-fork__branch::before {
  content: '';
  position: absolute;
  inset-inline-start: calc(-1 * var(--rd-fork-gutter));
  inset-block-start: 0;
  width: calc(var(--rd-fork-gutter) + var(--rd-fork-reach));
  height: 50%;
  min-height: 18px;
  border-inline-start: var(--rd-rule-w) solid var(--amethyst);
  border-block-end: var(--rd-rule-w) solid var(--rd-amethyst-line);
  border-end-start-radius: var(--rd-fork-radius);
  pointer-events: none;
  clip-path: inset(0 0 0 0);
  animation: reader-fork-split var(--rd-dur-fork) var(--rd-ease-out) both;
  transition: border-color var(--rd-dur) var(--rd-ease), opacity var(--rd-dur) var(--rd-ease);
}
/* The stagger. Six is the practical ceiling for an authored branch; a
   pathological seventh and beyond simply share the last delay. */
.reader-fork__branch:nth-child(1)::before { animation-delay: 0ms; }
.reader-fork__branch:nth-child(2)::before { animation-delay: 70ms; }
.reader-fork__branch:nth-child(3)::before { animation-delay: 140ms; }
.reader-fork__branch:nth-child(4)::before { animation-delay: 210ms; }
.reader-fork__branch:nth-child(5)::before { animation-delay: 280ms; }
.reader-fork__branch:nth-child(n + 6)::before { animation-delay: 350ms; }

@keyframes reader-fork-split {
  from { clip-path: inset(0 0 100% 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* The choice itself. NOT a pill-button list — the brief is explicit that "a
   choice is a fork, not a form control". It is a label at the end of a branch:
   Fraunces at a small size, on a leaf that only gains a border once the reader
   is pointing at it. */
.reader-fork__choice {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  min-height: var(--rd-control-h-lg);
  padding: var(--rd-space-2) var(--rd-space-3);
  text-align: start;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--rd-radius-sm);
  color: var(--rd-text);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--rd-dur-fast) var(--rd-ease),
              border-color var(--rd-dur-fast) var(--rd-ease),
              opacity var(--rd-dur) var(--rd-ease);
}
.reader-fork__label {
  font-family: var(--rd-font-display);
  font-optical-sizing: auto;
  font-size: var(--rd-display-xs);
  font-weight: var(--rd-weight-semi);
  letter-spacing: var(--rd-tracking-display);
  line-height: 1.25;
  color: var(--rd-text);
}
.reader-fork__hint {
  font-family: var(--rd-font-ui);
  font-size: var(--rd-text-sm);
  line-height: 1.35;
  color: var(--rd-text-muted);
}

.reader-fork__choice:hover {
  background: var(--rd-amethyst-wash);
  border-color: var(--rd-amethyst-line);
}
/* Hovering anywhere on the branch lights its whole connector, so the line and
   the label it leads to are one object rather than a rule beside a button. */
.reader-fork__branch:hover::before { border-color: var(--amethyst); }
.reader-fork__choice:focus-visible {
  outline: none;
  background: var(--rd-amethyst-wash);
  box-shadow: var(--rd-focus-ring);
}
.reader-fork__branch:focus-within::before { border-color: var(--amethyst); }

/* --- Resolution. The reader has chosen; the fork collapses back to the one
   trunk and the story continues on it. ----------------------------------- */
.reader-fork.is-resolved .reader-fork__trunk {
  height: 100%;
  background: linear-gradient(
    to bottom,
    rgba(var(--rd-amethyst-rgb), 0) 0%,
    var(--amethyst) 18%,
    var(--amethyst) 100%
  );
}
.reader-fork__branch.is-chosen::before { border-color: var(--amethyst); }
.reader-fork__branch.is-chosen .reader-fork__label { color: var(--amethyst); }
/* Unchosen branches run the split backwards and fade — they collapse INTO the
   trunk rather than merely disappearing, which is the whole idea. */
.reader-fork.is-resolved .reader-fork__branch:not(.is-chosen)::before {
  animation: reader-fork-collapse var(--rd-dur-slow) var(--rd-ease) both;
}
.reader-fork.is-resolved .reader-fork__branch:not(.is-chosen) .reader-fork__choice {
  opacity: 0.28;
}
@keyframes reader-fork-collapse {
  from { clip-path: inset(0 0 0 0); }
  to   { clip-path: inset(0 0 100% 0); }
}
.reader-fork__choice:disabled { cursor: default; }
.reader-fork__choice:disabled:hover { background: transparent; border-color: transparent; }

/* A branch waiting on the server. The rule pulses along its own stroke — the
   same ruling-line metaphor §7 uses, at branch scale. */
.reader-fork__branch.is-pending::before { border-color: var(--amethyst); }
.reader-fork__branch.is-pending .reader-fork__label::after {
  content: '';
  display: inline-block;
  vertical-align: middle;
  margin-inline-start: var(--rd-space-2);
  width: 24px;
  height: var(--rd-rule-w);
  border-radius: var(--rd-radius-pill);
  background: var(--rd-rule);
  background-image: linear-gradient(90deg, transparent, var(--amethyst), transparent);
  background-repeat: no-repeat;
  background-size: 45% 100%;
  animation: reader-rule-draw 1.1s var(--rd-ease) infinite;
}

/* Reduced motion: the fork still FORKS — the geometry is the signature, the
   animation is only its entrance. Lines are simply already drawn. */
@media (prefers-reduced-motion: reduce) {
  .reader-fork__branch::before,
  .reader-fork.is-resolved .reader-fork__branch:not(.is-chosen)::before {
    animation: none;
    clip-path: none;
  }
  .reader-fork.is-resolved .reader-fork__branch:not(.is-chosen)::before { opacity: 0.2; }
  .reader-fork__branch.is-pending .reader-fork__label::after {
    animation: none;
    background-image: none;
    background: var(--amethyst);
  }
}

/* Narrow viewports: the gutter tightens but the fork never becomes a stack of
   pills — the branch geometry is the product's signature at every width. */
@media (max-width: 560px) {
  .reader-fork {
    --rd-fork-gutter: 20px;
    --rd-fork-reach: 12px;
    --rd-fork-radius: 10px;
  }
}


/* ---------------------------------------------------------------------------
 * 9. PROSE COMPONENTS — the transcript's reading grammar
 *
 * IMP-0618 owns the player's full composition; what belongs HERE is the shared
 * grammar the rest of the reader also has to speak, so a scene block, a recap
 * and a story synopsis are the same typographic object wherever they appear.
 *
 * The rule the brief sets and these encode: dialogue is not a chat bubble.
 * A speaker is an attribution line above the words, in Inter, small and
 * tracked — the way a script or a novel's dialogue tag reads — and the speech
 * itself is prose in the reading serif. No tails, no left/right lanes, no
 * per-speaker geometry.
 * ------------------------------------------------------------------------ */

/* A beat: one unit of the manuscript. Narration, dialogue or the reader's own
   action are the same object with different attribution. */
.reader-beat {
  position: relative;
  padding-block: var(--rd-space-3);
  min-width: 0;
}
.reader-beat + .reader-beat { border-block-start: 1px solid var(--rd-rule-soft); }
.reader-beat__attribution {
  display: flex;
  align-items: center;
  gap: var(--rd-space-2);
  margin-block-end: var(--rd-space-1);
  font-family: var(--rd-font-ui);
  font-size: var(--rd-text-xs);
  font-weight: var(--rd-weight-semi);
  letter-spacing: var(--rd-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--rd-text-faint);
}
.reader-beat__text {
  font-family: var(--rd-font-reading);
  font-size: var(--rd-prose);
  line-height: var(--rd-leading-prose);
  color: var(--rd-text);
  white-space: pre-wrap;
  max-width: var(--rd-measure);
}
/* Dialogue: the attribution is amethyst, and the words are the only italic in
   the transcript. That is the entire distinction — no bubble. */
.reader-beat--dialogue .reader-beat__attribution { color: var(--amethyst); }
.reader-beat--dialogue .reader-beat__text { font-style: italic; }
/* The reader's own action. Ember is the brief's warmth accent; this is a
   highlight moment in the manuscript, not a structural UI state. */
.reader-beat--action .reader-beat__attribution { color: var(--ember); }
.reader-beat--action .reader-beat__text {
  font-family: var(--rd-font-ui);
  font-size: var(--rd-text-base);
  line-height: var(--rd-leading-ui);
  color: var(--rd-text-muted);
}
/* A system aside — nothing to read here, so it is the quietest thing on the
   page and never uses the reading face. */
.reader-beat--system .reader-beat__text {
  font-family: var(--rd-font-ui);
  font-size: var(--rd-text-md);
  color: var(--rd-text-faint);
}

/* --- LEGACY BRIDGE: the transcript renderer -----------------------------
   session-runtime.js rebuilds the transcript client-side after hydration and
   still emits `.message-content` / `.scene-narration` / `.dialogue-text`.
   Rewriting that renderer is IMP-0618's job (it owns the player's composition);
   what belongs to THIS improvement is the type system, so the three prose
   selectors are pointed at the reading role here. Without this the server's
   first paint would be Source Serif 4 and the hydrated page would silently
   swap to Georgia — the single most visible instance of "typography changes by
   block type" that IMP-0619 is filed about.

   `--reading-column` is what session-runtime.css and mobile.css both measure
   the stage and the choice panel against; it is given the system's value here
   so the transcript, the fork and the input all sit on one column. --------- */
:root { --reading-column: var(--rd-column); }

.message-content,
.scene-narration,
.dialogue-text,
.scene-dialogue .dialogue-text,
.recap-content {
  font-family: var(--rd-font-reading);
  font-size: var(--rd-prose);
  line-height: var(--rd-leading-prose);
  letter-spacing: 0;
}
.message-user .message-content,
.message-system .message-content {
  font-family: var(--rd-font-ui);
  font-size: var(--rd-text-base);
  line-height: var(--rd-leading-ui);
}
/* Speaker attributions are Inter, small and tracked — a dialogue tag, not a
   chat-bubble nameplate. They were a 800-weight uppercase seafoam/wisteria
   pair keyed to which side of the column the bubble sat on. */
.dialogue-speaker,
.scene-dialogue .dialogue-speaker,
.scene-dialogue.dialogue-right .dialogue-speaker,
.user-action-prefix {
  font-family: var(--rd-font-ui);
  font-size: var(--rd-text-xs);
  font-weight: var(--rd-weight-semi);
  letter-spacing: var(--rd-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--amethyst);
}
.user-action-prefix { color: var(--ember); }
/* The passive-continue pill was the one place a 5th font stack was inlined. */
.message-passive-continue {
  font: var(--rd-weight-medium) var(--rd-text-sm) / 1.2 var(--rd-font-ui);
}


/* A pull quote: the story-detail hook, the excerpt, the cliffhanger line. */
.reader-quote {
  margin: 0;
  padding-inline-start: var(--rd-space-4);
  border-inline-start: var(--rd-rule-w) solid var(--rd-amethyst-line);
  font-family: var(--rd-font-reading);
  font-size: var(--rd-prose-lg);
  font-style: italic;
  line-height: 1.5;
  color: var(--rd-text);
  max-width: var(--rd-measure);
}

/* A recap: what happened before. Prose, set back from the trunk. */
.reader-recap {
  background: var(--rd-surface);
  border: 1px solid var(--rd-rule);
  border-radius: var(--rd-radius);
  padding: var(--rd-space-4);
}
.reader-recap__label {
  display: flex;
  align-items: center;
  gap: var(--rd-space-2);
  margin-block-end: var(--rd-space-2);
  font-family: var(--rd-font-ui);
  font-size: var(--rd-text-xs);
  font-weight: var(--rd-weight-semi);
  letter-spacing: var(--rd-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--rd-text-faint);
}
.reader-recap__body {
  margin: 0;
  font-family: var(--rd-font-reading);
  font-size: var(--rd-prose-sm);
  line-height: var(--rd-leading-prose);
  color: var(--rd-text-muted);
}


/* ---------------------------------------------------------------------------
 * 10. UTILITIES
 * ------------------------------------------------------------------------ */

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

/* The rare light surface. Per the brief, --parchment is for "cinematic hero
   moments, printed/export views, nothing else", so it is reachable only
   through this one opt-in class and carries its own foreground pair —
   amethyst-deep, because plain amethyst on parchment is 2.7:1. */
.reader-parchment {
  background: var(--parchment);
  color: var(--ink);
  --rd-text: var(--ink);
  --rd-text-muted: #4a4238;
  --rd-text-faint: #6b6155;
  --rd-surface: #ffffff;
  --rd-rule: #d9d0be;
  --rd-rule-soft: #e7dfd0;
  --rd-rule-strong: #c3b8a2;
}
.reader-parchment .reader-btn--primary {
  background: var(--amethyst-deep);
  border-color: var(--amethyst-deep);
  color: var(--parchment);
}
