/* ==========================================================================
   Wisdom Vault — "The Private Athenaeum"
   00-tokens: design tokens, reset, base typography
   ========================================================================== */

:root {
  --serif: "Iowan Old Style", "Palatino Nova", Palatino, "Book Antiqua",
    "URW Palladio L", P052, Charter, Georgia, serif;
  --sans: "Avenir Next", Avenir, Seravek, "Segoe UI", "Helvetica Neue",
    Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* Daylight reading room */
  --paper: #f4efe3;
  --paper-2: #ede6d4;
  --paper-3: #e5dcc6;
  --ink: #26221a;
  /* ink-soft/ink-faint deepened one step 2026-07 (sol56 V1 #2): faint text
     — row subs, captions, labels, empty-state copy — was reading ~2.9:1
     against --paper, well under small-text AA. Same hue, darker lightness:
     ink-soft now ~5.9:1 (was 5.2), ink-faint ~4.5:1 (was 2.9). --line(-soft)
     nudged the same one step for border legibility; parchment hue held. */
  --ink-soft: #625b4c;
  --ink-faint: #676152; /* rebased 2026-07-21 (AIL r2 adjudication #2 —
    the card-metadata token: domain labels like "Influence", .row-sub,
    .spine-no render it at 11-13px on --paper-2/--paper-3, the cream
    CARD surfaces, not just --paper): was #736c5b, 4.19:1 on --paper-2
    and 3.82:1 on --paper-3 (both sub-AA despite 4.55 on --paper itself)
    -> 4.95/4.51/5.37 on paper-2/paper-3/paper respectively. Same hue,
    darker only. */
  --line: rgba(38, 34, 26, 0.21);
  --line-soft: rgba(38, 34, 26, 0.12);
  --accent: #8c3b2a;
  --accent-soft: rgba(140, 59, 42, 0.1);
  --gilt: #a67c37;
  --gilt-soft: rgba(166, 124, 55, 0.16);
  --ok: #4a6741;
  --shadow: 0 1px 2px rgba(38, 34, 26, 0.06), 0 8px 28px rgba(38, 34, 26, 0.08);
  --shadow-lift: 0 2px 4px rgba(38, 34, 26, 0.08), 0 14px 44px rgba(38, 34, 26, 0.14);
  --grain-alpha: 0.05;

  /* ---- skin axis (orthogonal to theme) --------------------------------
     Typography/density/ornament defaults — this is the "athenaeum" skin's
     contract. [data-skin="..."] overrides in 05-skins.css redefine these;
     [data-skin="athenaeum"] is intentionally absent from that file because
     it is identical to the defaults declared right here (single source of
     truth — see 05-skins.css header comment). */
  --font-body: var(--serif);
  --font-display: var(--serif);
  --body-size: 17px;
  --body-leading: 1.62;
  --heading-leading: 1.25;
  --content-width: 720px;
  --row-pad: 15px 6px;
  --rule-bg: linear-gradient(90deg, var(--gilt), transparent 70%);
  --dropcap-size: 3.1em;
  --dropcap-lh: 0.82;
  --dropcap-float: left;
  --dropcap-pad: 6px 8px 0 0;
  --dropcap-color: var(--accent);
  --dropcap-weight: 600;
}

/* ---- theme packs -------------------------------------------------------
   Eighteen selectable token sets, swapped via data-theme on :root.
   :root above is Athenaeum Light; [data-theme="dark"] is Athenaeum Dark;
   sepia / slate / contrast / forest / midnight / manuscript (settings label:
   Vellum) / wine / fjord / phosphor / iris / quartz / ocean / ember / moss /
   plum / carbon follow.
   Every pack redefines the full contract: paper(×3) / ink(×3) / line(×2) /
   accent / gilt / ok / shadows. Body ink is checked to ≥7:1 contrast
   against paper (WCAG AAA) for every pack. Dark packs must ALSO be added
   to the dark-chip selector list in 35-map.css (atlas chips flip to a
   66%-lightness variant there — see the comment on that list). */

[data-theme="dark"] {
  /* Athenaeum Dark — lamplight (ink-soft/ink-faint/line lightened one
     step 2026-07, same rationale as the light pack above: ink-faint was
     ~4.0:1 against --paper, now ~4.6:1; ink-soft ~7.0:1 -> ~7.9:1) */
  --paper: #171310;
  --paper-2: #201a15;
  --paper-3: #292219;
  --ink: #e9e1cd;
  --ink-soft: #b2a994;
  --ink-faint: #948973; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #897f69, 3.97:1 on --paper-3 (worst real card surface) -> 4.55:1.
    Same hue, lighter only. */
  --line: rgba(233, 225, 205, 0.21);
  --line-soft: rgba(233, 225, 205, 0.12);
  --accent: #d29a4d;
  --accent-soft: rgba(210, 154, 77, 0.13);
  --gilt: #c9974b;
  --gilt-soft: rgba(201, 151, 75, 0.16);
  --ok: #8aa07f;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 28px rgba(0, 0, 0, 0.45);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.5), 0 14px 44px rgba(0, 0, 0, 0.55);
  --grain-alpha: 0.04;
}

[data-theme="sepia"] {
  /* Sepia — warm long-reading, aged golden paper (deepened 2026-07 so it
     no longer twins with the paler Vellum/manuscript parchment;
     ink/paper contrast 9.9:1). --ink-faint deepened one more step
     2026-07-21 (AIL r1 code-lane #3): was #93805d, 2.91:1 against
     --paper — well under small-text AA (row subs render it at 12px).
     Same hue/saturation, darker lightness only: #716248, 4.50:1.
     AIL r2 (fable F9): that rebase hit --paper only (zero margin); row-
     subs actually render inside .card/.card.today-card, whose ground is
     --paper-2 (4.04:1) or --paper-3 (3.58:1), both sub-AA. Deepened one
     more step: #60533d — 5.10/4.53/5.69 on paper/paper-2/paper-3. */
  --paper: #f0dfb8;
  --paper-2: #e9d3a2;
  --paper-3: #dfc78e;
  --ink: #3c2f1c;
  --ink-soft: #6e5b3e;
  --ink-faint: #60533d;
  --line: rgba(60, 47, 28, 0.2);
  --line-soft: rgba(60, 47, 28, 0.1);
  --accent: #94481d;
  --accent-soft: rgba(148, 72, 29, 0.12);
  --gilt: #8a6423;
  --gilt-soft: rgba(138, 100, 35, 0.18);
  --ok: #5b6e3d;
  --shadow: 0 1px 2px rgba(60, 47, 28, 0.07), 0 8px 28px rgba(60, 47, 28, 0.1);
  --shadow-lift: 0 2px 4px rgba(60, 47, 28, 0.09), 0 14px 44px rgba(60, 47, 28, 0.16);
  --grain-alpha: 0.07;
}

[data-theme="slate"] {
  /* Slate — cool neutral, blue-grey study */
  --paper: #1b1f24;
  --paper-2: #22272e;
  --paper-3: #2b323b;
  --ink: #dde3ea;
  --ink-soft: #9aa5b1;
  --ink-faint: #919ba6; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #707c8a, 3.05:1 on --paper-3 (worst real card surface) -> 4.59:1.
    Same hue, lighter only. */
  --line: rgba(221, 227, 234, 0.16);
  --line-soft: rgba(221, 227, 234, 0.08);
  --accent: #8ab4d8;
  --accent-soft: rgba(138, 180, 216, 0.13);
  --gilt: #c0aa72;
  --gilt-soft: rgba(192, 170, 114, 0.16);
  --ok: #8fbf9f;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 28px rgba(0, 0, 0, 0.42);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.5), 0 14px 44px rgba(0, 0, 0, 0.52);
  --grain-alpha: 0.035;
}

[data-theme="contrast"] {
  /* High Contrast — WCAG-AAA-oriented, print-sharp */
  --paper: #ffffff;
  --paper-2: #ffffff;
  --paper-3: #ededed;
  --ink: #000000;
  --ink-soft: #1f1f1f;
  --ink-faint: #3d3d3d;
  --line: rgba(0, 0, 0, 0.6);
  --line-soft: rgba(0, 0, 0, 0.28);
  --accent: #8b0000;
  --accent-soft: rgba(139, 0, 0, 0.09);
  --gilt: #5c4400;
  --gilt-soft: rgba(92, 68, 0, 0.13);
  --ok: #0a5c2e;
  --shadow: 0 0 0 1px rgba(0, 0, 0, 0.35);
  --shadow-lift: 0 0 0 2px rgba(0, 0, 0, 0.55);
  --grain-alpha: 0;
}

[data-theme="forest"] {
  /* Forest — deep green reading lodge */
  --paper: #131a14;
  --paper-2: #1a231b;
  --paper-3: #233024;
  --ink: #e2e8dc;
  --ink-soft: #a3b09a;
  --ink-faint: #8a9983; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #75856e, 3.51:1 on --paper-3 (worst real card surface) -> 4.58:1.
    Same hue, lighter only. */
  --line: rgba(226, 232, 220, 0.16);
  --line-soft: rgba(226, 232, 220, 0.08);
  --accent: #a8c686;
  --accent-soft: rgba(168, 198, 134, 0.13);
  --gilt: #c9b458;
  --gilt-soft: rgba(201, 180, 88, 0.15);
  --ok: #8aa07f;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 28px rgba(0, 0, 0, 0.42);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.5), 0 14px 44px rgba(0, 0, 0, 0.52);
  --grain-alpha: 0.05;
}

[data-theme="midnight"] {
  /* Midnight — deep blue-black, cool ink (ink/paper contrast 14.7:1) */
  --paper: #0b0e15;
  --paper-2: #10141c;
  --paper-3: #161b26;
  --ink: #d9e1ee;
  --ink-soft: #94a1b8;
  --ink-faint: #79839d; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #66718c, 3.53:1 on --paper-3 (worst real card surface) -> 4.55:1.
    Same hue, lighter only. */
  --line: rgba(217, 225, 238, 0.16);
  --line-soft: rgba(217, 225, 238, 0.08);
  --accent: #6f9bd8;
  --accent-soft: rgba(111, 155, 216, 0.13);
  --gilt: #c3934a;
  --gilt-soft: rgba(195, 147, 74, 0.16);
  --ok: #82ab86;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 28px rgba(0, 0, 0, 0.45);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.5), 0 14px 44px rgba(0, 0, 0, 0.55);
  --grain-alpha: 0.035;
}

[data-theme="manuscript"] {
  /* Manuscript — warm parchment light, brown ink (ink/paper contrast 13.2:1) */
  --paper: #f4ead2;
  --paper-2: #ecdfc0;
  --paper-3: #e1d0a8;
  --ink: #2e2013;
  --ink-soft: #5c4a34;
  --ink-faint: #68573f; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #8a7454, 2.93:1 on --paper-3 (worst real card surface) -> 4.56:1.
    Same hue, darker only. */
  --line: rgba(46, 32, 19, 0.18);
  --line-soft: rgba(46, 32, 19, 0.09);
  --accent: #7a3b12;
  --accent-soft: rgba(122, 59, 18, 0.11);
  --gilt: #8f6a24;
  --gilt-soft: rgba(143, 106, 36, 0.16);
  --ok: #4f6b34;
  --shadow: 0 1px 2px rgba(46, 32, 19, 0.07), 0 8px 28px rgba(46, 32, 19, 0.1);
  --shadow-lift: 0 2px 4px rgba(46, 32, 19, 0.09), 0 14px 44px rgba(46, 32, 19, 0.16);
  --grain-alpha: 0.08;
}

[data-theme="wine"] {
  /* Wine — dark claret; red-leaning paper + rosé accent (pulled off pink
     2026-07 so it separates from Plum's orchid aubergine;
     ink/paper contrast 13.7:1) */
  --paper: #211013;
  --paper-2: #2a1418;
  --paper-3: #351a1f;
  --ink: #ecdbde;
  --ink-soft: #af8f96;
  --ink-faint: #9b838b; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #806870, 3.13:1 on --paper-3 (worst real card surface) -> 4.56:1.
    Same hue, lighter only. */
  --line: rgba(236, 219, 222, 0.16);
  --line-soft: rgba(236, 219, 222, 0.08);
  --accent: #d5787c;
  --accent-soft: rgba(213, 120, 124, 0.13);
  --gilt: #caa15a;
  --gilt-soft: rgba(202, 161, 90, 0.16);
  --ok: #8aab86;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 28px rgba(0, 0, 0, 0.42);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.5), 0 14px 44px rgba(0, 0, 0, 0.52);
  --grain-alpha: 0.045;
}

[data-theme="fjord"] {
  /* Fjord — cool nordic gray-blue, light (ink/paper contrast 13.6:1) */
  --paper: #e7edf1;
  --paper-2: #dde5eb;
  --paper-3: #cfdae3;
  --ink: #16232c;
  --ink-soft: #47606f;
  --ink-faint: #506069; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #718793, 2.65:1 on --paper-3 (worst real card surface) -> 4.60:1.
    Same hue, darker only. */
  --line: rgba(22, 35, 44, 0.18);
  --line-soft: rgba(22, 35, 44, 0.09);
  --accent: #2f6690;
  --accent-soft: rgba(47, 102, 144, 0.1);
  --gilt: #83693a;
  --gilt-soft: rgba(131, 105, 58, 0.15);
  --ok: #3e6b4c;
  --shadow: 0 1px 2px rgba(22, 35, 44, 0.06), 0 8px 28px rgba(22, 35, 44, 0.08);
  --shadow-lift: 0 2px 4px rgba(22, 35, 44, 0.08), 0 14px 44px rgba(22, 35, 44, 0.14);
  --grain-alpha: 0.04;
}

[data-theme="phosphor"] {
  /* Phosphor — near-black, soft restrained green ink (ink/paper contrast 12.0:1) */
  --paper: #0a0d0a;
  --paper-2: #0f130f;
  --paper-3: #151a15;
  --ink: #a9d6ac;
  --ink-soft: #7ba181;
  --ink-faint: #688974; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #567160, 3.30:1 on --paper-3 (worst real card surface) -> 4.55:1.
    Same hue, lighter only. */
  --line: rgba(169, 214, 172, 0.14);
  --line-soft: rgba(169, 214, 172, 0.07);
  --accent: #6fae7a;
  --accent-soft: rgba(111, 174, 122, 0.12);
  --gilt: #b99a55;
  --gilt-soft: rgba(185, 154, 85, 0.15);
  --ok: #7bbf83;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.45), 0 8px 28px rgba(0, 0, 0, 0.5);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.55), 0 14px 44px rgba(0, 0, 0, 0.6);
  --grain-alpha: 0.03;
}

[data-theme="iris"] {
  /* Iris — dusk violet, dark (ink/paper contrast 13.9:1) */
  --paper: #150f1e;
  --paper-2: #1c1526;
  --paper-3: #241b30;
  --ink: #e3daf0;
  --ink-soft: #a293ba;
  --ink-faint: #8c82a1; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #75698c, 3.26:1 on --paper-3 (worst real card surface) -> 4.57:1.
    Same hue, lighter only. */
  --line: rgba(227, 218, 240, 0.16);
  --line-soft: rgba(227, 218, 240, 0.08);
  --accent: #a480d9;
  --accent-soft: rgba(164, 128, 217, 0.14);
  --gilt: #c9a24d;
  --gilt-soft: rgba(201, 162, 77, 0.16);
  --ok: #8ab08a;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 28px rgba(0, 0, 0, 0.42);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.5), 0 14px 44px rgba(0, 0, 0, 0.52);
  --grain-alpha: 0.045;
}

[data-theme="quartz"] {
  /* Quartz — soft rose-grey, light (ink/paper contrast 13.0:1) */
  --paper: #f0e9ea;
  --paper-2: #e8dfe1;
  --paper-3: #ddd1d3;
  --ink: #2a2128;
  --ink-soft: #5e4f57;
  --ink-faint: #64585d; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #8a7a80, 2.73:1 on --paper-3 (worst real card surface) -> 4.57:1.
    Same hue, darker only. */
  --line: rgba(42, 33, 40, 0.16);
  --line-soft: rgba(42, 33, 40, 0.08);
  --accent: #a8506b;
  --accent-soft: rgba(168, 80, 107, 0.1);
  --gilt: #9c7a4a;
  --gilt-soft: rgba(156, 122, 74, 0.15);
  --ok: #5c7a52;
  --shadow: 0 1px 2px rgba(42, 33, 40, 0.06), 0 8px 28px rgba(42, 33, 40, 0.08);
  --shadow-lift: 0 2px 4px rgba(42, 33, 40, 0.08), 0 14px 44px rgba(42, 33, 40, 0.14);
  --grain-alpha: 0.05;
}

[data-theme="ocean"] {
  /* Ocean — deep sea-teal, dark (papers pulled tealward 2026-07 so the
     pack reads "sea", not a twin of Midnight's blue-black;
     ink/paper contrast 14.0:1) */
  --paper: #081a21;
  --paper-2: #0d222b;
  --paper-3: #132c36;
  --ink: #d4e8ec;
  --ink-soft: #93aebd;
  --ink-faint: #7c94a0; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #6a8492, 3.70:1 on --paper-3 (worst real card surface) -> 4.58:1.
    Same hue, lighter only. */
  --line: rgba(212, 232, 236, 0.16);
  --line-soft: rgba(212, 232, 236, 0.08);
  --accent: #4fa3c9;
  --accent-soft: rgba(79, 163, 201, 0.13);
  --gilt: #c9a24d;
  --gilt-soft: rgba(201, 162, 77, 0.16);
  --ok: #7fb08a;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 28px rgba(0, 0, 0, 0.45);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.5), 0 14px 44px rgba(0, 0, 0, 0.55);
  --grain-alpha: 0.035;
}

[data-theme="ember"] {
  /* Ember — coal-red charcoal, hot amber accents, dark (papers deepened
     redward + accent heated 2026-07 so it separates from Athenaeum Dark's
     lamplight; ink/paper contrast 13.0:1) */
  --paper: #211410;
  --paper-2: #2a1a14;
  --paper-3: #35221a;
  --ink: #ecd9b8;
  --ink-soft: #b8a281;
  --ink-faint: #9d8b6f; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #8c7a5f, 3.63:1 on --paper-3 (worst real card surface) -> 4.56:1.
    Same hue, lighter only. */
  --line: rgba(236, 217, 184, 0.16);
  --line-soft: rgba(236, 217, 184, 0.08);
  --accent: #e68a33;
  --accent-soft: rgba(230, 138, 51, 0.14);
  --gilt: #d9a544;
  --gilt-soft: rgba(217, 165, 68, 0.17);
  --ok: #8fae6c;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.42), 0 8px 28px rgba(0, 0, 0, 0.46);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.52), 0 14px 44px rgba(0, 0, 0, 0.56);
  --grain-alpha: 0.045;
}

[data-theme="moss"] {
  /* Moss — sage, light (ink/paper contrast 12.7:1) */
  --paper: #eaeee0;
  --paper-2: #e1e6d3;
  --paper-3: #d4dcc2;
  --ink: #1f2a1a;
  --ink-soft: #4c5a41;
  --ink-faint: #57614e; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #78876c, 2.70:1 on --paper-3 (worst real card surface) -> 4.59:1.
    Same hue, darker only. */
  --line: rgba(31, 42, 26, 0.18);
  --line-soft: rgba(31, 42, 26, 0.09);
  --accent: #5c7a3e;
  --accent-soft: rgba(92, 122, 62, 0.1);
  --gilt: #8a7327;
  --gilt-soft: rgba(138, 115, 39, 0.15);
  --ok: #4a7a4f;
  --shadow: 0 1px 2px rgba(31, 42, 26, 0.06), 0 8px 28px rgba(31, 42, 26, 0.09);
  --shadow-lift: 0 2px 4px rgba(31, 42, 26, 0.08), 0 14px 44px rgba(31, 42, 26, 0.15);
  --grain-alpha: 0.055;
}

[data-theme="plum"] {
  /* Plum — rich aubergine, dark (ink/paper contrast 14.2:1) */
  --paper: #1a0e18;
  --paper-2: #22131f;
  --paper-3: #2c1a28;
  --ink: #ecdbe8;
  --ink-soft: #af93a9;
  --ink-faint: #968291; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #7f6a7a, 3.30:1 on --paper-3 (worst real card surface) -> 4.59:1.
    Same hue, lighter only. */
  --line: rgba(236, 219, 232, 0.16);
  --line-soft: rgba(236, 219, 232, 0.08);
  --accent: #c168a0;
  --accent-soft: rgba(193, 104, 160, 0.13);
  --gilt: #c9974f;
  --gilt-soft: rgba(201, 151, 79, 0.16);
  --ok: #8aab86;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 28px rgba(0, 0, 0, 0.44);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.5), 0 14px 44px rgba(0, 0, 0, 0.54);
  --grain-alpha: 0.045;
}

[data-theme="carbon"] {
  /* Carbon — neutral graphite with brass fittings, dark (gilt retuned from
     pure grey #9a9a9a 2026-07: grey sat 1 step from --ink-soft, so the
     load-bearing ◆ / tier chips lost their signal; a desaturated brass
     keeps the pack near-monochrome but the marker alive;
     ink/paper contrast 15.0:1) */
  --paper: #121212;
  --paper-2: #191919;
  --paper-3: #212121;
  --ink: #e6e6e6;
  --ink-soft: #a3a3a3;
  --ink-faint: #898989; /* rebased 2026-07-21 (AIL r3 lane G, finding #1):
    was #737373, 3.40:1 on --paper-3 (worst real card surface) -> 4.60:1.
    Same hue (neutral), lighter only. */
  --line: rgba(230, 230, 230, 0.14);
  --line-soft: rgba(230, 230, 230, 0.07);
  --accent: #6e9bc4;
  --accent-soft: rgba(110, 155, 196, 0.12);
  --gilt: #a5936c;
  --gilt-soft: rgba(165, 147, 108, 0.15);
  --ok: #7fae7f;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.45), 0 8px 28px rgba(0, 0, 0, 0.5);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.55), 0 14px 44px rgba(0, 0, 0, 0.6);
  --grain-alpha: 0.025;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { height: 100%; }

body {
  min-height: 100%;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--body-size);
  line-height: var(--body-leading);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* paper grain — pure data-URI turbulence, no network */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: var(--grain-alpha);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E");
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

input, select {
  font: inherit;
  color: inherit;
}

::selection { background: var(--gilt-soft); }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: var(--heading-leading);
}

/* small-caps utility label — the app's chrome voice.
   Also carried by real h2/h3 section headings, so it must neutralise the
   browser's heading margins and size rather than inherit them. */
.label {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0;
  line-height: 1.45;
}

/* Keyboard users land here before the 16-item rail; visible only on focus. */
.skip-link {
  position: fixed;
  left: 12px;
  /* a percentage here resolves against a zero-height containing block and
     leaves the link visible — offset by a concrete distance instead */
  top: -80px;
  z-index: 100;
  padding: 10px 16px;
  border-radius: 8px;
  background: var(--accent-soft);
  color: var(--accent);
  border: 1px solid var(--accent);
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 600;
  text-decoration: none;
}
.skip-link:focus { top: 12px; }

.fleuron { color: var(--gilt); }

/* focus */
:focus-visible {
  outline: 2px solid var(--gilt);
  outline-offset: 2px;
  border-radius: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ==========================================================================
   Wisdom Vault — "The Private Athenaeum"
   05-skins: the SKIN axis — typography / density / ornament.

   Orthogonal to the theme (data-theme) axis in 00-tokens.css: skins never
   set color tokens (--paper/--ink/--accent/--gilt/etc.), only the
   typography/density/ornament custom properties declared at :root in
   00-tokens.css (--font-body, --font-display, --body-size, --body-leading,
   --heading-leading, --content-width, --row-pad, --rule-bg, --dropcap-*).
   Swapped via data-skin on :root, mirroring the data-theme pattern.

   [data-skin="athenaeum"] has no block here on purpose — its values ARE
   the :root defaults in 00-tokens.css (the current, pre-skin-axis look).
   That is the pixel-parity contract: adding this file must not move a
   single computed style for the default skin, because there is nothing
   here to override it with. modernist / manuscript / compact below are
   the only three skins that actually redefine anything.
   ========================================================================== */

[data-skin="modernist"] {
  /* Modernist — self-contained OS system-sans stack, no external fonts.
     No drop caps, tighter headings, a flat rule instead of the gilt
     fade. */
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --font-display: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --heading-leading: 1.15;
  --rule-bg: var(--line);
  --dropcap-size: 1em;
  --dropcap-lh: inherit;
  --dropcap-float: none;
  --dropcap-pad: 0;
  --dropcap-color: inherit;
  --dropcap-weight: inherit;
}

[data-skin="manuscript"] {
  /* Manuscript — the slow-reading skin: wider line-height, larger body
     size, a narrower content column (more surrounding whitespace reads
     as "generous margins"), drop caps kept on and slightly larger to
     match the bigger body type. Font stack unchanged (still --serif). */
  --body-size: 18.5px;
  --body-leading: 1.85;
  --content-width: 640px;
  --dropcap-size: 3.4em;
}

[data-skin="compact"] {
  /* Compact — the power-scanner skin: smaller body, tighter line-height,
     tighter headings, denser list rows, no drop caps. Leading sits at
     1.48, not the original 1.42: at 15px over the full 720px measure the
     tighter value read as a wall of text on desktop (fine at 375px);
     1.48 keeps the density while restoring the scan rhythm. */
  --body-size: 15px;
  --body-leading: 1.48;
  --heading-leading: 1.15;
  --row-pad: 8px 6px;
  --dropcap-size: 1em;
  --dropcap-lh: inherit;
  --dropcap-float: none;
  --dropcap-pad: 0;
  --dropcap-color: inherit;
  --dropcap-weight: inherit;
}

/* ==========================================================================
   Wisdom Vault — "The Private Athenaeum"
   06-materials: the MATERIAL skin pair — glass + alloy.

   Two additional data-skin packs (SPEC-materials-docket.md §A), layered
   ONTO whichever data-theme is currently active. Unlike the typography-only
   packs in 05-skins.css, these two deliberately DO touch surface treatment
   — that is the entire point of a "material" (translucency/depth/speculars
   over ANY color theme). They do it through a --mat-* token contract:

     --mat-surface        panel bg (cards)
     --mat-surface-strong panel bg (nav rail / tab bar — denser, for
                           reliable legibility on persistent chrome)
     --mat-edge            inset "edge" treatment (glass: inner light
                           border; alloy: bevel pair)
     --mat-elev            outer drop shadow (glass: airy/faint; alloy:
                           tight/hard)
     --mat-blur             backdrop-filter value ("none" for alloy, which
                           is opaque)
     --mat-backdrop        a fixed, very subtle layer behind the whole app
                           (glass: mesh gradient to refract; alloy: brushed
                           repeating-linear-gradient texture)
     --mat-sheen            (alloy only) static specular sweep for cards/
                           buttons

   Every value is DERIVED from the active theme's own custom properties
   (--paper* / --ink/--accent/--gilt via color-mix()) — never a hardcoded
   theme-specific hex — so the pair renders correctly across all nineteen
   theme packs. color-mix() with the literal white/black keywords below is
   a theme-relative lighten/darken of each theme's OWN --paper-2/--ink
   tokens (the standard, theme-agnostic way to fake a specular highlight
   or a bevel shadow — highlights trend white, recesses trend black,
   regardless of whether the underlying theme itself is light or dark);
   it is not a hardcoded per-theme color.

   Because every rule below is scoped under [data-skin="glass"] /
   [data-skin="alloy"], athenaeum/modernist/manuscript/compact (and no
   data-skin at all) never match a single selector here — the default
   skin's computed styles are provably untouched byte-for-byte
   (test_skins_defaults pixel-pins it; see webapp/tests/test_skins_defaults.py).
   ========================================================================== */

/* ---- pack tokens ---------------------------------------------------------
   Panel alpha kept inside the spec's own ~0.55–0.7 range: 60% for cards,
   70% (the top of that range) for the nav rail / tab bar, since persistent
   navigation chrome needs the most reliable legibility. */

[data-skin="glass"] {
  --mat-surface: color-mix(in srgb, var(--paper-2) 60%, transparent);
  --mat-surface-strong: color-mix(in srgb, var(--paper-2) 70%, transparent);
  --mat-edge:
    inset 0 1px 0 0 color-mix(in srgb, white 50%, transparent),
    inset 0 0 0 1px color-mix(in srgb, white 14%, transparent);
  --mat-elev:
    0 2px 6px color-mix(in srgb, var(--ink) 5%, transparent),
    0 22px 56px color-mix(in srgb, var(--ink) 13%, transparent);
  --mat-blur: blur(18px) saturate(1.4);
  --mat-backdrop:
    radial-gradient(60% 50% at 18% -10%, color-mix(in srgb, var(--accent) 16%, transparent), transparent 60%),
    radial-gradient(55% 45% at 88% 110%, color-mix(in srgb, var(--gilt) 14%, transparent), transparent 60%);
}

[data-skin="alloy"] {
  /* vertical brushed-metal gradient: each theme's own paper tokens, pushed
     lighter at the top and darker at the bottom — the "#f2f2f4 -> #d8d8dc
     feel" from the spec, expressed relative to the theme instead of as a
     literal hex pair, so it works the same way in light and dark packs. */
  --mat-surface: linear-gradient(
    180deg,
    color-mix(in srgb, var(--paper-2) 88%, white 12%) 0%,
    color-mix(in srgb, var(--paper-3) 84%, black 6%) 100%
  );
  --mat-surface-strong: linear-gradient(
    180deg,
    color-mix(in srgb, var(--paper) 90%, white 10%) 0%,
    color-mix(in srgb, var(--paper-2) 84%, black 8%) 100%
  );
  --mat-edge:
    inset 1px 1px 0 0 color-mix(in srgb, white 45%, transparent),
    inset -1px -1px 0 0 color-mix(in srgb, black 30%, transparent);
  --mat-elev:
    0 1px 2px color-mix(in srgb, var(--ink) 20%, transparent),
    0 6px 14px color-mix(in srgb, var(--ink) 24%, transparent);
  --mat-blur: none;
  --mat-backdrop: repeating-linear-gradient(
    95deg,
    color-mix(in srgb, var(--ink) 4%, transparent) 0px,
    transparent 1px,
    transparent 3px
  );
  --mat-sheen: linear-gradient(
    115deg,
    transparent 30%,
    color-mix(in srgb, white 18%, transparent) 46%,
    transparent 62%
  );
}

/* ---- hard rule 1: reduced-transparency + no-backdrop-filter fallbacks ----
   Both packs collapse --mat-surface(-strong) to the plain opaque paper
   panel and drop the blur entirely. This is also the contrast-scrim floor:
   the panel becomes fully solid, so body text always sits on a background
   at least as opaque as the theme's own --paper-2 (the same surface every
   other skin already meets its contrast promise against). Order matters:
   these two blocks must stay AFTER the pack blocks above so they win the
   cascade when either condition matches (equal-specificity, later wins). */

@media (prefers-reduced-transparency: reduce) {
  [data-skin="glass"],
  [data-skin="alloy"] {
    --mat-surface: var(--paper-2);
    --mat-surface-strong: var(--paper-2);
    --mat-blur: none;
  }
}

@supports not (backdrop-filter: blur(1px)) {
  [data-skin="glass"],
  [data-skin="alloy"] {
    --mat-surface: var(--paper-2);
    --mat-surface-strong: var(--paper-2);
    --mat-blur: none;
  }
}

/* ---- backdrop: a fixed, very subtle layer behind the whole app ---------
   Sits at the same z-index as the paper-grain body::before in 00-tokens.css
   (both are painted behind #shell's z-index:1), visible in the gutters
   around panels and, for glass, refracted further through the translucent
   cards/nav on top of it. */

[data-skin="glass"] body::after,
[data-skin="alloy"] body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: var(--mat-backdrop);
}

/* ---- panel surfaces: cards -------------------------------------------- */

[data-skin="glass"] .card,
[data-skin="alloy"] .card {
  border: none;
  background: var(--mat-surface);
  box-shadow: var(--mat-edge), var(--mat-elev);
  backdrop-filter: var(--mat-blur, none);
  -webkit-backdrop-filter: var(--mat-blur, none);
}

/* ---- panel surfaces: nav rail + mobile tab bar ------------------------- */

[data-skin="glass"] #nav,
[data-skin="alloy"] #nav,
[data-skin="glass"] #tabbar,
[data-skin="alloy"] #tabbar {
  background: var(--mat-surface-strong);
  box-shadow: var(--mat-edge), var(--mat-elev);
  backdrop-filter: var(--mat-blur, none);
  -webkit-backdrop-filter: var(--mat-blur, none);
}

/* ---- alloy speculars: static sheen sweep on cards/buttons --------------
   No animation/transition is added — the sheen is a fixed gradient, and
   the blanket "@media (prefers-reduced-motion: reduce)" rule already in
   00-tokens.css covers any transition this file's hover states rely on
   (hard rule 2), so nothing extra is needed here. */

[data-skin="alloy"] .card,
[data-skin="alloy"] .btn {
  position: relative;
}

[data-skin="alloy"] .card::before,
[data-skin="alloy"] .btn::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--mat-sheen);
  pointer-events: none;
}

/* ==========================================================================
   10-layout: app shell, navigation rail, tab bar, view container
   ========================================================================== */

/* no horizontal scroll anywhere — clip (not hidden) so no scroll
   container is created and position: sticky keeps working */
html, body { overflow-x: clip; }

#shell {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  min-height: 100vh;
}

/* --- reading progress hairline (atom route only, 10-shell.js) ---------- */
#reading-bar {
  position: fixed;
  top: 0;
  left: 0;
  height: 2px;
  width: 0;
  z-index: 50;
  background: linear-gradient(90deg, var(--gilt), var(--accent));
  opacity: 0;
  pointer-events: none;
  /* prefers-reduced-motion: reduce (00-tokens.css) collapses both
     durations to ~0 — the bar still fills, it just jumps instead of
     easing, so the progress signal stays functional either way */
  transition: width 0.15s linear, opacity 0.15s ease;
}
#reading-bar.show { opacity: 1; }

/* --- navigation rail ---------------------------------------------------- */
#nav {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 28px 18px 22px;
  border-right: 1px solid var(--line-soft);
  background: linear-gradient(180deg, var(--paper), var(--paper-2));
  /* The rail is a fixed 100vh column but its content grows with the route
     list — at a 720px viewport the last item (Apps) fell below the fold with
     no way to reach it. Scroll the rail itself, and keep the scrollbar in the
     vault's own palette rather than shipping the browser default. */
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--line-soft) transparent;
}
#nav::-webkit-scrollbar { width: 6px; }
#nav::-webkit-scrollbar-track { background: transparent; }
#nav::-webkit-scrollbar-thumb {
  background: var(--line-soft);
  border-radius: 3px;
}
#nav:hover::-webkit-scrollbar-thumb { background: var(--ink-faint); }

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--ink);
  margin: 0 6px 30px;
}
.brand:hover { text-decoration: none; }

.brand-mark { width: 40px; height: 40px; border-radius: 9px; flex: none; }

.brand-word {
  font-family: var(--serif);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.24em;
  line-height: 1.35;
  text-transform: uppercase;
}

#nav-links { display: flex; flex-direction: column; gap: 2px; }

.nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border-radius: 8px;
  color: var(--ink-soft);
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  transition: background 0.15s ease, color 0.15s ease;
}
.nav-item:hover { background: var(--paper-3); color: var(--ink); text-decoration: none; }
.nav-item.active { background: var(--accent-soft); color: var(--accent); }
.nav-item.active .nav-glyph { color: var(--accent); }

.nav-glyph {
  width: 18px;
  text-align: center;
  font-size: 15px;
  color: var(--ink-faint);
  font-family: var(--serif);
}

.nav-foot { margin-top: auto; padding-top: 14px; border-top: 1px solid var(--line-soft); }

/* --- main view ----------------------------------------------------------- */
#view {
  min-height: 100vh;
  padding: 44px clamp(20px, 5vw, 72px) 96px;
  outline: none;
}

.view-inner { max-width: 1020px; margin: 0 auto; }
.view-inner.narrow { max-width: var(--content-width); }

/* staggered entrance */
.rise {
  opacity: 0;
  transform: translateY(10px);
  animation: rise 0.5s cubic-bezier(0.2, 0.65, 0.25, 1) forwards;
}
@keyframes rise { to { opacity: 1; transform: none; } }

/* view header */
.view-head { margin-bottom: 34px; }
.view-head .label { display: block; margin-bottom: 10px; }
.view-title {
  font-size: clamp(26px, 3.4vw, 36px);
  font-weight: 600;
  letter-spacing: -0.01em;
}
.view-sub { margin-top: 10px; color: var(--ink-soft); font-size: 15.5px; max-width: 62ch; }

.rule {
  border: none;
  height: 1px;
  background: var(--rule-bg);
  margin: 18px 0 0;
}

/* --- mobile tab bar ------------------------------------------------------ */
#tabbar { display: none; }

@media (max-width: 860px) {
  #shell { grid-template-columns: 1fr; }
  #nav { display: none; }
  #view { padding: 26px 18px 110px; min-height: auto; }

  #tabbar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 40;
    display: flex;
    justify-content: space-around;
    padding: 8px 4px calc(10px + env(safe-area-inset-bottom));
    background: color-mix(in srgb, var(--paper-2) 92%, transparent);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border-top: 1px solid var(--line-soft);
  }
  .tab-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    color: var(--ink-faint);
    font-family: var(--sans);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 4px 8px;
    border-radius: 8px;
  }
  .tab-item:hover { text-decoration: none; }
  .tab-item.active { color: var(--accent); }
  .tab-item .nav-glyph { font-size: 18px; width: auto; color: inherit; }
}

.boot-state {
  min-height: 60vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  color: var(--ink-soft);
}
.boot-fleuron { font-size: 30px; color: var(--gilt); animation: pulse 1.6s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: 0.35; } }

.empty-state {
  padding: 48px 20px;
  text-align: center;
  color: var(--ink-soft);
  font-style: italic;
}

/* ==========================================================================
   20-components: cards, chips, meters, list rows, buttons, toggles
   ========================================================================== */

/* --- cards ---------------------------------------------------------------- */
.card {
  background: var(--paper-2);
  border: 1px solid var(--line-soft);
  border-radius: 12px;
  padding: 22px 24px;
  box-shadow: var(--shadow);
}

a.card { display: block; color: inherit; transition: transform 0.18s ease, box-shadow 0.18s ease; }
a.card:hover { text-decoration: none; transform: translateY(-2px); box-shadow: var(--shadow-lift); }

.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 16px; }

/* --- domain spine tiles ----------------------------------------------------- */
.spine {
  position: relative;
  padding: 20px 20px 18px 26px;
  overflow: hidden;
}
.spine::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 5px;
  background: linear-gradient(180deg, var(--gilt), var(--accent));
  opacity: 0.85;
}
.spine-no {
  font-family: var(--serif);
  font-size: 30px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  margin-bottom: 12px;
}
.spine-name { font-size: 17px; font-weight: 600; margin-bottom: 6px; }
.spine-desc {
  font-size: 13px;
  color: var(--ink-soft);
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-bottom: 14px;
}
.spine-meta { display: flex; justify-content: space-between; align-items: center; }

/* --- meters (progress) ------------------------------------------------------ */
.meter {
  height: 3px;
  border-radius: 2px;
  background: var(--line-soft);
  overflow: hidden;
  flex: 1;
}
.meter > i {
  display: block;
  height: 100%;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--gilt), var(--accent));
  transition: width 0.6s cubic-bezier(0.2, 0.65, 0.25, 1);
}
.meter-row { display: flex; align-items: center; gap: 10px; }
.meter-pct {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-faint);
  min-width: 34px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* --- chips -------------------------------------------------------------------- */
.chip {
  display: inline-block;
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 20px;
  border: 1px solid var(--line);
  color: var(--ink-soft);
  white-space: nowrap;
}
.chip.accent { border-color: transparent; background: var(--accent-soft); color: var(--accent); }
.chip.gilt { border-color: transparent; background: var(--gilt-soft); color: var(--gilt); }
.chip.read { border-color: transparent; background: var(--gilt-soft); color: var(--ok); }
a.chip:hover { text-decoration: none; border-color: var(--gilt); color: var(--ink); }
.chip-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }

/* --- list rows ------------------------------------------------------------------- */
.rows { display: flex; flex-direction: column; }
.row {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding: var(--row-pad);
  border-bottom: 1px solid var(--line-soft);
  color: inherit;
}
.row:hover { text-decoration: none; background: var(--paper-2); }
.row-main { flex: 1; min-width: 0; }
.row-title {
  font-size: 16px;
  font-weight: 500;
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.row-title mark { background: var(--gilt-soft); color: inherit; padding: 0 1px; }
.lb-mark { color: var(--gilt); font-size: 11px; margin-right: 1px; }
.row-sub { margin-top: 4px; font-family: var(--sans); font-size: 12px; color: var(--ink-faint); }
.row-side { display: flex; align-items: center; gap: 10px; flex: none; }
.row .dot {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: 1px solid var(--line);
  align-self: center;
}
.row .dot.read { background: var(--gilt); border-color: var(--gilt); }

/* --- buttons ------------------------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  padding: 10px 20px;
  border-radius: 24px;
  border: 1px solid var(--line);
  color: var(--ink);
  background: var(--paper-2);
  transition: all 0.16s ease;
}
.btn:hover { border-color: var(--gilt); box-shadow: var(--shadow); text-decoration: none; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--paper); }
.btn.primary:hover { filter: brightness(1.08); }
.btn.done { background: var(--gilt-soft); border-color: transparent; color: var(--ok); }
.btn-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }

/* --- toggle switch ------------------------------------------------------------------- */
.switch { position: relative; width: 42px; height: 24px; flex: none; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; cursor: pointer; z-index: 1; margin: 0; }
.switch i {
  position: absolute;
  inset: 0;
  border-radius: 14px;
  background: var(--paper-3);
  border: 1px solid var(--line);
  transition: background 0.18s ease;
}
.switch i::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--paper);
  border: 1px solid var(--line);
  transition: transform 0.18s ease;
}
.switch input:checked + i { background: var(--accent); border-color: var(--accent); }
.switch input:checked + i::after { transform: translateX(18px); }

/* --- stats ---------------------------------------------------------------------------- */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; }
.stat { padding: 18px 20px; }
.stat-num {
  font-family: var(--serif);
  font-size: 34px;
  font-weight: 600;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.stat-num small { font-size: 17px; color: var(--ink-faint); font-weight: 400; }
.stat .label { margin-top: 6px; display: block; }

/* --- search input ---------------------------------------------------------------------- */
.search-box { position: relative; margin-bottom: 26px; }
.search-box input {
  width: 100%;
  font-family: var(--serif);
  font-size: 21px;
  padding: 12px 4px 12px 34px;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
}
.search-box input:focus { outline: none; border-bottom-color: var(--gilt); }
.search-box input::placeholder { color: var(--ink-faint); font-style: italic; }
.search-box .search-glyph {
  position: absolute;
  left: 2px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--gilt);
  font-size: 18px;
}

/* --- search: domain filter chips, type badges, match snippets --------------------------- */
.search-filter { margin: -6px 0 18px; }
.search-filter:empty { margin: 0; }
.fchip { cursor: pointer; transition: all 0.15s ease; }
.fchip:hover { border-color: var(--gilt); color: var(--ink); }
.fchip.active { background: var(--accent); border-color: var(--accent); color: var(--paper); }

.tbadge { font-size: 9px; padding: 1px 7px; letter-spacing: 0.12em; vertical-align: middle; }
.tbadge.tb-source { border-color: transparent; background: var(--gilt-soft); color: var(--gilt); }
.tbadge.tb-bridge { color: var(--gilt); border-color: var(--gilt); }
.tbadge.tb-debate { color: var(--accent); border-color: var(--accent); }
.tbadge.tb-chain { color: var(--ok); border-color: var(--ok); }

.row-snip {
  margin-top: 5px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-soft);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.row-snip mark { background: var(--gilt-soft); color: inherit; padding: 0 1px; }

/* --- tier covenant badge (G-VAULT-20) ---------------------------------------------------- */
.tier-badge { font-size: 9.5px; padding: 2px 8px; vertical-align: middle; }

/* --- tabs -------------------------------------------------------------------------------- */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line-soft); margin-bottom: 22px; }
.tab {
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding: 10px 16px;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.tab.active { color: var(--accent); border-bottom-color: var(--accent); }

/* ==========================================================================
   30-views: atom reader, home, review, notes, settings specifics
   ========================================================================== */

/* --- atom reader ------------------------------------------------------------ */
/* opus r1 F4: the default (athenaeum) skin's --content-width (720px)
   read at roughly 100ch on desktop — well past the ~65-75ch optimal
   reading measure for a shell whose whole promise is typographic
   reading quality. Cap at 40rem (640px @ the 16px root default)
   regardless of skin; skins already at or under 40rem (e.g. the 640px
   skin in 05-skins.css) are unaffected by min(). */
.reader { max-width: min(var(--content-width), 40rem); margin: 0 auto; }

.reader-crumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 26px;
  font-family: var(--sans);
  font-size: 12.5px;
  color: var(--ink-faint);
}
.reader-crumb a { color: var(--ink-soft); }
.reader-crumb .sep { color: var(--gilt); }

.atom-claim {
  font-size: clamp(23px, 3vw, 30px);
  font-weight: 600;
  line-height: 1.32;
  letter-spacing: -0.005em;
  margin-bottom: 18px;
}

.atom-meta { margin-bottom: 34px; }

.atom-body { font-size: 17.5px; }
.atom-body p { margin: 0 0 1.25em; }
.atom-body p:last-child { margin-bottom: 0; }

/* drop cap on the opening paragraph — ornament is skin-scoped (05-skins.css
   turns it off for modernist/compact via the --dropcap-* variables) */
.atom-body > p:first-of-type::first-letter {
  font-size: var(--dropcap-size);
  line-height: var(--dropcap-lh);
  float: var(--dropcap-float);
  padding: var(--dropcap-pad);
  color: var(--dropcap-color);
  font-weight: var(--dropcap-weight);
}

.atom-body h2, .atom-body h3, .atom-body h4 {
  margin: 1.7em 0 0.7em;
  font-size: 1.1em;
}
.atom-body h2::before, .note-body h2::before {
  content: "\2766\00a0\00a0";
  color: var(--gilt);
  font-size: 0.8em;
}
.atom-body h2.sec-limits { color: var(--accent); }
.atom-body ul, .atom-body ol { margin: 0 0 1.25em 1.4em; }
.atom-body li { margin-bottom: 0.45em; }
.atom-body blockquote {
  margin: 0 0 1.25em;
  padding: 4px 0 4px 20px;
  border-left: 2px solid var(--gilt);
  color: var(--ink-soft);
  font-style: italic;
}
.atom-body code {
  font-family: var(--mono);
  font-size: 0.86em;
  background: var(--paper-3);
  padding: 1px 5px;
  border-radius: 4px;
}
.atom-body hr { border: none; text-align: center; margin: 2em 0; }
.atom-body hr::after { content: "\2766"; color: var(--gilt); font-size: 14px; }

.wl { border-bottom: 1px dotted var(--gilt); }
.wl:hover { text-decoration: none; border-bottom-style: solid; background: var(--gilt-soft); }
.wl-dead { color: var(--ink-soft); border-bottom: 1px dashed var(--line); cursor: default; }
.wl-img {
  font-family: var(--sans);
  font-size: 12px;
  color: var(--ink-faint);
  border: 1px dashed var(--line);
  border-radius: 4px;
  padding: 1px 7px;
}

/* end-of-atom colophon */
.atom-end {
  text-align: center;
  margin: 40px 0 28px;
  color: var(--gilt);
  font-size: 18px;
}

/* connections panel */
.conn-panel {
  margin-top: 20px;
  border-top: 1px solid var(--line);
  padding-top: 26px;
}
.conn-group { margin-bottom: 20px; }
.conn-group > .label { display: block; margin-bottom: 10px; }

/* deliberate empty state: a semantic outlier, not a broken feature */
.conn-empty {
  margin-top: 12px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-soft);
}
.conn-item {
  display: flex;
  gap: 12px;
  align-items: baseline;
  padding: 8px 0;
  border-bottom: 1px solid var(--line-soft);
}
.conn-type {
  flex: none;
  min-width: 86px;
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gilt);
}
.conn-body { min-width: 0; font-size: 14.5px; line-height: 1.5; }
.conn-note { color: var(--ink-soft); font-size: 13.5px; margin-top: 3px; }
.conn-note-target { color: var(--ink); font-weight: 600; }

/* backlinks: collapse beyond the first 6 behind a native <details> toggle */
.conn-back-list .conn-item:last-of-type { border-bottom: none; }
.conn-more { margin-top: 2px; }
.conn-more summary {
  cursor: pointer;
  padding: 8px 0;
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--gilt);
  list-style: none;
}
.conn-more summary::-webkit-details-marker { display: none; }
.conn-more summary::before { content: "\203a\00a0"; }
.conn-more[open] summary::before { content: "\2039\00a0"; }
.conn-more .conn-item:last-child { border-bottom: none; }

/* prev / next pager */
.pager {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-top: 34px;
}
.pager a {
  padding: 14px 16px;
  color: inherit;
}
.pager .label { display: block; margin-bottom: 6px; }
.pager-title {
  font-size: 13.5px;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.pager a.next { text-align: right; }

/* reader action bar */
.reader-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin: 26px 0 8px;
}

/* end-of-atom teaser hook — a cliffhanger instead of a dead stop */
.next-thread {
  margin: 4px 0 10px;
  font-family: var(--serif);
  font-size: 15px;
  font-style: italic;
  color: var(--ink-soft);
}
.next-thread a { color: var(--accent); border-bottom: 1px dotted var(--accent); }
.next-thread a:hover { border-bottom-style: solid; text-decoration: none; }

/* session ticker — tonight's tally, under the reader crumb / Today hand */
.session-ticker {
  margin: -16px 0 26px;
  font-family: var(--serif);
  font-size: 13px;
  font-style: italic;
  color: var(--ink-faint);
}
.today .session-ticker { margin: 10px 0 0; }

/* swipe-trigger affordance: a brief nudge toward the turned page
   (mirrors the arrow-key pager; wired in 30-views-read.js) */
@keyframes swipe-nudge-prev {
  0% { transform: translateX(0); }
  35% { transform: translateX(16px); }
  100% { transform: translateX(0); }
}
@keyframes swipe-nudge-next {
  0% { transform: translateX(0); }
  35% { transform: translateX(-16px); }
  100% { transform: translateX(0); }
}
.reader.swipe-nudge-prev { animation: swipe-nudge-prev 220ms ease-out; }
.reader.swipe-nudge-next { animation: swipe-nudge-next 220ms ease-out; }

/* floating Limits jump — the crown-jewel section, one tap away */
.limits-jump {
  position: fixed;
  right: 22px;
  bottom: 26px;
  z-index: 35;
  padding: 9px 16px;
  border-radius: 20px;
  border: 1px solid var(--accent);
  background: var(--paper-2);
  color: var(--accent);
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  box-shadow: var(--shadow-lift);
}
.limits-jump:hover { background: var(--accent-soft); }

/* sol56 V1 #1: at the mobile width the pill used to float at right:22px,
   squarely inside the prose column, and could sit on top of whatever text
   had scrolled underneath it. Dock it flush to the viewport's right edge
   instead — rounded only on the inward corner, so it reads as a tab
   attached to the edge rather than a card floating over the column — and
   shrink it so its footprint stays inside the page's own right gutter
   (#view's 18px side padding) rather than the text measure. Still sits
   above the tab bar (bottom unchanged from desktop's base value). */
@media (max-width: 860px) {
  .limits-jump {
    right: 0;
    bottom: 96px;
    padding: 10px 11px 10px 14px;
    border-radius: 14px 0 0 14px;
    border-right: none;
    font-size: 11px;
  }
}

/* --- home ------------------------------------------------------------------------ */
.masthead { text-align: center; margin: 18px 0 40px; }
.masthead .fleuron { font-size: 22px; display: block; margin-bottom: 14px; }
.masthead h1 {
  font-size: clamp(30px, 4.5vw, 44px);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
}
.masthead .view-sub { margin: 12px auto 0; }
.masthead .rule {
  width: 180px;
  margin: 22px auto 0;
  background: linear-gradient(90deg, transparent, var(--gilt), transparent);
}

.home-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 16px; }
@media (max-width: 720px) { .home-cols { grid-template-columns: 1fr; } }

.cta-card { display: flex; flex-direction: column; gap: 10px; }
.cta-card .btn { align-self: flex-start; margin-top: 6px; }
.cta-kicker { font-size: 15px; color: var(--ink-soft); line-height: 1.5; }

/* second on-ramp beside the primary empty-state button (dashEmptyStateHTML,
   48-views-dashboard.js) — a quieter inline link, not a second .btn, so it
   reads as "or" rather than competing with the primary action */
.cta-alt-link {
  align-self: flex-start;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  border-bottom: 1px dotted var(--gilt);
}
.cta-alt-link:hover { color: var(--accent); border-bottom-style: solid; text-decoration: none; }
.resume-title {
  font-size: 16.5px;
  font-weight: 600;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.streak-flame { color: var(--accent); }

/* first-run starter five */
.starter-card { margin-top: 16px; }
.starter-card .cta-kicker { display: block; margin-top: 8px; }
.starter-rows { margin-top: 10px; }
.starter-rows .row:last-child { border-bottom: none; }

/* --- review ------------------------------------------------------------------------ */
.review-stage { max-width: 720px; margin: 0 auto; }
.review-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 26px;
}

/* --- notes (bridges/debates/chains) ---------------------------------------------- */
.note-kind-bridge { color: var(--gilt); }
.note-kind-debate { color: var(--accent); }
.note-kind-chain { color: var(--ok); }

.note-body { font-size: 17px; }
.note-body p { margin: 0 0 1.2em; }
.note-body h2, .note-body h3 { margin: 1.6em 0 0.7em; font-size: 1.08em; }
.note-body ul, .note-body ol { margin: 0 0 1.2em 1.4em; }
.note-body blockquote {
  margin: 0 0 1.2em;
  padding-left: 20px;
  border-left: 2px solid var(--gilt);
  color: var(--ink-soft);
  font-style: italic;
}

.note-refs { margin-top: 30px; border-top: 1px solid var(--line); padding-top: 22px; }
.note-refs .label { display: block; margin-bottom: 10px; }

/* --- settings ---------------------------------------------------------------------- */
.setting-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  padding: 18px 4px;
  border-bottom: 1px solid var(--line-soft);
}
.setting-main { flex: 1; }
.setting-name { font-weight: 600; font-size: 16px; }
.setting-desc { font-size: 13.5px; color: var(--ink-soft); margin-top: 3px; }
.setting-caption {
  margin-top: 8px;
  font-family: var(--sans);
  font-size: 12px;
  color: var(--ink-faint);
}
.seg { display: flex; border: 1px solid var(--line); border-radius: 20px; overflow: hidden; }
.seg button {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.05em;
  padding: 7px 14px;
  color: var(--ink-soft);
}
.seg button.active { background: var(--accent); color: var(--paper); }

/* theme dropdown */
.seg-select select {
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.03em;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--paper-2);
  color: var(--ink);
  cursor: pointer;
}
.seg-select select:hover { border-color: var(--gilt); }

/* sync-key field — same chrome as the theme dropdown above */
.key-input {
  font-family: var(--sans);
  font-size: 13px;
  letter-spacing: 0.03em;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--paper-2);
  color: var(--ink);
  width: 170px;
}
.key-input::placeholder { color: var(--ink-faint); }
.key-input:focus { outline: none; border-color: var(--gilt); }

.toast {
  position: fixed;
  bottom: 28px;
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  background: var(--ink);
  color: var(--paper);
  font-family: var(--sans);
  font-size: 13px;
  padding: 10px 22px;
  border-radius: 22px;
  box-shadow: var(--shadow-lift);
  opacity: 0;
  transition: opacity 0.25s ease, transform 0.25s ease;
  z-index: 60;
  pointer-events: none;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

@media (max-width: 860px) {
  .toast { bottom: 92px; }
}

/* ==========================================================================
   35-map: the atlas — chip bands, bezier edge overlay, detail panel
   ========================================================================== */

.map-tools { display: flex; gap: 12px; align-items: center; margin-bottom: 22px; }

#map-stage { position: relative; }

#map-svg {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  overflow: visible;
}

/* --- bands ------------------------------------------------------------- */
.map-band { padding: 16px 0 18px; border-top: 1px solid var(--line-soft); }
.map-band:first-of-type { border-top: none; }

.map-band-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 12px;
}
.map-band-head .mdot { align-self: center; }
.map-hint {
  font-family: var(--sans);
  font-size: 11.5px;
  font-style: italic;
  color: var(--ink-faint);
}

.map-chips { display: flex; flex-wrap: wrap; gap: 7px; }

/* --- chips --------------------------------------------------------------- */
.mchip, .map-band-head { --c: hsl(var(--h, 40) 38% 38%); }
/* every DARK pack needs the light chip variant — .mchip.sel paints
   var(--paper) text over --c, and 38%-lightness fills drop that text to
   ~3:1 on dark papers (found in the 2026-07 appearance review: only 3 of
   11 dark packs were listed). Keep this list in sync when adding packs. */
[data-theme="dark"] .mchip, [data-theme="dark"] .map-band-head,
[data-theme="slate"] .mchip, [data-theme="slate"] .map-band-head,
[data-theme="forest"] .mchip, [data-theme="forest"] .map-band-head,
[data-theme="midnight"] .mchip, [data-theme="midnight"] .map-band-head,
[data-theme="wine"] .mchip, [data-theme="wine"] .map-band-head,
[data-theme="phosphor"] .mchip, [data-theme="phosphor"] .map-band-head,
[data-theme="iris"] .mchip, [data-theme="iris"] .map-band-head,
[data-theme="ocean"] .mchip, [data-theme="ocean"] .map-band-head,
[data-theme="ember"] .mchip, [data-theme="ember"] .map-band-head,
[data-theme="plum"] .mchip, [data-theme="plum"] .map-band-head,
[data-theme="carbon"] .mchip, [data-theme="carbon"] .map-band-head {
  --c: hsl(var(--h, 40) 42% 66%);
}
.mchip.mc-bridge { --c: var(--gilt); }
.mchip.mc-debate { --c: var(--accent); }
.mchip.mc-chain { --c: var(--ok); }

.mchip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  max-width: 250px;
  padding: 5px 13px;
  border-radius: 18px;
  border: 1px solid var(--line);
  background: var(--paper-2);
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-soft);
  cursor: pointer;
  transition: opacity 0.18s ease, box-shadow 0.18s ease,
    border-color 0.18s ease, background 0.18s ease;
}
.mchip span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mchip:hover { border-color: var(--c); color: var(--ink); }

.mdot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--c, var(--gilt));
}

/* selection states */
.mchip.dim { opacity: 0.2; }
.mchip.lit {
  opacity: 1;
  border-color: transparent;
  box-shadow: 0 0 0 2px var(--c);
  color: var(--ink);
}
.mchip.sel {
  opacity: 1;
  background: var(--c);
  border-color: var(--c);
  color: var(--paper);
  box-shadow: var(--shadow-lift);
}
.mchip.sel .mdot { background: var(--paper); }

.mchip.mini { font-size: 11.5px; padding: 4px 11px; max-width: 100%; }

/* --- load skeleton: shimmer placeholders while map.json + the atoms index
   resolve (25-views-map.js mapSkeletonHTML/mapSkelBandHTML) — replaces the
   brief blank frame on the 32 MB corpus's first hit with a working signal.
   Static under reduced motion: a flat --paper-3 bar, no shimmer sweep. --- */
.map-skel-label {
  width: 78px;
  height: 11px;
  border-radius: 3px;
  margin-bottom: 12px;
  background: var(--paper-3);
}
.map-skel-chip {
  height: 28px;
  border-radius: 18px;
  background: linear-gradient(90deg,
    var(--paper-2) 25%, var(--paper-3) 37%, var(--paper-2) 63%);
  background-size: 400% 100%;
  animation: map-skel-shimmer 1.5s ease-in-out infinite;
}
@keyframes map-skel-shimmer {
  0% { background-position: 100% 0; }
  100% { background-position: 0 0; }
}
@media (prefers-reduced-motion: reduce) {
  .map-skel-chip { animation: none; background: var(--paper-3); }
}

/* --- detail panel ----------------------------------------------------------- */
#map-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(410px, 94vw);
  z-index: 45;
  background: var(--paper-2);
  border-left: 1px solid var(--line-soft);
  box-shadow: var(--shadow-lift);
  padding: 30px 26px 40px;
  overflow-y: auto;
  transform: translateX(105%);
  transition: transform 0.28s cubic-bezier(0.2, 0.65, 0.25, 1);
}
#map-panel.open { transform: none; }

.map-close {
  position: absolute;
  top: 12px;
  right: 16px;
  font-size: 24px;
  line-height: 1;
  color: var(--ink-faint);
  padding: 4px 8px;
}
.map-close:hover { color: var(--accent); }

.mp-title { font-family: var(--serif); font-size: 19px; line-height: 1.3; margin: 12px 0 4px; }
.mp-sub { font-family: var(--sans); font-size: 12px; color: var(--ink-faint); margin-bottom: 4px; }
.mp-desc { font-size: 14px; line-height: 1.55; color: var(--ink-soft); margin: 8px 0 4px; }

.mp-progress { margin: 14px 0 18px; }
.mp-progress .label { display: block; margin-top: 8px; }

.mp-group { margin-top: 18px; }
.mp-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }

.mp-connected { margin-top: 24px; border-top: 1px solid var(--line-soft); padding-top: 16px; }
.mp-connected > .label { color: var(--gilt); }

.mp-atoms { display: flex; flex-direction: column; margin-top: 8px; }
.mp-atom {
  display: flex;
  gap: 10px;
  align-items: baseline;
  padding: 8px 0;
  border-bottom: 1px solid var(--line-soft);
  color: inherit;
  font-size: 13.5px;
  line-height: 1.45;
}
.mp-atom:hover { background: var(--paper-3); text-decoration: none; }
.mp-atom-n {
  flex: none;
  min-width: 20px;
  text-align: right;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--gilt);
}
.mp-atom-t {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

#map-panel .btn { margin-top: 6px; }

@media (max-width: 860px) {
  .map-tools { flex-wrap: wrap; }
  #map-panel { padding-bottom: 110px; }
}

/* mobile atlas: bezier overlay off, panel neighbors become a LIST
   (edge skipping itself lives in 25-views-map.js MAP_LIST_QUERY) */
@media (max-width: 719px) {
  #map-svg { display: none; }
  .mp-chips { flex-direction: column; align-items: stretch; gap: 4px; }
  .mp-chips .mchip {
    max-width: 100%;
    justify-content: flex-start;
    border-radius: 8px;
  }
}

/* Wisdom Vault — 36-nav-simplify: the 4-tab mobile bar's supporting styles.
   Own file (not 30-views.css) so the concurrent material-skin lane and this
   Tower edit can never collide in one file. */

/* Library view: the Paths on-ramp that replaced the Paths tab */
.library-paths-link {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  margin-bottom: 22px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  color: var(--ink);
  text-decoration: none;
}
.library-paths-link:hover { border-color: var(--accent); }
.library-paths-link .lpl-arrow { margin-left: auto; color: var(--accent); }

/* More page: mobile-only navigate section (the sidebar rail is hidden under
   860px, so every non-tab destination needs this surface to stay reachable) */
.more-nav { display: none; }
@media (max-width: 860px) {
  .more-nav { display: block; margin-bottom: 26px; }
  .more-nav .chip-row { margin-top: 8px; }
  .more-nav .chip {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    text-decoration: none;
  }
}

/* ==========================================================================
   40-practical: reading paths, highlights & notes, export brief
   (theme-safe: tokens only — dark comes from 00-tokens overrides)
   ========================================================================== */

/* --- nav badge (brief count) ---------------------------------------------- */
.nav-badge {
  display: none;
  margin-left: auto;
  min-width: 20px;
  padding: 1px 6px;
  border-radius: 12px;
  background: var(--accent);
  color: var(--paper);
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 700;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.nav-badge.show { display: inline-block; }

/* --- brief toggle (compact star in rows, wide button in reader) ----------- */
.brief-toggle {
  position: relative; /* anchors the coarse-pointer hit-slop below */
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid var(--line);
  color: var(--ink-faint);
  font-size: 14px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s ease;
  align-self: center;
}
.brief-toggle:hover { border-color: var(--gilt); color: var(--gilt); }
.brief-toggle.on {
  background: var(--gilt-soft);
  border-color: transparent;
  color: var(--gilt);
}

/* --- small icon buttons (brief reorder, highlight remove) ----------------- */
.icon-btn {
  position: relative; /* anchors the coarse-pointer hit-slop below */
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  border: 1px solid var(--line-soft);
  color: var(--ink-soft);
  font-family: var(--sans);
  font-size: 13px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s ease;
}
.icon-btn:hover:not(:disabled) { border-color: var(--gilt); color: var(--ink); }
.icon-btn:disabled { opacity: 0.3; cursor: default; }

/* --- coarse-pointer hit-slop (AIL r1 code-lane #4) -------------------------
   .brief-toggle / .icon-btn / .canon-toggle (50-v2.css) are 30x30 / 28x28 —
   below the 44x44 touch-target floor. An invisible ::after centered on each
   button expands the CLICKABLE area to 44x44 on coarse (touch) pointers
   without growing the drawn circle/box — precision mouse pointers are
   untouched. */
@media (pointer: coarse) {
  .brief-toggle::after,
  .icon-btn::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
  }
}

/* --- paths ------------------------------------------------------------------ */
.path-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 18px;
}
.path-card { display: flex; flex-direction: column; }
.path-title {
  font-family: var(--serif);
  font-size: 21px;
  font-weight: 600;
  margin-top: 10px;
  line-height: 1.3;
}
.path-desc {
  margin-top: 8px;
  font-size: 13.5px;
  color: var(--ink-soft);
  line-height: 1.55;
  flex: 1;
}

.path-step { align-items: center; }
.step-no {
  flex: none;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-faint);
  min-width: 22px;
  font-variant-numeric: tabular-nums;
}
.path-step.stop {
  background: var(--gilt-soft);
  border-left: 3px solid var(--gilt);
  border-radius: 6px;
  padding-left: 10px;
}
.stop-glyph { flex: none; color: var(--gilt); font-size: 15px; align-self: center; }

/* in-reader path navigation bar */
.path-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0 0 22px;
  padding: 14px 18px;
  border: 1px solid var(--line-soft);
  border-left: 3px solid var(--gilt);
  border-radius: 10px;
  background: var(--paper-2);
  box-shadow: var(--shadow);
}
.path-bar-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.path-bar-title {
  font-family: var(--serif);
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
}
.path-bar-count {
  font-family: var(--sans);
  font-size: 11.5px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.path-bar-nav { display: flex; gap: 8px; flex: none; }

/* --- highlight affordance ------------------------------------------------- */
.hl-float {
  position: absolute;
  z-index: 60;
  display: none;
  padding: 7px 14px;
  border-radius: 18px;
  border: 1px solid var(--gilt);
  background: var(--paper-2);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  box-shadow: var(--shadow-lift);
}
.hl-float.show { display: inline-flex; }
.hl-float:hover { background: var(--gilt-soft); }

/* --- highlights + note panel (reader) -------------------------------------- */
.mynote-panel {
  margin-top: 34px;
  padding: 20px 22px;
  border: 1px solid var(--line-soft);
  border-radius: 12px;
  background: var(--paper-2);
}
.hl-list { margin-top: 10px; }
.hl-item { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 8px; }
.hl-item .hl-quote { flex: 1; }
.hl-quote {
  margin: 0 0 8px;
  padding: 8px 14px;
  border-left: 3px solid var(--gilt);
  background: var(--gilt-soft);
  border-radius: 0 8px 8px 0;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink-soft);
  font-style: italic;
}
.hl-hint { font-size: 13px; color: var(--ink-faint); font-style: italic; }
.note-input {
  width: 100%;
  margin-top: 8px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.55;
  resize: vertical;
}
.note-input:focus { outline: none; border-color: var(--gilt); }
.note-saved {
  display: inline-block;
  margin-top: 6px;
  font-family: var(--sans);
  font-size: 11px;
  color: var(--ok);
  min-height: 14px;
}

/* --- my notes view ----------------------------------------------------------- */
.mynote-group { margin-bottom: 34px; }
.mynote-entry {
  margin-top: 12px;
  padding: 14px 16px;
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  background: var(--paper-2);
}
.mynote-title {
  display: block;
  font-family: var(--serif);
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 8px;
  line-height: 1.4;
}
.note-text { font-size: 14.5px; color: var(--ink-soft); line-height: 1.6; }

/* --- brief view ----------------------------------------------------------------- */
.brief-row { align-items: center; }
/* AIL r2 (item 7 / sol finding #6): the three .icon-btn siblings here
   (move up / move down / remove) are 28px drawn with 44x44 coarse-
   pointer hit-slop each (see the note above); at the old 5px gap, the
   centers sat only 33px apart while two 44px slop zones need >=44px of
   center separation, so the invisible hit areas overlapped by 11px and
   a tap near the boundary could hit the wrong control. 18px clears it:
   28 + 18 = 46 >= 44, a small margin over the exact 44px threshold. */
.brief-ctl { display: flex; gap: 18px; }

/* ==========================================================================
   50-v2: Reading Experience v2 — today hand, thread/debate flow bars,
   canon star, weighted mastery, listen panel, debate reading mode
   (theme-safe: tokens only — packs come from 00-tokens overrides)
   ========================================================================== */

/* --- today: the five-minute ritual (home hero) ----------------------------- */
.today { margin: 0 0 40px; }
.today-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 14px;
}
.today-date {
  font-family: var(--serif);
  font-size: 14px;
  font-style: italic;
  color: var(--ink-soft);
}
.today-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
}
.today-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 18px 20px;
  border-top: 3px solid var(--gilt);
}
.today-card[data-slot="path"] { border-top-color: var(--accent); }
.today-card[data-slot="spaced"] { border-top-color: var(--gilt); }
.today-card[data-slot="semantic"] { border-top-color: var(--ok); }
.today-card .label { letter-spacing: 0.14em; }
.today-title {
  font-size: 15.5px;
  font-weight: 600;
  line-height: 1.42;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.today-sub {
  font-family: var(--sans);
  font-size: 12px;
  color: var(--ink-faint);
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.today-actions {
  margin-top: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding-top: 6px;
}
.today-actions .btn { padding: 7px 15px; font-size: 12px; }
/* stills r1: the random-atom link read as small/low-contrast annotation
   sitting just above the fixed mobile tab bar. --ink-soft (one step
   darker than --ink-faint) + a min-height flex anchor turn it into a
   real, fully tappable secondary action (the anchor itself is the
   44px-tall box, not just its text line). */
.today-foot {
  margin-top: 12px;
  font-family: var(--sans);
  font-size: 12.5px;
}
.today-foot a {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: var(--ink-soft);
}
.today-foot a:hover { color: var(--accent); }

/* --- flow bars: thread trail + debate mode --------------------------------- */
.path-bar.trail-bar { border-left-color: var(--accent); }
.path-bar.debate-bar { border-left-color: var(--accent); }
.debate-bar .path-bar-title,
.trail-bar .path-bar-title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 14.5px;
}

/* --- canon star (compact in rows, wide button in reader) ------------------- */
.canon-toggle {
  position: relative; /* anchors the coarse-pointer hit-slop below */
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid var(--line);
  color: var(--ink-faint);
  font-size: 14px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s ease;
  align-self: center;
}
.canon-toggle:hover { border-color: var(--accent); color: var(--accent); }
.canon-toggle.on {
  background: var(--accent-soft);
  border-color: transparent;
  color: var(--accent);
}
/* coarse-pointer hit-slop — same technique as .brief-toggle/.icon-btn
   (40-practical.css, AIL r1 code-lane #4): 44x44 invisible tap zone,
   drawn circle unchanged. */
@media (pointer: coarse) {
  .canon-toggle::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
  }
}

/* --- listen panel ----------------------------------------------------------- */
.listen-panel {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin-top: 16px;
  padding: 12px 16px;
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  background: var(--paper-2);
}
.listen-ctl {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}
.listen-ctl select {
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  padding: 5px 10px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
}
.listen-ctl select:hover { border-color: var(--gilt); }

/* --- debate reading mode (flow overview) ------------------------------------- */
.debate-group { margin-bottom: 30px; }
.debate-group > .label { display: block; }
.side-a { color: var(--gilt); }
.side-b { color: var(--accent); }
.side-m { color: var(--ok); }
.side-note { color: var(--ink-soft); }
.debate-step { align-items: center; }

/* --- home: single-column resume when the hand owns the hero ------------------ */
.home-cols.one { grid-template-columns: 1fr; }

/* --- home: momentum strip under the Today hand ------------------------------- */
.home-momentum { margin: -24px 0 36px; }
.home-momentum .session-ticker { margin: 0 0 10px; }

/* streak-at-risk cue — a quiet line, never a popup */
.streak-risk {
  margin: 0 0 12px;
  font-family: var(--serif);
  font-size: 13.5px;
  font-style: italic;
}
.streak-risk a { color: var(--accent); }
.streak-risk a:hover { text-decoration: underline; }

/* nearly-finished nudges — up to two cards, side by side where room allows */
.nearly-done-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 14px;
  margin-top: 4px;
}
.nearly-done {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px 18px;
  border-left: 3px solid var(--gilt);
  color: inherit;
}
.nearly-done-line { font-size: 14.5px; line-height: 1.5; }
.nearly-done-line em { color: var(--accent); font-style: italic; }

/* --- first run -----------------------------------------------------------
   Before any atom is read, the four progress stats are all zero — a wall of
   zeros reads as failure on a vault the reader has not started yet. Show the
   vault's own scale instead, and name the one action that begins it. Once any
   progress exists the stat grid returns (20-views-browse.js). */
.first-run {
  margin-top: 26px;
  padding: 26px 28px 28px;
  border: 1px solid var(--line-soft);
  border-radius: 14px;
  background: linear-gradient(180deg, var(--paper-2), var(--paper));
}
.first-run-lede {
  margin: 12px 0 0;
  max-width: 58ch;
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink);
}
.first-run-scale {
  margin: 14px 0 0;
  font-family: var(--sans);
  font-size: 13px;
  color: var(--ink-faint);
}

/* ==========================================================================
   55-dashboard: Reading Dashboard — habit strip, read history, domain
   coverage (theme-safe: tokens only — packs come from 00-tokens overrides)
   ========================================================================== */

.dash-section { margin-top: 40px; }
.dash-section:first-of-type { margin-top: 0; }

/* --- home: entry card into the dashboard (fallback entry point — the
   375px tab bar overflowed at 7 items, see PR notes) --------------------- */
.dash-entry-card { margin-top: 16px; }
.dash-entry-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-top: 6px;
}
.dash-entry-text {
  font-size: 14.5px;
  color: var(--ink-soft);
  line-height: 1.5;
}
.dash-entry-arrow {
  flex: none;
  color: var(--gilt);
  font-size: 18px;
}

/* --- habit: book-equivalent line under the atoms-read stat -------------- */
.dash-book-eq {
  margin-top: 8px;
  font-family: var(--serif);
  font-size: 13px;
  font-style: italic;
  color: var(--ink-soft);
}

/* --- habit: real word totals (atoms-read stat + this-week/last-week stat) */
.dash-words-total {
  margin-top: 4px;
  font-family: var(--sans);
  font-size: 12px;
  color: var(--ink-faint);
}
.dash-week-words {
  margin-top: 6px;
  font-family: var(--sans);
  font-size: 11.5px;
  color: var(--ink-faint);
}

/* --- habit: most recent book-equivalent milestone ------------------------ */
.dash-milestone {
  margin-top: 12px;
  font-family: var(--serif);
  font-size: 13.5px;
  font-style: italic;
  color: var(--ink-soft);
}

/* --- habit: month-on-month velocity line --------------------------------- */
.dash-velocity {
  margin-top: 10px;
  font-family: var(--serif);
  font-size: 13.5px;
  font-style: italic;
  color: var(--ink-soft);
}

/* --- domain coverage: whole-vault pace forecast --------------------------- */
.dash-forecast {
  margin-top: 16px;
  font-family: var(--serif);
  font-size: 13.5px;
  font-style: italic;
  color: var(--ink-soft);
}

/* --- habit: 12-week activity strip --------------------------------------- */
.dash-heat-card { display: flex; flex-direction: column; }
.dash-heat-wrap { display: flex; gap: 5px; align-items: flex-start; }
.dash-heat-labels {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: none;
}
.dash-heat-daylabel {
  height: 13px;
  line-height: 13px;
  font-family: var(--sans);
  font-size: 9px;
  color: var(--ink-faint);
  text-align: right;
}
.dash-heat {
  display: flex;
  gap: 3px;
  overflow-x: auto;
}
.dash-heat-week {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.dash-heat-cell {
  width: 13px;
  height: 13px;
  border-radius: 3px;
  background: var(--line-soft);
}
.dash-heat-cell[data-level="1"] { background: var(--gilt-soft); }
.dash-heat-cell[data-level="2"] { background: color-mix(in srgb, var(--gilt) 55%, var(--paper-2)); }
.dash-heat-cell[data-level="3"] { background: color-mix(in srgb, var(--accent) 60%, var(--gilt)); }
.dash-heat-cell[data-level="4"] { background: var(--accent); }
.dash-heat-cell[data-today="1"] { outline: 2px solid var(--gilt); outline-offset: 1px; }
.dash-heat-cell.future { visibility: hidden; }
.dash-heat-legend {
  margin-top: 10px;
  display: flex;
  align-items: center;
  gap: 4px;
  font-family: var(--sans);
  font-size: 10.5px;
  color: var(--ink-faint);
}
.dash-heat-legend .dash-heat-cell { width: 11px; height: 11px; }

/* --- habit: 12-week words-per-week bar chart ------------------------------ */
.dash-weekly-card { display: flex; flex-direction: column; }
.dash-weekly-chart-wrap { display: flex; flex-direction: column; gap: 8px; }
.dash-weekly-chart { width: 100%; height: 90px; display: block; }
.dash-week-bar { fill: var(--gilt-soft); }
.dash-week-bar.best { fill: var(--accent); }
.dash-week-best {
  font-family: var(--serif);
  font-size: 12.5px;
  font-style: italic;
  color: var(--ink-soft);
}

/* --- what I've read: relative-date side label ---------------------------- */
.dash-recent-when {
  font-family: var(--sans);
  font-size: 12px;
  color: var(--ink-faint);
  white-space: nowrap;
}

/* --- domain coverage: frontier nudge (least-recently-touched shelf) ------ */
.dash-frontier {
  margin-bottom: 14px;
  font-family: var(--serif);
  font-size: 13.5px;
  font-style: italic;
  color: var(--ink-soft);
}
.dash-frontier a { color: var(--accent); }

/* --- domain coverage rows -------------------------------------------------- */
.dash-domain-row {
  padding: 14px 6px;
  border-bottom: 1px solid var(--line-soft);
}
.dash-domain-row:last-child { border-bottom: none; }
.dash-domain-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 8px;
}
.dash-domain-name {
  font-size: 15.5px;
  font-weight: 600;
  color: inherit;
}
.dash-domain-name:hover { color: var(--accent); text-decoration: none; }
.dash-domain-nums {
  flex: none;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* --- whole-vault equivalence footer ---------------------------------------- */
.dash-vault-eq { font-style: italic; }

/* ==========================================================================
   56-history: full read-history browse (#/history) — time/source/domain
   buckets rendered as native <details> (mirrors .conn-more in 30-views.css),
   the By time/By source/By domain toggle (mirrors the .fchip/.fchip.active
   filter-chip idiom in 20-components.css), and the revision-status chip.
   Theme-safe: tokens only — packs come from 00-tokens overrides.
   ========================================================================== */

.hist-mode-row .fchip { cursor: pointer; }

/* --- buckets: native <details>/<summary>, same chevron idiom as
   .conn-more (30-views.css) so collapse behavior reads as one system ---- */
.hist-bucket { margin-bottom: 4px; border-bottom: 1px solid var(--line-soft); }
.hist-bucket:last-child { border-bottom: none; }
.hist-bucket-head {
  cursor: pointer;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 2px;
  list-style: none;
}
.hist-bucket-head::-webkit-details-marker { display: none; }
.hist-bucket-label {
  font-family: var(--serif);
  font-size: 15.5px;
  font-weight: 600;
  color: var(--ink);
}
.hist-bucket-label::before { content: "\203a\00a0"; color: var(--gilt); }
.hist-bucket[open] > .hist-bucket-head .hist-bucket-label::before { content: "\2039\00a0"; }
.hist-bucket-count {
  flex: none;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.hist-bucket-rows { padding-bottom: 6px; }

/* --- per-row side: revision-status chip + relative date, stacked -------- */
.hist-row-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}

/* --- revision-status chip (reuses the base .chip shape; two color reads:
   overdue = the same warm "gilt" the app already uses for due/kept states,
   scheduled = a quiet neutral) ------------------------------------------- */
.hist-status { white-space: nowrap; }
.hist-status-due { border-color: transparent; background: var(--gilt-soft); color: var(--gilt); }
.hist-status-scheduled { color: var(--ink-faint); }

/* --- dashboard: "See all N reads →" hand-off link, sized to sit quietly
   under the countsHTML chip-row above it ---------------------------------- */
.dash-see-all-history {
  display: inline-block;
  margin-top: 10px;
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--gilt);
}
.dash-see-all-history:hover { color: var(--accent); text-decoration: none; }
