/* ============================================================
   CODEX ATLAS — stylesheet

   🛑 CONTENT AGENTS: DO NOT EDIT THIS FILE.
   This is app code (CSS), not vault content. Content agents should
   only stage files under 01_traditions/ … 09_symbols/ + 00_meta/.
   See AGENTS.md "CONTENT AGENTS MUST NOT TOUCH APP CODE" for the rule.
   ============================================================

   ╔══════════════════════════════════════════════════════════╗
   ║  MASTER STYLE GUIDE — Phase 21O (2026-05-21)             ║
   ║  Canonical UI primitives. Reuse, don't reinvent.         ║
   ║                                                          ║
   ║  POPUP MENUS (dropdown lists of named options):          ║
   ║    .nav-hub-menu / .nh-item     ← global view-switcher   ║
   ║    .forge-mode-menu / .fm-item  ← in-view picker (modes) ║
   ║    Both share: 12-px rounded border, gold-22 border,     ║
   ║    rgba(13,17,25,0.88-0.92) bg, blur(16px), 240 z,       ║
   ║    grow-from-trigger scale+opacity transition, items     ║
   ║    with gold border-left on hover/active.                ║
   ║    → Build new ones as .nh-* or .fm-* aliases. Don't     ║
   ║      introduce a third "panel of options" primitive.     ║
   ║                                                          ║
   ║  BOOLEAN TOGGLE ROWS (label + ON/OFF):                   ║
   ║    .forge-viewset-row .vs-check  ← 14×14 square box      ║
   ║    Empty box = OFF, gold-filled box = ON. No row-level   ║
   ║    border/background to signal state — the BOX is the    ║
   ║    indicator. Hover gets a faint gold-tint background    ║
   ║    only as an affordance.                                ║
   ║    → Build new boolean toggles around this primitive.    ║
   ║                                                          ║
   ║  PILL CONTAINERS (top-left FORGE status strip,           ║
   ║                   bottom-bar zoom/legend/view buttons):  ║
   ║    36-px height, 10-px radius, gold-22 border,           ║
   ║    rgba(13,17,25,0.78) bg, blur(12px), 230 z.            ║
   ║                                                          ║
   ║  DIVIDER PATTERN inside a pill (e.g. FORGE | Deities):   ║
   ║    Use `border-left: 1px solid rgba(212,165,90,0.28)`    ║
   ║    on the right segment. Hide any `·` separator span     ║
   ║    next to it. NEVER nest a bordered box inside another  ║
   ║    bordered box — that's the "ugly nested pill" trap.    ║
   ║                                                          ║
   ║  ETHIC: every Phase ≥21 commit should either REUSE one   ║
   ║  of these primitives or update this header to add a new  ║
   ║  one. Drift between similar-purpose components is what   ║
   ║  produces "ugly" feedback loops. If you find a new       ║
   ║  shared pattern, document it here and refer agents to    ║
   ║  this block from the inline class comments.              ║
   ╚══════════════════════════════════════════════════════════╝
   ============================================================ */
:root {
  --bg-0: #07090f;
  --bg-1: #0d1119;
  --bg-2: #141a26;
  --bg-3: #1c2333;
  --border: #232b3d;
  --border-soft: #1a2030;
  --text-0: #f1ede2;
  --text-1: #c8c4b8;
  --text-2: #8b8e98;
  --text-3: #5a5e6a;
  --gold: #d4a55a;
  --gold-soft: #a87f3e;
  --copper: #c47453;
  --sage: #6e8c6b;
  --crimson: #c44a5a;
  --indigo: #5a6cc4;
  --slate: #4a5a7a;

  --nav-w: 220px;
  --detail-w: 400px;
  --nav-w-collapsed: 48px;
  /* --detail-w-collapsed DELETED 2026-06-10 (INCIDENT §4): collapsed
     panel reserves nothing; the V01 36px rail is gone. */
  /* Effective panel widths — override on body.nav/detail-collapsed so
     svg#svg can compute an explicit width that Safari reads correctly. */
  --eff-nav-w:    var(--nav-w);
  --eff-detail-w: var(--detail-w);

  --serif: "Cormorant Garamond", "Iowan Old Style", Palatino, Georgia, serif;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;

  /* TYPE SCALE — the only legal font-size vocabulary. See 00_meta/app-architecture.md §2. */
  --h1-size: 22px;   /* modal / panel titles (detail h3 sits here) */
  --h2-size: 16px;   /* in-pane section titles */
  --h3-size: 14px;   /* sub-section / row title */
  --lbl-lg: 12px;    /* primary labels (nav items) */
  --lbl-md: 10.5px;  /* secondary labels (subtitle, row meta) */
  --lbl-sm: 9.5px;   /* caps section labels */
  --micro:  9.2px;   /* SVG micro-labels only */

  /* MOTION — keep these three durations / curve. See architecture §1. */
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --t-micro:   140ms;
  --t-layout:  240ms;
  --t-overlay: 280ms;

  /* Premium-motion tokens — from Stripe (Benjamin De Cock) + Linear refresh +
     Cosmograph defaults. Use these for graph + interactive surfaces.
     AUDIT/premium-dynamics-research-2026-05-17.md for full sourcing. */
  --ease-out-expo:  cubic-bezier(0.16, 1, 0.3, 1);   /* state changes (Linear, Stripe entrances) */
  --ease-out-quart: cubic-bezier(0.165, 0.84, 0.44, 1); /* draw-ins / reveals (Stripe SVG lines) */
  --ease-standard:  cubic-bezier(0.4, 0, 0.2, 1);    /* Material standard — back-and-forth state */
  --motion-instant: 120ms;   /* button-state floor (Linear ~120-150) */
  --motion-quick:   180ms;   /* hover / selection state change */
  --motion-base:    260ms;   /* dim / blur layering transitions */
  --motion-slow:    420ms;   /* draw-in / reveal */
  /* Dim opacity floor (Datawrapper 0.15 / Cosmograph 0.10) — premium not academic */
  --dim-opacity:    0.15;
  --dim-blur:       2px;

  /* SOURCE-INTEGRITY TIER COLORS — used only when body.tier-overlay-on is set.
     Scale: T1 (primary, deep gold) → T2 (scholarly, silver) → T3 (reputable secondary, warm grey)
     → T4 (controversial-but-catalogued, muted crimson) → none (no refs yet, faint). */
  --tier-1:    #d4a55a;
  --tier-2:    #b8c3d0;
  --tier-3:    #8a8a82;
  --tier-4:    #a85a5a;
  --tier-none: #3e424a;

  --panel-bg:     rgba(13, 17, 25, 0.82);
  --panel-blur:   blur(18px) saturate(140%);
  --panel-shadow: 0 12px 32px -8px rgba(0,0,0,0.55);
  --panel-edge:   1px solid rgba(35, 43, 61, 0.55);
}

* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--bg-0); color: var(--text-1);
  font-family: var(--sans); font-size: 13px; line-height: 1.5;
  overflow: hidden;
  transition: background 320ms ease, color 320ms ease;
}

/* ─── Global scrollbar primitive (2026-05-28) ───
   Thin gold-translucent bar with breathing room top + bottom so it
   doesn't kiss the container edges. Applies to every scrollable
   box (.app-pill-menu, .forge-side-panel, .forge-reader-body,
   .forge-viewset-panel, .dp-body, .sr-* etc.). Container-specific
   rules already in this file override these for the bits that
   need different aesthetic (e.g. dp-body had its own 6px rule —
   now redundant with this primitive, left intact for now).
   Firefox: scrollbar-width:thin only allows 2 width steps (thin/
   auto) — width is a hint, not exact. Webkit honors the 6px. */
* {
  scrollbar-width: thin;
  scrollbar-color: rgba(212,165,90,0.28) transparent;
}
*::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
*::-webkit-scrollbar-track {
  background: transparent;
  margin: 10px 0;          /* top/bottom breathing room — vertical bars */
}
*::-webkit-scrollbar-track:horizontal {
  margin: 0 10px;          /* left/right breathing room — horizontal bars */
}
*::-webkit-scrollbar-thumb {
  background: rgba(212,165,90,0.22);
  border-radius: 3px;
  transition: background 120ms ease;
}
*::-webkit-scrollbar-thumb:hover {
  background: rgba(212,165,90,0.40);
}
*::-webkit-scrollbar-corner { background: transparent; }

/* FOCUS-VISIBLE UTILITY — every keyboard-reachable control gets a visible ring.
   Per architecture §4: any selector that overrides this must provide a replacement,
   never `outline: none` alone. Mouse-click focus is suppressed (no ring) — only
   keyboard navigation surfaces it. */
:where(button, select, input, textarea, [role="button"], [tabindex]):focus { outline: none; }
:where(button, select, input, textarea, [role="button"], [tabindex]):focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 3px;
}

/* ---------- STYLE PRESETS (palette + typography fused) ---------- */
/* Default = Codex (defined in :root). Each body.style-* class overrides BOTH color vars and font vars. */

/* Default = Codex (defined in :root — kept unchanged). The featured set was
   curated 2026-07-16 (John's direction) down to three top-tier alternates:
   Quantum (mono-minimal), Human (warm light), Mystic (blue→purple glass).
   The prior 12 experimental presets were retired the same commit. Each
   body.style-* rebinds tokens only (+ a small scoped tweak where the
   preset's identity demands it — architecture §6). --serif stays a serif. */

/* QUANTUM — mono-minimal. Near-black + greys + white; the chrome desaturates
   to silver so the colourful lore imagery on the canvas speaks for itself. */
body.style-quantum {
  --bg-0: #060607; --bg-1: #0e0e10; --bg-2: #161618; --bg-3: #202023;
  --border: #2b2b2f; --border-soft: #191919;
  --text-0: #fafafa; --text-1: #c6c6ca; --text-2: #86868c; --text-3: #55555b;
  --gold: #f0f0f2; --gold-soft: #9a9aa0;                 /* accent = near-white, not gold */
  --copper: #b8b8bc; --sage: #a4a4a8; --crimson: #cccccf; --indigo: #b0b0b6; --slate: #6c6c72;
  --panel-bg: rgba(14, 14, 16, 0.74);
  --panel-blur: blur(14px) saturate(105%);
  --panel-edge: 1px solid rgba(255, 255, 255, 0.08);
  --panel-shadow: 0 14px 34px -10px rgba(0, 0, 0, 0.7);
}

/* HUMAN — modern & quiet. Neutral muted-grey dark palette at the same
   brightness as the working dark themes (so the graph stays clean), with the
   identity carried by a super-clean modern SANS (Inter) rather than colour.
   DELIBERATE architecture-§6 exception (John, 2026-07-16): --serif is set to a
   sans here on purpose — Human's whole character is the clean sans display
   type, so headings intentionally render in Inter, not a serif. Accent stays a
   restrained warm neutral so the greys + type do the standing-out. */
body.style-human {
  --bg-0: #0f0f11; --bg-1: #161619; --bg-2: #1e1e22; --bg-3: #28282e;
  --border: #34343b; --border-soft: #202024;
  --text-0: #f2f2f4; --text-1: #c2c2c8; --text-2: #86868e; --text-3: #56565e;
  --gold: #c2b4a2; --gold-soft: #8f8477;                 /* restrained warm-neutral accent */
  --copper: #b28d74; --sage: #8b9a86; --crimson: #b1848c; --indigo: #8b93ac; --slate: #797f8a;
  --panel-bg: rgba(22, 22, 25, 0.74);
  --panel-blur: blur(16px) saturate(105%);
  --panel-edge: 1px solid rgba(255, 255, 255, 0.07);
  --panel-shadow: 0 14px 34px -12px rgba(0, 0, 0, 0.6);
  --serif: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --sans:  "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

/* MYSTIC — a smooth blue→purple field, gold + white type, and glass panels
   (12px blur, low opacity) that float for a 3-D read. Restrained, not garish. */
body.style-mystic {
  --bg-0: #0b0a1e; --bg-1: #141232; --bg-2: #1d1a44; --bg-3: #2a2660;
  --border: #3a3470; --border-soft: #241f4e;
  --text-0: #ffffff; --text-1: #d9d3ec; --text-2: #a49ccb; --text-3: #6f68a0;
  --gold: #e8c878; --gold-soft: #b89a54;                 /* gold type */
  --copper: #c88fd6; --sage: #8fa4e6; --crimson: #d67aae; --indigo: #7c86ec; --slate: #5a5490;
  --panel-bg: rgba(24, 20, 54, 0.52);                    /* low-opacity glass */
  --panel-blur: blur(12px) saturate(150%);               /* the 12px John asked for */
  --panel-edge: 1px solid rgba(184, 164, 230, 0.20);
  --panel-shadow: 0 18px 44px -12px rgba(0, 0, 0, 0.62);
}
/* Smooth blue→purple field behind the glass. Scoped bg tweak — precedent:
   style-technical's scoped rules. Kept subtle so panels stay readable. */
body.style-mystic {
  background:
    radial-gradient(ellipse at 18% -5%, rgba(96, 116, 224, 0.30), transparent 55%),
    radial-gradient(ellipse at 88% 105%, rgba(150, 92, 214, 0.32), transparent 55%),
    linear-gradient(152deg, #0b0a1e 0%, #171338 46%, #241a48 100%);
  background-attachment: fixed;
}

/* ---------- STYLE DROPDOWN (preset picker button + menu) ---------- */
.style-button {
  background: transparent; border: 1px solid var(--border);
  color: var(--text-1); font-family: var(--sans); font-size: 10.5px;
  padding: 5px 10px; border-radius: 3px; cursor: pointer;
  letter-spacing: 0.14em; text-transform: uppercase;
  display: flex; align-items: center; gap: 8px;
  transition: all 160ms ease;
}
.style-button:hover { border-color: var(--gold-soft); color: var(--gold); }
.style-button.open { border-color: var(--gold); color: var(--gold); background: rgba(212,165,90,0.08); }
.style-button .caret { font-size: 9px; transition: transform 180ms ease; }
.style-button.open .caret { transform: rotate(180deg); }
.style-button .swatch-dot {
  width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0;
  background: var(--gold); box-shadow: 0 0 0 1px rgba(255,255,255,0.18);
}

.style-menu {
  position: fixed;
  left: calc(var(--nav-w) + 8px); bottom: 56px;
  width: 240px;
  transition: left 220ms ease, bottom 180ms ease,
              transform 200ms cubic-bezier(0.2, 0.8, 0.2, 1),
              opacity 160ms ease,
              visibility 0s linear 200ms;
  background: linear-gradient(180deg, rgba(13,17,25,0.97), rgba(7,9,15,0.98));
  backdrop-filter: blur(14px);
  border: 1px solid var(--gold-soft);
  border-radius: 4px;
  padding: 6px;
  z-index: 250;
  box-shadow: 0 12px 36px rgba(0,0,0,0.6);
  transform: translateY(8px);
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: transform 200ms cubic-bezier(0.2, 0.8, 0.2, 1),
              opacity 160ms ease,
              visibility 0s linear 200ms;
}
.style-menu.open {
  transform: translateY(0);
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
  transition: transform 200ms cubic-bezier(0.2, 0.8, 0.2, 1),
              opacity 160ms ease,
              visibility 0s linear 0s;
}
.style-option {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 9px; border-radius: 3px;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background 120ms ease, border-color 120ms ease;
}
.style-option:hover { background: rgba(255,255,255,0.04); }
.style-option.active { background: rgba(212,165,90,0.08); border-color: var(--gold-soft); }
.style-option .so-swatch {
  width: 14px; height: 14px; border-radius: 50%;
  flex-shrink: 0;
  border: 1px solid rgba(255,255,255,0.15);
}
.style-option .so-name {
  font-size: 12.5px; letter-spacing: 0.04em;
  flex: 1;
  color: var(--text-1);
}
.style-option.active .so-name { color: var(--gold); }
.style-option .so-tag {
  font-family: "JetBrains Mono", "IBM Plex Mono", monospace; font-size: 9px;
  color: var(--text-3); letter-spacing: 0.06em; text-transform: uppercase;
}

/* Per-preset swatches (background = bg-0, dot = accent) */
.style-option[data-style="codex"]       .so-swatch { background: radial-gradient(circle at 65% 35%, #d4a55a 0 4px, transparent 5px), #07090f; }
.style-option[data-style="crypt"]       .so-swatch { background: radial-gradient(circle at 65% 35%, #ffd980 0 4px, transparent 5px), #000; }
.style-option[data-style="mystic"]      .so-swatch { background: radial-gradient(circle at 65% 35%, #c8a4e0 0 4px, transparent 5px), #0a0814; }
.style-option[data-style="twilight"]    .so-swatch { background: radial-gradient(circle at 65% 35%, #e8a888 0 4px, transparent 5px), #08101c; }
.style-option[data-style="technical"]   .so-swatch { background: radial-gradient(circle at 65% 35%, #5e95d9 0 4px, transparent 5px), #0a0a0a; }
.style-option[data-style="parchment"]   .so-swatch { background: radial-gradient(circle at 65% 35%, #6e4818 0 4px, transparent 5px), #f4ecd8; border-color: rgba(0,0,0,0.18); }
.style-option[data-style="nag-hammadi"] .so-swatch { background: radial-gradient(circle at 65% 35%, #e4b070 0 4px, transparent 5px), #120c06; }
.style-option[data-style="passion"]     .so-swatch { background: radial-gradient(circle at 65% 35%, #c08440 0 4px, transparent 5px), #14080a; }
.style-option[data-style="atlantis"]    .so-swatch { background: radial-gradient(circle at 65% 35%, #d8b478 0 4px, transparent 5px), #061824; }
.style-option[data-style="eye"]         .so-swatch { background: radial-gradient(circle at 65% 35%, #f0c860 0 4px, transparent 5px), #050505; }
.style-option[data-style="hermes"]      .so-swatch { background: radial-gradient(circle at 65% 35%, #c8b890 0 4px, transparent 5px), #16181c; }
.style-option[data-style="vatican"]     .so-swatch { background: radial-gradient(circle at 65% 35%, #903828 0 4px, transparent 5px), #f0e8d4; border-color: rgba(0,0,0,0.18); }
.style-option[data-style="orthodox"]    .so-swatch { background: radial-gradient(circle at 65% 35%, #e8b860 0 4px, transparent 5px), #1a0810; }

/* Per-preset font preview in the option label */
.style-option[data-style="codex"]       .so-name { font-family: "Cormorant Garamond", Georgia, serif; }
.style-option[data-style="crypt"]       .so-name { font-family: "EB Garamond", Georgia, serif; }
.style-option[data-style="mystic"]      .so-name { font-family: "Cormorant Garamond", Georgia, serif; }
.style-option[data-style="twilight"]    .so-name { font-family: "Inter", system-ui, sans-serif; }
.style-option[data-style="technical"]   .so-name { font-family: "IBM Plex Sans", "Inter", system-ui, sans-serif; font-size: 11.5px; letter-spacing: 0; }
.style-option[data-style="parchment"]   .so-name { font-family: "EB Garamond", Georgia, serif; }
.style-option[data-style="nag-hammadi"] .so-name { font-family: "Cormorant Garamond", Georgia, serif; }
.style-option[data-style="passion"]     .so-name { font-family: "EB Garamond", Georgia, serif; }
.style-option[data-style="atlantis"]    .so-name { font-family: "Cormorant Garamond", Georgia, serif; }
.style-option[data-style="eye"]         .so-name { font-family: "EB Garamond", Georgia, serif; letter-spacing: 0.08em; }
.style-option[data-style="hermes"]      .so-name { font-family: "Cormorant Garamond", Georgia, serif; }
.style-option[data-style="vatican"]     .so-name { font-family: "EB Garamond", Georgia, serif; }
.style-option[data-style="orthodox"]    .so-name { font-family: "EB Garamond", Georgia, serif; }
a { color: var(--gold); text-decoration: none; }
a:hover { color: var(--text-0); }
button { font: inherit; cursor: pointer; }

body {
  position: relative;
  height: 100vh;
  width: 100vw;
  /* 2026-05-27 — legacy footer ripped out; --footer-h is permanently 0.
     Variable retained because some other rules still reference it; the
     body.footer-collapsed class no longer exists / is toggled. */
  --footer-h: 0px;
  overflow: hidden;
}
body.nav-collapsed     { --eff-nav-w:    var(--nav-w-collapsed); }
/* Phase 21A (2026-05-21) — sidebar fully hidden across the
   whole site. Replaces nav-collapsed as the default. Setting
   --eff-nav-w: 0 lets every left-anchored element (main.canvas,
   footer, ...) snap to the viewport edge so the Forge BG image
   has nothing reserving width on its left. */
body.nav-hidden        { --eff-nav-w: 0; --nav-w: 0px; }
body.nav-hidden nav.side,
body.nav-hidden .side-tab { display: none !important; }

/* ── Floating nav hub trigger + dropdown (Phase 21A, 2026-05-21) ── */
.nav-hub-trigger {
  position: fixed;
  top: 14px; left: 14px;
  width: 36px; height: 36px;
  border-radius: 10px;
  border: 1px solid rgba(212,165,90,0.22);
  background: rgba(13,17,25,0.78);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: var(--gold, #d4a55a);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  z-index: 250;
  transition: transform 140ms cubic-bezier(0.2, 0.8, 0.2, 1),
              border-color 140ms ease, background 140ms ease;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0;
}
.nav-hub-trigger:hover {
  border-color: var(--gold, #d4a55a);
  background: rgba(20,26,38,0.92);
}
.nav-hub-trigger[aria-expanded="true"] {
  background: rgba(20,26,38,0.96);
  border-color: var(--gold, #d4a55a);
}
.nav-hub-trigger[aria-expanded="true"] .nav-hub-glyph {
  transform: rotate(180deg);
}
.nav-hub-glyph {
  display: inline-block;
  transition: transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* The menu itself — floats DOWN from under the trigger.
   Hidden by default; .is-open expands it with a smooth scale +
   opacity transition that reads like it grew from the trigger. */
.nav-hub-menu {
  position: fixed;
  top: 56px;       /* just below the 36-px trigger + its 14-px top inset */
  left: 14px;
  width: 240px;
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  border-radius: 12px;
  border: 1px solid rgba(212,165,90,0.22);
  background: rgba(13,17,25,0.88);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  box-shadow: 0 8px 32px rgba(0,0,0,0.45);
  padding: 8px 0;
  z-index: 240;
  /* Hidden state */
  opacity: 0;
  pointer-events: none;
  transform: translateY(-8px) scale(0.96);
  transform-origin: 28px -16px;  /* anchor near the trigger glyph */
  transition: opacity 160ms ease, transform 200ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.nav-hub-menu.is-open {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0) scale(1);
}
.nav-hub-menu .nh-section {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-2, #9099a8);
  padding: 10px 14px 4px;
}
.nav-hub-menu .nh-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px;
  font-family: var(--sans, Inter, sans-serif);
  font-size: 13px;
  color: var(--text-1, #e5e7eb);
  cursor: pointer;
  user-select: none;
  border-left: 2px solid transparent;
  transition: background 90ms ease, border-color 90ms ease, color 90ms ease;
}
.nav-hub-menu .nh-item:hover {
  background: rgba(212,165,90,0.10);
  border-left-color: var(--gold, #d4a55a);
  color: var(--gold-1, #e8c889);
}
.nav-hub-menu .nh-item.is-active {
  border-left-color: var(--gold, #d4a55a);
  color: var(--gold-1, #e8c889);
}
.nav-hub-menu .nh-sym {
  display: inline-block;
  width: 18px; text-align: center;
  color: var(--text-2, #9099a8);
  font-size: 14px;
}
.nav-hub-menu .nh-item:hover .nh-sym,
.nav-hub-menu .nh-item.is-active .nh-sym {
  color: var(--gold, #d4a55a);
}
.nav-hub-menu .nh-divider {
  height: 1px; margin: 6px 12px;
  background: rgba(212,165,90,0.10);
}

/* ════════════════════════════════════════════════════════════════
   Phase 22-D (2026-05-23) — Preferences drawer chrome
   ════════════════════════════════════════════════════════════════
   The nav-hub-menu now carries the Preferences drawer (header,
   account, atlas, old-prototypes, about). Same .nh-item primitive
   as the legacy view list — additive rules for header + section
   metadata + stats block.
   ════════════════════════════════════════════════════════════════ */
.nav-hub-menu { width: 280px; }   /* widen slightly for two-line items */
.nav-hub-menu .nh-header {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px 8px;
  border-bottom: 1px solid rgba(212,165,90,0.10);
  margin-bottom: 4px;
}
.nav-hub-menu .nh-header-glyph {
  font-size: 22px;
  color: var(--gold, #d4a55a);
  text-shadow: 0 0 6px rgba(212,165,90,0.30);
}
.nav-hub-menu .nh-header-title {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-1, #e8c889);
}
.nav-hub-menu .nh-header-subtitle {
  font-family: var(--sans, Inter, sans-serif);
  font-size: 10px;
  font-style: italic;
  color: var(--text-3, #6b7280);
  margin-top: 1px;
}
.nav-hub-menu .nh-section-em {
  font-style: normal;
  font-size: 9px;
  color: var(--text-3, #6b7280);
  letter-spacing: 0.06em;
  text-transform: none;
  margin-left: 4px;
}
.nav-hub-menu .nh-subsection {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-3, #6b7280);
  padding: 8px 16px 2px;
  opacity: 0.7;
}
.nav-hub-menu .nh-meta {
  flex: 0 0 auto;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-3, #6b7280);
  padding: 1px 5px;
  border: 1px solid rgba(255,255,255,0.10);
  border-radius: 2px;
  margin-left: auto;
}
.nav-hub-menu .nh-item--live .nh-meta {
  color: var(--gold-1, #e8c889);
  border-color: rgba(212,165,90,0.45);
  background: rgba(212,165,90,0.10);
}
/* Collapsible "Old prototypes" section — native <details>. Summary
   doubles as the section header; clicking flips open/closed without
   a JS handler. The caret rotates 180° when open. */
.nav-hub-menu .nh-collapse { padding: 0; }
.nav-hub-menu .nh-collapse-summary {
  display: flex; align-items: center; gap: 6px;
  padding: 8px 16px 6px;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-3, #6b7280);
  cursor: pointer;
  list-style: none;
  user-select: none;
}
/* Hide the default disclosure marker on Webkit + Gecko. */
.nav-hub-menu .nh-collapse-summary::-webkit-details-marker { display: none; }
.nav-hub-menu .nh-collapse-summary::marker { content: ""; }
.nav-hub-menu .nh-collapse-summary:hover { color: var(--gold-1, #e8c889); }
.nav-hub-menu .nh-collapse-label { flex: 0 0 auto; }
.nav-hub-menu .nh-collapse-caret {
  margin-left: auto;
  font-size: 10px;
  transition: transform 140ms ease;
}
.nav-hub-menu .nh-collapse[open] .nh-collapse-caret {
  transform: rotate(180deg);
}
.nav-hub-menu .nh-collapse-body {
  padding: 4px 0 2px;
  /* Subtle inset so the wrapped item list reads as a nested group
     under the collapse summary, not floating in the drawer. */
  border-left: 2px solid rgba(212,165,90,0.10);
  margin: 0 12px;
}
.nav-hub-menu .nh-stats {
  padding: 6px 16px 10px;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 10.5px;
}
.nav-hub-menu .nh-stat-row {
  display: flex; justify-content: space-between;
  padding: 2px 0;
  color: var(--text-2, #9099a8);
}
.nav-hub-menu .nh-stat-k {
  text-transform: uppercase;
  letter-spacing: 0.10em;
  font-size: 9px;
  color: var(--text-3, #6b7280);
  padding-top: 1px;
}
.nav-hub-menu .nh-stat-v {
  color: var(--gold-1, #e8c889);
  font-variant-numeric: tabular-nums;
}

/* ════════════════════════════════════════════════════════════════
   Phase 22-D (2026-05-23) — Atlas Statement modal
   ════════════════════════════════════════════════════════════════
   Centered overlay modal — backdrop blurs the wheel; the card
   carries CODEX §I-V abstract. Same dark-glass chrome contract as
   .forge-side-tip / .forge-side-panel — no new visual primitive.
   ════════════════════════════════════════════════════════════════ */
.codex-modal {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: none;
}
.codex-modal.is-open { display: block; }
.codex-modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(8, 11, 17, 0.74);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.codex-modal-card {
  position: relative;
  max-width: 680px;
  width: calc(100vw - 48px);
  max-height: calc(100vh - 80px);
  margin: 40px auto;
  padding: 32px 40px 28px;
  background: rgba(13,17,25,0.96);
  border: 1px solid rgba(212,165,90,0.28);
  border-radius: 14px;
  box-shadow: 0 18px 56px rgba(0,0,0,0.55);
  overflow-y: auto;
  color: var(--text-1, #e5e7eb);
  font-family: var(--sans, Inter, sans-serif);
  line-height: 1.55;
  font-size: 13.5px;
}
.codex-modal-close {
  position: absolute; top: 12px; right: 14px;
  width: 30px; height: 30px;
  background: transparent;
  border: 0;
  color: var(--text-3, #6b7280);
  font-size: 22px; line-height: 1;
  cursor: pointer;
  transition: color 100ms ease;
}
.codex-modal-close:hover { color: var(--gold, #d4a55a); }
.codex-modal-title {
  margin: 0 0 4px;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 14px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-1, #e8c889);
}
.codex-modal-sub {
  font-family: var(--sans, Inter, sans-serif);
  font-style: italic;
  font-size: 12px;
  color: var(--text-3, #6b7280);
  margin-bottom: 24px;
}
.codex-modal-body h2 {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.20em;
  text-transform: uppercase;
  color: var(--gold, #d4a55a);
  margin: 28px 0 10px;
}
.codex-modal-body p { margin: 0 0 12px; }
.codex-modal-body ol,
.codex-modal-body ul { margin: 0 0 12px; padding-left: 22px; }
.codex-modal-body li { margin-bottom: 8px; }
.codex-modal-body b { color: var(--gold-1, #e8c889); font-weight: 600; }
.codex-modal-body i { color: var(--text-2, #b5b9c5); font-style: italic; }
.codex-modal-body code {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 12px;
  color: var(--gold-1, #e8c889);
  background: rgba(212,165,90,0.06);
  padding: 1px 5px;
  border-radius: 3px;
}
.codex-modal-table {
  width: 100%; border-collapse: collapse;
  margin: 6px 0 14px;
  font-size: 12.5px;
}
.codex-modal-table th {
  text-align: left; vertical-align: top;
  padding: 6px 12px 6px 0;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 10.5px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--gold, #d4a55a);
  width: 92px;
  border-top: 1px solid rgba(212,165,90,0.10);
}
.codex-modal-table td {
  padding: 6px 0;
  color: var(--text-2, #b5b9c5);
  border-top: 1px solid rgba(212,165,90,0.10);
}
.codex-modal-aside {
  margin-top: 18px;
  padding: 10px 14px;
  background: rgba(212,165,90,0.06);
  border-left: 2px solid rgba(212,165,90,0.35);
  border-radius: 0 6px 6px 0;
  font-size: 12px;
  color: var(--text-2, #b5b9c5);
  font-style: italic;
}

/* ════════════════════════════════════════════════════════════════
   Phase 22-A (2026-05-23) — APP-SHELL TOP-BAR PILL (SCAFFOLD)
   ════════════════════════════════════════════════════════════════
   The elegant dual-pill that lives at the app shell level, on every
   view. Two independent click targets fused by a vertical `|` —
   visually one object, functionally two dropdowns. LEFT = master
   view (Forge / Timeline / Map / Star Map / Board); RIGHT = class
   subset (Deities / Persons / Themes / etc.).

   This phase ships HTML + CSS only — no behavior wiring. The
   dropdowns exist but their item lists are empty until Phase 22-B
   (master-view selector) and Phase 22-C (class selector).

   Visual contract per AUDIT/topbar-pill-refactor-design-2026-05-23.md
   §2: same glass-on-dark chrome as .nav-hub-trigger + .forge-status-
   mode (their styles are the reusable primitive — don't introduce a
   third).
   ════════════════════════════════════════════════════════════════ */
/* Phase 22-B/AX (2026-05-23) — REVISED visual per John feedback.
   Match the existing .forge-status compact aesthetic: position
   next to the ✦ trigger (NOT centered), squared rectangle with
   10px corners, NO icon inside the button, mixed-case "Deities"
   not all-caps "DEITIES". Same chrome contract as .forge-status
   (border-radius 10px, height 36px to match ✦ trigger row, font
   size 11px mono, gold text on dark-glass).

   Old centered-pill 32px-tall / 16px-radius / icon-inside design
   was per the original audit; John's eye prefers the squarer
   compact .forge-status style — keeping the visual primitive
   consistent across the app shell.  */
.app-pill-wrap {
  position: fixed;
  top: 14px;
  left: 62px;          /* same as old .forge-status — 14 (left inset)
                          + 36 (✦ trigger width) + 12 (gap) */
  z-index: 245;
  pointer-events: none;
}

/* ============================================================
 * ✦ USER MENU (account drawer) — V2-native rebuild 2026-05-28
 * Trigger sits at top:14, left:14 (the 36px slot the app-pill-
 * wrap leaves at left:62). Same visual primitive as the
 * app-pill: dark blur background, gold accent border, JetBrains
 * Mono labels. Menu drops below the trigger via JS position-
 * fixed math (positionMenu in src/js/user-menu.js).
 * ============================================================ */
.user-menu-trigger {
  position: fixed;
  top: 14px;
  left: 14px;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  border: 1px solid rgba(212,165,90,0.22);
  background: rgba(13,17,25,0.78);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 4px 14px rgba(0,0,0,0.28);
  color: var(--gold, #d4a55a);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 246;
  transition: color 100ms ease, border-color 100ms ease, background 100ms ease;
}
.user-menu-trigger:hover {
  color: var(--gold-1, #e8c889);
  border-color: rgba(212,165,90,0.45);
}
.user-menu-trigger[aria-expanded="true"] {
  color: var(--gold-1, #e8c889);
  border-color: rgba(212,165,90,0.55);
  background: rgba(13,17,25,0.92);
}
.user-menu-glyph {
  font-size: 16px;
  line-height: 1;
  pointer-events: none;
}

.user-menu {
  position: fixed;
  min-width: 240px;
  max-width: 320px;
  padding: 10px 0 8px 0;
  border-radius: 12px;
  border: 1px solid rgba(212,165,90,0.22);
  background: rgba(13,17,25,0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 10px 32px rgba(0,0,0,0.42);
  z-index: 244;     /* below the trigger so the trigger's border outlines it */
  opacity: 0;
  pointer-events: none;
  transform: translateY(-4px);
  transition: opacity 120ms ease, transform 120ms ease;
}
.user-menu.is-open {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}
.user-menu-header {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 14px 10px 14px;
}
.user-menu-brand-glyph {
  color: var(--gold, #d4a55a);
  font-size: 14px;
  line-height: 1;
}
.user-menu-brand-text {
  font-family: var(--serif, "Cormorant Garamond", Georgia, serif);
  font-size: 14px;
  color: var(--text-0, #e6e6e6);
  letter-spacing: 0.04em;
}
.user-menu-divider {
  height: 1px;
  background: rgba(212,165,90,0.12);
  margin: 6px 10px;
}
.user-menu-section {
  display: flex; flex-direction: column;
  padding: 4px 0;
}
.user-menu-section-label {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(212,165,90,0.55);
  padding: 4px 14px 6px 14px;
}
.user-menu-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 14px;
  background: transparent;
  border: 0;
  text-align: left;
  color: var(--text-0, #e6e6e6);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background 80ms ease, color 80ms ease;
}
.user-menu-item:hover:not(.is-disabled) {
  background: rgba(212,165,90,0.08);
  color: var(--gold-1, #e8c889);
}
.user-menu-item.is-disabled {
  color: rgba(230,230,230,0.35);
  cursor: not-allowed;
}
.user-menu-item-glyph {
  width: 14px;
  flex-shrink: 0;
  text-align: center;
  color: var(--gold, #d4a55a);
  opacity: 0.85;
}
.user-menu-item.is-disabled .user-menu-item-glyph {
  opacity: 0.35;
}
.user-menu-item-label {
  flex: 1 1 auto;
}
.user-menu-item-hint {
  color: rgba(230,230,230,0.40);
  font-size: 9.5px;
  letter-spacing: 0.05em;
}

.app-pill {
  display: inline-flex;
  align-items: stretch;
  height: 36px;        /* same as ✦ trigger so they baseline together */
  border-radius: 10px; /* squared with soft rounded corners */
  border: 1px solid rgba(212,165,90,0.22);
  background: rgba(13,17,25,0.78);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 4px 14px rgba(0,0,0,0.28);
  overflow: hidden;
  pointer-events: auto;
}
.app-pill-side {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 22px 0 12px;   /* extra right padding for caret room */
  min-width: 0;             /* let label define width naturally */
  height: 100%;
  background: transparent;
  border: 0;
  color: var(--gold, #d4a55a);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.04em;   /* relaxed from .10em — matches forge-status */
  cursor: pointer;
  transition: background 100ms ease, color 100ms ease;
  position: relative;
}
.app-pill-side:hover {
  color: var(--gold-1, #e8c889);
}
.app-pill-side[aria-expanded="true"] {
  color: var(--gold-1, #e8c889);
}
/* Left side (master view) — uppercase like the old .forge-status-tag. */
.app-pill-master .app-pill-label {
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-weight: 500;
}
/* Right side (class) — mixed-case like the old .forge-status-mode label. */
.app-pill-class .app-pill-label {
  letter-spacing: 0.04em;
  /* 2026-06-04 (John) — the class pill ("CODEX") matches the master pill
     ("ATLAS") in all-caps; the codex breadcrumb (Christianity/Bible/Books,
     which use #app-pill-codex-*-label) is intentionally left Title Case. */
  text-transform: uppercase;
}
.app-pill-icon {
  /* Hidden per the revised compact style — the LABEL is the identity.
     Keep the span in DOM so existing JS doesn't break, but display:none
     it so the chrome reads like the old .forge-status pill. */
  display: none;
}
/* Phase 22-F (2026-05-24) — also strip the random glyph icons from
   the dropdown menu items (FORGE/TIMELINE/BOARD/MAP/STAR MAP rows
   and the Deities/Persons/… class rows). John: "remove the random
   symbol in front of Forge and Deities." The label is the identity
   on the trigger; same in the dropdown. */
.app-pill-menu-icon {
  display: none !important;   /* belt-and-braces — see notes below */
}

/* Phase 22-I (2026-05-24) — layout-aware VIEW / STYLE / FX panels.
   body.fv-layout-timeline hides .fv-wheel-only rows (radial-only
   controls); body.fv-layout-wheel hides .fv-timeline-only rows
   (band controls). Default state (no body class yet) acts like
   wheel so the first paint doesn't show timeline-only widgets. */
body.fv-layout-timeline .fv-wheel-only,
body.fv-layout-wheel    .fv-timeline-only,
body:not(.fv-layout-timeline) .fv-timeline-only {
  display: none !important;
}
/* Phase 22-I — VIEW > Layers timeline-only toggles. CSS class
   targets the SVG groups owned by timeline-chrome.js. */
body.fv-hide-tl-bands       .forge-timeline-bands       { display: none !important; }
body.fv-hide-tl-band-labels .forge-timeline-band-labels { display: none !important; }

/* Phase B-DATING-2 (2026-05-24) — Side-panel dating-basis pill.
   Each basis tier gets a distinct color so the user reads the
   confidence at a glance:
     B1-B4 = primary evidence → gold + neutral
     B5    = consensus emergence → amber (soft)
     B6    = family-median synth → grey (lowest dated)
     B7    = atemporal → faded grey */
.forge-side-panel-dating-basis {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.04em;
  padding: 2px 6px;
  border-radius: 3px;
  display: inline-block;
}
.forge-side-panel-dating-basis--b1,
.forge-side-panel-dating-basis--b2,
.forge-side-panel-dating-basis--b3,
.forge-side-panel-dating-basis--b4 {
  color: var(--gold-1, #e8c889);
  background: rgba(212,165,90,0.10);
  border: 1px solid rgba(212,165,90,0.30);
}
.forge-side-panel-dating-basis--b5 {
  color: rgba(212,165,90,0.75);
  background: rgba(212,165,90,0.06);
  border: 1px solid rgba(212,165,90,0.20);
}
.forge-side-panel-dating-basis--b6 {
  color: rgba(180,180,190,0.85);
  background: rgba(140,140,150,0.10);
  border: 1px solid rgba(140,140,150,0.28);
}
.forge-side-panel-dating-basis--b7 {
  color: rgba(160,160,170,0.65);
  background: rgba(140,140,150,0.06);
  border: 1px dashed rgba(140,140,150,0.30);
}
.forge-side-panel-dating-notes {
  opacity: 0.78;
  font-size: 11px;
  font-style: italic;
}

/* Phase 22-J (2026-05-24) → Phase 22-K (2026-05-24) — Force-hide
   WHEEL SVG overlays in timeline mode. These elements are
   positioned for the radial wheel layout. John kept hulls
   visible in timeline ("useful, exploring") — only family
   rim labels, dividers, and guide rings are hidden. */
body.fv-layout-timeline #forge-hull-labels,
body.fv-layout-timeline #forge-hull-dividers,
body.fv-layout-timeline #forge-hull-guide-rings {
  display: none !important;
}
.app-pill-label {
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: left;
  line-height: 1;
}
/* Gradient triangle caret — copies .forge-status-mode geometry exactly
   so the visual reads identical to the established pill primitive. */
.app-pill-caret {
  display: none;     /* hide the textual ▾; replace with gradient triangle */
}
/* Phase 22-H (2026-05-24) — drop the gradient-triangle caret on
   each pill side. John flagged them as "really annoying" — the
   labels are the identity; no dropdown indicator needed. The
   pills still open menus on click + keyboard. */
.app-pill-side::after {
  content: none;
}
/* Tighten right padding now that the caret slot is gone. The pill
   had 22px right padding to reserve room for the gradient
   triangle; without it 12px is enough. */
.app-pill-side {
  padding-right: 12px;
}
.app-pill-divider {
  width: 1px;
  background: rgba(212,165,90,0.22);
  flex: 0 0 auto;
}
/* Phase 22-C (2026-05-23) — when the active master view doesn't
   expose a class-selector API (e.g., legacy Astrology mounted as
   STAR MAP, MapLibre Atlas as MAP), the right side of the pill
   hides so the user doesn't click a dead control. The master side
   still works; the pill visually collapses to just the LEFT half. */
body.app-pill-no-class .app-pill-class,
body.app-pill-no-class .app-pill-divider { display: none; }
/* Phase scripture-mode step 4 (2026-05-28) — Atlas Codex secondary
   pill. Sibling .app-pill inside the same .app-pill-wrap as the
   master/class pill, so it inherits z-index:245 + pointer-events
   + stacking context. Visible only when class === 'scriptures'
   (codex-controls.js toggles body.app-pill-codex-visible). Hidden
   by default — body class drives reveal, same pattern as
   .app-pill-no-class above. */
.app-pill--codex { margin-left: 8px; display: none; }
body.app-pill-codex-visible .app-pill--codex { display: inline-flex; }
/* Hard guard: codex pill is meaningful ONLY when the forge engine
   is the active master view (Atlas wheel OR Timeline layout OR the
   Scripture route which mounts the same wheel). When the user
   navigates to Map / Star Map / legacy SVG views, the codex pill
   must vanish even if the body class app-pill-codex-visible is
   stale. Codex's body classes are toggled by the forge view's local-
   state observer which can fall behind cross-view navigation.
   2026-05-30 — added :not(.view-scripture) per John's Codex hierarchy
   directive: Bible click routes ?view=scripture and mounts the same
   wheel; the codex breadcrumb MUST appear there. */
body:not(.view-forge):not(.view-timeline):not(.view-scripture) .app-pill--codex { display: none !important; }
/* Progressive-disclosure lock state on Codex pill buttons.
   Books → Lens → Read sequence: each step locked until the
   prerequisite is picked. Locked buttons stay visible (so the
   workflow is discoverable) but are dimmed + not clickable. */
.app-pill-side.is-locked {
  opacity: 0.32;
  cursor: not-allowed;
  pointer-events: none;
}
.app-pill-side.is-locked .app-pill-caret { opacity: 0.4; }
/* Dropdown panels — anchored under their trigger button via JS
   (app-pill.js positionMenu() reads getBoundingClientRect on open
   and sets top/left inline). The pill itself lives at top:14
   left:62, NOT centered, so no CSS fallback positioning would be
   correct — we just paint at top:0 left:0 until JS positions.
   Same pattern the legacy wireModeDropdown used. */
.app-pill-menu {
  position: fixed;
  top: 0; left: 0;       /* JS overrides on open */
  /* Phase 22-X (2026-05-24) — tighter menu. Was 220px which was
     wider than the trigger button + had redundant horizontal
     padding. 140px lets labels alone size the dropdown. */
  min-width: 140px;
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  border-radius: 10px;
  border: 1px solid rgba(212,165,90,0.22);
  background: rgba(13,17,25,0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 8px 32px rgba(0,0,0,0.50);
  padding: 8px 0;
  z-index: 246;
  /* Hidden by default; .is-open is the visible state */
  opacity: 0;
  pointer-events: none;
  transform: translateY(-6px) scale(0.97);
  transform-origin: 28px -8px;
  transition: opacity 140ms ease, transform 180ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.app-pill-menu.is-open {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0) scale(1);
}
/* Empty-state placeholder (visible only when the menu opens without
   any items wired — i.e., before Phase 22-B/22-C land their content).
   Renders a faint "wiring in next phase" hint so the scaffold doesn't
   read as broken. */
.app-pill-menu:empty::after {
  content: "wiring in next phase";
  display: block;
  padding: 10px 14px;
  color: var(--text-3, #6b7280);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Phase 22-B (2026-05-23) — dropdown items inside the pill menus.
   Same vocabulary as .nav-hub-menu .nh-item: gold-on-hover, left-
   border accent on .is-active, mono caps label. Reuses the
   primitive style per the audit's style-guide rule. */
.app-pill-menu-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 8px 14px;
  background: transparent;
  border: 0;
  border-left: 2px solid transparent;
  text-align: left;
  font-family: var(--sans, Inter, sans-serif);
  font-size: 13px;
  color: var(--text-1, #e5e7eb);
  cursor: pointer;
  user-select: none;
  transition: background 90ms ease, border-color 90ms ease, color 90ms ease;
}
.app-pill-menu-item:hover {
  background: rgba(212,165,90,0.10);
  border-left-color: var(--gold, #d4a55a);
  color: var(--gold-1, #e8c889);
}
.app-pill-menu-item.is-active {
  border-left-color: var(--gold, #d4a55a);
  color: var(--gold-1, #e8c889);
}
/* Phase 22-G (2026-05-24) — Icon override REMOVED. The earlier
   `display:none` at line 851 was being defeated by this rule
   (later-wins cascade). John asked 3× to remove the icons; this
   was the silent reason it kept regressing. */
.app-pill-menu-label {
  flex: 1 1 auto;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
}
.app-pill-menu-check {
  flex: 0 0 auto;
  color: var(--gold, #d4a55a);
  font-size: 9px;
  opacity: 0.85;
}
.app-pill-menu-hint {
  flex: 0 0 auto;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--text-3, #6b7280);
  text-transform: uppercase;
}
.app-pill-menu-item--meta {
  /* "Old prototypes" entry — slightly dimmer to read as utility,
     not as a primary master view. */
  color: var(--text-2, #9099a8);
}
/* Codex Read-menu section header — canonical-section divider inside
   the book-picker dropdown (PENTATEUCH / GOSPELS / FORMER PROPHETS
   etc.). 2026-05-28 — added with the Read button. */
.app-pill-menu-section-label {
  padding: 8px 14px 4px;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  letter-spacing: 0.10em;
  color: var(--gold, #d4a55a);
  text-transform: uppercase;
  border-top: 1px solid rgba(212,165,90,0.10);
}
.app-pill-menu-section-label:first-child {
  border-top: 0;
  padding-top: 4px;
}
.app-pill-menu-item.is-stub {
  color: var(--text-3, #5a626d);
  opacity: 0.55;
}
.app-pill-menu-item.is-stub .app-pill-menu-hint {
  font-style: italic;
}
.app-pill-menu-divider {
  height: 1px;
  margin: 4px 12px;
  background: rgba(212,165,90,0.12);
}

/* Responsive collapse — Phase 22-E (2026-05-24). Three breakpoints
   keep the pill usable across viewports:
   - default: full ~150px each side, 18px letter-spacing on master
   - <960px:  tighter padding, master letter-spacing tightens to 0.12
   - <600px:  shrink heights; hide the LEFT label (master icon +
              caret only) so the RIGHT (class) side still has room
   - <360px:  pill hides entirely; ✦ drawer carries navigation */
@media (max-width: 960px) {
  .app-pill-side { padding: 0 18px 0 10px; }
  .app-pill-master .app-pill-label { letter-spacing: 0.12em; }
}
@media (max-width: 600px) {
  .app-pill { height: 32px; }
  .app-pill-side { padding: 0 16px 0 8px; font-size: 10px; }
  .app-pill-master .app-pill-label { display: none; }
  .app-pill-master::after { right: 5px; }
}
@media (max-width: 360px) {
  .app-pill-wrap { display: none; }
}

/* ── Phase 21A2 (2026-05-21) ─ Debug-stats button + popover ── */
.forge-debug-btn {
  width: 38px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  margin-left: 6px;
  background: rgba(13,17,25,0.78);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 6px;
  color: var(--text-2, #9099a8);
  font-family: var(--mono, "JetBrains Mono", monospace);
  font-size: 14px; line-height: 1;
  cursor: pointer;
  /* Phase 21L (2026-05-21) — the parent .forge-bottombar is
     pointer-events: none (so canvas hits pass through gaps);
     interactive children must opt back in. */
  pointer-events: auto;
  transition: border-color 120ms ease, color 120ms ease, background 120ms ease;
}
.forge-debug-btn:hover {
  border-color: var(--gold, #d4a55a);
  color: var(--gold, #d4a55a);
}
.forge-debug-btn[aria-expanded="true"] {
  border-color: var(--gold, #d4a55a);
  color: var(--gold, #d4a55a);
  background: rgba(20,26,38,0.92);
}
.forge-debug-panel {
  position: fixed;
  bottom: 58px;        /* sits just above the bottom-bar pill row */
  right: 14px;
  width: 240px;
  padding: 10px 12px;
  background: rgba(13,17,25,0.92);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 8px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 6px 24px rgba(0,0,0,0.4);
  z-index: 235;
  display: none;
  font-family: var(--mono, "JetBrains Mono", monospace);
  font-size: 10.5px;
}
.forge-debug-panel.is-open { display: block; }
.forge-debug-panel .forge-debug-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 3px 0;
  border-bottom: 1px dashed rgba(212,165,90,0.07);
}
.forge-debug-panel .forge-debug-row:last-child { border-bottom: 0; }
.forge-debug-panel .forge-debug-k {
  color: var(--text-3, #6b7280);
  text-transform: uppercase;
  letter-spacing: 0.12em;
}
.forge-debug-panel .forge-debug-v {
  color: var(--text-1, #e5e7eb);
}
/* ── Phase debug-bar-move (2026-05-28) ──
   The opt-in floating perf bar (pinned via the # popover).
   Was inline-styled in index.html until 2026-05-28; now a real
   primitive so JS doesn't need to ship style text. Background
   color set by JS to color-code rAF interval performance. */
.forge-hud-banner {
  position: fixed;
  top: 10px; left: 50%;
  transform: translateX(-50%);
  background: #2a6;        /* default green — JS recolors per perf */
  color: #fff;
  padding: 8px 16px;
  z-index: 250;            /* above app-pill (245-246), under modals */
  font: bold 12px var(--mono, ui-monospace, Menlo, Monaco, monospace);
  border-radius: 6px;
  pointer-events: none;    /* purely informational — never blocks clicks */
  box-shadow: 0 4px 12px rgba(0,0,0,0.5);
  min-width: 680px;
  text-align: center;
}
/* Pin-toggle button inside the # debug popover. Pinned/unpinned
   reads from atlas.debug.pinned in LS. Matches existing popover
   row chrome. */
.forge-debug-panel .forge-debug-pin-row {
  margin-top: 8px;
  padding-top: 8px !important;
  border-top: 1px solid rgba(212,165,90,0.18);
  border-bottom: 0 !important;
}
.forge-debug-pin-btn {
  appearance: none;
  background: transparent;
  border: 1px solid rgba(212,165,90,0.32);
  border-radius: 4px;
  color: var(--gold, #d4a55a);
  padding: 2px 10px;
  font: inherit;
  font-size: 10.5px;
  cursor: pointer;
  letter-spacing: 0.06em;
  transition: background 120ms ease, border-color 120ms ease;
}
.forge-debug-pin-btn:hover {
  background: rgba(212,165,90,0.10);
  border-color: var(--gold, #d4a55a);
}

/* ── Phase 21B (2026-05-21) — BG-image visibility fixes ── */
/* The body-root `.forge-bg-image` was being covered by the
   stage / pane / canvas opaque backgrounds. Make them
   transparent in view-forge mode so the BG paints through. */
body.view-forge main.canvas,
body.view-forge .forge-pane,
body.view-forge .forge-shell-v1 {
  background: transparent !important;
}
body.view-forge .forge-stage {
  /* Keep the subtle radial atmosphere gradient (low-alpha rgba)
     but drop the opaque base colour so the body-root BG image
     shows through. */
  --forge-bg: transparent;
}

/* ── Phase 21B (2026-05-21) — View-settings dropdown ── */
.forge-viewset-wrap {
  position: relative;
  display: inline-flex; align-items: center;
  /* Bottom-bar parent is pointer-events: none — opt in. */
  pointer-events: auto;
}
.forge-viewset-btn {
  /* Phase 21AQ (2026-05-23) — compact to match LEGEND + zoom-gizmo
     sibling styling (was 32px / 0 12px / 0.16em — bigger than its
     neighbours; visual mismatch in the bottombar). */
  padding: 5px 10px;
  background: rgba(13,17,25,0.78);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 6px;
  color: var(--text-2, #9099a8);
  font-family: var(--mono, "JetBrains Mono", monospace);
  font-size: 11px;
  letter-spacing: 0.08em;
  cursor: pointer;
  pointer-events: auto;
  transition: border-color 120ms ease, color 120ms ease, background 120ms ease;
}
.forge-viewset-btn:hover,
.forge-viewset-btn[aria-expanded="true"] {
  border-color: var(--gold, #d4a55a);
  color: var(--gold, #d4a55a);
  background: rgba(20,26,38,0.92);
}
.forge-viewset-panel {
  position: absolute;
  bottom: 40px;     /* drops UPWARD over the button */
  left: 0;
  min-width: 220px;
  /* Phase 21AW (2026-05-23) — CAP the panel height to the viewport
     so it never overflows off-screen. Earlier this session grew the
     panel from 4 sections to 5 (Layers / Color theme / Family order
     / Node distribution / Source tiers) — the cumulative ~35 rows
     blew past the available drop-up window on smaller laptops, and
     the top sections became unreachable.
     Reservation = ~80px (bottom bar ~40px + the 40px drop-up offset
     above the button + a small safety margin). Internal scroll
     handles the rest with a thin gold-tinted scrollbar that matches
     the atlas aesthetic. */
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 6px 0;
  background: rgba(13,17,25,0.92);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 8px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 6px 24px rgba(0,0,0,0.45);
  z-index: 235;
  display: none;
}
.forge-viewset-panel.is-open { display: block; }
/* Thin gold-tinted scrollbar — same vocabulary as the side panel. */
.forge-viewset-panel::-webkit-scrollbar { width: 6px; }
.forge-viewset-panel::-webkit-scrollbar-track { background: transparent; }
.forge-viewset-panel::-webkit-scrollbar-thumb {
  background: rgba(212,165,90,0.25);
  border-radius: 3px;
}
.forge-viewset-panel::-webkit-scrollbar-thumb:hover {
  background: rgba(212,165,90,0.45);
}
/* Firefox scrollbar styling. */
.forge-viewset-panel {
  scrollbar-width: thin;
  scrollbar-color: rgba(212,165,90,0.25) transparent;
}
.forge-viewset-row {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  /* Phase 21AW (2026-05-23) — tighter vertical padding so 35 rows
     fit comfortably inside the viewport-capped panel. Was 8px → 5px
     vertical. Hit-target stays comfortable (14×14 checkbox dominates
     the row height). */
  padding: 5px 14px;
  background: transparent;
  border: 0;
  text-align: left;
  font-family: var(--sans, Inter, sans-serif);
  font-size: 12px;
  color: var(--text-1, #e5e7eb);
  cursor: pointer;
  transition: background 90ms ease, color 90ms ease;
}
.forge-viewset-row:hover { background: rgba(212,165,90,0.10); }
.forge-viewset-row[disabled] { color: var(--text-3, #6b7280); cursor: not-allowed; opacity: 0.6; }
.forge-viewset-row em { font-style: normal; color: var(--text-3, #6b7280); font-size: 10px; margin-left: 4px; }

/* ═══════════════════════════════════════════════════════════════
   View-settings rows — Phase 21O (2026-05-21)
   ═══════════════════════════════════════════════════════════════
   STYLE-GUIDE NOTE: each row is "label + square checkbox in front".
   The SQUARE is the ON/OFF indicator — empty box = OFF, gold-filled
   box = ON. No row-level border, no background highlight on .is-on.
   Hover keeps the standard gold-tint row-hover for affordance only.
   Use this same pattern for any future boolean-toggle list.
   ═══════════════════════════════════════════════════════════════ */
.forge-viewset-row .vs-check {
  display: inline-block;
  width: 14px; height: 14px;
  border-radius: 3px;
  border: 1px solid rgba(212,165,90,0.55);
  background: transparent;
  position: relative;
  flex: 0 0 auto;
  transition: background 100ms ease, border-color 100ms ease;
}
.forge-viewset-row.is-on .vs-check {
  background: var(--gold, #d4a55a);
  border-color: var(--gold, #d4a55a);
}
/* Subtle gold tint on the label of an ON row, no background. */
.forge-viewset-row.is-on { color: var(--gold-1, #e8c889); }
.forge-viewset-row.is-on:hover { background: rgba(212,165,90,0.10); }

/* ═══════════════════════════════════════════════════════════════
   View-settings — Phase 21S (2026-05-22)
   Section header + divider + radio-dot variants. The radio dot
   (.vs-radio) is the same 14×14 box as the checkbox, but rendered
   as a CIRCLE — gold-filled when its row is .is-on. Same primitive
   spirit: the indicator is the dot; no row-level border.
   ═══════════════════════════════════════════════════════════════ */
.forge-viewset-section {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-3, #6b7280);
  /* Phase 21AW (2026-05-23) — tighter section header padding to
     reduce total panel height (5 sections × 12px saved = 60px). */
  padding: 6px 16px 3px;
}
.forge-viewset-divider {
  height: 1px;
  margin: 3px 12px;
  background: rgba(212,165,90,0.10);
}
.forge-viewset-row .vs-radio {
  display: inline-block;
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 1px solid rgba(212,165,90,0.55);
  background: transparent;
  position: relative;
  flex: 0 0 auto;
  transition: background 100ms ease, border-color 100ms ease;
}
.forge-viewset-row.is-on .vs-radio {
  background: var(--gold, #d4a55a);
  border-color: var(--gold, #d4a55a);
  /* Subtle inner-ring affordance — the filled dot has a thin gold
     ring around it so the active radio reads at a glance. */
  box-shadow: inset 0 0 0 2px var(--bg-1, #0d1119);
}

/* Layer-toggle effects driven by body classes set in JS.
   Phase 21U (2026-05-22) — hulls and separators are FULLY
   independent: hiding hulls keeps the dividers visible. Earlier
   the `fv-hide-hulls` rule blanket-hid `.forge-hulls-overlay`,
   which contains BOTH the pie-slice polys AND the divider lines —
   so toggling hulls off also killed separators. Fixed by
   targeting just the polys + the family-titles labels here. */
/* Phase 21AH (2026-05-22) — family titles are now an INDEPENDENT
   toggle from hulls. fv-hide-hulls hides only the pie polygons;
   fv-hide-family-titles hides only the labels. */
body.fv-hide-hulls         #forge-hull-polys    { display: none !important; }
body.fv-hide-family-titles #forge-hull-labels   { display: none !important; }
body.fv-hide-dividers      #forge-hull-dividers     { display: none !important; }
body.fv-hide-guide-rings   #forge-hull-guide-rings  { display: none !important; }
body.fv-hide-wires         .forge-canvas { /* the actual hide is renderer-side: drawFrame forces effectiveDim to 1.0 when this body class is set, which zeros idle wire alpha while leaving HOT/selected wires fully visible. */ }

/* ═══════════════════════════════════════════════════════════════
   Phase 21AS (2026-05-23) — Source-tier rows + pills
   ═══════════════════════════════════════════════════════════════
   Each tier row in the view-settings panel shows a small badge
   pill (T1..T5) with a tier-specific color. The badge is
   informational — the actual ON/OFF state is the standard
   `.vs-check` square. The T5 row gets a faint red top-border so
   the high-risk tier reads as visually segregated.
   See 00_meta/CODEX.md §IV for the tier definitions. The wire-
   filter that hides edges of off-tier is renderer-side (forge.js
   recomputeFocus → edgeTargets HIDDEN); these CSS hooks exist for
   future legend chrome / side-panel disclaimer styling.
   ═══════════════════════════════════════════════════════════════ */
.forge-viewset-row--tier { gap: 8px; }
.vs-tier-pill {
  display: inline-block;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.06em;
  padding: 2px 5px;
  border-radius: 3px;
  background: rgba(255,255,255,0.06);
  color: var(--text-2, #9ca3af);
  border: 1px solid rgba(255,255,255,0.10);
  line-height: 1;
  flex: 0 0 auto;
}
/* T1 = mainstream silent default — keep the pill VISIBLE so the
   disclaimer system is legible on every row, but quiet (grey-ish)
   so it doesn't visually shout on the 99% of edges that ARE T1. */
.vs-tier-pill--t1 { color: rgba(229,231,235,0.55); border-color: rgba(255,255,255,0.18); background: rgba(255,255,255,0.04); }
.vs-tier-pill--t2 { color: #c3b87f; border-color: rgba(195,184,127,0.35); }
.vs-tier-pill--t3 { color: #c89867; border-color: rgba(200,152,103,0.40); }
.vs-tier-pill--t4 { color: #c47878; border-color: rgba(196,120,120,0.40); }
.vs-tier-pill--t5 {
  color: #e25b5b;
  border-color: rgba(226,91,91,0.55);
  background: rgba(226,91,91,0.08);
}
/* High-risk row separator — subtle red top border above T5 so the
   disclaimer-required tier reads as segregated from the rest. */
.forge-viewset-row--high-risk {
  border-top: 1px dashed rgba(226,91,91,0.20);
  margin-top: 2px;
}
.forge-viewset-row--high-risk em { color: rgba(226,91,91,0.65); }

/* ═══════════════════════════════════════════════════════════════
   Phase 21AX (2026-05-23) — CODEX v1.2 — ⛔ BLACK ALERT toggle
   ═══════════════════════════════════════════════════════════════
   The political-risk toggle is ORTHOGONAL to the tier system. It
   uses BLACK + RED chrome (not the soft red of T5 alone) so the
   row reads as a separate, higher-severity opt-in surface.
   See 00_meta/CODEX.md §IV.5.
   ═══════════════════════════════════════════════════════════════ */
.forge-viewset-row--black-alert {
  border-top: 2px solid rgba(226,91,91,0.65);
  margin-top: 4px;
  background: rgba(226,91,91,0.05);
}
.forge-viewset-row--black-alert:hover { background: rgba(226,91,91,0.12); }
.forge-viewset-row--black-alert em { color: rgba(226,91,91,0.80); }
.vs-alert-badge {
  display: inline-block;
  font-size: 14px;
  line-height: 1;
  flex: 0 0 auto;
  color: #e25b5b;
  text-shadow: 0 0 4px rgba(226,91,91,0.45);
}
/* Active state — when politicalRisk is ON, the row is "armed". */
.forge-viewset-row--black-alert.is-on {
  background: rgba(226,91,91,0.18);
  color: #ffd5d5;
}
.forge-viewset-row--black-alert.is-on .vs-check {
  background: #e25b5b;
  border-color: #e25b5b;
}

/* ── Phase 21B (2026-05-21) — Search autocomplete (drop-up) ── */
.forge-search-wrap {
  position: relative;
  display: inline-flex; align-items: center;
  /* Bottom-bar parent is pointer-events: none — opt in so the
     autocomplete suggestion list can receive clicks. */
  pointer-events: auto;
}
.forge-search-suggest {
  position: absolute;
  bottom: 40px;
  left: 0;
  width: 260px;
  max-height: 320px;
  overflow-y: auto;
  padding: 4px 0;
  background: rgba(13,17,25,0.94);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 8px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 6px 24px rgba(0,0,0,0.45);
  z-index: 235;
  display: none;
}
.forge-search-suggest.is-open { display: block; }
.forge-search-suggest-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 6px 12px;
  background: transparent;
  border: 0;
  text-align: left;
  font-family: var(--sans, Inter, sans-serif);
  font-size: 12px;
  color: var(--text-1, #e5e7eb);
  cursor: pointer;
}
.forge-search-suggest-item:hover { background: rgba(212,165,90,0.10); }
.forge-search-suggest-item .fss-dot {
  width: 8px; height: 8px; border-radius: 50%;
  flex: 0 0 auto;
}
.forge-search-suggest-item .fss-title {
  flex: 1 1 auto;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.forge-search-suggest-item .fss-fam {
  font-size: 10px;
  color: var(--text-3, #6b7280);
  letter-spacing: 0.06em;
  white-space: nowrap;
}
/* 2026-06-10 (INCIDENT §4) — collapsed panel reserves NOTHING on any
   view (was var(--detail-w-collapsed) = the V01 36px rail). */
body.detail-collapsed  { --eff-detail-w: 0px; }

/* BRAND-SECTION (lives at top of left nav) */
.brand-section {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 18px 14px 22px;
  border-bottom: 1px solid var(--border-soft);
  position: relative;
}
.brand-section::after {
  content: "";
  position: absolute; left: 16px; right: 16px; bottom: -1px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold-soft), transparent);
  opacity: 0.4;
}
.brand-section .glyph {
  font-family: var(--serif); font-size: 16px; color: var(--gold);
  letter-spacing: 0.06em; flex-shrink: 0; width: 16px; text-align: center;
}
.brand-section .brand-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; transition: opacity 150ms ease; }
.brand-section h1 {
  margin: 0; font-family: var(--serif); font-weight: 600;
  font-size: 13px; letter-spacing: 0.10em; color: var(--text-0);
  text-transform: uppercase; white-space: nowrap;
}
.brand-section .tagline {
  margin: 0; font-size: 9.5px; color: var(--text-2);
  font-style: italic; letter-spacing: 0.03em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
body.nav-collapsed .brand-section { padding: 14px 0; justify-content: center; }
body.nav-collapsed .brand-section .brand-text { opacity: 0; display: none; }

/* UTILITY-SECTION (lives at bottom of left nav) */
.utility-section {
  display: flex; flex-direction: column; gap: 6px;
  padding: 12px 14px 14px;
  border-top: 1px solid var(--border-soft);
  background: linear-gradient(180deg, transparent, rgba(0,0,0,0.18));
}
.utility-section .stats {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px 10px;
  font-family: var(--mono); font-size: 9.5px; color: var(--text-3);
  letter-spacing: 0.04em; margin-top: 4px;
}
.utility-section .stat { white-space: nowrap; }
.utility-section .stat strong { color: var(--gold-soft); font-weight: 500; margin-right: 4px; }
.utility-section .util-sym { font-size: 12px; }

body.nav-collapsed .utility-section { padding: 10px 6px; align-items: center; }
body.nav-collapsed .utility-section .util-lbl { display: none; }
body.nav-collapsed .utility-section .caret { display: none; }
body.nav-collapsed .utility-section .stats { display: none; }
body.nav-collapsed .utility-section .style-button,
body.nav-collapsed .utility-section .themes-button,
body.nav-collapsed .utility-section .tier-button {
  width: 32px; padding: 6px; justify-content: center;
}
body.nav-collapsed .utility-section .tier-button .util-lbl { display: none; }

/* When nav collapses, the bottom-anchored style-menu + the full-overlay themes-menu
   need to follow the nav's new left edge. */
body.nav-collapsed .style-menu { left: calc(var(--nav-w-collapsed) + 8px); }
body.nav-collapsed .themes-menu { left: var(--nav-w-collapsed); }

body.nav-collapsed .brand-section { padding: 14px 0 12px; justify-content: center; }

/* THEMES DROPDOWN */
.themes-button {
  background: transparent; border: 1px solid var(--border);
  color: var(--text-1); font-family: var(--sans); font-size: 10.5px;
  padding: 5px 11px; border-radius: 3px; cursor: pointer;
  letter-spacing: 0.14em; text-transform: uppercase;
  display: flex; align-items: center; gap: 8px;
  transition: all 180ms ease;
}
.themes-button:hover { border-color: var(--gold-soft); color: var(--gold); }
.themes-button.open { border-color: var(--gold); color: var(--gold); background: rgba(212,165,90,0.08); }
.themes-button .caret { font-size: 9px; transition: transform 180ms ease; }
.themes-button.open .caret { transform: rotate(180deg); }

/* SOURCE-TIER TOGGLE BUTTON (opus-design-2). Sits in the side-nav utility-section
   between Themes and Stats. Active state shows a gold fill; the 4 dot-swatches act
   as a built-in legend hint. */
.tier-button {
  background: transparent; border: 1px solid var(--border);
  color: var(--text-1); font-family: var(--sans); font-size: 10.5px;
  padding: 5px 11px; border-radius: 3px; cursor: pointer;
  letter-spacing: 0.14em; text-transform: uppercase;
  display: flex; align-items: center; gap: 8px;
  transition: all var(--t-micro) var(--ease);
}
.tier-button:hover { border-color: var(--gold-soft); color: var(--gold); }
.tier-button.active { border-color: var(--gold); color: var(--gold); background: rgba(212,165,90,0.08); }
.tier-button .tier-swatches { display: inline-flex; gap: 3px; }
.tier-button .ts-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--ts-color, var(--tier-none));
}
.tier-button .ts-dot[data-t="1"] { --ts-color: var(--tier-1); }
.tier-button .ts-dot[data-t="2"] { --ts-color: var(--tier-2); }
.tier-button .ts-dot[data-t="3"] { --ts-color: var(--tier-3); }
.tier-button .ts-dot[data-t="4"] { --ts-color: var(--tier-4); }

/* OVERLAY CSS — only fires when body.tier-overlay-on. Targets every node-class
   that has a data-tier attribute. Stroke color = tier color; stroke width bumps
   slightly so the ring is visible against the fill. Filter-dimmed and hover/hot
   states still take precedence via their own selectors. */
body.tier-overlay-on .node-circle[data-tier],
body.tier-overlay-on .scripture-node[data-tier],
body.tier-overlay-on .alch-circle[data-tier],
body.tier-overlay-on .tl-event-shape[data-tier],
body.tier-overlay-on .tl-event-dot[data-tier] {
  stroke-width: 2;
  transition: stroke var(--t-micro) var(--ease), stroke-width var(--t-micro) var(--ease);
}
body.tier-overlay-on [data-tier="1"]    { stroke: var(--tier-1); }
body.tier-overlay-on [data-tier="2"]    { stroke: var(--tier-2); }
body.tier-overlay-on [data-tier="3"]    { stroke: var(--tier-3); }
body.tier-overlay-on [data-tier="4"]    { stroke: var(--tier-4); }
body.tier-overlay-on [data-tier="none"] { stroke: var(--tier-none); stroke-dasharray: 2 2; }

/* TIER LEGEND (opus-design-2) — floating distribution panel, top-right corner of
   the canvas, only visible when body.tier-overlay-on. Mirrors the existing
   .legend pattern but with histogram-bar rows so tier distribution is glanceable. */
.tier-legend {
  position: absolute; top: 56px; right: 24px;
  width: 260px; padding: 14px 16px;
  background: rgba(13,17,25,0.92); backdrop-filter: blur(6px);
  border: 1px solid var(--gold-soft); border-radius: 4px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.45);
  z-index: 6; pointer-events: auto;
  opacity: 0; transform: translateY(-4px);
  transition: opacity var(--t-layout) var(--ease), transform var(--t-layout) var(--ease);
  pointer-events: none;
  font-family: var(--sans); font-size: var(--lbl-md);
  color: var(--text-1);
}
body.tier-overlay-on .tier-legend { opacity: 1; transform: translateY(0); pointer-events: auto; }
.tier-legend .tl-header {
  display: flex; align-items: baseline; justify-content: space-between;
  padding-bottom: 8px; margin-bottom: 10px;
  border-bottom: 1px solid var(--border-soft);
}
.tier-legend .tl-title {
  font-family: var(--serif); font-size: var(--h3-size);
  color: var(--text-0); letter-spacing: 0.06em;
  text-transform: uppercase; font-weight: 500;
}
.tier-legend .tl-total {
  font-family: var(--mono); font-size: 10px;
  color: var(--text-3); letter-spacing: 0.04em;
}
.tier-legend .tl-row {
  display: grid; grid-template-columns: 10px 1fr 70px 44px;
  gap: 8px; align-items: center;
  padding: 4px 0;
}
.tier-legend .tl-swatch {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--tl-row-color, var(--tier-none));
}
.tier-legend .tl-row[data-t="1"]    { --tl-row-color: var(--tier-1); }
.tier-legend .tl-row[data-t="2"]    { --tl-row-color: var(--tier-2); }
.tier-legend .tl-row[data-t="3"]    { --tl-row-color: var(--tier-3); }
.tier-legend .tl-row[data-t="4"]    { --tl-row-color: var(--tier-4); }
.tier-legend .tl-row[data-t="none"] { --tl-row-color: var(--tier-none); }
.tier-legend .tl-row[data-t="none"] .tl-swatch { border: 1px dashed var(--text-3); background: transparent; }
.tier-legend .tl-name {
  font-family: var(--mono); font-size: 10px;
  color: var(--text-1); letter-spacing: 0.04em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tier-legend .tl-bar {
  height: 4px; background: var(--bg-2); border-radius: 2px; overflow: hidden;
}
.tier-legend .tl-bar-fill {
  display: block; height: 100%;
  background: var(--tl-row-color, var(--tier-none));
  transition: width var(--t-layout) var(--ease);
}
.tier-legend .tl-count {
  font-family: var(--mono); font-size: 10px;
  color: var(--text-0); text-align: right;
  display: flex; flex-direction: column; align-items: flex-end;
}
.tier-legend .tl-pct { color: var(--text-3); font-size: 9px; }
.tier-legend .tl-foot {
  margin-top: 10px; padding-top: 10px;
  border-top: 1px solid var(--border-soft);
  font-style: italic; font-size: 10px; color: var(--text-3);
  line-height: 1.5;
}

.themes-menu {
  /* Constrained to the canvas region (between nav and detail panel) so it never overlays
     the detail panel — that previously trapped clicks inside detail behind the menu. */
  position: fixed; top: 0; left: var(--nav-w); right: var(--detail-w);
  background: linear-gradient(180deg, rgba(13,17,25,0.97) 0%, rgba(7,9,15,0.98) 100%);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--gold-soft);
  z-index: 200; padding: 32px 48px 40px;
  max-height: 80vh; overflow-y: auto;
  /* slide-from-top — closed state is fully out of view, so no residual bar */
  transform: translateY(-110%);
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: transform 280ms cubic-bezier(0.2, 0.8, 0.2, 1),
              opacity   200ms ease,
              visibility 0s linear 280ms;
  box-shadow: 0 12px 36px rgba(0,0,0,0.6);
}
.themes-menu.open {
  transform: translateY(0);
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
  transition: transform 280ms cubic-bezier(0.2, 0.8, 0.2, 1),
              opacity   200ms ease,
              visibility 0s linear 0s;
}
/* When chrome collapses, the menu's edges track the nav/detail edges. */
body.nav-collapsed    .themes-menu { left:  var(--nav-w-collapsed); }
body.detail-collapsed .themes-menu { right: 0; }
.themes-menu .tm-header {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 22px; padding-bottom: 14px; border-bottom: 1px solid var(--border);
}
.themes-menu h3 {
  margin: 0; font-family: var(--serif); font-size: 16px;
  letter-spacing: 0.10em; color: var(--text-0); font-weight: 500;
  text-transform: uppercase;
}
.themes-menu .tm-sub { font-size: 11px; color: var(--text-2); font-style: italic; }
.themes-menu .tm-actions { display: flex; align-items: center; gap: 8px; }
.themes-menu .tm-close,
.themes-menu .tm-clear {
  background: transparent; border: 1px solid var(--border);
  color: var(--text-2); font-size: 11px; padding: 4px 12px; border-radius: 3px;
  letter-spacing: 0.06em; cursor: pointer;
  font-family: var(--sans);
  transition: color 140ms ease, border-color 140ms ease, background 140ms ease;
}
.themes-menu .tm-close:hover { color: var(--gold); border-color: var(--gold-soft); }
.themes-menu .tm-clear { color: var(--gold-soft); border-color: var(--gold-soft); }
.themes-menu .tm-clear:hover { color: var(--gold); border-color: var(--gold); background: rgba(212,165,90,0.08); }
.themes-grid {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
.themes-cat {
  font-family: var(--serif); font-size: 12px;
  color: var(--gold-soft); letter-spacing: 0.18em; text-transform: uppercase;
  margin-top: 18px; margin-bottom: 6px; grid-column: 1 / -1;
  padding-bottom: 4px; border-bottom: 1px solid var(--border-soft);
  font-weight: 500;
}
.themes-cat:first-child { margin-top: 0; }
.theme-card {
  position: relative;
  background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 4px; padding: 14px 16px 16px;
  cursor: pointer; transition: all 200ms ease;
  overflow: hidden;
}
.theme-card::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(135deg, var(--theme-color, var(--gold)) 0%, transparent 60%);
  opacity: 0.08; transition: opacity 200ms ease;
}
.theme-card:hover { border-color: var(--theme-color, var(--gold-soft)); transform: translateY(-1px); }
.theme-card:hover::before { opacity: 0.20; }
.theme-card.active { border-color: var(--theme-color, var(--gold)); box-shadow: 0 0 0 1px var(--theme-color, var(--gold)); }
.theme-card .tc-name {
  font-family: var(--serif); font-size: 16px; color: var(--text-0);
  font-weight: 500; letter-spacing: 0.04em; margin-bottom: 6px;
  position: relative; z-index: 1;
}
.theme-card .tc-count {
  font-family: var(--mono); font-size: 10px; color: var(--text-2);
  letter-spacing: 0.08em; position: relative; z-index: 1;
}
.theme-card .tc-swatch {
  position: absolute; top: 14px; right: 14px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--theme-color, var(--gold));
  box-shadow: 0 0 12px var(--theme-color, var(--gold));
}

/* NAV */
nav.side {
  position: fixed;
  left: 0; top: 0; bottom: 0;
  width: var(--nav-w); z-index: 150;
  background: var(--panel-bg);
  backdrop-filter: var(--panel-blur);
  -webkit-backdrop-filter: var(--panel-blur);
  border-right: var(--panel-edge);
  box-shadow: var(--panel-shadow);
  overflow: hidden;
  display: flex; flex-direction: column;
  transition: width var(--t-layout) var(--ease);
}
/* Collapsed nav = thin icon strip (48px), NOT slid off-screen. */
body.nav-collapsed nav.side { width: var(--nav-w-collapsed); }

/* SIDE-TAB — the visible toggle. Sits at the right edge of the sidebar when expanded,
   slides to the viewport's left edge when collapsed, so it's always reachable. */
/* SIDE-TAB — discreet nav toggle. Previous version was an 18×64 attached tab
   with chrome; the user wanted something less intrusive. This version: a tiny
   16×16 chevron with no background, semi-transparent until hover. Positioned
   at the top of the nav strip (consistent location in both states), so the
   eye finds it without it ever dominating the canvas. */
.side-tab {
  position: fixed;
  left: calc(var(--nav-w) - 26px);
  top: 14px;
  width: 22px; height: 22px;
  margin: 0;
  background: rgba(212,165,90,0.08);
  border: 1px solid var(--border-soft); border-radius: 3px;
  cursor: pointer; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  color: var(--gold-soft); font-family: var(--mono); font-size: 14px; line-height: 1; font-weight: 600;
  opacity: 0.9;
  transition: left 240ms cubic-bezier(0.2, 0.8, 0.2, 1), opacity 160ms, color 160ms, background 160ms, border-color 160ms;
}
.side-tab:hover { opacity: 1; color: var(--gold); background: rgba(212,165,90,0.18); border-color: var(--gold-soft); }
/* When the nav is collapsed (icon strip), the chevron sits centered in the strip's top. */
body.nav-collapsed .side-tab {
  left: calc((var(--nav-w-collapsed) - 22px) / 2);
}
.nav-toggle {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  width: 28px; height: 28px;
  background: var(--bg-2); border: 1px solid var(--border);
  color: var(--text-2); border-radius: 3px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 14px; line-height: 1;
  transition: all 150ms ease;
}
.nav-toggle:hover { color: var(--gold); border-color: var(--gold-soft); }
.nav-inner { padding: 10px 0 14px; overflow-y: auto; flex: 1; }
nav.side .item {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 20px; font-size: 12px; color: var(--text-2);
  cursor: pointer; border-left: 2px solid transparent;
  transition: all 150ms ease; letter-spacing: 0.02em; white-space: nowrap;
}
nav.side .item:hover { color: var(--text-0); background: var(--bg-2); }
nav.side .item.active {
  color: var(--gold); border-left-color: var(--gold);
  background: linear-gradient(90deg, rgba(212,165,90,0.10), transparent);
}
nav.side .item .sym { font-family: var(--serif); font-size: 15px; width: 16px; text-align: center; color: inherit; opacity: 0.85; flex-shrink: 0; }
nav.side .item .lbl { transition: opacity 150ms ease; }
nav.side .section-label {
  padding: 14px 20px 5px; font-size: 9.5px;
  text-transform: uppercase; letter-spacing: 0.16em;
  color: var(--text-3); font-weight: 600; white-space: nowrap;
}
body.nav-collapsed .nav-inner { padding-left: 0; padding-right: 0; }
body.nav-collapsed nav.side .item { padding: 11px 0; justify-content: center; position: relative; }
body.nav-collapsed nav.side .item .lbl { opacity: 0; display: none; }
/* Hover-tooltip when nav is collapsed — pops to the right of the icon strip
   showing the full label. Pulled from the .lbl text via JS (sets data-tooltip
   on every .item on first render). */
/* Tooltip on the side-nav icons — pops to the right when hovered. Works in
   BOTH collapsed and expanded states so the user always gets a confirmation
   of what each icon means. (When expanded the .lbl is also visible, but the
   tooltip is the canonical "what does this icon mean" affordance.) */
nav.side .item:hover::after {
  content: attr(data-tooltip);
  position: absolute;
  left: calc(100% + 12px); top: 50%; transform: translateY(-50%);
  background: rgba(14,16,22,0.96);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--text-0);
  border: 1px solid var(--border-soft);
  padding: 5px 11px; border-radius: 3px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  white-space: nowrap; pointer-events: none;
  box-shadow: 0 4px 14px rgba(0,0,0,0.45);
  z-index: 210;
}
nav.side .item { position: relative; }
body.nav-collapsed nav.side .item:hover::before {
  content: '';
  position: absolute;
  left: calc(100% + 6px); top: 50%; transform: translateY(-50%);
  width: 0; height: 0;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-right: 6px solid var(--border-soft);
  pointer-events: none; z-index: 210;
}
body.nav-collapsed nav.side .section-label { opacity: 0; padding: 8px 0; height: 8px; overflow: hidden; }

/* CANVAS */
main.canvas {
  position: fixed;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  background: radial-gradient(ellipse at center, var(--bg-1) 0%, var(--bg-0) 80%);
}
/* On the timeline (a wide horizontal layout), the radial gradient makes the LEFT and RIGHT
   edges look darker than the centre — reads as a "bg color change". Force a uniform fill there. */
body.view-timeline main.canvas { background: var(--bg-0); }
body.view-atlas    main.canvas { background: var(--bg-0); }

/* SVG wrapper — a plain div handles the panel-clearing geometry. vw/% units and
   calc() work correctly on divs; SVG elements have browser quirks with these.
   The --eff-* vars cascade from body.nav/detail-collapsed automatically. */
#svg-wrap {
  position: absolute;
  top: 0; height: 100%;
  left: var(--eff-nav-w);
  width: calc(100% - var(--eff-nav-w) - var(--eff-detail-w));
  overflow: visible;
  transition: left var(--t-layout) var(--ease), width var(--t-layout) var(--ease);
}
/* SVG fills the wrapper reliably — width:100% on a sized block parent works everywhere */
main.canvas > div#svg-wrap > svg#svg {
  display: block;
  width: 100%; height: 100%;
  overflow: visible;
}
/* Map-thumb SVG keeps its own 100% rule */
.view-header {
  position: absolute; top: 14px;
  left: calc(var(--nav-w) + 24px);
  right: calc(var(--detail-w) + 24px);
  z-index: 5;
  display: flex; align-items: baseline; justify-content: space-between;
  pointer-events: none;
  gap: 16px;
  transition: left var(--t-layout) var(--ease), right var(--t-layout) var(--ease);
}
body.nav-collapsed    .view-header { left:  calc(var(--nav-w-collapsed) + 24px); }
body.detail-collapsed .view-header { right: 24px; }
.view-header > div:first-child { min-width: 0; flex: 1 1 auto; }   /* title block can shrink */
.view-controls { pointer-events: auto; display: flex; gap: 8px; align-items: center; flex-shrink: 0; }
.view-header h2 { margin: 0; font-family: var(--serif); font-size: var(--h2-size); color: var(--text-0); font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; white-space: nowrap; }
/* Subtitles removed site-wide 2026-05-15 per user feedback ("super low quality and not useful").
   The subtitle SPAN stays in the DOM (renderers still set its text) but it's hidden. */
.view-header .subtitle { display: none; }
.btn {
  background: var(--bg-2); border: 1px solid var(--border);
  color: var(--text-1); font: inherit; font-size: 11px;
  padding: 6px 12px; border-radius: 3px; cursor: pointer;
  letter-spacing: 0.04em; transition: all 150ms ease;
  white-space: nowrap;
}
.btn:hover { background: var(--bg-3); color: var(--text-0); border-color: var(--gold-soft); }
.btn.active { background: var(--gold); color: var(--bg-0); border-color: var(--gold); }
.btn-mini { padding: 4px 8px; font-size: 10px; }
.pantheon-mode-toggle { display: inline-flex; align-items: center; border: 1px solid var(--border); border-radius: 3px; }
.pantheon-mode-toggle .btn { border: 0; border-radius: 0; padding: 4px 10px; }
.pantheon-mode-toggle .btn:not(:last-child) { border-right: 1px solid var(--border); }
.pantheon-mode-toggle .btn.active { background: rgba(212,165,90,0.10); color: var(--gold); }
/* Pantheon mode selector (the dropdown form added to support 6 modes: deities / authors /
   symbols / events / scripture-shortcut / monuments-placeholder). Styled as a native
   <select> with the same btn-mini look as its toolbar siblings. */
.pantheon-mode-select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  background-color: var(--bg-2);
  background-image: linear-gradient(45deg, transparent 50%, var(--text-3) 50%),
                    linear-gradient(135deg, var(--text-3) 50%, transparent 50%);
  background-position: calc(100% - 12px) 52%, calc(100% - 8px) 52%;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
  padding-right: 22px;
  cursor: pointer;
  font-weight: 500;
}
.pantheon-mode-select:hover { color: var(--gold); border-color: var(--gold-soft); }
.pantheon-mode-select:focus { outline: none; border-color: var(--gold-soft); }
.tl-family-select {
  appearance: none; -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-2) 50%),
                    linear-gradient(135deg, var(--text-2) 50%, transparent 50%);
  background-position: calc(100% - 10px) 50%, calc(100% - 6px) 50%;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
  padding-right: 20px;
  cursor: pointer;
}
.tl-family-select:hover { color: var(--gold); border-color: var(--gold-soft); }
.tl-family-select option { background: var(--bg-1); color: var(--text-1); }

/* DETAIL */
/* Panel uses width-based collapse with a stuck-animation guard in JS (see
   detail-toggle handler). The map pane is decoupled from --eff-detail-w so
   the panel slide never re-flows the diagram. */
aside.detail {
  position: fixed;
  right: 0; top: 0; bottom: 0;
  width: var(--detail-w); z-index: 150;
  background: var(--panel-bg);
  backdrop-filter: var(--panel-blur);
  -webkit-backdrop-filter: var(--panel-blur);
  border-left: var(--panel-edge);
  box-shadow: -8px 0 24px -8px rgba(0,0,0,0.45);
  overflow: hidden;
  display: flex; flex-direction: column;
  transition: width var(--t-layout) var(--ease);
}
/* 2026-06-10 (INCIDENT §4) — collapsed = GONE, on every view (this
   was forge-only via body.view-forge scoping since Phase 19E — the
   rule-#8 violation that masked the V01 rail on the flagship view).
   The V01 .detail-toggle chevron is DELETED with its markup. */
body.detail-collapsed aside.detail { display: none; }
.detail-close {
  /* 2026-06-13 — was a 45%-grey glyph with no background: invisible over
     the node image at the panel top (John: "the side panels dont CLOSE
     theres no option to close"). Now a clearly-visible dark chip that
     reads on any backdrop, raised above the image. */
  position: absolute; top: 12px; right: 14px; z-index: 6;
  width: 30px; height: 30px;
  background: rgba(13,17,25,0.72); border: 1px solid rgba(255,255,255,0.14);
  border-radius: 50%;
  color: rgba(245,245,245,0.92);
  font-size: 14px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  box-shadow: 0 4px 12px -4px rgba(0,0,0,0.6);
  transition: color 150ms ease, background 150ms ease, border-color 150ms ease;
}
.detail-close:hover {
  color: var(--gold);
  background: rgba(13,17,25,0.92);
  border-color: var(--gold);
}
.detail-inner {
  /* symmetric since 2026-06-10 — the 38px left gutter existed to clear
     the deleted V01 chevron */
  flex: 1; overflow-y: auto; padding: 16px 18px 24px 18px;
  transition: opacity 150ms ease;
}
body.detail-collapsed .detail-inner { opacity: 0; pointer-events: none; }
/* 2026-06-10 — the V01 detail-content styles (.thumb/.meta .pill/
 * .body-md/.links-out/.link-edge/serif h3) were DELETED together with
 * the legacy renderDetail() renderer (rule #8). The canonical node
 * inspector (src/js/inspector.js) emits the shared
 * .forge-side-panel-* markup language instead — one visual system
 * for every surface that opens a node. */
aside.detail .empty {
  color: rgba(230,230,230,0.4);
  font: 400 11px/1.6 "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 90px 12px;
  text-align: center;
}

/* FOOTER — 2026-05-27 — DELETED. The legacy <footer> + #footer-toggle were
   prototype V01 chrome hardcoded into index.html. Rip-out commit dropped
   both the HTML elements and every JS consumer (filter-search input
   listener, btn-reset-filters click handler, footer-toggle click handler,
   footer-status text setter). All associated CSS rules (footer { ... },
   .footer-toggle, footer .filter-group, footer label, footer select,
   .active-filter, body.footer-collapsed adjustments) deleted with them.
   Per-view search/filter lives in each view's contextual pill or panel. */

/* GRAPH STYLES */
.sector-hull {
  fill-opacity: 0.07; stroke-opacity: 0.30; stroke-width: 0.8;
  pointer-events: none;
  transition: fill-opacity 250ms ease, stroke-opacity 250ms ease;
}
.sector-hull.dim { fill-opacity: 0.02; stroke-opacity: 0.08; }
.sector-hull.hot { fill-opacity: 0.16; stroke-opacity: 0.6; }

.hull {
  fill-opacity: 0.06; stroke-opacity: 0.35; stroke-width: 1;
  pointer-events: none; transition: fill-opacity 200ms ease;
}
.hull.dim { fill-opacity: 0.02; stroke-opacity: 0.10; }
.hull.hot { fill-opacity: 0.15; stroke-opacity: 0.6; }

.node-circle {
  cursor: pointer; transition: stroke-width 120ms ease, opacity 200ms ease, r 200ms ease;
  stroke: rgba(255,255,255,0.18); stroke-width: 1.0;
}
.node-circle:hover { stroke: var(--gold); stroke-width: 2.4; }
.node-circle.selected { stroke: var(--gold); stroke-width: 3; }
.node-circle.dim {
  opacity: 0.10;
  /* Locked/dimmed nodes should not catch pointer events — only highlighted nodes
     are interactive while a sticky selection is active. */
  pointer-events: none;
}

/* visual filter — keeps positions, fades non-matching */
.node-circle.filter-dim {
  opacity: 0.12;
  pointer-events: none;   /* same rule for family-filter dimming */
}
.node-label.filter-dim  { opacity: 0 !important; pointer-events: none; }  /* hide non-matching node names entirely */
.edge-line.filter-dim   { stroke-opacity: 0.020 !important; }
.sector-hull.filter-dim { fill-opacity: 0.018; stroke-opacity: 0.08; }
.family-label.filter-dim { opacity: 0.55; }  /* keep zone names visible — they mark the territory */

/* legend row hover-preview — ghost-dims non-matching family while pointer is on the row */
.node-circle.preview-fade { opacity: 0.16; pointer-events: none; }
.node-label.preview-fade  { opacity: 0 !important; }
.sector-hull.preview-fade { fill-opacity: 0.02; stroke-opacity: 0.10; }
.family-label.preview-fade { opacity: 0.30; }

/* hover-reveal overrides filter-dim — reveals cross-filter neighbors on hover */
.node-circle.filter-dim.hover-reveal { opacity: 0.85; }
.node-label.filter-dim.hover-reveal  { opacity: 0.90; }
.edge-line.filter-dim.hover-reveal   { stroke-opacity: 0.85 !important; stroke-width: 1.6 !important; }
.sector-hull.filter-dim.hover-reveal { fill-opacity: 0.10; stroke-opacity: 0.4; }
.family-label.filter-dim.hover-reveal { opacity: 0.85; }
.node-circle.hot { stroke: var(--gold); stroke-width: 2.4; }

.node-label {
  font-family: var(--sans); font-size: 10px; fill: var(--text-2);
  pointer-events: none; text-anchor: middle;
  paint-order: stroke; stroke: var(--bg-0); stroke-width: 0.22em;
  transition: opacity 200ms ease;
}
.node-label.hub { fill: var(--text-0); font-weight: 500; font-size: 11px; }
.node-label.dim { opacity: 0; }

.edge-line {
  fill: none; pointer-events: none;
  vector-effect: non-scaling-stroke;
  /* DEFAULT stroke is a quiet slate-blue — same for every edge type, regardless of
     semantic. User: "I HATE BIG THICK LINES... pleasant blue... not overwhelming."
     The per-type color (gold/red/etc.) lives in --edge-type-color (set inline by JS via
     style('--edge-type-color', st.c)) and only appears when the edge is .hot (hovered or
     selected) or revealed via filter-dim+hover. */
  stroke: rgba(120, 140, 182, 0.72);
  transition: stroke-opacity 180ms ease, stroke-width 180ms ease, stroke 180ms ease;
}
.edge-line.dim    { stroke-opacity: 0.02 !important; }
/* Highlighted edges: type color from the CSS var, capped at 1.6px. */
.edge-line.hot    {
  stroke: var(--edge-type-color, rgba(212, 165, 90, 0.9)) !important;
  stroke-opacity: 0.9 !important; stroke-width: 1.6 !important;
}
.edge-line.filter-dim.hover-reveal {
  stroke: var(--edge-type-color, rgba(212, 165, 90, 0.85)) !important;
  stroke-opacity: 0.8 !important; stroke-width: 1.3 !important;
}

/* Cross-symbol edges in Pantheon Symbols mode. The .xsym class marks all cross-symbol-
   edge types (ancestor-of, parallel-form, syncretic-fusion, appropriated-by,
   polemic-inversion, visual-cognate); the .xsym-xfamily sub-class marks the subset that
   spans two distinct origin-traditions — the user's "MASSIVE wins". */
.edge-line.xsym {
  stroke-linecap: round;
}
.edge-line.xsym-xfamily {
  /* Subtle drop-shadow so cross-family edges read above the wedge fills. */
  filter: drop-shadow(0 0 1px rgba(212,165,90,0.45));
}

.family-label {
  font-family: var(--serif); font-size: 13px; letter-spacing: 0.22em;
  fill: var(--text-2); text-transform: uppercase; pointer-events: none;
  text-anchor: middle; font-weight: 500;
  paint-order: stroke; stroke: var(--bg-0); stroke-width: 0.22em;
  transition: opacity 200ms ease, font-size 200ms ease, fill 200ms ease;
}
.family-label.bright { fill: var(--text-0); }
.family-label.dim    { opacity: 0.25; }

.phase-ring {
  fill: none; stroke: var(--border); stroke-dasharray: 2 5; stroke-opacity: 0.45;
}
.phase-ring-label {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.16em;
  fill: var(--text-3); pointer-events: none; text-transform: uppercase;
}

/* TIMELINE */
/* Chart-area background — fixes the "Black on the left where time condensates" complaint.
   Strong-enough slate overlay that the timeline reads as a drawn surface across the whole
   width. Was too subtle before (0.045 alpha was indistinguishable from the void-black
   canvas). 0.10 alpha is the floor for "you can actually see it". */
.tl-chart-bg { fill: rgba(80, 90, 115, 0.10); }
/* Compressed-gap cut zone — formerly DARKENED with rgba(0,0,0,0.18), which is what made
   the left side look black (prehistory has the biggest gaps, so most of the left edge was
   black overlay). Now LIGHTER than the chart-bg, so the cut reads as "we skipped some
   time here" without going darker than the rest of the canvas. The zigzag-stroke remains
   the primary marker. */
/* Compression-gap cut zone — NO TINT. The zigzag stroke (drawn in JS) is the only marker
   of a cut. Previously this had a gold tint that turned the whole prehistoric left side
   brown (prehistory has the biggest gaps → most of the canvas-left was overlay). */
.tl-break-fill { fill: transparent; }
/* Bottom zoom-preset toolbar — sits between the main chart and the mini overview.
   Quick-toggle buttons to set the visible date range to a specific number of years. */
.tl-zoom-presets {
  position: absolute; z-index: 25;
  bottom: calc(var(--footer-h) + 90px);
  left: 50%; transform: translateX(-50%);
  display: flex; gap: 6px; padding: 4px 8px;
  background: rgba(13, 17, 25, 0.72); backdrop-filter: blur(6px);
  border: 1px solid var(--border); border-radius: 4px;
  font-family: var(--mono); font-size: 10px; pointer-events: auto;
}
.tl-zoom-presets .lbl {
  color: var(--text-3); padding: 3px 4px 3px 0;
  letter-spacing: 0.08em; text-transform: uppercase; align-self: center;
}
.tl-zoom-presets button {
  background: transparent; border: 1px solid var(--border);
  color: var(--text-2); padding: 3px 8px; border-radius: 3px;
  cursor: pointer; font: inherit; font-size: 10px;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.tl-zoom-presets button:hover {
  color: var(--gold); border-color: var(--gold-soft); background: rgba(212,165,90,0.05);
}
.tl-zoom-presets button.active {
  color: var(--gold); border-color: var(--gold-soft); background: rgba(212,165,90,0.10);
}
.tl-zoom-presets .sep {
  width: 1px; height: 16px; background: var(--border); margin: 0 4px; align-self: center;
}
.tl-zoom-presets .yr-input {
  background: var(--bg-2); border: 1px solid var(--border);
  color: var(--text-1); padding: 3px 8px; border-radius: 3px;
  font: inherit; font-size: 10px; width: 90px; outline: none;
  transition: border-color 120ms;
}
.tl-zoom-presets .yr-input:focus { border-color: var(--gold-soft); }
.tl-zoom-presets .yr-input::placeholder { color: var(--text-3); opacity: 0.6; }
.tl-band { fill: rgba(255,255,255,0.02); }
.tl-band-label {
  font-family: var(--serif); font-size: 12px; fill: var(--text-3);
  letter-spacing: 0.14em; text-transform: uppercase;
  paint-order: stroke; stroke: var(--bg-0); stroke-width: 4px;
}
.tl-axis text { fill: var(--text-2); font-family: var(--mono); font-size: 10px; }
.tl-era-line {
  stroke: var(--text-2); stroke-width: 0.5;
  stroke-opacity: 0.14; stroke-dasharray: 2 5;
  pointer-events: none;
}
.tl-break {
  pointer-events: none;
}
.tl-break-fill { /* dark fill across the cut so events behind don't show through */ }
.tl-break-zigzag { /* drawn by JS */ }
.tl-break-label {
  fill: var(--gold-soft); font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.08em; opacity: 0.85;
}
.tl-era-line.major { stroke-opacity: 0.22; stroke-dasharray: none; stroke-width: 0.6; }
.tl-era-label {
  fill: var(--text-3); font-family: var(--mono); font-size: 8.5px;
  letter-spacing: 0.10em; text-anchor: start; pointer-events: none; opacity: 0.55;
}
.tl-axis path, .tl-axis line { stroke: var(--border); }
.tl-event { cursor: pointer; }
/* Main pass uses <path class="tl-event-shape">; mini overview uses <circle class="tl-event-dot">. */
.tl-event circle.tl-event-dot,
.tl-event path.tl-event-shape {
  stroke: rgba(255,255,255,0.18); stroke-width: 1.0;
  transition: stroke 150ms ease, stroke-width 150ms ease, opacity 220ms cubic-bezier(0.2,0.8,0.2,1);
}
.tl-event:hover circle.tl-event-dot,
.tl-event:hover path.tl-event-shape { stroke: var(--gold); stroke-width: 2.2; }
.tl-event-label {
  font-family: var(--sans); fill: var(--text-2);
  pointer-events: none;
  paint-order: stroke; stroke: var(--bg-0); stroke-width: 0.22em;
  /* opacity transition drives the tier-fade and collision-fade visuals — no more display:none flips. */
  transition: font-size 200ms cubic-bezier(0.2,0.8,0.2,1),
              opacity 240ms cubic-bezier(0.2,0.8,0.2,1);
}
/* Both tier-gating and collision-resolution hide a label by adding .tl-hidden. CSS fades
   the opacity smoothly via the transition above. pointer-events:none prevents hidden labels
   from intercepting hover. */
.tl-event-label.tl-hidden { opacity: 0; pointer-events: none; }
/* Bubbles get a subtle fade too — for future "fade unrelated nodes when one is selected" UX. */
.tl-event.tl-dim path.tl-event-shape,
.tl-event.tl-dim circle.tl-event-dot { opacity: 0.18; }
.tl-pan-region { cursor: grab; }
.tl-pan-region:active { cursor: grabbing; }
.tl-brush .selection {
  fill: var(--gold); fill-opacity: 0.10; stroke: var(--gold-soft);
}

/* LISTS */
.list-pane {
  position: absolute;
  top: 56px; bottom: 24px;
  left: calc(var(--eff-nav-w) + 24px);
  right: calc(var(--eff-detail-w) + 24px);
  overflow-y: auto; padding-right: 12px;
  transition: left var(--t-layout) var(--ease), right var(--t-layout) var(--ease);
}
.list-pane .row {
  display: grid; grid-template-columns: 28px 1fr auto auto;
  gap: 14px; align-items: baseline;
  padding: 10px 14px; border-bottom: 1px solid var(--border-soft);
  cursor: pointer; transition: background 120ms ease;
}
.list-pane .row:hover { background: var(--bg-2); }
.list-pane .row .swatch { width: 12px; height: 12px; border-radius: 50%; margin-top: 4px; align-self: flex-start; }
.list-pane .row .row-title { color: var(--text-0); font-size: var(--h3-size); }
.list-pane .row .row-meta { font-family: var(--mono); font-size: var(--lbl-md); color: var(--text-2); letter-spacing: 0.04em; }
.list-pane .row .row-trad { color: var(--gold-soft); font-size: 11px; }

/* LIST-PANE HEADER — shared group-header pattern for index views. Replaces ad-hoc
   inline-styled headers in VIEWS.edges (and any future grouped list). The accent
   color is supplied via --lph-accent (set by JS per group, falls back to gold-soft). */
.list-pane-header {
  display: flex; align-items: center; gap: 8px;
  margin: 18px 0 6px; padding: 0 14px;
  font-family: var(--mono); font-size: 11px;
  color: var(--lph-accent, var(--gold-soft));
  letter-spacing: 0.12em; text-transform: uppercase;
}
.list-pane-header .lph-rule {
  display: inline-block; width: 14px; height: 2px;
  background: var(--lph-accent, var(--gold-soft));
}
.list-pane-header .lph-count { color: var(--text-3); }
.list-pane-empty {
  color: var(--text-3); padding: 24px; font-style: italic;
  font-family: var(--serif); font-size: var(--h3-size);
}

/* PATTERNS view */
.patterns-pane .pattern-card {
  padding: 14px 18px 12px;
  border-bottom: 1px solid var(--border-soft);
  cursor: pointer;
  transition: background 120ms ease;
}
.patterns-pane .pattern-card:hover { background: var(--bg-2); }
.patterns-pane .pattern-card-head {
  display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px;
}
.pattern-badge {
  flex-shrink: 0;
  font-family: var(--mono); font-size: 9px; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  border: 1px solid; border-radius: 3px;
  padding: 2px 7px; line-height: 1.6;
}
.patterns-pane .pattern-title {
  font-family: var(--serif); font-size: var(--h3-size);
  color: var(--text-0); font-weight: 500; line-height: 1.35;
}
.patterns-pane .pattern-summary {
  font-size: 12px; color: var(--text-2); line-height: 1.6;
  max-width: 760px;
}
.patterns-pane .pattern-sources {
  display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px;
}
.pattern-source {
  font-family: var(--mono); font-size: 10px;
  color: var(--gold-soft); background: rgba(212,165,90,0.08);
  border: 1px solid rgba(212,165,90,0.25); border-radius: 3px;
  padding: 2px 8px; cursor: pointer; transition: background 120ms ease;
}
.pattern-source:hover { background: rgba(212,165,90,0.18); color: var(--gold); }
.pattern-source--missing { color: var(--text-3); border-color: var(--border-soft); background: transparent; cursor: default; }

/* OBSERVATIONS view */
.obs-pane .obs-card {
  padding: 20px 24px 16px;
  border-bottom: 1px solid var(--border-soft);
  max-width: 860px;
}
.obs-pane .obs-head {
  display: flex; align-items: baseline; gap: 10px; margin-bottom: 8px;
}
.obs-badge {
  flex-shrink: 0;
  font-family: var(--mono); font-size: 9px; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  border: 1px solid; border-radius: 3px;
  padding: 2px 7px; line-height: 1.6;
}
.obs-pane .obs-title {
  font-family: var(--serif); font-size: 17px;
  color: var(--text-0); font-weight: 500; line-height: 1.3;
}
.obs-pane .obs-summary {
  font-size: 13px; color: var(--gold-soft);
  font-style: italic; line-height: 1.6; margin-bottom: 10px;
}
.obs-pane .obs-body {
  font-size: 12px; color: var(--text-2); line-height: 1.75;
}
.obs-pane .obs-evidence {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 12px;
}
.obs-ev-label {
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.10em;
  text-transform: uppercase; color: var(--text-3); margin-right: 2px;
}

/* CHAINS view */
.chains-pane { padding: 18px 20px 40px; overflow-y: auto; }
.chain-card {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 8px; margin-bottom: 28px; overflow: hidden;
}
.chain-head {
  padding: 16px 18px 12px; border-bottom: 1px solid var(--border);
}
.chain-head-top {
  display: flex; align-items: center; gap: 10px; margin-bottom: 8px;
}
.chain-badge {
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.12em;
  font-weight: 700; padding: 2px 8px; border-radius: 3px; flex-shrink: 0;
}
.chain-span {
  font-family: var(--mono); font-size: 10px; color: var(--text-3);
  letter-spacing: 0.05em;
}
.chain-title {
  font-size: 14px; font-weight: 600; color: var(--text-1);
  margin: 0 0 8px; line-height: 1.3;
}
.chain-summary {
  font-size: 11px; color: var(--text-2); line-height: 1.6; margin: 0;
  font-style: italic;
}
.chain-links { padding: 10px 18px 16px; }
.chain-link {
  display: flex; gap: 14px; align-items: flex-start; min-height: 52px;
}
.chain-link-left {
  display: flex; flex-direction: column; align-items: center;
  flex-shrink: 0; width: 80px; padding-top: 2px;
}
.chain-date {
  font-family: var(--mono); font-size: 9px; color: var(--text-3);
  letter-spacing: 0.04em; text-align: center; margin-bottom: 4px;
  white-space: nowrap;
}
.chain-dot-col {
  display: flex; flex-direction: column; align-items: center; flex: 1;
}
.chain-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--gold); flex-shrink: 0; margin-bottom: 2px;
}
.chain-line {
  width: 1px; flex: 1; min-height: 24px;
  background: linear-gradient(to bottom, var(--gold-soft), transparent);
  margin-bottom: 4px;
}
.chain-link-right { flex: 1; padding-bottom: 12px; }
.chain-node-label {
  display: inline-block; font-size: 12px; font-weight: 600;
  color: var(--gold); margin-bottom: 4px;
  text-decoration: none; border-bottom: 1px solid transparent;
  transition: border-color 0.15s;
}
.chain-node-label:hover { border-bottom-color: var(--gold); }
.chain-note {
  font-size: 11px; color: var(--text-2); line-height: 1.6; margin: 0;
}

/* ALCHEMY view */
.alch-toolbox {
  position: absolute; bottom: calc(var(--footer-h) + 18px); left: 50%; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 14px;
  background: rgba(13,17,25,0.88); backdrop-filter: blur(8px);
  border: 1px solid var(--gold-soft); border-radius: 999px;
  padding: 8px 18px; z-index: 30;
  box-shadow: 0 8px 30px rgba(0,0,0,0.4);
}
.alch-add-btn {
  background: transparent; border: 1px solid var(--gold-soft); border-radius: 999px;
  color: var(--gold); font-family: var(--sans); font-size: 11px;
  padding: 6px 14px; letter-spacing: 0.10em; text-transform: uppercase;
  cursor: pointer; transition: all 140ms ease;
}
.alch-add-btn:hover { background: rgba(212,165,90,0.10); border-color: var(--gold); }
.alch-toolbox .alch-hint {
  font-family: var(--mono); font-size: 10px; color: var(--text-3);
  letter-spacing: 0.04em; font-style: italic;
}

/* UTILITY TOOLS: layout selector + spacing slider, inline in the toolbox pill. */
.alch-tools-divider {
  width: 1px; height: 16px;
  background: var(--border);
  display: inline-block;
}
.alch-layout-group {
  display: inline-flex; align-items: center; gap: 2px;
  background: rgba(7,9,15,0.45);
  border: 1px solid var(--border); border-radius: 999px;
  padding: 2px;
}
.alch-layout-btn {
  width: 26px; height: 24px;
  background: transparent; border: 0; border-radius: 999px;
  color: var(--text-2); font-family: var(--mono); font-size: 14px; line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: color 130ms, background 130ms;
}
.alch-layout-btn:hover { color: var(--gold); background: rgba(212,165,90,0.08); }
.alch-layout-btn.active {
  color: var(--gold);
  background: rgba(212,165,90,0.18);
  box-shadow: inset 0 0 0 1px var(--gold-soft);
}
/* ELK arrange-popup trigger — wider so it fits "⌬ ELK ▾" + popup menu below it. */
.alch-layout-btn.alch-elk-btn {
  width: auto; padding: 0 10px;
  font-size: 11px; letter-spacing: 0.04em;
}
.alch-elk-menu {
  position: fixed;
  background: rgba(14,16,22,0.96);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.55);
  min-width: 240px; padding: 5px 0;
  z-index: 220;
  font-family: var(--serif); font-size: 13px;
}
.alch-elk-menu-item {
  padding: 7px 14px; cursor: pointer;
  color: var(--text-1); transition: background 100ms ease;
}
.alch-elk-menu-item:hover { background: var(--bg-2); color: var(--gold); }
.alch-spacing-label {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 10px; color: var(--text-3);
  letter-spacing: 0.06em;
}
.alch-spacing-icon { font-size: 12px; color: var(--text-3); }
#alch-spacing-slider {
  -webkit-appearance: none; appearance: none;
  width: 90px; height: 4px;
  background: var(--bg-2);
  border-radius: 2px; outline: none;
  cursor: pointer;
}
#alch-spacing-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 12px; height: 12px;
  background: var(--gold); border: 1px solid var(--gold-soft);
  border-radius: 50%; cursor: pointer;
  box-shadow: 0 0 4px rgba(212,165,90,0.40);
}
#alch-spacing-slider::-moz-range-thumb {
  width: 12px; height: 12px;
  background: var(--gold); border: 1px solid var(--gold-soft);
  border-radius: 50%; cursor: pointer;
  box-shadow: 0 0 4px rgba(212,165,90,0.40);
}
#alch-spacing-slider::-moz-range-track {
  background: var(--bg-2); height: 4px; border-radius: 2px;
}
.view-controls .alch-count {
  font-family: var(--mono); font-size: 10px; color: var(--text-2);
  letter-spacing: 0.04em; padding-right: 4px;
}

.alch-palette {
  position: absolute; bottom: 70px; left: 50%; transform: translateX(-50%);
  width: 380px;
  background: linear-gradient(180deg, rgba(13,17,25,0.97), rgba(7,9,15,0.98));
  backdrop-filter: blur(14px);
  border: 1px solid var(--gold-soft); border-radius: 6px;
  padding: 10px; z-index: 40;
  box-shadow: 0 16px 48px rgba(0,0,0,0.55);
}
#alch-search {
  width: 100%;
  background: var(--bg-2); border: 1px solid var(--border); color: var(--text-0);
  font-family: var(--sans); font-size: 13px; padding: 8px 12px; border-radius: 4px;
  outline: none; box-sizing: border-box;
}
#alch-search:focus { border-color: var(--gold-soft); }
.alch-results { max-height: 320px; overflow-y: auto; margin-top: 6px; }
.alch-result {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 10px; border-radius: 3px; cursor: pointer;
  font-size: 12px;
}
.alch-result:hover, .alch-result.active { background: rgba(212,165,90,0.10); }
.alch-r-swatch { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.alch-r-title { color: var(--text-0); flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.alch-r-meta { font-family: var(--mono); font-size: 9.5px; color: var(--text-3); letter-spacing: 0.04em; }
.alch-empty {
  padding: 14px 10px; color: var(--text-3); font-size: 11px;
  font-style: italic; text-align: center;
}
.alch-hint-row {
  margin-top: 6px; padding: 6px 10px 0; border-top: 1px solid var(--border);
  font-family: var(--mono); font-size: 9px; color: var(--text-3);
  letter-spacing: 0.06em; text-align: center;
}

.alch-node { cursor: pointer; }
.alch-node.bridge .alch-circle { opacity: 0.78; }
.alch-node.bridge:hover .alch-circle { opacity: 1; }
.alch-node-label {
  font-family: var(--sans); fill: var(--text-1);
  pointer-events: none; text-anchor: middle; font-size: 11px;
  paint-order: stroke; stroke: var(--bg-0); stroke-width: 0.22em;
}
.alch-node-label.pick { fill: var(--text-0); font-weight: 500; font-size: 12.5px; }
.alch-node-label.bridge { fill: var(--text-2); font-size: 9.5px; font-style: italic; }
.alch-link {
  /* Quiet slate-blue default — matches .edge-line discipline. Type color lives in
     --edge-type-color (set inline by JS); only the .hot state reveals it. */
  stroke: rgba(120, 140, 182, 0.72);
  vector-effect: non-scaling-stroke;
  transition: stroke-opacity 180ms ease, stroke-width 180ms ease, stroke 180ms ease;
}
.alch-link.hot {
  stroke: var(--edge-type-color, var(--gold)) !important;
  stroke-opacity: 0.9 !important; stroke-width: 1.6 !important;
}
.alch-link.dim { stroke-opacity: 0.05 !important; }
.alch-link-label {
  font-family: var(--mono); font-size: 8.5px; fill: var(--text-3);
  text-transform: uppercase; letter-spacing: 0.06em;
  pointer-events: none;
  paint-order: stroke; stroke: var(--bg-0); stroke-width: 0.25em;
}
.alch-remove { cursor: pointer; fill: var(--text-2); font-family: var(--mono); font-size: 9px; }
.alch-remove-wrap:hover .alch-remove { fill: var(--gold); }
.alch-remove-wrap:hover circle.alch-remove { fill: var(--bg-3); stroke: var(--gold); }

/* ALCHEMY PRESETS — upper-right dropdown (replaces the prior left-side .alch-presets-pane
   which hid behind the main nav when it expanded). Trigger button lives in view-controls;
   dropdown panel below it (positioned by JS, anchored to trigger). */
.alch-presets-trigger {
  display: inline-flex; align-items: center; gap: 6px;
}
.alch-presets-trigger .caret {
  font-size: 9px; color: var(--text-3); margin-left: 2px;
}
.alch-presets-trigger-label {
  max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.alch-save-wrap { display: inline-flex; align-items: center; gap: 4px; }
.alch-save-input {
  background: var(--bg-2); border: 1px solid var(--border);
  color: var(--text-0); font-family: var(--sans); font-size: 11px;
  padding: 4px 8px; border-radius: 3px; outline: none;
  width: 160px;
  transition: border-color 140ms;
}
.alch-save-input:focus { border-color: var(--gold-soft); }
.alch-save-input.invalid { border-color: #b04848; }
.alch-save-input::placeholder { color: var(--text-3); font-style: italic; }
.alch-save-confirm, .alch-save-cancel {
  width: 22px; padding: 4px 0; text-align: center;
}
.alch-save-confirm { color: var(--gold); border-color: var(--gold-soft); }
.alch-save-confirm:hover { background: rgba(212,165,90,0.10); }
.alch-save-cancel { color: var(--text-3); }
.alch-presets-dropdown {
  position: absolute; z-index: 50;
  width: 320px; max-height: 70vh;
  display: flex; flex-direction: column;
  background: var(--panel-bg);
  backdrop-filter: var(--panel-blur);
  -webkit-backdrop-filter: var(--panel-blur);
  border: var(--panel-edge); border-radius: 4px;
  font-family: var(--sans); color: var(--text-1);
  box-shadow: 0 8px 32px rgba(0,0,0,0.50);
  overflow: hidden;
}
.alch-presets-dropdown > * { padding: 0 12px; }
.alch-presets-dropdown > .alch-presets-intro,
.alch-presets-dropdown > .alch-presets-active {
  flex: 0 0 auto;
  margin: 12px 12px 8px;
  padding: 0;
}
.alch-presets-section-label {
  flex: 0 0 auto;
  font-family: var(--mono); font-size: 9.5px; color: var(--text-3);
  letter-spacing: 0.14em; text-transform: uppercase;
  padding: 6px 14px 4px; border-top: 1px solid var(--border);
  background: rgba(7,9,15,0.40);
}
.alch-presets-dropdown > .alch-presets-list {
  flex: 1 1 auto; overflow-y: auto;
  padding: 8px 12px;
}
.alch-presets-empty-custom {
  font-family: var(--serif); font-style: italic; font-size: 10.5px;
  color: var(--text-3); padding: 6px 14px 10px; line-height: 1.4;
}
.alch-preset-delete {
  float: right;
  background: transparent; border: 0;
  color: var(--text-3); cursor: pointer;
  font-family: var(--mono); font-size: 13px; line-height: 1;
  padding: 0 4px; transition: color 130ms;
}
.alch-preset-delete:hover { color: #d46060; }
.alch-presets-intro {
  font-family: var(--serif); font-style: italic; font-size: 11.5px;
  color: var(--text-2); padding: 4px 6px 10px; line-height: 1.45;
  border-bottom: 1px solid rgba(212,165,90,0.10); margin-bottom: 8px;
}
.alch-presets-active {
  background: linear-gradient(180deg, rgba(212,165,90,0.10), rgba(212,165,90,0.04));
  border: 1px solid var(--gold-soft); border-radius: 3px;
  padding: 8px 10px; margin-bottom: 10px;
}
.alch-presets-active-name {
  font-family: var(--serif); font-size: 12px; color: var(--gold);
  letter-spacing: 0.08em; text-transform: uppercase; font-weight: 500; margin-bottom: 4px;
}
.alch-presets-active-headline {
  font-family: var(--serif); font-size: 11px; color: var(--text-1);
  font-style: italic; line-height: 1.45;
}
.alch-presets-list { display: flex; flex-direction: column; gap: 6px; }
.alch-preset-card {
  border: 1px solid var(--border); border-radius: 3px;
  padding: 8px 10px; background: var(--bg-1);
  transition: border-color 140ms, background 140ms;
}
.alch-preset-card:hover { border-color: var(--gold-soft); background: var(--bg-2); }
.alch-preset-card.active {
  border-color: var(--gold);
  background: linear-gradient(180deg, rgba(212,165,90,0.06), transparent);
}
.alch-preset-name {
  font-family: var(--serif); font-size: 12px; color: var(--text-0);
  letter-spacing: 0.04em; font-weight: 500; margin-bottom: 3px;
}
.alch-preset-headline {
  font-family: var(--sans); font-size: 10.5px; color: var(--text-2);
  line-height: 1.4; margin-bottom: 7px;
}
.alch-preset-action-row {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.alch-preset-load {
  background: transparent; border: 1px solid var(--gold-soft); border-radius: 2px;
  color: var(--gold); font-family: var(--mono); font-size: 10px;
  padding: 4px 10px; letter-spacing: 0.08em; text-transform: uppercase;
  cursor: pointer; transition: all 140ms ease;
}
.alch-preset-load:hover { background: rgba(212,165,90,0.12); border-color: var(--gold); }
.alch-preset-card.active .alch-preset-load { background: rgba(212,165,90,0.10); }
.alch-preset-meta {
  font-family: var(--mono); font-size: 9px; color: var(--text-3);
  letter-spacing: 0.06em;
}
.alch-preset-confirm-row {
  display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
  padding-top: 4px;
}
.alch-preset-confirm-q {
  font-family: var(--mono); font-size: 9.5px; color: var(--text-2);
  letter-spacing: 0.04em; flex: 1 1 100%; margin-bottom: 4px;
}
.alch-preset-confirm {
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 2px;
  color: var(--text-1); font-family: var(--mono); font-size: 9.5px;
  padding: 3px 9px; letter-spacing: 0.06em; cursor: pointer;
  transition: all 130ms ease;
}
.alch-preset-confirm:hover { border-color: var(--gold-soft); color: var(--text-0); }
.alch-preset-append { color: var(--gold); border-color: var(--gold-soft); }
.alch-preset-replace { color: #d4a04a; border-color: rgba(212,165,90,0.45); }
.alch-preset-cancel { color: var(--text-3); }

/* Scrollable body wrapper for grouped preset sections */
.alch-presets-body {
  flex: 1 1 auto; overflow-y: auto;
  display: flex; flex-direction: column;
}
.alch-presets-body .alch-presets-list { padding: 4px 12px 8px; }
.alch-presets-body .alch-presets-section-label { flex: 0 0 auto; }
.alch-presets-body .alch-presets-empty-custom { padding: 6px 16px 12px; }

/* Category badge tags on preset cards */
.alch-preset-tag {
  display: inline-block; vertical-align: middle;
  font-family: var(--mono); font-size: 8px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase;
  padding: 1px 5px; border-radius: 2px;
  margin-right: 5px; margin-top: -1px;
  opacity: .88;
}
.alch-preset-tag.egypt    { background: rgba(195,155,50,.16); color: #c8a83e; border: 1px solid rgba(195,155,50,.28); }
.alch-preset-tag.hermetic { background: rgba(140,80,200,.16); color: #a070d8; border: 1px solid rgba(140,80,200,.26); }
.alch-preset-tag.templar  { background: rgba(180,45,45,.16);  color: #c06262; border: 1px solid rgba(180,45,45,.26); }
.alch-preset-tag.gnostic  { background: rgba(70,60,165,.16);  color: #8878cc; border: 1px solid rgba(70,60,165,.26); }
.alch-preset-tag.cross    { background: rgba(40,105,175,.16); color: #6090cc; border: 1px solid rgba(40,105,175,.26); }
.alch-preset-tag.flood    { background: rgba(30,115,145,.16); color: #50a0c2; border: 1px solid rgba(30,115,145,.26); }
.alch-preset-tag.astrology   { background: rgba(105,65,30,.16);  color: #b07850; border: 1px solid rgba(105,65,30,.26); }
.alch-preset-tag.investigation {
  background: rgba(0,185,165,.18); color: #00c8b0;
  border: 1px solid rgba(0,185,165,.38);
  opacity: 1; letter-spacing: .11em;
}
.alch-preset-tag.transmission {
  background: rgba(220,140,40,.16); color: #e09030;
  border: 1px solid rgba(220,140,40,.34);
  opacity: 1; letter-spacing: .09em;
}
.alch-preset-tag.cross-tradition {
  background: rgba(40,105,175,.16); color: #6090cc;
  border: 1px solid rgba(40,105,175,.26);
  opacity: 1; letter-spacing: .09em;
}
.alch-preset-tag.wins-s {
  background: rgba(180,50,50,.18); color: #d06868;
  border: 1px solid rgba(180,50,50,.32); opacity: 1; letter-spacing: .10em;
}
.alch-preset-tag.wins-a {
  background: rgba(195,140,40,.16); color: #c8962a;
  border: 1px solid rgba(195,140,40,.30); opacity: 1; letter-spacing: .09em;
}
.alch-preset-tag.wins-b {
  background: rgba(60,140,120,.16); color: #3d9e88;
  border: 1px solid rgba(60,140,120,.28); opacity: 1; letter-spacing: .09em;
}

/* Collapsible preset section behavior */
.alch-section-hidden { display: none !important; }
.alch-section-caret {
  display: inline-block; width: 12px;
  font-size: 8px; opacity: 0.6;
  margin-right: 4px; transition: none;
}
.alch-presets-section-label { cursor: pointer; user-select: none; }
.alch-presets-section-label:hover { color: var(--text-1); background: rgba(255,255,255,0.03); }

/* ---- Investigation dropdown (sits next to Presets in Alchemy nav) ---- */
.alch-invest-trigger { position: relative; }
.alch-invest-trigger.has-alert { border-color: rgba(255,140,30,0.5); color: #ff9a40; }
.invest-trigger-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px; border-radius: 50%;
  background: rgba(255,130,30,0.85); color: #fff;
  font-size: 8px; font-weight: 700; font-family: var(--mono);
  margin-left: 4px; vertical-align: middle; line-height: 1;
}
.alch-invest-dropdown {
  position: absolute; z-index: 999;
  width: 420px; max-height: 72vh; overflow-y: auto;
  background: var(--panel-bg); backdrop-filter: var(--panel-blur);
  border: 1px solid var(--panel-edge); border-radius: 6px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.58); padding: 10px 0;
}
.alch-invest-intro {
  font-family: var(--mono); font-size: 9.5px; color: var(--text-3);
  letter-spacing: 0.04em; padding: 2px 14px 9px; line-height: 1.5;
  border-bottom: 1px solid var(--border);
}
.alch-invest-list { padding: 4px 0; }
.alch-invest-card { padding: 11px 14px 9px; border-bottom: 1px solid var(--border); }
.alch-invest-card:last-child { border-bottom: none; }
.alch-invest-card.alert { border-left: 2px solid rgba(255,130,30,0.65); }
.alch-invest-header { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; }
.alch-invest-flag {
  font-family: var(--mono); font-size: 8px; font-weight: 700; color: #ff8a1e;
  letter-spacing: 0.08em; background: rgba(255,130,30,0.12);
  border: 1px solid rgba(255,130,30,0.3); border-radius: 2px; padding: 1px 5px; white-space: nowrap;
}
.alch-invest-name { font-family: var(--serif); font-size: 11.5px; font-weight: 600; color: var(--text-0); }
.alch-invest-status { font-family: var(--mono); font-size: 8px; color: var(--text-3); letter-spacing: 0.07em; text-transform: uppercase; margin-left: auto; }
.alch-invest-headline { font-family: var(--sans); font-size: 9.5px; color: var(--text-2); line-height: 1.55; margin-bottom: 9px; }
.alch-invest-threads { margin-bottom: 9px; }
.alch-invest-thread {
  display: grid; grid-template-columns: 76px 1fr; gap: 3px 8px;
  padding: 4px 0; border-top: 1px solid rgba(255,255,255,0.04); align-items: start;
}
.alch-invest-thread:first-child { border-top: none; }
.alch-invest-thread-tier { font-family: var(--mono); font-size: 8px; letter-spacing: 0.05em; text-align: right; padding-top: 1px; white-space: nowrap; }
.tier-1       { color: var(--gold); }
.tier-2       { color: rgba(212,165,90,0.65); }
.tier-3       { color: var(--text-3); }
.tier-parallel{ color: #7ab4d0; }
.alch-invest-thread-label { font-family: var(--sans); font-size: 9.5px; color: var(--text-1); font-weight: 500; }
.alch-invest-thread-note  { grid-column: 2; font-family: var(--mono); font-size: 8.5px; color: var(--text-3); line-height: 1.45; letter-spacing: 0.02em; }
.alch-invest-action-row { display: flex; align-items: center; gap: 7px; padding-top: 5px; }
.alch-invest-load {
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 2px;
  color: var(--text-1); font-family: var(--mono); font-size: 9.5px;
  padding: 3px 10px; letter-spacing: 0.05em; cursor: pointer; transition: all 130ms ease;
}
.alch-invest-load:hover { border-color: var(--gold-soft); color: var(--gold); }
.alch-invest-confirm-row { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; padding-top: 5px; }
.alch-invest-confirm-q { font-family: var(--mono); font-size: 9.5px; color: var(--text-2); letter-spacing: 0.04em; flex: 1 1 100%; margin-bottom: 4px; }
.alch-invest-confirm {
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 2px;
  color: var(--text-1); font-family: var(--mono); font-size: 9.5px;
  padding: 3px 9px; letter-spacing: 0.06em; cursor: pointer; transition: all 130ms ease;
}
.alch-invest-confirm:hover { border-color: var(--gold-soft); color: var(--text-0); }
.alch-invest-append  { color: var(--gold); border-color: var(--gold-soft); }
.alch-invest-replace { color: #d4a04a; border-color: rgba(212,165,90,0.45); }
.alch-invest-cancel  { color: var(--text-3); }

/* ============================================================
   ATLAS view (opus-map-1, 2026-05-15) — MapLibre GL world map.
   The basemap is a label-free vector backdrop; nodes ride above it
   as DOM markers (one .atlas-marker per geo-tagged node). Tier
   overlay applies because each marker carries data-tier. Motion
   uses --t-* / --ease tokens; type uses --serif / --mono.
   ============================================================ */

/* Suppress the canvas radial gradient on Atlas so the map fills cleanly. */
body.view-atlas main.canvas { background: var(--bg-0); }

/* ============================================================
   ALCHEMY (card pinboard) — research workbench. Cards are HTML
   for accessibility + text-selection; pan/zoom via CSS transform
   on the inner board; connection lines on an SVG overlay above.
   ============================================================ */


/* Pantheon v2 (WebGL R&D) — sigma.js mount + DOM-overlay family rim labels.
   Hidden behind ?webgl=1 URL flag.
   The detail panel is treated as a FLOATING overlay — pane geometry does NOT
   track --eff-detail-w, so opening/closing the panel never resizes the map
   (no reflow, no sigma resize, no jitter). The collapsed-rail width is the
   only right-edge inset we honour. */
.pantheon-v2-pane {
  position: absolute;
  /* Top=12, bottom=0 — the diagram fills the entire pane vertically; the
     view-header title floats OVER the top of the diagram with a transparent
     backdrop. Maximises viewing area, kills the "opaque title bar" effect. */
  top: 12px; bottom: 0;
  left: calc(var(--eff-nav-w) + 24px);
  right: 24px;   /* was calc(--detail-w-collapsed + 24px); the V01 rail is gone */
  overflow: hidden;
  transition: left var(--t-layout) var(--ease);
}
.pantheon-v2-pane canvas { display: block; }

/* SVG overlay for translucent family hulls + curved bezier edges.
   Sits as the FIRST child of the pane so sigma's canvases (added later)
   paint above it — dots > edges > hulls in z-order. */
.ph2-svg-overlay {
  position: absolute; inset: 0;
  pointer-events: none;
  overflow: visible;
  /* Promote to its own compositor layer so per-frame transform updates
     (afterRender → translate/scale) don't trigger paint of the whole pane.
     Massive smoothness win during zoom/pan. */
  will-change: transform;
}
.ph2-hulls-g, .ph2-edges-g, .ph2-ticks-g { will-change: transform; }
/* Hulls are NOT clickable directly — clicks pass through to sigma, which
   fires clickStage; the clickStage handler does an SVG hit-test against
   each hull (`isPointInFill`) and routes accordingly. Letting hulls grab
   pointer events used to BLOCK every node click on the wheel. */
.ph2-node-labels-overlay, .ph2-rim-overlay { will-change: contents; }
/* HULLS — rounded annular wedges, one per family. Geometry matches
   production's .sector-hull (Rinner-22 → Router+22, padAngle 0.014,
   cornerRadius 8). Quiet by default; hot when family-filter is locked. */
.ph2-hull {
  /* Quiet fill — stroke alone reads the family boundary. The dots should
     dominate the wedge, not the colour bar behind them. */
  fill-opacity: var(--ph2-hull-opacity, 0.04);
  stroke-opacity: var(--ph2-hull-stroke-opacity, 0.30);
  stroke-width: var(--ph2-hull-stroke-width, 0.8);
  transition: fill-opacity 250ms ease, stroke-opacity 250ms ease;
  vector-effect: non-scaling-stroke;
}
.ph2-hull.dim          { fill-opacity: var(--ph2-hull-dim-fill, 0.025); stroke-opacity: 0.08; }
.ph2-hull.hot          { fill-opacity: var(--ph2-hull-hot-fill, 0.20);  stroke-opacity: 0.60; }
.ph2-hull.preview-fade { fill-opacity: 0.03;  stroke-opacity: 0.10; }
/* EDGES — verbatim copy of production .edge-line (app.css:1052-1083).
   stroke-width + stroke-opacity are set as INLINE SVG attrs by the build
   loop from EDGE_STYLE. --edge-type-color is the inline CSS var for hot. */
/* ── EDGE COLOR / GRADIENT (spec: AUDIT/edge-color-spec-2026-05-17.md) ──
   Idle:    one slate stroke for all non-headline edges (atmosphere).
   Hot:     bucket color, .ph2-edge-hot-width thickness.
   Headline (Polemic, Fusion, ancestor-of): idle in bucket color, never slate.
   Directional (Transmission, Attestation, parent-of/child-of/ancestor-of/
   appropriated-by): a <linearGradient> is pre-built per edge; JS swaps it
   in inline on .hot. Headline directional edges paint the gradient at idle.
   --base-op and --hot-op are per-edge from the bucket spec; the dev panel
   --ph2-edge-opacity-mult multiplies the idle layer only. */
.ph2-edge {
  fill: none; pointer-events: none;
  vector-effect: non-scaling-stroke;
  /* Single slate for the entire idle layer — atmosphere, not story. */
  stroke: rgba(80, 95, 130, 0.85);
  stroke-opacity: calc(var(--base-op, 0.10) * var(--ph2-edge-opacity-mult, 1));
  stroke-width:   calc(var(--base-w,  0.30) * var(--ph2-edge-width-mult,   1));
  transition: stroke-opacity 180ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)),
              stroke-width   180ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)),
              stroke         180ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
/* HEADLINE buckets (Polemic, Fusion, ancestor-of) idle in bucket color —
   the user should READ these at rest without hovering. */
.ph2-edge.ph2-edge-headline {
  stroke: var(--edge-bucket-color, rgba(168, 62, 74, 0.9));
}
.ph2-edge.dim {
  /* No-op — idle opacity preserved on hover. Hot edges brighten; the rest
     stay where they were. The atmosphere layer is information. */
}
.ph2-edge.hot {
  /* `stroke` is intentionally WITHOUT !important so JS-set inline
     `style.stroke = url(#grad-id)` wins for directional edges (Transmission,
     Attestation, kinship descent, appropriated-by). Non-directional .hot
     edges fall back to the bucket colour via the CSS var. */
  stroke: var(--edge-bucket-color, rgba(212, 165, 90, 0.9));
  stroke-opacity: var(--hot-op, 0.9) !important;
  stroke-width: var(--ph2-edge-hot-width, 1.0) !important;
}
/* Directional hot edges have their gradient set inline via JS — the inline
   style.stroke wins over the .hot stroke rule. (See applyEdgeHoverState.) */
.ph2-edge.filter-dim.hover-reveal {
  stroke: var(--edge-bucket-color, rgba(212, 165, 90, 0.85)) !important;
  stroke-opacity: 0.8 !important;
  stroke-width: 1.3 !important;
}
.ph2-edge.xsym { stroke-linecap: round; }
.ph2-edge.xsym-xfamily {
  filter: drop-shadow(0 0 1px rgba(212, 165, 90, 0.45));
}

/* HOVER CARD V2 — academic trading-card. Wide cover-cropped image on top,
   body column below: type-glyph + title, curated `role` tagline (NO invented
   prose; falls back to attributed Wikipedia extract), family · period meta,
   connection breakdown by edge-bucket, then platform-tag chips. Tags render
   as proper labels — same vocabulary as the family-filter chips, not as
   hashtags. The card itself reads as a peer of `Families ▾` and the zoom
   widgets: mono, 3 px radius, border-soft, blur(10px). */
.ph2-thumb-card {
  position: fixed; pointer-events: none;
  background: rgba(14,16,22,0.94);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--border-soft);
  border-radius: 3px;
  z-index: 1000;
  font-family: var(--mono); color: var(--text-0); font-size: 11px;
  letter-spacing: 0.02em;
  box-shadow: 0 8px 24px rgba(0,0,0,0.62);
  left: 0; top: 0;
  opacity: 0;
  transform: translateY(2px);
  transition: opacity 140ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)),
              transform 140ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
.ph2-thumb-card[style*="display: block"] { opacity: 1; transform: translateY(0); }

.ph2-thumb-card-v2 {
  display: flex; flex-direction: column;
  width: var(--ph2-thumb-card-w, 288px);
  padding: 0;
  overflow: hidden;
}
.ph2-thumb-imgwrap {
  position: relative;
  width: 100%; height: var(--ph2-thumb-img-h, 144px);
  background: linear-gradient(180deg, var(--bg-1) 0%, var(--bg-0) 100%);
  overflow: hidden;
  border-bottom: 1px solid var(--border-soft);
}
.ph2-thumb-img {
  display: block;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 30%;
}
/* Subtle vignette so the image grounds into the card */
.ph2-thumb-imgwrap::after {
  content: '';
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(0,0,0,0) 60%, rgba(8,10,16,0.55) 100%);
}
/* Glyph badge in the corner — quiet, just a type signal on the image. */
.ph2-thumb-imgglyph {
  position: absolute; left: 8px; top: 8px;
  width: 22px; height: 22px;
  display: grid; place-items: center;
  background: rgba(10,12,18,0.7);
  border: 1px solid var(--border-soft);
  border-radius: 3px;
  color: var(--text-1);
}
.ph2-thumb-imgglyph svg { display: block; }
/* Fallback (no thumbnail): center the glyph at large size. */
.ph2-thumb-imgwrap-fallback { background: var(--bg-1); }
.ph2-thumb-imgwrap-fallback::after { display: none; }
.ph2-thumb-imgwrap-fallback .ph2-thumb-imgglyph {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 64px; height: 64px;
  background: transparent; border: none;
  color: var(--text-2);
}
.ph2-thumb-imgwrap-fallback .ph2-thumb-imgglyph svg { width: 48px; height: 48px; }

.ph2-thumb-body {
  display: flex; flex-direction: column;
  gap: 6px;
  padding: 10px 12px 12px;
  min-width: 0;
}
.ph2-thumb-titlerow {
  display: flex; align-items: center; gap: 7px;
  min-width: 0;
}
.ph2-thumb-typeglyph {
  flex: 0 0 auto;
  display: inline-grid; place-items: center;
  width: 14px; height: 14px;
  color: var(--gold);
}
.ph2-thumb-typeglyph svg { display: block; }
.ph2-thumb-title {
  font-family: var(--sans);
  font-size: 14px; font-weight: 500;
  color: var(--text-0); line-height: 1.1;
  letter-spacing: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ph2-thumb-tagline {
  font-family: var(--sans);
  font-style: italic;
  font-size: 12px; line-height: 1.32;
  color: var(--text-1);
  letter-spacing: 0;
  /* Line-clamp; ellipsis if longer. Default 2; dev panel can lift to 4. */
  display: -webkit-box; -webkit-line-clamp: var(--ph2-thumb-tagline-lines, 2); -webkit-box-orient: vertical;
  overflow: hidden;
}
.ph2-thumb-tagline-src {
  font-style: normal;
  font-family: var(--mono);
  font-size: 9.5px;
  color: var(--text-3);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-left: 4px;
}
.ph2-thumb-meta {
  font-size: 10.5px; color: var(--text-2); font-family: var(--mono);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ph2-thumb-sep { color: var(--text-3); margin: 0 2px; }

.ph2-thumb-conn-total {
  margin-top: 2px;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-3);
}
.ph2-thumb-conn-list {
  list-style: none; padding: 0; margin: 2px 0 0;
  display: flex; flex-direction: column;
}
.ph2-thumb-conn-row {
  display: flex; align-items: center; gap: 6px;
  padding: 1px 0;
  font-family: var(--mono); font-size: 10.5px;
  color: var(--text-1);
}
.ph2-thumb-conn-swatch {
  flex: 0 0 auto;
  width: 12px; height: 2px;
  border-radius: 1px;
  background: var(--text-3);
}
/* Edge-bucket colors — these match the BUCKETS hex set in pantheon-v2.js.
   Single source of truth ideally; for now duplicated here so the hover card
   doesn't need a JS palette injection. Update both if the spec changes. */
.ph2-thumb-conn-swatch[data-bucket="transmission"] { background: #C9743A; }
.ph2-thumb-conn-swatch[data-bucket="parallel"]     { background: #5A9A8F; }
.ph2-thumb-conn-swatch[data-bucket="association"]  { background: #4A5AA4; }
.ph2-thumb-conn-swatch[data-bucket="kinship"]      { background: #C9A5D4; }
.ph2-thumb-conn-swatch[data-bucket="attestation"]  { background: #D4A55A; }
.ph2-thumb-conn-swatch[data-bucket="polemic"]      { background: #A83E4A; }
.ph2-thumb-conn-swatch[data-bucket="fusion"]       { background: #C4783A; }
.ph2-thumb-conn-name {
  flex: 1 1 auto;
  color: var(--text-2);
  text-transform: capitalize;
  letter-spacing: 0.02em;
}
.ph2-thumb-conn-n {
  flex: 0 0 auto;
  color: var(--text-1);
  font-variant-numeric: tabular-nums;
}
.ph2-thumb-conn-rest .ph2-thumb-conn-name { color: var(--text-3); }
.ph2-thumb-conn-rest .ph2-thumb-conn-n    { color: var(--text-3); }

/* Tag chips — proper platform labels, not hashtags. Same vocabulary as the
   family-filter chip (.ph2-filter-row swatches) and the toolbar buttons. */
.ph2-thumb-tags {
  display: flex; flex-wrap: wrap; gap: 4px;
  margin-top: 4px;
}
.ph2-thumb-tag {
  display: inline-flex; align-items: center;
  padding: 2px 7px;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--text-1);
  background: var(--bg-2);
  border: 1px solid var(--border-soft);
  border-radius: 2px;
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden; text-overflow: ellipsis;
}

/* ── TYPE-GLYPH OVERLAY (the wheel's per-node shape vocabulary) ──
   One small SVG per node sits inside its colored family disk, conveying
   the node-type (deity / document / ritual / symbol / music / monument…).
   Sigma owns the colored disk via WebGL; this overlay rides above. Quiet
   white-translucent stroke/fill so the glyph reads against family color
   without competing with the label or the edges. */
/* Stack:
   - sigma canvases:           z-index auto (0)  — node disks
   - .ph2-edges-overlay:       z-index 2         — wire connections (above disks)
   - .ph2-type-glyphs-layer:   z-index 3         — per-node type symbols
   - .ph2-node-labels-overlay: z-index 4         — DOM labels
   Edges-above-nodes is intentional: on a locked focus, the hot wires need to
   read clearly over the dim disks (which fall to ~10% with their family hue,
   not white). Hulls + ticks stay BELOW sigma (in .ph2-svg-overlay) so node
   disks paint on top of family backgrounds and hull-click hit-test still
   routes via sigma's mouse canvas. */
.ph2-edges-overlay     { z-index: 2; pointer-events: none; }
.ph2-type-glyphs-layer { z-index: 3; }
.ph2-type-glyph {
  overflow: visible;
  /* color is set per-element inline to a lighter hue of the node's family
     color (see typeGlyphsLayer build loop). currentColor inside the SVG
     paths inherits that tint. Falls back here for any glyph that escapes
     the per-element setter. */
  color: var(--text-1);
  opacity: var(--ph2-type-glyph-opacity, 0.86);
  pointer-events: none;
  transition: opacity 160ms cubic-bezier(0.16, 1, 0.3, 1);
}
/* Focus dim — applied by applyTypeGlyphDim() when a node is in the DIM
   state (hover or lock context active but this node is outside the focus
   set) or its family is filtered out. Fades to 10% so the wire-edges
   above-and-the-hot-disks read as the dominant visual signal. */
.ph2-type-glyph.ph2-type-glyph-dim {
  opacity: 0.10;
}

.ph2-rim-overlay {
  position: absolute; inset: 0;
  pointer-events: none;
  z-index: 5;
}

/* PHASE E — DOM NODE LABELS overlay.
   One <div> per deity, positioned absolutely via JS (synced to sigma camera).
   Transform centers each label horizontally and stacks it ABOVE the node.
   Halo via text-shadow mimics production's paint-order:stroke trick. */
.ph2-node-labels-overlay {
  position: absolute; inset: 0;
  pointer-events: none;
  z-index: 4;          /* above sigma canvas, below rim labels (z-index 5) */
  contain: layout;
}
.ph2-node-label {
  position: absolute;
  left: 0; top: 0;
  transform: translate(-50%, -100%);
  pointer-events: none;
  font-family: var(--sans);
  font-size: var(--ph2-node-label-size, 10px);
  line-height: 1.05;
  color: var(--text-2);
  white-space: nowrap;
  text-align: center;
  /* Halo: dark stroke around glyphs so labels read over edges + hulls */
  text-shadow:
    0 0 2px var(--bg-0),
     1px  1px 0 var(--bg-0),
    -1px  1px 0 var(--bg-0),
     1px -1px 0 var(--bg-0),
    -1px -1px 0 var(--bg-0);
  transition: opacity 200ms ease, color 200ms ease;
  will-change: left, top;
}
.ph2-node-label.hub {
  color: var(--text-0);
  font-weight: 500;
  font-size: var(--ph2-node-hub-label-size, 11px);
}
.ph2-node-label.dim { opacity: 0.15; }
/* PHASE F — HORIZONTAL family rim labels (production parity, app.css:1086).
   Position + transform percentages set inline per-label so each reads
   naturally based on its angular position around the ring.
   Serif uppercase letterform + dark halo so they read over the hulls. */
.ph2-rim-label {
  position: absolute;
  left: 0; top: 0;
  font-family: var(--serif);
  font-weight: 500;
  font-size: var(--ph2-rim-label-size, 13px);
  letter-spacing: var(--ph2-rim-label-spacing, 0.22em);
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--text-2);
  opacity: var(--ph2-rim-label-opacity, 0.92);
  /* Halo trick — production uses paint-order:stroke; in DOM the equivalent
     is a tight text-shadow stack so glyphs read over translucent hulls. */
  text-shadow:
    0 0 2px var(--bg-0),
     1px  1px 0 var(--bg-0),
    -1px  1px 0 var(--bg-0),
     1px -1px 0 var(--bg-0),
    -1px -1px 0 var(--bg-0);
  transition: opacity 200ms ease, color 200ms ease;
}
/* Brighter for the big families (≥6 members) — same convention as production .family-label.bright */
.ph2-rim-label.ph2-rim-label-bright { color: var(--text-0); }

/* PHASE F — radial tick line from inside the hull rim out toward each
   family label. Painted in the SVG overlay, so it inherits the Y-flipped
   camera transform from syncOverlay(). Color set inline per-tick to the
   family color. */
.ph2-rim-tick {
  stroke-width: 0.8;
  stroke-opacity: var(--ph2-tick-opacity, 0.45);
  vector-effect: non-scaling-stroke;
  transition: stroke-opacity 200ms ease;
}
.ph2-rim-tick.dim { stroke-opacity: 0.06; }
.ph2-error {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--red, #c25450); font-family: var(--serif);
}

/* Pantheon v2 toolbar — labels-mode toggle + ego-focus + recenter. Top-right
   above the wheel so it doesn't collide with the family-legend on the left. */
.ph2-toolbar {
  position: absolute; top: 18px; z-index: 10;
  /* DETAIL-PANEL AWARE: stays just inside the detail panel's left edge.
     When the detail panel is collapsed (rail width = --detail-w-collapsed),
     this evaluates to right:22px (current behaviour). When it's open
     (rail width = --detail-w), the toolbar slides left to clear the panel.
     `eff-detail-w` already tracks body.detail-collapsed automatically. */
  /* 2026-06-10 — --detail-w-collapsed deleted (collapsed reserves 0);
     eff-detail-w alone gives collapsed→22px, open→panel+22px. */
  right: calc(var(--eff-detail-w) + 22px);
  display: flex; gap: 6px;
  pointer-events: auto;
  transition: right var(--t-layout) var(--ease);
}
/* Toolbar buttons — uniform pill design across every control in the top
   bar. Select and button elements share the same shell. */
.ph2-btn {
  background: rgba(14,16,22,0.35);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--border-soft);
  color: var(--text-1);
  font-family: var(--mono); font-size: 10.5px;
  letter-spacing: 0.06em;
  padding: 5px 11px; border-radius: 3px;
  cursor: pointer;
  height: 26px;
  display: inline-flex; align-items: center; gap: 6px;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.ph2-btn:hover { background: rgba(14,16,22,0.70); color: var(--gold); border-color: var(--gold-soft); }
/* Native <select> needs explicit appearance reset so it doesn't show the
   OS chrome chevron — gives the select the same pill as the buttons. */
select.ph2-btn {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--text-2) 50%),
    linear-gradient(135deg, var(--text-2) 50%, transparent 50%);
  background-position:
    calc(100% - 12px) center,
    calc(100% - 8px) center;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
  padding-right: 22px;
}
select.ph2-btn:hover {
  background-image:
    linear-gradient(45deg, transparent 50%, var(--gold) 50%),
    linear-gradient(135deg, var(--gold) 50%, transparent 50%);
}
.ph2-btn:hover { color: var(--gold); border-color: var(--gold-soft); }
.ph2-btn-on { color: var(--gold); background: rgba(212,165,90,0.16); border-color: var(--gold-soft); }

/* ── FAMILY-FILTER DROPDOWN — toolbar tick-box menu ──────────────────
   Multi-select: pick one or many families to isolate. Reset clears.
   Lives inline in the toolbar next to the mode select. */
.ph2-filter-menu { position: relative; display: inline-block; }
.ph2-filter-trigger { white-space: nowrap; }
.ph2-filter-dropdown {
  position: absolute; top: calc(100% + 6px); left: 0;
  min-width: 220px; max-height: 60vh; overflow: hidden;
  background: rgba(13,17,25,0.97);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.55);
  display: none;
  flex-direction: column;
  z-index: 50;
}
.ph2-filter-menu.open .ph2-filter-dropdown { display: flex; }
.ph2-filter-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 7px 11px; border-bottom: 1px solid var(--border-soft);
  font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-2);
}
.ph2-filter-reset {
  background: rgba(212,165,90,0.12);
  border: 1px solid var(--gold-soft);
  color: var(--gold);
  font-family: var(--mono); font-size: 9.5px;
  padding: 3px 8px; border-radius: 2px;
  cursor: pointer; letter-spacing: 0.06em;
}
.ph2-filter-reset:hover { background: rgba(212,165,90,0.22); }
.ph2-filter-body {
  overflow-y: auto; padding: 4px 0;
}
.ph2-filter-body::-webkit-scrollbar { width: 6px; }
.ph2-filter-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 3px; }
.ph2-filter-row {
  display: grid;
  grid-template-columns: 18px 12px 1fr auto;
  align-items: center; gap: 8px;
  padding: 6px 12px;
  cursor: pointer;
  transition: background 120ms ease;
}
.ph2-filter-row:hover { background: rgba(255,255,255,0.04); }
.ph2-filter-check { accent-color: var(--gold); margin: 0; }
.ph2-filter-swatch { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.ph2-filter-name { font-family: var(--sans); font-size: 11px; color: var(--text-1); }
.ph2-filter-count { font-family: var(--mono); font-size: 10px; color: var(--text-3); }

/* ── MODE DROPDOWN — single-select panel, same chrome as family filter ── */
.ph2-mode-menu { position: relative; display: inline-block; }
.ph2-mode-trigger { white-space: nowrap; }
.ph2-mode-dropdown {
  position: absolute; top: calc(100% + 6px); left: 0;
  min-width: 200px; max-height: 60vh; overflow: hidden;
  background: rgba(13,17,25,0.97);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.55);
  display: none;
  flex-direction: column;
  z-index: 50;
}
.ph2-mode-menu.open .ph2-mode-dropdown { display: flex; }
.ph2-mode-body { overflow-y: auto; padding: 4px 0; }
.ph2-mode-body::-webkit-scrollbar { width: 6px; }
.ph2-mode-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 3px; }
.ph2-mode-row {
  display: grid;
  grid-template-columns: 18px 1fr 12px;
  align-items: center; gap: 10px;
  padding: 6px 12px;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
  font-family: var(--sans); font-size: 11px;
  color: var(--text-1);
}
.ph2-mode-row:hover { background: rgba(255,255,255,0.04); color: var(--gold); }
.ph2-mode-row.active { background: rgba(212,165,90,0.12); color: var(--gold); }
.ph2-mode-glyph { font-family: var(--serif); font-size: 13px; color: var(--text-2); text-align: center; }
.ph2-mode-row.active .ph2-mode-glyph,
.ph2-mode-row:hover  .ph2-mode-glyph { color: var(--gold); }
.ph2-mode-tick { font-size: 11px; color: var(--gold); opacity: 0; }
.ph2-mode-row.active .ph2-mode-tick { opacity: 1; }

/* ── INLINE ZOOM GROUP (lives inside .ph2-toolbar) ─────────────────── */
.ph2-toolbar-zoom {
  display: inline-flex;
  align-items: center;
  margin-left: 4px;
  padding: 0;
}
.ph2-toolbar-zoom .ph2-btn {
  border-radius: 0;
  margin: 0;
  border-right-width: 0;
}
.ph2-toolbar-zoom .ph2-btn:first-child { border-radius: 3px 0 0 3px; }
.ph2-toolbar-zoom .ph2-btn:last-child  { border-radius: 0 3px 3px 0; border-right-width: 1px; }
.ph2-tz-btn { min-width: 26px; padding: 5px 8px; justify-content: center; }
.ph2-tz-pct { min-width: 52px; justify-content: center; font-weight: 600; color: var(--text-0); }
/* old .ph2-zoom-widget rules retired — see .ph2-toolbar-zoom above */

/* ── WIRE-LEGEND TOGGLE + PANEL (bottom-left) ───────────────────────── */
.ph2-wire-legend-toggle {
  /* Position-fixed sibling of <footer> for the same reason as .footer-toggle:
     when the footer translateY's, fixed elements need their own anchor. Sits
     directly above the footer-toggle so the two stack as a tidy pair at the
     bottom-left rail. Same width / height / styling as .footer-toggle so the
     pair reads as a uniform control. */
  position: fixed;
  left: calc(var(--nav-w) + 10px);
  bottom: 86px;   /* footer-toggle bottom (54) + its height (22) + 10 gap */
  width: 26px; height: 22px;
  background: rgba(13, 17, 25, 0.86);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  border: 1px solid var(--border);
  color: var(--text-2);
  border-radius: 3px;
  font-size: 13px; line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  z-index: 52;
  transition: color 140ms, border-color 140ms,
              bottom 240ms cubic-bezier(0.2, 0.8, 0.2, 1),
              left 240ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.ph2-wire-legend-toggle:hover { color: var(--gold); border-color: var(--gold-soft); }
.ph2-wire-legend-toggle.ph2-btn-on { color: var(--gold); border-color: var(--gold-soft); background: rgba(212,165,90,0.16); }
body.nav-collapsed    .ph2-wire-legend-toggle { left: calc(var(--nav-w-collapsed) + 10px); }
/* body.footer-collapsed adjustment removed 2026-05-27 — footer gone. */

.ph2-wire-legend-panel {
  position: fixed;
  left: calc(var(--nav-w) + 10px); bottom: 116px;
  width: 280px;
  background: rgba(13, 17, 25, 0.97);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.55);
  padding: 10px 12px;
  z-index: 53;
  display: none;
  font-family: var(--mono); font-size: 10.5px;
  color: var(--text-1);
  transition: bottom 240ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.ph2-wire-legend-panel.open { display: block; }
body.nav-collapsed    .ph2-wire-legend-panel { left: calc(var(--nav-w-collapsed) + 10px); }
/* body.footer-collapsed adjustment removed 2026-05-27 — footer gone. */
.ph2-wl-head {
  font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 8px;
}
.ph2-wl-rows { display: flex; flex-direction: column; gap: 5px; }
.ph2-wl-row { display: grid; grid-template-columns: 12px 84px 1fr; gap: 8px; align-items: center; }
.ph2-wl-swatch { width: 10px; height: 10px; border-radius: 50%; }
.ph2-wl-name { font-weight: 600; color: var(--text-0); }
.ph2-wl-note { color: var(--text-3); font-size: 9.5px; }
.ph2-wl-foot {
  margin-top: 8px; padding-top: 8px;
  border-top: 1px solid var(--border-soft);
  color: var(--text-3); font-size: 9.5px; line-height: 1.5;
}
.ph2-wl-foot code { color: var(--gold); font-size: 9.5px; }

/* OLD bottom-left legend — kept as no-op so any stale ref doesn't error.
   The toolbar filter menu is now the only family-filter UI. */
.ph2-legend {
  position: absolute; bottom: 18px; left: 22px; z-index: 10;
  background: rgba(14,16,22,0.85);
  backdrop-filter: blur(6px);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  padding: 10px 14px 12px;
  max-height: 60vh; overflow-y: auto;
  min-width: 200px;
}
.ph2-legend-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 8px;
}
.ph2-legend-title {
  font-family: var(--mono); font-size: 9.5px;
  color: var(--text-3); letter-spacing: 0.14em;
}
.ph2-legend-burger {
  background: none; border: none; cursor: pointer;
  color: var(--text-3); font-size: 14px; line-height: 1; padding: 0 2px;
}
.ph2-legend-burger:hover { color: var(--gold); }
.ph2-legend-body {
  display: flex; flex-direction: column; gap: 2px;
  font-family: var(--serif); font-size: 11.5px;
  overflow: hidden;
  max-height: 400px;
  transition: max-height 200ms ease;
}
.ph2-legend.collapsed .ph2-legend-body { max-height: 0; }
/* Legacy class aliases kept for backwards compat */
.ph2-legend-rows {
  display: flex; flex-direction: column; gap: 2px;
  font-family: var(--serif); font-size: 11.5px;
}
.ph2-legend-row {
  display: grid; grid-template-columns: 14px 1fr auto;
  gap: 8px; align-items: center;
  padding: 4px 4px;
  cursor: pointer; border-radius: 2px;
  transition: background 120ms ease;
}
.ph2-legend-row:hover { background: var(--bg-2); }
.ph2-legend-row.ph2-legend-active { background: rgba(212,165,90,0.18); color: var(--gold); }
.ph2-legend-swatch { width: 10px; height: 10px; border-radius: 50%; }
.ph2-legend-name { color: var(--text-1); }
.ph2-legend-count { color: var(--text-3); font-family: var(--mono); font-size: 10px; }
/* .ph2-mode-select retired — replaced by custom .ph2-mode-menu dropdown */
.pantheon-v2-placeholder {
  max-width: 620px; padding: 36px 44px;
  border: 1px solid var(--border-soft); border-radius: 6px;
  background: rgba(168,123,181,0.04);
  font-family: var(--serif);
}
.pantheon-v2-placeholder .ph2-title {
  margin: 0 0 14px; font-size: 20px; color: var(--gold);
  letter-spacing: 0.04em;
}
.pantheon-v2-placeholder .ph2-desc {
  font-size: 13px; color: var(--text-2); line-height: 1.6; margin-bottom: 16px;
}
.pantheon-v2-placeholder .ph2-desc code {
  background: rgba(212,165,90,0.10); padding: 1px 5px; border-radius: 2px;
  font-family: var(--mono); font-size: 11px;
}
.pantheon-v2-placeholder .ph2-checklist {
  list-style: none; padding: 0; margin: 0 0 16px;
  font-family: var(--mono); font-size: 11px; color: var(--text-3);
  letter-spacing: 0.04em; line-height: 1.9;
}
.pantheon-v2-placeholder .ph2-footer {
  font-size: 11px; color: var(--text-3); font-style: italic; margin: 0;
}





/* ASTROLOGY pane — stub state. Same layout idiom as .atlas-pane: full canvas
   minus sidebar/detail widths via --eff-nav-w / --eff-detail-w. The mode-switch
   pill row is rendered into #view-controls (top bar) and shares .btn.btn-mini styling. */
.astrology-pane {
  position: absolute;
  top: 56px; bottom: 24px;
  left: calc(var(--eff-nav-w) + 24px);
  right: calc(var(--eff-detail-w) + 24px);
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  transition: left var(--t-layout) var(--ease), right var(--t-layout) var(--ease);
}
.astrology-stub {
  max-width: 640px; padding: 36px 44px;
  border: 1px solid var(--border-soft); border-radius: 6px;
  background: rgba(212,165,90,0.04);
  color: var(--text-1); font-family: var(--serif);
  text-align: center;
}
.astrology-stub .as-mode-title {
  font-size: 22px; color: var(--gold);
  letter-spacing: 0.04em; margin-bottom: 18px;
}
.astrology-stub .as-mode-body {
  font-size: 14px; line-height: 1.6; color: var(--text-2);
  margin-bottom: 22px;
}
.astrology-stub .as-mode-meta {
  font-family: var(--mono); font-size: 10px;
  color: var(--text-3); letter-spacing: 0.08em;
  text-transform: uppercase;
}
.btn-mini.astrology-mode.active {
  border-color: var(--gold-soft); color: var(--gold);
  background: rgba(212,165,90,0.10);
}

/* ASTROLOGY · DECANIC mode — 36-decan wheel + side-panel of 5 cross-tradition cells. */
.astrology-pane.astrology-pane-decanic { display: block; align-items: stretch; justify-content: stretch; }
.astrology-pane.astrology-pane-live { display: block; align-items: stretch; justify-content: stretch; }
.astro-decanic-loading, .astro-decanic-error {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--text-3); font-family: var(--serif);
}
.astro-decanic-error { color: var(--red, #c25450); }
.astro-decanic-layout {
  position: absolute; inset: 0;
  display: grid; grid-template-columns: 1fr 360px; gap: 0;
}
.astro-decanic-svg-wrap { position: relative; overflow: hidden; }
.astro-decanic-side {
  border-left: 1px solid var(--border-soft);
  padding: 20px 22px;
  overflow-y: auto;
  background: rgba(8,8,12,0.2);
}
.astro-decanic-side .ads-title {
  margin: 0 0 8px;
  font-family: var(--serif); font-size: 16px; color: var(--gold);
  letter-spacing: 0.04em;
}
.astro-decanic-side .ads-intro {
  font-family: var(--mono); font-size: 10.5px; color: var(--text-3);
  line-height: 1.55; margin-bottom: 18px;
}
.ads-decan-head {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  border-bottom: 1px solid var(--border-soft); padding-bottom: 8px; margin-bottom: 14px;
}
.ads-decan-n { font-family: var(--serif); font-size: 22px; color: var(--gold); }
.ads-decan-deg { font-family: var(--mono); font-size: 11px; color: var(--text-2); }
.ads-uncertain { font-family: var(--mono); font-size: 10px; color: #d4a55a; background: rgba(212,165,90,0.10); padding: 2px 6px; border-radius: 3px; cursor: help; }
.ads-cell {
  border-left: 2px solid var(--cell-accent, var(--border-soft));
  padding: 8px 10px; margin-bottom: 10px;
  background: rgba(212,165,90,0.025);
}
.ads-cell-head {
  font-family: var(--mono); font-size: 9.5px;
  color: var(--text-3); letter-spacing: 0.16em; text-transform: uppercase;
  margin-bottom: 4px;
}
.ads-cell-body { font-family: var(--serif); font-size: 12.5px; color: var(--text-1); line-height: 1.5; }
.ads-cell-body b { color: var(--text-0); font-weight: 600; }
.ads-meta { font-family: var(--mono); font-size: 10.5px; color: var(--text-3); margin-top: 2px; }
.ads-alt { font-family: var(--mono); font-size: 10px; color: var(--text-3); margin-left: 4px; }
.ads-image { font-style: italic; color: var(--text-2); margin-top: 4px; font-size: 12px; }
.ads-notes {
  font-family: var(--serif); font-size: 12px; line-height: 1.55;
  color: var(--text-2); padding: 10px 12px;
  background: rgba(90,108,196,0.05); border-left: 2px solid var(--gold-soft);
  margin: 12px 0 8px;
}
.ads-caveat {
  font-family: var(--mono); font-size: 10.5px; color: #d4a55a;
  background: rgba(212,165,90,0.08); padding: 6px 10px; border-radius: 3px;
  margin: 4px 0 12px;
}
.ads-vault-anchors { margin-top: 10px; }
.ads-vault-list { font-family: var(--mono); font-size: 10.5px; color: var(--text-2); line-height: 1.7; }
.ads-vault-link { color: var(--gold-soft); text-decoration: none; cursor: pointer; }
.ads-vault-link:hover { color: var(--gold); text-decoration: underline; }
.ads-empty { color: var(--text-3); font-style: italic; }

.astro-decan-sector.selected { stroke: var(--gold); stroke-width: 2.2; }
.astro-decanic-svg .astro-decanic-sign-label { letter-spacing: 0.04em; }

/* ASTROLOGY · PANTHEON mode — 7 planet wedges, cross-tradition deities inside. */
.astrology-pane-astro-pantheon { display: block; align-items: stretch; justify-content: stretch; }
.astro-pantheon-layout {
  position: absolute; inset: 0;
  display: grid; grid-template-columns: 1fr 380px; grid-template-rows: 1fr;
  height: 100%;
}
.astro-pantheon-svg-wrap { position: relative; overflow: hidden; min-height: 0; }
.astro-pantheon-side {
  border-left: 1px solid var(--border-soft);
  padding: 22px 22px 26px;
  overflow-y: auto; min-height: 0;
  background: rgba(8,8,12,0.2);
}
.astro-pantheon-side .aph-title {
  margin: 0 0 10px;
  font-family: var(--serif); font-size: 16px; color: var(--gold);
  letter-spacing: 0.04em;
}
.aph-intro {
  font-family: var(--serif); font-size: 12.5px; line-height: 1.55;
  color: var(--text-2); margin-bottom: 14px;
}
.aph-intro b { color: var(--text-0); }
.aph-howto {
  background: rgba(212,165,90,0.04);
  border-left: 2px solid var(--gold-soft);
  padding: 10px 14px; margin-bottom: 18px;
}
.aph-howto-title {
  font-family: var(--mono); font-size: 9.5px;
  color: var(--gold-soft); letter-spacing: 0.16em; text-transform: uppercase;
  margin-bottom: 6px;
}
.aph-howto-list {
  margin: 0; padding-left: 18px;
  font-family: var(--serif); font-size: 12px; line-height: 1.55; color: var(--text-2);
}
.aph-howto-list li { margin-bottom: 3px; }
.aph-planet-head {
  display: flex; align-items: baseline; gap: 12px;
  border-bottom: 1px solid var(--border-soft);
  padding-bottom: 8px; margin-bottom: 12px;
}
.aph-planet-glyph { font-family: var(--serif); font-size: 30px; }
.aph-planet-name { font-family: var(--serif); font-size: 20px; color: var(--p-accent, var(--gold)); letter-spacing: 0.04em; }
.aph-planet-ruler {
  font-style: italic; font-family: var(--serif); font-size: 12px;
  color: var(--text-3); margin-bottom: 14px;
}
.aph-deity-list { display: flex; flex-direction: column; gap: 2px; }
.aph-deity-row {
  display: grid; grid-template-columns: 12px 1fr; column-gap: 9px;
  align-items: baseline;
  padding: 7px 6px;
  border-bottom: 1px solid var(--border-soft);
  cursor: pointer; transition: background 120ms ease;
}
.aph-deity-row:hover { background: var(--bg-2); }
.aph-deity-swatch { width: 10px; height: 10px; border-radius: 50%; margin-top: 4px; }
.aph-deity-title { font-family: var(--serif); font-size: 13px; color: var(--text-0); grid-column: 2; }
.aph-deity-trad { grid-column: 2; font-family: var(--mono); font-size: 10px; color: var(--gold-soft); letter-spacing: 0.04em; }
.aph-deity-note { grid-column: 2; font-family: var(--serif); font-size: 11.5px; color: var(--text-2); font-style: italic; }
.aph-missing {
  margin-top: 12px; padding: 8px 12px;
  font-family: var(--mono); font-size: 10px; color: var(--text-3);
  background: rgba(255,255,255,0.03); border-radius: 3px;
}
.aph-foot {
  margin-top: 18px;
  font-family: var(--mono); font-size: 9.5px;
  color: var(--text-3); letter-spacing: 0.06em; line-height: 1.5;
}
.aph-deity:hover circle { stroke-width: 2.5; }

/* === ASTRO-PANTHEON visual idiom v2 (sonnet-astro-pantheon-style-1, 2026-05-15) ===
   Ports the main Pantheon's grammar onto the 7-planet wheel: tangential planet
   labels, family-colour outer rim + leader-tick, sqrt-sized deity dots, hover
   trails. Layered ABOVE the v1 .aph-deity rule above so the dot-stroke override
   only fires for un-classed hovers (we use explicit .aph-deity-lit for the
   active hover-trail state). */
.aph-wedge {
  transition: fill-opacity 220ms ease, stroke-opacity 220ms ease;
}
.aph-wedge.aph-wedge-dim {
  fill-opacity: 0.025 !important; stroke-opacity: 0.12 !important;
}
.aph-wedge-rim {
  transition: fill-opacity 220ms ease;
}
.aph-family-tick {
  pointer-events: none;
}
.aph-planet-label-text {
  font-family: var(--serif);
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  paint-order: stroke;
  stroke: var(--bg-0);
  stroke-width: 0.22em;
  font-weight: 500;
}
.aph-planet-label-count {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.10em;
  fill: var(--text-3);
  text-transform: uppercase;
  paint-order: stroke;
  stroke: var(--bg-0);
  stroke-width: 0.22em;
}
.aph-planet-label:hover .aph-planet-label-text { filter: brightness(1.25); }
.aph-inner-glyph {
  font-family: var(--serif);
  font-size: 19px;
  opacity: 0.55;
  pointer-events: none;
  text-shadow: 0 0 4px rgba(0,0,0,0.55);
  paint-order: stroke;
  stroke: rgba(0,0,0,0.5);
  stroke-width: 0.6px;
}
.aph-deity-dot {
  transition: stroke-width 130ms ease, opacity 200ms ease, fill-opacity 200ms ease;
  stroke: var(--bg-0);
}
.aph-deity-label {
  font-family: var(--serif);
  font-size: 10.5px;
  fill: var(--text-1);
  pointer-events: none;
  paint-order: stroke;
  stroke: var(--bg-0);
  stroke-width: 0.22em;
  transition: opacity 200ms ease, fill 200ms ease;
}
.aph-deity:hover .aph-deity-dot {
  stroke: var(--gold);
  stroke-width: 2.4;
}
.aph-deity:hover .aph-deity-label {
  fill: var(--text-0);
}
/* Hover-trail dim/lit states — mirror Pantheon's .filter-dim + .hover-reveal pair. */
.aph-deity.aph-deity-dim .aph-deity-dot { opacity: 0.16; }
.aph-deity.aph-deity-dim .aph-deity-label { opacity: 0; }
.aph-deity.aph-deity-lit .aph-deity-dot { opacity: 1; fill-opacity: 1; }
.aph-deity.aph-deity-lit .aph-deity-label { opacity: 1; fill: var(--text-0); font-weight: 500; }
.aph-trail-line {
  stroke: var(--gold, #d4a55a);
  stroke-opacity: 0.78;
  stroke-width: 1.4;
  fill: none;
  pointer-events: none;
  filter: drop-shadow(0 0 1.5px rgba(212,165,90,0.55));
}

/* === DECANIC CLARITY LAYER (sonnet-decanic-clarity, 2026-05-15) === */

/* Planet glyph (sun moon mercury venus mars jupiter saturn) inside each sector — high-contrast white. */
.astro-decan-glyph {
  font-family: var(--serif);
  font-size: 15px;
  fill: #ffffff;
  pointer-events: none;
  text-shadow: 0 0 3px rgba(0,0,0,0.55);
  paint-order: stroke fill;
  stroke: rgba(0,0,0,0.45);
  stroke-width: 0.6px;
}

/* Small decan number (1-36) toward the inner radius. */
.astro-decan-num {
  font-family: var(--mono);
  font-size: 9px;
  fill: rgba(255,255,255,0.78);
  pointer-events: none;
  letter-spacing: 0.02em;
}

/* Sign-name ribbon — thin annular band between wheel and outer sign-glyphs. */
.astro-decanic-ribbon-seg {
  fill: rgba(212,165,90,0.06);
  stroke: var(--gold-soft);
  stroke-opacity: 0.45;
  stroke-width: 0.8;
}
.astro-decanic-ribbon-text {
  font-family: var(--serif);
  font-size: 10.5px;
  letter-spacing: 0.10em;
  fill: var(--gold-soft);
}

/* Hover tooltip floating over the SVG canvas. */
.astro-decanic-tooltip {
  position: absolute;
  z-index: 30;
  pointer-events: none;
  background: rgba(10,10,16,0.94);
  border: 1px solid var(--gold-soft);
  border-radius: 4px;
  padding: 6px 9px;
  min-width: 150px;
  max-width: 220px;
  box-shadow: 0 4px 14px rgba(0,0,0,0.55);
  color: var(--text-1);
}
.astro-decanic-tooltip .adt-row1 {
  font-family: var(--serif); font-size: 12.5px;
  color: var(--gold); margin-bottom: 2px;
}
.astro-decanic-tooltip .adt-row2 {
  font-family: var(--mono); font-size: 10px;
  color: var(--text-2); letter-spacing: 0.02em;
}
.astro-decanic-tooltip .adt-row3 {
  font-family: var(--mono); font-size: 10.5px;
  color: var(--text-1); margin-top: 4px;
}
.astro-decanic-tooltip .adt-glyph {
  font-family: var(--serif); font-size: 14px; margin-right: 2px;
}

/* Side-panel intro / how-to / legend block. */
.ads-intro-body {
  font-family: var(--serif);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-1);
  margin: 0 0 14px;
}
.ads-intro-body b { color: var(--gold); font-weight: 600; }

.ads-howto {
  background: rgba(90,108,196,0.06);
  border-left: 2px solid var(--gold-soft);
  padding: 8px 12px 10px;
  margin: 0 0 14px;
}
.ads-howto-title {
  font-family: var(--mono); font-size: 9.5px;
  color: var(--text-3); letter-spacing: 0.16em; text-transform: uppercase;
  margin-bottom: 6px;
}
.ads-howto-list {
  margin: 0; padding-left: 18px;
  font-family: var(--serif); font-size: 12px; line-height: 1.55;
  color: var(--text-1);
}
.ads-howto-list li { margin-bottom: 3px; }
.ads-howto-list b { color: var(--text-0); font-weight: 600; }

.ads-legend {
  background: rgba(212,165,90,0.04);
  border: 1px solid var(--border-soft);
  border-radius: 3px;
  padding: 8px 10px 10px;
  margin: 0 0 18px;
}
.ads-legend-title {
  font-family: var(--mono); font-size: 9.5px;
  color: var(--text-3); letter-spacing: 0.16em; text-transform: uppercase;
  margin-bottom: 6px;
}
.ads-legend-grid {
  display: grid;
  grid-template-columns: 16px auto 16px auto;
  gap: 4px 8px;
  align-items: center;
}
.ads-legend-swatch {
  display: inline-block;
  width: 14px; height: 14px;
  border-radius: 2px;
  border: 1px solid rgba(255,255,255,0.10);
}
.ads-legend-label {
  font-family: var(--serif); font-size: 11.5px;
  color: var(--text-1);
}
.ads-legend-foot {
  font-family: var(--mono); font-size: 9.5px;
  color: var(--text-3); margin-top: 8px; letter-spacing: 0.04em;
}

/* One-line "what is this decan?" lead above the head row. */
.ads-decan-lead {
  font-family: var(--serif);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-1);
  background: rgba(212,165,90,0.05);
  border-left: 2px solid var(--gold);
  padding: 8px 12px;
  margin: 0 0 12px;
}
.ads-decan-lead b { color: var(--gold); font-weight: 600; }

/* Face-ruler pill inside the decan head row. */
.ads-decan-ruler {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  padding: 2px 8px;
  border-radius: 3px;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border-soft);
}
/* === END DECANIC CLARITY LAYER === */

/* ASTROLOGY · WHEEL mode — natal/event chart with tropical zodiac wheel. */
.astro-wheel-layout {
  position: absolute; inset: 0;
  display: grid; grid-template-columns: 1fr 320px; gap: 0;
}
.astro-wheel-svg-wrap { position: relative; overflow: hidden; }
.astro-wheel-error {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--red, #c25450); font-family: var(--serif);
}
.astro-wheel-side {
  border-left: 1px solid var(--border-soft); padding: 20px 22px;
  background: rgba(8,8,12,0.2); overflow-y: auto;
}
.astro-wheel-side .aws-title {
  margin: 0 0 14px; font-family: var(--serif); font-size: 16px; color: var(--gold);
  letter-spacing: 0.04em;
}
.aws-controls { margin-bottom: 18px; }
.aws-label {
  display: inline-block; margin-right: 12px; margin-bottom: 10px;
  font-family: var(--mono); font-size: 10px; color: var(--text-3); letter-spacing: 0.08em; text-transform: uppercase;
}
.aws-label input {
  background: var(--bg-2); border: 1px solid var(--border-soft); color: var(--text-1);
  padding: 4px 6px; font-family: var(--mono); font-size: 11px; border-radius: 3px;
  margin-top: 3px;
}
.aws-presets { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.aws-presets .btn-mini { font-size: 10px; padding: 3px 7px; }
.aws-positions {
  display: flex; flex-direction: column; gap: 4px;
  font-family: var(--mono); font-size: 11px;
}
.aws-row {
  display: grid; grid-template-columns: 22px 60px 1fr 60px 16px;
  gap: 8px; align-items: center;
  padding: 4px 6px; border-bottom: 1px solid var(--border-soft);
  cursor: pointer; transition: background 120ms ease;
}
.aws-row:hover { background: var(--bg-2); }
.aws-glyph { font-family: var(--serif); font-size: 16px; text-align: center; }
.aws-name { color: var(--text-1); }
.aws-sign { color: var(--text-2); }
.aws-deg { color: var(--text-3); text-align: right; }
.aws-retro { color: #d4a55a; font-size: 12px; text-align: center; }
.aws-footer {
  margin-top: 18px; font-family: var(--mono); font-size: 9.5px;
  color: var(--text-3); letter-spacing: 0.1em;
}

/* ASTROLOGY · NOW mode — unrolled zodiac strip + time-scrubber. */
.astro-now-layout {
  position: absolute; inset: 0;
  display: grid; grid-template-rows: 1fr auto; gap: 0;
}
.astro-now-strip-wrap { position: relative; overflow: hidden; }
.astro-now-error {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--red, #c25450); font-family: var(--serif);
}
.astro-now-scrub-wrap {
  border-top: 1px solid var(--border-soft); padding: 10px 22px 12px;
  background: rgba(8,8,12,0.25);
  /* Tightened 2026-05-15 — the controls were jumping during scrubbing because
     auto-fit grid columns + variable decan-name lengths reflowed. Fixed below. */
}
.anw-scrub-row { display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; min-height: 26px; }
.anw-scrub-row .btn-mini { font-size: 10px; padding: 3px 8px; }
.anw-scrub-row .anw-now { color: var(--gold); border-color: var(--gold-soft); }
.anw-scrubber {
  flex: 1; min-width: 240px;
  accent-color: var(--gold);
}
.anw-year {
  font-family: var(--mono); font-size: 11px; color: var(--gold-soft);
  letter-spacing: 0.08em; min-width: 80px; text-align: right;
}
/* Stable 7-column grid: one cell per planet, no reflow regardless of decan-name length.
   Each cell has fixed min-height so vertical jitter is eliminated. */
.anw-positions {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 2px 14px; margin-top: 6px;
  font-family: var(--mono); font-size: 11px;
}
.anw-row {
  display: grid; grid-template-columns: 18px 1fr; row-gap: 0; column-gap: 6px;
  align-items: baseline;
  padding: 4px 4px; cursor: pointer; border-bottom: 1px solid var(--border-soft);
  transition: background 120ms ease;
  min-height: 44px;       /* fixed — prevents jumping when decan-text varies */
  overflow: hidden;
}
/* Stacked layout inside each cell — glyph + (name on top line, loc below, decan below) */
.anw-row .anw-glyph { grid-row: 1 / span 3; align-self: start; padding-top: 2px; }
.anw-row .anw-name  { grid-column: 2; }
.anw-row .anw-loc   { grid-column: 2; }
.anw-row .anw-decan { grid-column: 2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* "→ decanic" affordance — small gold link on each planet row (Now + Wheel
   side panels) that jumps to Decanic mode with that planet's current decan
   pre-focused. Click the row itself = open mythological detail; click this
   inner link = see the position's cross-tradition cross-reference. */
.anw-decanic-link, .aws-decanic-link {
  color: var(--gold-soft);
  text-decoration: none;
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.04em;
  margin-left: 6px;
  white-space: nowrap;
  opacity: 0.65;
  transition: opacity 120ms ease, color 120ms ease;
}
.anw-decanic-link:hover, .aws-decanic-link:hover {
  color: var(--gold); opacity: 1; text-decoration: underline;
}

.anw-row:hover { background: var(--bg-2); }
.anw-glyph { font-family: var(--serif); font-size: 14px; text-align: center; }
.anw-name { color: var(--text-1); }
.anw-loc { color: var(--text-2); }
.anw-decan { color: var(--text-3); font-size: 10px; }
.anw-footer {
  margin-top: 12px; font-family: var(--mono); font-size: 9.5px;
  color: var(--text-3); letter-spacing: 0.08em;
}

/* Now mode — parallel events timeline (sonnet-now-events-1).
   The events strip lives inside the same SVG as the zodiac strip; these
   classes style the scrubber-row range-switch controls and the count chip. */
.anw-range-row {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-top: 8px;
  font-family: var(--mono); font-size: 10px;
  color: var(--text-3);
}
.anw-range-row .anw-range-label {
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-3);
}
.anw-range-row .btn-mini.anw-range { font-size: 10px; padding: 3px 8px; }
.anw-range-row .btn-mini.anw-range.active {
  color: var(--gold); border-color: var(--gold-soft);
  background: rgba(212,165,90,0.10);
}
.anw-range-count {
  margin-left: 6px; color: var(--text-3);
  letter-spacing: 0.06em; font-style: italic;
}
/* SVG dot hover — slight visual lift via stroke opacity. */
.astro-now-event-dot:hover circle { stroke-opacity: 1; }

/* Codex graph pane — shared WebGL graph canvas (sigma.js). Same positioning
   posture as .atlas-pane: full-bleed within the canvas area, behind the
   detail panel. Sigma renders its own <canvas> elements as children. */
.codex-graph-pane {
  position: absolute;
  left: var(--eff-nav-w);
  right: var(--eff-detail-w);
  top: 0; bottom: 0;
  z-index: 2;
  background: var(--bg-0);
  transition: left var(--t-layout) var(--ease), right var(--t-layout) var(--ease);
  /* prevent overscroll bounce on mobile during pinch-zoom */
  overscroll-behavior: contain;
  touch-action: none;
}
.codex-graph-pane canvas {
  display: block;
}

/* Atlas pane — the outer positioning wrapper for the map. Owns position:absolute
   and the empty-state centering. MapLibre lives in the inner .atlas-map div. */
.atlas-pane {
  position: absolute;
  inset: 0;
  z-index: 2;   /* above #svg-wrap (z-index unset) so the map isn't buried */
  width: 100%;
  height: 100%;
  background: var(--bg-0);
}
.atlas-pane.atlas-empty-mode {
  display: flex !important;
  align-items: center;
  justify-content: center;
}
/* Inner MapLibre target — MapLibre overrides position:relative inline,
   so we rely on width/height 100% within the explicitly-sized .atlas-pane. */
.atlas-map {
  width: 100%;
  height: 100%;
}
.atlas-empty-card {
  max-width: 380px;
  padding: 24px 28px;
  background: linear-gradient(180deg, var(--bg-1) 0%, var(--bg-2) 100%);
  border: 1px solid var(--border);
  border-radius: 4px;
  text-align: center;
  box-shadow: 0 24px 48px -16px rgba(0,0,0,0.55);
}
.atlas-empty-headline {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--h2-size);
  color: var(--text-2);
  margin-bottom: 12px;
}
.atlas-empty-sub {
  font-family: var(--mono);
  font-size: var(--lbl-md);
  letter-spacing: 0.08em;
  color: var(--text-3);
  text-transform: uppercase;
}

/* ---- Node markers (DOM children of MapLibre Marker wrapper) ---- */
.atlas-marker {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  transition: opacity var(--t-micro) var(--ease);
}
.atlas-marker-dot {
  display: inline-block;
  width: var(--dot-size, 6px);
  height: var(--dot-size, 6px);
  border-radius: 999px;
  background: var(--dot-color, #7a8090);
  box-shadow: 0 0 0 1px rgba(255,255,255,0.18), 0 1px 3px rgba(0,0,0,0.55);
  transition: box-shadow var(--t-micro) var(--ease), transform var(--t-micro) var(--ease);
}
.atlas-marker-label {
  font-family: var(--serif);
  font-size: var(--micro);
  color: var(--text-2);
  letter-spacing: 0.01em;
  text-shadow: 0 0 4px var(--bg-0), 0 0 2px var(--bg-0), 0 1px 0 var(--bg-0);
  pointer-events: none;
  transition: color var(--t-micro) var(--ease), font-size var(--t-micro) var(--ease);
}
/* Hub tier (top ~5%) — promoted hierarchy in serif + slightly larger */
.atlas-marker.hub .atlas-marker-label {
  font-size: var(--lbl-md);
  color: var(--text-0);
  letter-spacing: 0.02em;
}
.atlas-marker.tier-0 .atlas-marker-label { font-weight: 600; }
.atlas-marker.tier-1 .atlas-marker-label { font-weight: 500; }
.atlas-marker.tier-2 .atlas-marker-label,
.atlas-marker.tier-3 .atlas-marker-label { font-weight: 400; }

/* dim mode — when only the dot should show */
.atlas-marker.dim .atlas-marker-label { opacity: 0; }

/* Hover / hot states */
.atlas-marker:hover .atlas-marker-dot,
.atlas-marker.hot .atlas-marker-dot {
  box-shadow: 0 0 0 2px var(--gold), 0 0 8px var(--gold-soft);
  transform: scale(1.15);
}
.atlas-marker:hover .atlas-marker-label,
.atlas-marker.hot .atlas-marker-label {
  color: var(--gold);
}
.atlas-marker.atlas-dim {
  opacity: 0.22 !important;
}
.atlas-marker.atlas-dim .atlas-marker-label { color: var(--text-3); }

/* Hidden by bbox declutter — kept in DOM but visually suppressed */
.atlas-marker.hidden-by-declutter .atlas-marker-label { visibility: hidden; }

/* ---- Cluster-list popup (shown when zooming-in can't separate co-located points) ---- */
.atlas-cluster-popup-wrap .maplibregl-popup-content {
  background: var(--bg-1);
  border: 1px solid var(--gold-soft);
  border-radius: 4px;
  padding: 0;
  box-shadow: 0 16px 32px -8px rgba(0,0,0,0.55);
  font-family: var(--sans);
}
.atlas-cluster-popup-wrap .maplibregl-popup-close-button {
  color: var(--text-2);
  font-size: 18px;
  padding: 2px 8px;
  background: transparent;
  border: 0;
}
.atlas-cluster-popup-wrap .maplibregl-popup-close-button:hover { color: var(--gold); }
.atlas-cluster-popup-wrap .maplibregl-popup-tip {
  border-top-color: var(--gold-soft);
  border-bottom-color: var(--gold-soft);
}
.atlas-cluster-popup { width: 280px; }
.atlas-cluster-header {
  font-family: var(--mono);
  font-size: var(--lbl-md);
  letter-spacing: 0.06em;
  color: var(--gold);
  text-transform: uppercase;
  padding: 10px 14px 8px;
  border-bottom: 1px solid var(--border-soft);
}
.atlas-cluster-list {
  max-height: 280px;
  overflow-y: auto;
  padding: 4px 0;
}
.atlas-cluster-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 14px;
  cursor: pointer;
  font-family: var(--serif);
  font-size: 13px;
  color: var(--text-1);
  transition: background var(--t-micro) var(--ease), color var(--t-micro) var(--ease);
}
.atlas-cluster-row:hover {
  background: var(--bg-2);
  color: var(--gold);
}
.atlas-cluster-dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 999px;
  flex-shrink: 0;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.18);
}
.atlas-cluster-title {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- ERA-RANGE SLIDER (opus-map-era, 2026-05-15) — bottom-docked dual-handle
   range slider for trimming the era window. Replaces the 6-preset <select>. ---- */
.atlas-era-bar {
  position: absolute;
  left: 50%;
  /* Track --footer-h so the era-bar floats just above the footer, never under it. */
  bottom: calc(var(--footer-h) + 14px);
  transform: translateX(-50%);
  width: min(900px, calc(100% - 96px));
  z-index: 35;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  background: var(--panel-bg);
  backdrop-filter: var(--panel-blur);
  -webkit-backdrop-filter: var(--panel-blur);
  border: var(--panel-edge);
  border-radius: 999px;
  box-shadow: var(--panel-shadow);
  font-family: var(--mono);
}
.atlas-era-readout {
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--gold-soft);
  white-space: nowrap;
  min-width: 64px;
  text-align: center;
  flex-shrink: 0;
}
.atlas-era-track {
  position: relative;
  flex: 1 1 auto;
  height: 28px;
  cursor: pointer;
  touch-action: none;
}
.atlas-era-bands {
  position: absolute;
  left: 0; right: 0; top: 11px;
  height: 6px;
  border-radius: 3px;
  pointer-events: none;
}
.atlas-era-fill {
  position: absolute;
  top: 11px;
  height: 6px;
  background: linear-gradient(90deg, var(--gold-soft), var(--gold));
  border-radius: 3px;
  pointer-events: none;
  box-shadow: 0 0 8px rgba(212,165,90,0.4);
}
.atlas-era-tick {
  position: absolute;
  top: 4px;
  width: 1px;
  height: 20px;
  background: var(--text-3);
  opacity: 0.6;
  pointer-events: none;
}
.atlas-era-tick-zero {
  background: var(--text-2);
  opacity: 0.85;
}
.atlas-era-handle {
  position: absolute;
  top: 4px;
  width: 14px;
  height: 20px;
  margin-left: -7px;
  background: var(--bg-1);
  border: 2px solid var(--gold);
  border-radius: 3px;
  cursor: grab;
  padding: 0;
  box-shadow: 0 1px 4px rgba(0,0,0,0.4);
  transition: transform var(--t-micro) var(--ease), border-color var(--t-micro) var(--ease);
}
.atlas-era-handle:hover {
  transform: scaleY(1.15);
  border-color: var(--text-0);
}
.atlas-era-handle:active {
  cursor: grabbing;
  border-color: var(--text-0);
  background: var(--bg-2);
}
.atlas-era-reset {
  flex-shrink: 0;
  width: 30px;
  height: 26px;
  padding: 0;
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text-2);
}
.atlas-era-reset:hover { color: var(--gold); }

/* ---- MapLibre control theming — match our token palette ---- */
.atlas-map .maplibregl-ctrl-group {
  background: var(--bg-1);
  border: 1px solid var(--border);
  box-shadow: 0 8px 18px -10px rgba(0,0,0,0.6);
}
.atlas-map .maplibregl-ctrl-group button {
  background: var(--bg-1);
  border-color: var(--border);
  transition: background var(--t-micro) var(--ease);
}
.atlas-map .maplibregl-ctrl-group button:hover {
  background: var(--bg-3);
}
.atlas-map .maplibregl-ctrl-group button + button {
  border-top-color: var(--border-soft);
}
.atlas-map .maplibregl-ctrl-zoom-in span,
.atlas-map .maplibregl-ctrl-zoom-out span {
  filter: invert(0.9) sepia(0.15) hue-rotate(20deg) saturate(0.6);
}
.atlas-map .maplibregl-ctrl-attrib {
  background: rgba(13,17,25,0.62);
  color: var(--text-3);
  font-family: var(--mono);
  font-size: var(--micro);
}
.atlas-map .maplibregl-ctrl-attrib a {
  color: var(--text-2);
}
.atlas-map .maplibregl-ctrl-attrib a:hover {
  color: var(--gold);
}
.atlas-map .maplibregl-ctrl-attrib-button {
  background-color: var(--bg-1);
}
.atlas-map .maplibregl-canvas:focus { outline: none; }

/* AUTHORS view */
.authors-pane .authors-toolbar {
  position: sticky; top: 0; z-index: 2;
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px;
  background: linear-gradient(180deg, var(--bg-1) 0%, rgba(13,17,25,0.92) 100%);
  border-bottom: 1px solid var(--border);
  font-family: var(--mono); font-size: 10px;
  color: var(--text-3); letter-spacing: 0.06em;
}
.authors-pane .at-count { color: var(--text-2); }
.authors-pane .at-spacer { flex: 1; }
.authors-pane .at-lbl { color: var(--text-3); text-transform: uppercase; margin-right: 2px; }
.authors-pane .at-sort {
  background: transparent; border: 1px solid var(--border);
  color: var(--text-2); font-family: inherit; font-size: 10px;
  padding: 3px 8px; border-radius: 3px; cursor: pointer;
  letter-spacing: 0.08em; text-transform: uppercase;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.authors-pane .at-sort:hover { color: var(--gold); border-color: var(--gold-soft); }
.authors-pane .at-sort.active { color: var(--gold); border-color: var(--gold); background: rgba(212,165,90,0.08); }

.authors-pane .authors-era {
  font-family: var(--serif); font-size: 11px;
  color: var(--gold-soft); letter-spacing: 0.14em; text-transform: uppercase;
  padding: 18px 14px 5px; margin-top: 4px;
  border-bottom: 1px solid var(--border-soft);
}
.authors-pane .at-era-count { color: var(--text-3); font-family: var(--mono); letter-spacing: 0.04em; text-transform: none; }
.authors-pane .row { grid-template-columns: 18px 1fr auto auto auto; align-items: start; gap: 14px; }
.authors-pane .row .authors-date {
  white-space: nowrap; min-width: 90px; text-align: right;
  color: var(--text-2);
}
.authors-pane .at-divider { color: var(--text-3); margin: 0 4px; opacity: 0.5; }
.authors-pane .at-attrib {
  display: inline-block;
  font-family: var(--mono); font-size: 8.5px;
  color: var(--text-3); letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 1px 4px; border: 1px solid var(--border);
  border-radius: 2px;
  vertical-align: 1px; margin-right: 4px;
}

/* ABOUT */
.about-pane {
  position: absolute; inset: 56px 0 0;
  overflow-y: auto; padding: 16px 48px 48px;
  max-width: 760px; margin: 0 auto; left: 0; right: 0;
}
.about-pane h3 { font-family: var(--serif); color: var(--gold); margin-top: 1.8em; font-size: 18px; letter-spacing: 0.06em; font-weight: 500; }
.about-pane p, .about-pane li { font-size: 13.5px; line-height: 1.7; color: var(--text-1); }
.about-pane code { background: var(--bg-2); padding: 1px 5px; font-family: var(--mono); font-size: 11.5px; border-radius: 2px; }

/* ============================================================
   LEGACY / ARCHIVE VIEWER — Phase 24 V1 (2026-05-25)
   Reuses .about-pane typography conventions (serif headers,
   gold accents, mono code) per SEVERITY DOGMA §5.7.
   ============================================================ */
.legacy-pane {
  position: absolute; inset: 56px 0 0;
  display: grid; grid-template-columns: 280px 1fr;
  gap: 0; overflow: hidden;
}
.legacy-pane .lg-sidebar {
  border-right: 1px solid var(--line-1);
  background: var(--bg-1);
  overflow-y: auto; padding: 12px 0;
  font-size: 12.5px;
}
.legacy-pane .lg-sidebar-title {
  font-family: var(--serif);
  color: var(--gold); font-size: 13px; letter-spacing: 0.12em;
  text-transform: uppercase; padding: 4px 16px 12px;
}
.legacy-pane .lg-cat { margin: 0; padding: 0; border-top: 1px solid var(--line-1); }
.legacy-pane .lg-cat > summary {
  padding: 10px 16px; cursor: pointer;
  font-family: var(--serif); color: var(--text-1);
  font-size: 13px; letter-spacing: 0.04em;
  display: flex; justify-content: space-between; align-items: center;
  list-style: none;
}
.legacy-pane .lg-cat > summary::-webkit-details-marker { display: none; }
.legacy-pane .lg-cat > summary:hover { background: var(--bg-2); color: var(--text-0); }
.legacy-pane .lg-cat[open] > summary { color: var(--text-0); }
.legacy-pane .lg-cat-count {
  font-family: var(--mono); font-size: 11px; color: var(--text-3);
  background: var(--bg-2); padding: 1px 8px; border-radius: 8px;
}
.legacy-pane .lg-cat-body { padding: 2px 0 8px; }
.legacy-pane .lg-item {
  display: block; width: 100%; text-align: left;
  background: transparent; border: 0; border-left: 2px solid transparent;
  padding: 7px 16px 7px 22px; cursor: pointer;
  color: var(--text-1); font-family: inherit; font-size: 12.5px;
  line-height: 1.35;
}
.legacy-pane .lg-item:hover { background: var(--bg-2); color: var(--text-0); }
.legacy-pane .lg-item.active {
  background: var(--bg-2); color: var(--text-0);
  border-left-color: var(--gold);
}
.legacy-pane .lg-item-title { display: block; }
.legacy-pane .lg-item-meta {
  display: block;
  font-family: var(--mono); font-size: 10.5px; color: var(--text-3);
  margin-top: 2px; letter-spacing: 0.04em;
}

.legacy-pane .lg-detail {
  overflow-y: auto; padding: 32px 56px 64px;
  max-width: 900px; margin: 0 auto;
}
.legacy-pane .lg-empty h2 {
  font-family: var(--serif); color: var(--gold);
  font-size: 24px; letter-spacing: 0.06em; font-weight: 500;
  margin-top: 24px;
}
.legacy-pane .lg-empty p {
  font-size: 13.5px; line-height: 1.7; color: var(--text-1);
}
.legacy-pane .lg-counts {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 10px; margin: 28px 0;
}
.legacy-pane .lg-count-card {
  background: var(--bg-1); border: 1px solid var(--line-1);
  padding: 14px 12px; text-align: center;
}
.legacy-pane .lg-count-card strong {
  display: block; font-family: var(--serif); font-size: 28px;
  color: var(--gold); margin-bottom: 4px; font-weight: 400;
}
.legacy-pane .lg-count-card span {
  display: block; font-family: var(--mono); font-size: 10.5px;
  color: var(--text-2); letter-spacing: 0.06em;
}
.legacy-pane .lg-meta {
  margin-top: 20px; font-family: var(--mono); font-size: 11px;
  color: var(--text-3); letter-spacing: 0.04em;
}

.legacy-pane .lg-doc-header {
  display: flex; justify-content: space-between; align-items: baseline;
  padding-bottom: 12px; margin-bottom: 16px;
  border-bottom: 1px solid var(--line-1);
}
.legacy-pane .lg-doc-path {
  font-family: var(--mono); font-size: 11.5px; color: var(--text-2);
  word-break: break-all;
}
.legacy-pane .lg-doc-cat {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em;
  color: var(--gold); text-transform: uppercase;
}
.legacy-pane .lg-doc-body { font-size: 13.5px; line-height: 1.7; color: var(--text-1); }
.legacy-pane .lg-doc-body h1 { font-family: var(--serif); color: var(--gold); font-size: 22px; letter-spacing: 0.06em; margin-top: 0.6em; font-weight: 500; }
.legacy-pane .lg-doc-body h2 { font-family: var(--serif); color: var(--gold); font-size: 18px; letter-spacing: 0.06em; margin-top: 1.6em; font-weight: 500; }
.legacy-pane .lg-doc-body h3 { font-family: var(--serif); color: var(--text-0); font-size: 16px; letter-spacing: 0.04em; margin-top: 1.4em; font-weight: 500; }
.legacy-pane .lg-doc-body h4, .legacy-pane .lg-doc-body h5, .legacy-pane .lg-doc-body h6 { font-family: var(--serif); color: var(--text-1); font-size: 14px; margin-top: 1.2em; font-weight: 500; }
.legacy-pane .lg-doc-body p { margin: 0.7em 0; }
.legacy-pane .lg-doc-body ul { padding-left: 1.4em; margin: 0.6em 0; }
.legacy-pane .lg-doc-body li { margin: 0.2em 0; }
.legacy-pane .lg-doc-body code { background: var(--bg-2); padding: 1px 5px; font-family: var(--mono); font-size: 11.5px; border-radius: 2px; color: var(--text-0); }
.legacy-pane .lg-doc-body pre.lg-code { background: var(--bg-1); border: 1px solid var(--line-1); padding: 12px 14px; font-family: var(--mono); font-size: 11.5px; color: var(--text-1); overflow-x: auto; margin: 0.8em 0; }
.legacy-pane .lg-doc-body hr { border: 0; border-top: 1px solid var(--line-1); margin: 1.8em 0; }
.legacy-pane .lg-doc-body strong { color: var(--text-0); }
.legacy-pane .lg-doc-body em { color: var(--text-0); }
.legacy-pane .lg-doc-body a { color: var(--gold-soft); text-decoration: none; border-bottom: 1px dotted var(--gold-soft); }
.legacy-pane .lg-doc-body a:hover { color: var(--gold); border-bottom-style: solid; }
.legacy-pane .lg-doc-body .lg-wiki {
  font-family: var(--mono); font-size: 12px; color: var(--text-2);
  background: var(--bg-1); padding: 0 4px; border-radius: 2px;
}
.legacy-pane .lg-doc-body table.lg-table {
  border-collapse: collapse; width: 100%; margin: 0.8em 0;
  font-size: 12.5px;
}
.legacy-pane .lg-doc-body table.lg-table th,
.legacy-pane .lg-doc-body table.lg-table td {
  border: 1px solid var(--line-1); padding: 6px 10px; text-align: left;
  vertical-align: top;
}
.legacy-pane .lg-doc-body table.lg-table th {
  background: var(--bg-1); font-family: var(--serif);
  color: var(--gold); font-weight: 500;
}

.legacy-pane .lg-loading,
.legacy-pane .lg-error {
  padding: 24px; font-family: var(--mono); font-size: 12.5px;
  color: var(--text-2);
}
.legacy-pane .lg-error { color: var(--accent-warn, #c44a5a); }

/* SCROLLBARS */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--bg-3); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--border); }

/* MISSING DATA */
#missing-data {
  position: fixed; inset: 0; background: var(--bg-0);
  display: none; align-items: center; justify-content: center;
  flex-direction: column; gap: 16px; z-index: 100;
  color: var(--text-1); font-size: 14px; text-align: center; padding: 24px;
}
#missing-data h2 { font-family: var(--serif); color: var(--gold); margin: 0; }
#missing-data code { background: var(--bg-2); padding: 4px 10px; border-radius: 3px; font-family: var(--mono); }

/* LEGEND */
.btn-reset {
  background: transparent; border: 1px solid var(--border);
  color: var(--text-2); font-family: var(--mono); font-size: 10.5px;
  letter-spacing: 0.06em; padding: 4px 10px; border-radius: 3px;
  cursor: pointer; transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
}
.btn-reset:hover { color: var(--gold); border-color: var(--gold-soft); background: rgba(212,165,90,0.06); }
.btn-reset.active { color: var(--gold); border-color: var(--gold); }

/* 2026-05-29 — V01 .zoom-meter and .map-thumb style blocks deleted.
   Both elements were removed from index.html (V01 chrome scorched-earth
   pass per feedback_per_view_hide_list_forbidden_2026-05-29). The V2
   views own their own zoom + map primitives (Forge bottombar zoom-readout,
   Atlas pane via MapLibre, etc). */

/* PANTHEON FAMILY LEGEND — sticky-head pattern. The burger toggle stays in .legend-head
   (non-scrolling) so it never moves and never gets scrolled out of view. Rows scroll
   independently inside .legend-body. Same pattern as .alch-presets-pane. */
.legend {
  position: absolute; bottom: calc(var(--footer-h) + 12px);
  left: calc(var(--nav-w) + 24px);
  background: var(--panel-bg);
  backdrop-filter: var(--panel-blur);
  -webkit-backdrop-filter: var(--panel-blur);
  border: var(--panel-edge); border-radius: 4px;
  font-size: 11px; color: var(--text-2);
  pointer-events: auto; max-width: 240px;
  display: flex; flex-direction: column;
  max-height: 50vh;
  overflow: hidden;   /* IMPORTANT: pane never scrolls; .legend-body does */
  transition: left var(--t-layout) var(--ease), max-width 180ms ease, max-height 180ms ease, bottom 200ms ease;
}
body.nav-collapsed .legend { left: calc(var(--nav-w-collapsed) + 24px); }
.legend.collapsed {
  max-height: 36px; max-width: 36px;
}
.legend-head {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 10px 8px 14px;
  border-bottom: 1px solid var(--border);
  background: rgba(7,9,15,0.45);
}
.legend.collapsed .legend-head { border-bottom: 0; padding: 6px; justify-content: center; }
.legend.collapsed .legend-head .ltitle { display: none; }
.legend-body {
  flex: 1 1 auto; overflow-y: auto;
  padding: 8px 12px 10px;
  display: flex; flex-direction: column; gap: 3px;
}
.legend.collapsed .legend-body { display: none; }
.legend-burger {
  width: 22px; height: 22px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 14px; color: var(--text-2);
  background: transparent; border: 1px solid transparent; border-radius: 3px;
  cursor: pointer; transition: color 120ms, background 120ms, border-color 120ms;
  user-select: none; line-height: 1;
}
.legend-burger:hover { color: var(--gold); border-color: var(--border); background: var(--bg-2); }
.legend .ltitle { color: var(--text-3); text-transform: uppercase; letter-spacing: 0.12em; font-size: 9.5px; }
.legend .lrow {
  display: flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 2px 4px; border-radius: 2px; transition: background 120ms ease;
}
.legend .lrow:hover { background: var(--bg-3); color: var(--text-0); }
.legend .lrow.active { background: rgba(212,165,90,0.12); color: var(--text-0); }
.legend .lswatch { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.legend .lcount { font-family: var(--mono); font-size: 9.5px; color: var(--text-3); margin-left: auto; }

/* TOOLTIP */
.tooltip {
  /* Use position:fixed so clientX/Y from mousemove map directly to viewport coords —
     no offset surprises from positioned ancestors (main, aside, etc.). */
  position: fixed; pointer-events: none;
  background: rgba(13,17,25,0.96); backdrop-filter: blur(8px);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 8px 12px; font-size: 12px; color: var(--text-0);
  max-width: 280px; z-index: 1000;
  font-family: var(--sans);
  box-shadow: 0 4px 20px rgba(0,0,0,0.5);
  opacity: 0; transition: opacity 100ms ease;
  left: 0; top: 0;
}
.tooltip.show { opacity: 1; }
.tooltip .ttitle { font-weight: 500; color: var(--text-0); margin-bottom: 2px; }
.tooltip .tmeta { font-size: 10.5px; color: var(--text-2); font-family: var(--mono); }
.tooltip .tt-thumb {
  display: block; width: 100%; max-width: 220px;
  max-height: 130px; object-fit: cover;
  object-position: center top;   /* favor face/head over chest/body in cropped portraits */
  border-radius: 3px; margin: -4px -2px 8px;
  border: 1px solid var(--border);
  background: var(--bg-2);
}

/* 2026-05-30 — SCRIPTURE-RADIAL CSS DELETED in full (V01 chart class —
   .scripture-corpus-wrap/btn/popup/option, .scripture-section-label/arc,
   .scripture-book-label/wedge, .scripture-hull/node/node-label, .scripture-
   trail, .scripture-lock-edge/chip, .scripture-empty, .btn.btn-mini.scripture-
   read-btn, and the V2-canonical body.view-scripture .scripture-* overrides
   at the bottom of this file). The scripture-radial visualization in
   app.js VIEWS.scripture was nuked the same commit per the cardinal
   "ONE CHART ONLY = the canonical Atlas/Forge wheel" rule. The Scripture
   Reader CSS (#scripture-reader-pane, .sr-*, body.view-scripture-reader)
   stays — Reader is canonical V2 chrome. */

/* ============================================================
   Scripture Reader — #scripture-reader-pane
   Full-width reading pane with internal sticky topbar.
   Entity card opens in the app's right detail panel.
   ============================================================ */

/* Hide global view-header while reader is active */
body.view-scripture-reader .view-header { display: none; }

#scripture-reader-pane {
  position: absolute;
  top: 0; height: 100%;
  left: var(--eff-nav-w);
  width: calc(100% - var(--eff-nav-w) - var(--eff-detail-w));
  transition: left var(--t-layout) var(--ease), width var(--t-layout) var(--ease);
  display: none;
  flex-direction: column;
  background: var(--bg-0);
  overflow: hidden;
}

.sr-layout {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

/* ---- internal sticky topbar ---- */
.sr-topbar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  height: 48px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-0);
  gap: 14px;
  position: sticky;
  top: 0;
  z-index: 10;
}
.sr-topbar-left {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  flex: 1;
}
.sr-topbar-title {
  font-family: var(--serif);
  font-size: 15px;
  font-weight: 600;
  color: var(--text-0);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sr-topbar-right {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-shrink: 0;
}

/* ---- scrollable body below topbar ---- */
.sr-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

/* ---- controls inside topbar ---- */
.sr-vc-back {
  color: var(--text-2) !important;
  border-color: var(--border) !important;
  font-family: var(--mono);
  letter-spacing: 0.04em;
}
.sr-vc-back:hover { color: var(--gold) !important; border-color: var(--gold-soft) !important; }

/* ---- text / language dropdown pickers ---- */
.sr-pop-wrap { position: relative; }
.sr-pop-btn {
  color: var(--text-2) !important;
  border-color: var(--border) !important;
}
.sr-pop-btn:hover, .sr-pop-btn.open {
  color: var(--text-1) !important;
  border-color: var(--gold-soft) !important;
}
.sr-pop-caret { font-size: 9px; opacity: 0.6; margin-left: 3px; }
.sr-pop-menu {
  display: none;
  position: absolute;
  top: calc(100% + 5px);
  left: 0;
  min-width: 170px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 4px;
  box-shadow: 0 4px 18px rgba(0,0,0,0.38);
  z-index: 400;
  padding: 4px 0;
}
.sr-pop-menu.open { display: block; }
.sr-pop-row {
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--text-2);
  padding: 7px 14px;
  cursor: pointer;
  transition: background 80ms, color 80ms;
}
.sr-pop-row:hover { background: var(--bg-2); color: var(--text-1); }
.sr-pop-row.active { color: var(--gold); }

/* ---- grouped text dropdown ---- */
.sr-text-menu-grouped { min-width: 280px; max-height: 420px; overflow-y: auto; right: 0; left: auto; }
.sr-pop-group-header {
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
  padding: 10px 14px 4px;
  border-top: 1px solid var(--border);
  margin-top: 4px;
}
.sr-pop-group-header:first-child { border-top: none; margin-top: 0; padding-top: 6px; }
.sr-pop-text-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 14px 6px 20px;
}
.sr-pop-text-title { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sr-pop-canon-tag {
  flex-shrink: 0;
  font-size: 9.5px;
  color: var(--text-3);
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px 5px;
  white-space: nowrap;
}
.sr-pop-text-row:hover .sr-pop-canon-tag { color: var(--text-2); }
.sr-pop-text-row.active .sr-pop-canon-tag { color: var(--gold); border-color: var(--gold-soft); }

/* ---- canon badge in topbar ---- */
.sr-canon-badge {
  display: inline-block;
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight: 500;
  color: var(--text-3);
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px 6px;
  margin-left: 8px;
  vertical-align: middle;
  position: relative;
  top: -1px;
  letter-spacing: 0.04em;
}

/* ---- context toggle button ---- */
.sr-vc-ctx {
  color: var(--text-3) !important;
  border-color: transparent !important;
}
.sr-vc-ctx:hover { color: var(--gold) !important; border-color: var(--gold-soft) !important; }
.sr-vc-ctx-open {
  color: var(--gold) !important;
  border-color: var(--gold-soft) !important;
  background: rgba(212,165,90,0.07) !important;
}

/* ---- collapsible context panel (intro + cross-tradition, hidden by default) ---- */
.sr-ctx-panel {
  flex-shrink: 0;
  border-bottom: 1px solid var(--border);
  background: var(--bg-1);
}
.sr-ctx-inner {
  padding: 18px 34px 16px;
  max-width: 72ch;
}

.sr-intro {
  font-family: var(--serif);
  font-size: 14.5px;
  font-style: italic;
  color: var(--text-2);
  line-height: 1.72;
  margin: 0 0 14px;
}
.sr-xtrad-list { display: flex; flex-direction: column; gap: 6px; }
.sr-xtrad-item { display: flex; flex-direction: column; gap: 1px; }
.sr-xtrad-item.linked { cursor: pointer; }
.sr-xtrad-item.linked:hover .sr-xtrad-name { color: var(--gold); }
.sr-xtrad-name {
  font-family: var(--serif);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-1);
  transition: color 120ms;
}
.sr-xtrad-note {
  font-size: 12px;
  color: var(--text-3);
  line-height: 1.5;
}

/* ---- scrollable text body ---- */
.sr-sections {
  flex: 1;
  overflow-y: auto;
  padding: 30px 48px 72px;
}

.sr-section { margin-bottom: 30px; }

.sr-section-heading {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 14px;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(212,165,90,0.18);
}

.sr-verse {
  display: flex;
  gap: 12px;
  margin-bottom: 10px;
  line-height: 1.85;
}

.sr-ref {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--text-3);
  letter-spacing: 0.03em;
  padding-top: 3px;
  flex-shrink: 0;
  min-width: 52px;
  text-align: right;
  opacity: 0.65;
}

.sr-vtext {
  font-family: var(--serif);
  font-size: 17.5px;
  color: var(--text-1);
  line-height: 1.85;
  max-width: 80ch;
  flex: 1;
}
/* Original-language mode — Hebrew/Akkadian/Sumerian/Egyptian */
.sr-vtext-original {
  font-family: 'Noto Serif Hebrew', var(--serif);
  font-size: 14.5px;
  color: var(--gold);
  letter-spacing: 0.01em;
  line-height: 2.0;
  font-style: normal;
}

/* entity marks */
mark.sr-ent {
  background: rgba(212,165,90,0.12);
  color: var(--gold);
  border-bottom: 1px solid rgba(212,165,90,0.42);
  border-radius: 2px;
  padding: 0 1px;
  cursor: pointer;
  font-style: inherit;
  transition: background 120ms, color 120ms;
}
mark.sr-ent:hover,
mark.sr-ent.active {
  background: rgba(212,165,90,0.24);
  color: var(--text-0);
}
mark.sr-ent.pinned {
  background: rgba(212,165,90,0.30);
  color: var(--text-0);
  border-bottom-color: var(--gold);
}
/* demo mark in empty-state hint — no pointer */
mark.sr-ent-demo {
  background: rgba(212,165,90,0.12);
  color: var(--gold);
  border-bottom: 1px solid rgba(212,165,90,0.42);
  border-radius: 2px;
  padding: 0 1px;
  font-style: inherit;
  cursor: default;
}

/* ---- entity card inside the right detail panel ---- */
.sr-detail-card {
  padding: 22px 20px 48px;
}

.sr-card-word {
  font-family: var(--serif);
  font-size: 22px;
  font-weight: 600;
  color: var(--text-0);
  line-height: 1.2;
}
.sr-card-type {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 3px;
  border: 1px solid;
}
.sr-type-deity     { color: #c8956a; border-color: rgba(200,149,106,0.4); background: rgba(200,149,106,0.08); }
.sr-type-symbol    { color: var(--gold); border-color: var(--gold-soft); background: rgba(212,165,90,0.08); }
.sr-type-theme     { color: #8ab4a0; border-color: rgba(138,180,160,0.4); background: rgba(138,180,160,0.08); }
.sr-type-tradition { color: #9aa4c8; border-color: rgba(154,164,200,0.4); background: rgba(154,164,200,0.08); }
.sr-type-event     { color: #b4a8c8; border-color: rgba(180,168,200,0.4); background: rgba(180,168,200,0.08); }
.sr-type-other     { color: var(--text-2); border-color: var(--border); background: none; }

.sr-card-nodeid {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--text-3);
  letter-spacing: 0.04em;
  margin-bottom: 12px;
}
.sr-card-note {
  font-family: var(--serif);
  font-size: 14px;
  color: var(--text-2);
  line-height: 1.75;
  margin-bottom: 16px;
}

.sr-card-parallels { margin-bottom: 16px; }
.sr-pl-heading {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 8px;
}
.sr-parallel {
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: 3px;
  margin-bottom: 5px;
  background: var(--bg-1);
}
.sr-parallel.linked { cursor: pointer; transition: border-color 120ms; }
.sr-parallel.linked:hover { border-color: var(--gold-soft); }
.sr-pl-label {
  font-family: var(--serif);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-1);
  margin-bottom: 3px;
  transition: color 120ms;
}
.sr-parallel.linked:hover .sr-pl-label { color: var(--gold); }
.sr-pl-note {
  font-family: var(--serif);
  font-size: 12.5px;
  font-style: italic;
  color: var(--text-3);
  line-height: 1.6;
}

.sr-atlas-btn {
  background: none;
  border: 1px solid var(--border);
  color: var(--text-2);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.05em;
  padding: 6px 13px;
  border-radius: 3px;
  cursor: pointer;
  transition: color 120ms, border-color 120ms;
}
.sr-atlas-btn:hover { color: var(--gold); border-color: var(--gold-soft); }
/* TYRANT remediation Phase 5 (2026-05-25) — finding #12.
   The vault-jump button needs a bottom gap before the body
   below it. Spacing lives in CSS, not as a `style="..."` inline
   on the JS template (which was a SEVERITY DOGMA strike-2
   violation per HOW-WE-WORK §5.7). Targeted by id since this
   is the only `.sr-atlas-btn` that needs the gap. */
#sr-vault-jump { margin-bottom: 14px; }

/* ── Transmissions index ──────────────────────────────────────── */
.sr-trans-body { overflow-y: auto; overflow-x: hidden; }
.sr-trans-search {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 3px;
  color: var(--text-1);
  font-family: var(--mono);
  font-size: 11px;
  padding: 5px 10px;
  width: 220px;
  outline: none;
  transition: border-color 120ms;
}
.sr-trans-search:focus { border-color: var(--gold-soft); }
.sr-trans-index { padding: 18px 24px 48px; }
.sr-trans-section { margin-bottom: 28px; }
.sr-trans-pair-group { margin-bottom: 20px; }
.sr-trans-pair-header {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--gold);
  padding: 5px 0 8px;
  border-bottom: 1px solid var(--border-soft);
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.sr-trans-count {
  background: rgba(212,165,90,0.12);
  color: var(--gold);
  border-radius: 10px;
  padding: 1px 7px;
  font-size: 9px;
}
.sr-trans-item {
  padding: 9px 12px;
  border: 1px solid var(--border-soft);
  border-radius: 3px;
  margin-bottom: 5px;
  background: var(--bg-0);
  transition: border-color 120ms;
}
.sr-trans-item.linked { cursor: pointer; }
.sr-trans-item.linked:hover { border-color: var(--gold-soft); background: var(--bg-1); }
.sr-trans-item-hd {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.sr-trans-src {
  font-family: var(--serif);
  font-size: 12px;
  font-weight: 600;
  color: var(--text-2);
  white-space: nowrap;
}
.sr-trans-item.linked:hover .sr-trans-src { color: var(--gold); }
.sr-trans-arrow { color: var(--text-3); font-size: 10px; flex-shrink: 0; }
.sr-trans-lbl {
  font-family: var(--serif);
  font-size: 12.5px;
  color: var(--text-1);
  line-height: 1.4;
}
.sr-trans-ntxt {
  font-family: var(--serif);
  font-size: 12px;
  color: var(--text-3);
  line-height: 1.6;
  font-style: italic;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}


/* ── Alphabets tab ──────────────────────────────────────────────── */
/* alphabet-tab-1, 2026-05-16 */

.alpha-pane {
  position: absolute;
  top: 56px; bottom: 24px;
  left: calc(var(--eff-nav-w) + 24px);
  right: calc(var(--eff-detail-w) + 24px);
  overflow: auto;
  transition: left var(--t-layout) var(--ease), right var(--t-layout) var(--ease);
}
.alpha-pane-live {
  overflow-y: auto;
  overflow-x: hidden;
}

/* Active mode pill */
.btn-mini.alpha-mode.active {
  border-color: var(--gold-soft); color: var(--gold);
  background: rgba(212,165,90,0.10);
}

/* ── Glyph viewer ──────────────────────────── */
.alpha-glyph-header {
  padding: 2rem 2.5rem 1.5rem;
  text-align: center;
  border-bottom: 1px solid var(--border-soft);
  background: rgba(212,165,90,0.03);
}
.alpha-glyph-header h2 {
  font-size: 1.3rem; font-family: var(--serif);
  color: var(--gold); margin: 0 0 0.5rem; letter-spacing: 0.02em;
}
.alpha-glyph-header p {
  color: var(--text-2); max-width: 620px; margin: 0 auto;
  font-size: 0.88rem; line-height: 1.6;
}

.alpha-glyph-grid-wrap {
  padding: 0.75rem 1rem;
}
/* Extra bottom room so fixed panel doesn't cover the last grid row */
body.view-alphabets main.canvas { padding-bottom: 220px; }

.alpha-glyph-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 8px;
}

.alpha-glyph-cell {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.85rem 0.5rem 0.65rem;
  cursor: pointer;
  transition: background 0.12s, border-color 0.14s, box-shadow 0.14s;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  user-select: none;
}
.alpha-glyph-cell:hover {
  background: var(--bg-2);
  border-color: var(--gold-soft);
  box-shadow: 0 4px 14px rgba(0,0,0,0.35);
}
.alpha-glyph-cell.expanded {
  background: rgba(212,165,90,0.08);
  border-color: var(--gold);
  box-shadow: 0 0 0 1px rgba(212,165,90,0.25);
}

/* Latin mode dropped-letters notice */
.agv-section-divider {
  grid-column: 1 / -1;
  padding: 1.1rem 0.25rem 0.4rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold);
  border-bottom: 1px solid var(--border-soft);
  opacity: 0.75;
}
.agv-section-divider:first-child { padding-top: 0.25rem; }

.agv-latin-notice {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline;
  padding: 8px 1rem 10px; border-bottom: 1px solid var(--border-soft);
  font-size: 0.72rem; line-height: 1.5;
}
.agv-ln-label { color: var(--gold-soft); font-weight: 600; }
.agv-ln-dropped { color: var(--text-3); }
.agv-ln-added { color: var(--text-3); }

/* Script selector row */
.agv-script-selector {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 10px 1rem 14px;
  border-bottom: 1px solid var(--border-soft);
}
.agv-script-btn {
  font-size: 0.72rem; letter-spacing: 0.08em;
  padding: 4px 12px; border-radius: 3px; cursor: pointer;
  background: transparent; border: 1px solid var(--border-soft);
  color: var(--text-2); transition: all 0.12s;
}
.agv-script-btn:hover { border-color: var(--gold-soft); color: var(--text-1); }
.agv-script-btn.active {
  background: rgba(212,165,90,0.12); border-color: var(--gold-soft);
  color: var(--gold-soft);
}

/* Main character — the "lead" script shown large */
.agc-main-char {
  font-size: 2.6rem; line-height: 1; color: var(--gold);
  min-height: 3rem; display: flex; align-items: center; justify-content: center;
}
/* Legacy hieroglyph class kept for font re-trigger after font load */
.agc-hieroglyph { font-family: 'Noto Sans Egyptian Hieroglyphs', serif; }

.agc-name {
  font-size: 0.72rem; font-weight: 600; color: var(--text-1);
  text-align: center;
}
.agc-meaning {
  font-size: 0.67rem; color: var(--text-3); text-align: center;
  font-style: italic;
}
/* Secondary chars row — the other scripts, shown small */
.agc-secondary {
  display: flex; gap: 6px; align-items: center; margin-top: 2px;
}
.agc-sec-char {
  font-size: 0.85rem; color: var(--text-3);
  line-height: 1;
}
/* Investigation preview — first sentence visible on the collapsed card */
.agc-preview {
  font-size: 0.67rem; color: var(--text-3); font-style: italic;
  line-height: 1.4; text-align: center;
  margin-top: 5px; padding: 0 4px;
  border-top: 1px solid rgba(90,172,168,0.15);
  padding-top: 5px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Detail panel — half-width floating panel, bottom-right */
.alpha-glyph-detail { display: none; }
.alpha-glyph-detail.active {
  display: block;
  position: fixed;
  bottom: 1.5rem;
  right: 1.5rem;
  width: 52vw;
  max-width: 820px;
  min-width: 480px;
  height: 210px;
  overflow: hidden;
  z-index: 200;
  border-radius: 12px;
  border: 1px solid var(--border);
  border-top: 2px solid var(--gold-soft);
  box-shadow: 0 8px 36px rgba(0,0,0,0.65), 0 0 0 1px rgba(212,165,90,0.07);
}

.alpha-glyph-expanded {
  background: var(--bg-1);
  border-radius: 12px;
  padding: 1rem 2.5rem 1rem 1.25rem;
  height: 100%;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: 130px 1fr 1fr;
  gap: 1rem;
  align-items: start;
  overflow: hidden;
  position: relative;
}

/* ── 3-column horizontal panel layout ── */
.age-col-letter {
  display: flex; flex-direction: column; align-items: center;
  gap: 0.2rem; text-align: center; overflow: hidden;
}
.age-col-chain {
  display: flex; flex-direction: column; gap: 0.35rem; overflow: hidden;
}
.age-col-inv {
  display: flex; flex-direction: column; overflow: hidden; height: 100%;
}

.age-hieroglyph-big {
  font-size: 3rem; line-height: 1; color: var(--gold);
}
.age-letter-name {
  font-size: 0.88rem; font-weight: 600; color: var(--text-0);
  text-align: center; font-family: var(--serif);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.age-gardiner {
  font-size: 0.62rem; color: var(--text-3); font-family: var(--mono);
}
.age-descendants {
  display: flex; flex-wrap: wrap; gap: 0.3rem 0.5rem; margin-top: 0.3rem;
  justify-content: center;
}
.age-desc-item {
  font-size: 0.78rem; color: var(--text-1);
  display: flex; align-items: center; gap: 0.25rem;
}
.age-desc-script {
  font-size: 0.58rem; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-3); background: var(--bg-2);
  padding: 0.1em 0.35em; border-radius: 2px;
}

.age-chain-label-row {
  font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-3);
}
.age-chain {
  display: flex; align-items: flex-start; gap: 0.3rem; flex-wrap: nowrap;
}
.age-chain-step {
  display: flex; flex-direction: column; align-items: center; gap: 0.15rem;
  min-width: 48px;
}
.age-chain-glyph { font-size: 1.5rem; line-height: 1; }
.age-chain-hier  { font-family: 'Noto Sans Egyptian Hieroglyphs', serif; color: var(--gold); }
.age-chain-proto { font-family: 'Noto Sans Egyptian Hieroglyphs', serif; color: var(--gold-soft); }
.age-chain-phoen { font-family: 'Noto Serif Hebrew', serif; color: var(--text-1); }
.age-chain-greek { font-family: var(--serif); font-size: 1.3rem; color: var(--text-0); }
.age-chain-latin { font-family: var(--sans); font-size: 1.3rem; font-weight: 700; color: var(--text-0); }
.age-chain-step-label { font-size: 0.6rem; color: var(--text-2); text-align: center; }
.age-chain-step-sub   { font-size: 0.57rem; color: var(--text-3); text-align: center; font-family: var(--mono); }
.age-arrow { color: var(--text-3); font-size: 1rem; padding-top: 0.35rem; }

.age-note {
  font-size: 0.8rem; line-height: 1.55; color: var(--text-2);
  font-family: var(--serif); font-style: italic;
  border-left: 2px solid var(--gold-soft); padding-left: 0.65rem;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* Investigation column */
.age-investigation {
  height: 100%;
  padding: 0.65rem 0.85rem 0.5rem;
  background: rgba(90,172,168,0.06);
  border: 1px solid rgba(90,172,168,0.22);
  border-radius: 6px;
  display: flex; flex-direction: column; gap: 0.4rem;
  overflow: hidden;
}
.age-inv-label {
  font-size: 0.6rem; letter-spacing: 0.13em; text-transform: uppercase;
  color: #5aaca8; font-weight: 600; flex-shrink: 0;
}
.age-inv-text {
  font-size: 0.82rem; line-height: 1.55; color: var(--text-0);
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
  flex-shrink: 1;
}
.age-inv-nodes {
  display: flex; flex-wrap: wrap; gap: 5px; flex-shrink: 0;
}
.age-inv-node {
  font-size: 0.68rem; padding: 2px 8px; border-radius: 3px; cursor: pointer;
  background: rgba(212,165,90,0.08); border: 1px solid rgba(212,165,90,0.3);
  color: var(--gold-soft); transition: background 0.12s; text-transform: capitalize;
}
.age-inv-node:hover { background: rgba(212,165,90,0.2); }

.age-close-btn {
  position: absolute; top: 0.6rem; right: 0.65rem;
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 50%; color: var(--text-2); font-size: 0.75rem;
  cursor: pointer; transition: all 0.12s; line-height: 1;
}
.age-close-btn:hover { border-color: var(--gold-soft); color: var(--gold); background: var(--bg-3); }

/* ── Cuneiform comparison strip ──────────────────── */
.alpha-cuneiform-strip {
  padding: 1.5rem 2rem;
  border-top: 1px solid var(--border-soft);
  background: rgba(0,0,0,0.04);
}
.alpha-cuneiform-strip h3 {
  margin: 0 0 0.4rem; font-size: 0.95rem;
  color: var(--text-1); font-family: var(--serif);
}
.alpha-cunei-intro {
  font-size: 0.82rem; color: var(--text-2); line-height: 1.6;
  max-width: 700px; margin: 0 0 1rem;
}
.alpha-cunei-cells {
  display: flex; gap: 1.25rem; flex-wrap: wrap;
}
.alpha-cunei-cell {
  display: flex; flex-direction: column; align-items: center; gap: 0.2rem;
  background: var(--bg-1); border: 1px solid var(--border-soft);
  padding: 0.6rem 0.8rem; border-radius: 4px; min-width: 64px;
}
.acc-sign {
  font-family: 'Noto Sans Cuneiform', 'Segoe UI Historic', monospace;
  font-size: 2rem; line-height: 1; color: var(--text-2);
}
.acc-name {
  font-size: 0.68rem; font-weight: 600; color: var(--text-1);
  font-family: var(--mono); text-transform: uppercase;
}
.acc-meaning {
  font-size: 0.62rem; color: var(--text-3); text-align: center;
}

/* ── Cuneiform viewer ────────────────────────────── */
.acv-compare-banner {
  padding: 1rem 2rem 1.25rem;
  background: rgba(212,165,90,0.04);
  border-bottom: 1px solid var(--border-soft);
}
.acv-chain {
  display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap;
  margin-bottom: 0.65rem;
}
.acv-chain-item {
  display: flex; flex-direction: column; align-items: center;
  font-size: 1.5rem; line-height: 1; color: var(--text-1);
  gap: 0.2rem;
}
.acv-chain-item small { font-size: 0.6rem; color: var(--text-3); text-align: center; font-family: var(--mono); }
.acv-chain-cuneiform { font-family: 'Noto Sans Cuneiform', 'Segoe UI Historic', monospace; color: var(--text-3); }
.acv-chain-hier { font-family: 'Noto Sans Egyptian Hieroglyphs', serif; color: var(--gold-soft); }
.acv-arrow { color: var(--text-3); font-size: 1.1rem; }
.acv-compare-note { font-size: 0.8rem; color: var(--text-3); max-width: 680px; line-height: 1.55; margin: 0; font-style: italic; }
.acv-bridge-note {
  margin-top: 0.9rem;
  padding: 0.75rem 1rem;
  background: rgba(90,140,212,0.07);
  border: 1px solid rgba(90,140,212,0.25);
  border-left: 3px solid rgba(90,140,212,0.55);
  border-radius: 6px;
  font-size: 0.82rem;
  line-height: 1.6;
  color: var(--text-2);
  max-width: 820px;
}
.acv-bridge-label {
  display: block;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: rgba(90,140,212,0.85);
  text-transform: uppercase;
  margin-bottom: 0.4rem;
}
.acv-sign { font-family: 'Noto Sans Cuneiform', 'Segoe UI Historic', monospace !important; font-size: 2.2rem !important; color: var(--text-2) !important; }
.acv-detail {
  display: flex; align-items: flex-start; gap: 1.25rem;
  padding: 1rem 3rem 1rem 1.5rem;
  background: rgba(212,165,90,0.05);
  border: 1px solid var(--border);
  border-radius: 8px;
  margin: 0.5rem 0 0.75rem;
  position: relative;
}
.acv-detail-sign {
  font-family: 'Noto Sans Cuneiform', 'Segoe UI Historic', monospace;
  font-size: 3rem; line-height: 1; color: var(--gold); flex-shrink: 0;
}
.acv-detail-body { flex: 1; }
.acv-detail-name { font-size: 1rem; font-weight: 600; color: var(--text-0); margin-bottom: 0.4rem; font-family: var(--serif); }
.acv-detail-note { font-size: 0.85rem; line-height: 1.6; color: var(--text-2); font-style: italic; border-left: 2px solid var(--gold-soft); padding-left: 0.65rem; }

/* ── Origin chain ─────────────────────────────────── */
.alpha-origin-container {
  padding: 1rem 1.5rem 2rem;
  overflow-x: auto;
  height: 100%;
  box-sizing: border-box;
  position: relative;
}

.alpha-origin-legend {
  display: flex; flex-wrap: wrap; gap: 1rem; margin-bottom: 1rem;
}
.aol-item { display: flex; align-items: center; gap: 0.4rem; font-size: 0.75rem; color: var(--text-2); }
.aol-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }

.alpha-origin-svg-wrap {
  width: 100%;
  min-height: 700px;
  position: relative;
}

.alpha-origin-svg { display: block; }

/* SVG elements */
.ao-gridline { stroke: var(--border-soft); stroke-width: 1; }
.ao-gridlabel { fill: var(--text-3); font-size: 10px; font-family: var(--mono); }
.ao-edge {
  fill: none; stroke: var(--gold-soft); stroke-width: 1.5;
  stroke-dasharray: none; opacity: 0.55;
}
.ao-edge-source { stroke: var(--text-3); stroke-dasharray: 4 3; opacity: 0.4; }
.ao-edge-sibling { stroke: var(--text-3); stroke-dasharray: 2 4; opacity: 0.35; }
.ao-node-sample {
  font-family: 'Noto Sans Egyptian Hieroglyphs', 'Noto Serif Hebrew', serif;
  font-size: 14px; dominant-baseline: middle; fill: currentColor;
}
.ao-node-label { font-size: 9px; fill: var(--text-2); font-family: var(--sans); }

/* Tooltip */
.ao-tooltip {
  position: absolute; z-index: 200;
  background: var(--bg-1); border: 1px solid var(--gold-soft);
  border-radius: 6px; padding: 0.75rem 1rem;
  max-width: 260px; pointer-events: none;
  box-shadow: 0 4px 20px rgba(0,0,0,0.3);
}
.aot-sample { font-size: 2rem; line-height: 1; margin-bottom: 0.25rem; }
.aot-name { font-size: 0.85rem; font-weight: 600; color: var(--text-0); margin-bottom: 0.2rem; }
.aot-date { font-size: 0.72rem; color: var(--text-3); font-family: var(--mono); }
.aot-family { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 0.5rem; }
.aot-note { font-size: 0.78rem; color: var(--text-2); line-height: 1.5; }

/* ── Mysticism ────────────────────────────────────── */
.alpha-mysticism-container {
  padding: 1.5rem 2rem 3rem;
  max-width: 1100px; margin: 0 auto;
}
.alpha-myst-header { margin-bottom: 1.5rem; }
.alpha-myst-header h2 {
  font-size: 1.3rem; font-family: var(--serif); color: var(--gold);
  margin: 0 0 0.4rem; letter-spacing: 0.02em;
}
.alpha-myst-header p {
  font-size: 0.87rem; color: var(--text-2); line-height: 1.6; max-width: 680px;
}
.alpha-myst-cols {
  display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 1.5rem; margin-bottom: 2rem;
}
@media (max-width: 800px) {
  .alpha-myst-cols { grid-template-columns: 1fr; }
}
.alpha-myst-col h3 {
  text-align: center; margin: 0 0 0.25rem; font-size: 0.95rem;
  font-family: var(--serif); color: var(--text-0); border-bottom: 1px solid var(--border-soft);
  padding-bottom: 0.5rem;
}
.alpha-myst-col-intro {
  font-size: 0.68rem; color: var(--text-3); text-align: center;
  margin-bottom: 0.6rem; font-family: var(--mono);
}
.alpha-myst-rows { font-size: 0.83rem; }
.alpha-myst-row {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.2rem 0.4rem; border-bottom: 1px solid var(--border-soft);
  transition: background 0.1s;
}
.alpha-myst-row:hover { background: var(--bg-1); }
.amr-glyph { width: 2rem; text-align: center; font-size: 1.15rem; }
.amr-heb { font-family: 'Noto Serif Hebrew', serif; direction: rtl; }
.amr-arabic { font-family: serif; direction: rtl; }
.amr-name { flex: 1; color: var(--text-2); font-size: 0.78rem; }
.amr-val { font-family: var(--mono); font-weight: 600; min-width: 3rem; text-align: right; color: var(--gold); }

.alpha-myst-examples { margin-top: 1.5rem; }
.alpha-myst-examples h3 {
  margin: 0 0 1rem; font-size: 1rem; font-family: var(--serif); color: var(--text-0);
}
.ame-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 1rem;
}
.ame-card {
  background: var(--bg-1); border: 1px solid var(--border-soft);
  padding: 1rem; border-radius: 4px; transition: border-color 0.15s;
}
.ame-card:hover { border-color: var(--gold-soft); }
.ame-tradition {
  font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--gold); margin-bottom: 0.3rem;
}
.ame-equation {
  font-size: 1.05rem; font-weight: 600; color: var(--text-0);
  margin-bottom: 0.2rem; font-family: 'Noto Serif Hebrew', serif;
}
.ame-translit {
  font-size: 0.75rem; color: var(--text-2); margin-bottom: 0.5rem;
  font-style: italic;
}
.ame-note {
  font-size: 0.78rem; color: var(--text-2); line-height: 1.55;
}

/* Calculator */
.alpha-myst-calculator { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid var(--border-soft); }
.alpha-myst-calculator h3 { margin: 0 0 0.3rem; font-size: 0.95rem; font-family: var(--serif); color: var(--text-0); }
.alpha-myst-calc-intro { font-size: 0.82rem; color: var(--text-2); margin-bottom: 0.75rem; }
.amc-inputs { display: flex; gap: 0.75rem; flex-wrap: wrap; margin-bottom: 0.75rem; }
.amc-input {
  background: var(--bg-1); border: 1px solid var(--border-soft);
  border-radius: 4px; padding: 0.4rem 0.75rem;
  color: var(--text-0); font-size: 1rem; width: 200px;
  font-family: 'Noto Serif Hebrew', serif;
  transition: border-color 0.15s;
}
.amc-input:focus { outline: none; border-color: var(--gold-soft); }
.amc-result {
  font-size: 0.9rem; color: var(--text-1); padding: 0.5rem 0;
  min-height: 2rem; font-family: var(--serif);
}
.amc-result-part { margin-right: 0.5rem; }
.amc-r-trad { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-3); margin-right: 0.3em; }
.amc-r-word { color: var(--text-0); }
.amc-result strong { color: var(--gold); font-size: 1.1em; }
.amc-sep { color: var(--text-3); }

/* ── Scripts grid ──────────────────────────────── */
.alpha-scripts-header {
  padding: 1.5rem 2rem 0.5rem;
  display: flex; align-items: baseline; gap: 1rem;
}
.alpha-scripts-header h2 {
  font-size: 1.1rem; font-family: var(--serif); color: var(--text-0); margin: 0;
}
.alpha-count { color: var(--text-3); font-size: 0.82rem; font-family: var(--mono); }
.alpha-scripts-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1rem; padding: 1rem 2rem 2rem;
}
.alpha-script-card {
  background: var(--bg-1); border: 1px solid var(--border-soft);
  padding: 0.9rem 1rem; cursor: pointer;
  transition: border-color 0.15s; border-radius: 3px;
}
.alpha-script-card:hover { border-color: var(--gold-soft); }
.asc-type {
  font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--text-3); margin-bottom: 0.25rem;
}
.asc-title {
  font-size: 0.9rem; font-weight: 600; color: var(--text-0); margin-bottom: 0.2rem;
}
.asc-tradition { font-size: 0.75rem; color: var(--text-2); }

/* ── Alpha Findings mode ─────────────────────────────────────────────────── */
.af-header {
  padding: 32px 40px 20px;
  border-bottom: 1px solid var(--border-soft);
}
.af-header h2 {
  font-family: var(--serif); font-size: 1.5rem; color: var(--gold-soft);
  margin: 0 0 8px;
}
.af-header p {
  font-size: 0.9rem; color: var(--text-2); margin: 0; max-width: 680px;
}
.af-section-label {
  font-size: 0.7rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-3); padding: 24px 40px 10px;
}
.af-cards {
  display: flex; flex-direction: column; gap: 1px;
  border-top: 1px solid var(--border-soft);
  border-bottom: 1px solid var(--border-soft);
  margin-bottom: 8px;
}
.af-card {
  padding: 20px 40px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  cursor: pointer; transition: background 0.12s;
}
.af-card:last-child { border-bottom: none; }
.af-card:hover { background: rgba(212,165,90,0.04); }
.af-card-head {
  display: flex; align-items: flex-start; gap: 12px; margin-bottom: 8px;
}
.af-badge {
  flex-shrink: 0; font-size: 0.65rem; letter-spacing: 0.1em;
  text-transform: uppercase; padding: 2px 7px; border-radius: 3px;
  border: 1px solid; margin-top: 2px;
}
.af-title {
  font-family: var(--serif); font-size: 1.05rem; color: var(--text-1);
  line-height: 1.35;
}
.af-summary {
  font-size: 0.875rem; color: var(--text-2); line-height: 1.6;
  max-width: 820px;
}
.af-body-wrap {
  margin-top: 10px;
}
.af-body-wrap summary {
  font-size: 0.78rem; color: var(--gold-soft); cursor: pointer;
  user-select: none; padding: 2px 0;
}
.af-body-wrap summary:hover { opacity: 0.8; }
.af-body {
  font-size: 0.82rem; color: var(--text-2); line-height: 1.7;
  max-width: 820px; padding: 12px 0 4px;
}
.af-chips {
  display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px;
}
.af-chip {
  font-size: 0.73rem; color: var(--gold-soft);
  background: rgba(212,165,90,0.08); border: 1px solid rgba(212,165,90,0.25);
  border-radius: 3px; padding: 2px 8px; cursor: pointer; transition: background 0.12s;
}
.af-chip:hover { background: rgba(212,165,90,0.18); }
.af-chip--miss { color: var(--text-3); background: transparent; border-color: var(--border-soft); cursor: default; }

/* Stub state */
.alpha-stub {
  max-width: 520px; padding: 36px 44px;
  border: 1px solid var(--border-soft); border-radius: 6px;
  background: rgba(212,165,90,0.04); color: var(--text-2);
  font-family: var(--serif); text-align: center; margin: auto;
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
}

/* ═══════════════════════════════════════════════════════════════════
   FORGE — Phase 0 scaffold
   -------------------------------------------------------------------
   Proprietary WebGPU engine route. Isolated like Pantheon V2 was.
   Phase 0 styles only — informational pane reporting engine status
   and the phase roadmap. Phase 1+ will add the actual rendering canvas
   and overlay chrome; this block is the design seed.
   ═══════════════════════════════════════════════════════════════════ */
.forge-pane {
  /* APP-SHELL CONTRACT — Phase 6d audit.
     The other views (Atlas / Timeline / Documents / etc.) sit
     inside `main.canvas` which is `position: fixed; inset: 0`
     — i.e. it spans the ENTIRE viewport on purpose, including
     under the left nav rail and the right detail rail.
     Each view's wrapper is responsible for insetting ITSELF
     using the cascading width vars:
       --eff-nav-w    : left rail effective width (`body.nav-collapsed`
                        flips to nav-w-collapsed)
       --eff-detail-w : right rail effective width
     `#svg-wrap` does this with `left: var(--eff-nav-w); width:
     calc(100% - var(--eff-nav-w) - var(--eff-detail-w))`.
     Forge was ignoring the contract (inset: 0) which is why
     the FORGE label was sitting UNDER the nav rail and the
     bottom bar was anchored to the viewport edge instead of
     the pane edge. Fixed: respect both rails like everyone
     else. The transition matches `--t-layout` so the pane
     slides with the rest of the chrome when rails collapse. */
  position: absolute;
  top: 0; bottom: 0;
  left:  var(--eff-nav-w);
  right: var(--eff-detail-w);
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(ellipse at center, rgba(212,165,90,0.04) 0%, transparent 60%),
    var(--bg-0);
  overflow: auto;
  transition: left var(--t-layout) var(--ease), right var(--t-layout) var(--ease);
  /* Phase 6d3 — drag-near-edge during a window resize was
     triggering the browser's text-selection (visible as a blue
     overlay across the canvas + status bar). The wheel is not
     text; selecting it serves no purpose. Suppress selection
     across the entire Forge surface; re-enable on inputs that
     explicitly need it (search field). */
  user-select: none;
  -webkit-user-select: none;
}
.forge-pane input,
.forge-pane select,
.forge-bottom-search,
.forge-status-search {
  user-select: text;
  -webkit-user-select: text;
}
.forge-error {
  max-width: 520px; padding: 24px 32px;
  font-family: var(--mono); font-size: 12px;
  color: var(--crimson, #c44a5a);
  border: 1px solid var(--crimson, #c44a5a);
  border-radius: 4px;
  background: rgba(196, 74, 90, 0.06);
  margin: auto;
}
.forge-shell {
  width: min(960px, 92vw);
  padding: 56px 44px 44px;
  display: flex; flex-direction: column; gap: 28px;
}
.forge-header {
  display: flex; align-items: baseline; gap: 16px;
  border-bottom: 1px solid var(--border-soft);
  padding-bottom: 14px;
}
.forge-h {
  font-family: var(--mono);
  font-size: 22px; font-weight: 500;
  letter-spacing: 0.32em;
  color: var(--gold);
  margin: 0;
}
.forge-sub {
  font-family: var(--mono); font-size: 10.5px;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--text-3);
}
.forge-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}
.forge-card {
  border: 1px solid var(--border-soft);
  border-radius: 3px;
  padding: 16px 18px 14px;
  background: rgba(14, 16, 22, 0.6);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  display: flex; flex-direction: column; gap: 12px;
}
.forge-card-full { grid-column: 1 / -1; }
.forge-card-label {
  font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--text-3);
}
.forge-card-rows {
  display: flex; flex-direction: column; gap: 4px;
}
.forge-row {
  display: flex; align-items: baseline; justify-content: space-between;
  font-family: var(--mono); font-size: 11.5px;
  color: var(--text-1);
  padding: 2px 0;
  border-bottom: 1px dashed rgba(255, 255, 255, 0.04);
}
.forge-row:last-child { border-bottom: none; }
.forge-k { color: var(--text-2); }
.forge-v { color: var(--text-0); font-variant-numeric: tabular-nums; }
.forge-v.ok      { color: var(--sage, #6e8c6b); }
.forge-v.pending { color: var(--text-3); font-style: italic; }
.forge-v.fail    { color: var(--crimson, #c44a5a); }

.forge-phases {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 6px;
}
.forge-phase {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--mono); font-size: 11.5px;
  color: var(--text-2);
  padding: 4px 8px;
  border-left: 2px solid transparent;
}
.forge-phase-tag {
  display: inline-grid; place-items: center;
  width: 22px; height: 22px;
  border: 1px solid var(--border-soft);
  border-radius: 3px;
  font-size: 10.5px; color: var(--text-3);
  flex: 0 0 auto;
}
.forge-phase.done {
  color: var(--text-1);
  border-left-color: var(--sage, #6e8c6b);
}
.forge-phase.done .forge-phase-tag {
  color: var(--sage, #6e8c6b);
  border-color: var(--sage, #6e8c6b);
}
.forge-phase.next {
  color: var(--text-0);
  border-left-color: var(--gold);
}
.forge-phase.next .forge-phase-tag {
  color: var(--gold);
  border-color: var(--gold-soft);
}
.forge-footnote {
  font-family: var(--mono); font-size: 10.5px;
  color: var(--text-3);
  border-top: 1px solid var(--border-soft);
  padding-top: 14px;
  line-height: 1.5;
}
.forge-footnote code {
  font-family: var(--mono); font-size: 10.5px;
  color: var(--text-1);
  background: rgba(255, 255, 255, 0.04);
  padding: 1px 4px; border-radius: 2px;
}

/* Phase 5B M-F6 (2026-05-20) — Forge marked as the active focus,
   other views demoted behind a "More views" disclosure. The
   construction badge from Phases 0-6d4 was replaced by a small
   active-focus pill since Forge is now the primary entry, not the
   under-construction one. */
.item.forge-nav .sym {
  color: var(--gold);
}
.item.forge-nav::after {
  content: '●';
  margin-left: 6px;
  font-size: 8px;
  color: var(--gold);
  opacity: 0.85;
}
body.nav-collapsed .item.forge-nav::after { display: none; }

/* Phase 5B M-F6 — "More views" disclosure. Collapses every non-
   Forge nav item behind a small summary. <details> handles open/
   closed state natively; we just style summary like a nav item +
   the body like a sub-list. */
.nav-more {
  margin-top: 10px;
  border-top: 1px solid var(--rule, rgba(255, 255, 255, 0.06));
  padding-top: 6px;
}
.nav-more > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  font-size: 12px;
  color: var(--text-2);
  border-radius: 4px;
  user-select: none;
  transition: color .12s ease, background .12s ease;
}
.nav-more > summary::-webkit-details-marker { display: none; }
.nav-more > summary:hover { color: var(--text-0); background: rgba(255, 255, 255, 0.025); }
.nav-more > summary .sym {
  display: inline-block;
  width: 16px; text-align: center;
  color: var(--text-3);
  font-size: 13px;
}
.nav-more[open] > summary { color: var(--text-1); }
.nav-more[open] > summary .sym { transform: rotate(90deg); transition: transform .15s ease; }
.nav-more-body {
  padding-top: 4px;
}
body.nav-collapsed .nav-more > summary .lbl { display: none; }

/* ═══════════════════════════════════════════════════════════════════
   FORGE — Phase 1: WebGPU bootstrap + first disk
   -------------------------------------------------------------------
   Pane = top status strip + full-area canvas stage. The Phase 0
   informational cards (.forge-card etc.) above are retained for
   diagnostics but no longer mount by default; the canvas does.
   ═══════════════════════════════════════════════════════════════════ */
.forge-shell-v1 {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  background: var(--bg-0);
}
/* Phase 21A2 (2026-05-21) — Forge status row is no longer a
   full-width top bar. It's now a FLOATING PILL fixed at top-left
   right of the nav-hub button (14 + 36 + 12 = 62 px). It carries
   only the FORGE tag + mode dropdown by default; the debug stats
   (device / nodes / edges / hover / lock / frame) collapse behind
   a debug toggle and only render when `.is-debug` is set. The
   visual style matches the bottom-bar pill controls (rounded,
   blurred dark background, gold accent). */
/* ═══════════════════════════════════════════════════════════════
   Phase 22-C (2026-05-23) — .forge-status row deprecated
   ═══════════════════════════════════════════════════════════════
   The visible FORGE | Deities pill that used to live here was
   DELETED in Phase 22-C. The UI now lives at the app-shell level
   (.app-pill in index.html, src/js/app-pill.js).

   The .forge-status DOM node stays in the page because the debug-
   stats popover (wireDebugStats) clones textContent from its child
   spans (#forge-status-device, -nodes, -edges, -hover, -lock,
   -frame) each open. JS writers throughout forge.js write to these
   spans via getElementById — which succeeds regardless of CSS, so
   display:none here is safe.

   When the debug-stats refactor lands (removing the live-clone
   pattern in favor of a direct probe API), this entire block goes.

   DELETED rules (~150 lines, restored at 4466334^ if needed):
   - .forge-status visible chrome (position, border, blur, padding)
   - .forge-status-tag (FORGE caps label)
   - .forge-status-mode (the legacy pill button)
   - .fsm-label (label inside the button)
   - .forge-status-sep:first-of-type (visible separators)
   - .forge-mode-menu + .fm-item + .fm-sym + .fm-label (dropdown)
   - .forge-status-spacer (right-edge push)
   ═══════════════════════════════════════════════════════════════ */
.forge-status { display: none !important; }

/* Phase 22-C (2026-05-23) — the .forge-status-search input + the
   duplicate .forge-status `display:flex` rule that used to live here
   were tied to the deleted top-status row. Both removed; the live
   bottom-bar search (`.forge-bottom-search`) handles search now. */

/* ════════════════════════════════════════════════════════════
   BOTTOMBAR FOUNDATION  (Phase 22-AD, 2026-05-24)
   ────────────────────────────────────────────────────────────
   `--bottombar-cell-h` is the SITE-WIDE canonical height for
   every clickable / editable / display cell in the bottom row.
   Every primitive — buttons, inputs, scrubber boxes — snaps to
   this height via `height: var(...)` + `box-sizing: border-box`.
   Change this ONCE, every cell follows. The single source of
   truth referenced by the height-parity rule below.
   ════════════════════════════════════════════════════════════ */
:root {
  --bottombar-cell-h: 24px;
}

/* Phase 6d — bottom bar inside .forge-stage. Floating row at
   the bottom edge holding the search input + zoom gizmo.
   Behind the dev panel z-stack so the panel can cover it. */
.forge-bottombar {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  z-index: 12;
  pointer-events: none;   /* children re-enable below */
}

/* Height parity — every interactive cell directly in or
   nested under .forge-bottombar gets the canonical height +
   border-box sizing. New primitives inherit this for free.
   The rule sits ABOVE per-primitive declarations so per-primitive
   padding still applies, but height is locked. */
.forge-bottombar button,
.forge-bottombar input,
.forge-bottombar .forge-scrub-box,
.forge-bottombar .forge-debug-btn {
  height: var(--bottombar-cell-h);
  box-sizing: border-box;
  line-height: 1;
}
.forge-zoom-gizmo,
.forge-bottom-search {
  pointer-events: auto;
}
.forge-zoom-gizmo {
  appearance: none; -webkit-appearance: none;
  background: rgba(13, 17, 25, 0.85);
  color: var(--gold);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.08em;
  border: 1px solid var(--border, #2a2e3a);
  border-radius: 4px;
  padding: 5px 10px;
  cursor: pointer;
  min-width: 70px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.forge-zoom-gizmo:hover { border-color: var(--gold-soft); color: var(--gold); }
.forge-zoom-gizmo.is-at-fit { color: var(--text-2); border-color: var(--border, #2a2e3a); }
.forge-bottom-search {
  appearance: none; -webkit-appearance: none;
  background: rgba(13, 17, 25, 0.85);
  color: var(--text-0);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 12px;
  letter-spacing: 0.04em;
  border: 1px solid var(--border, #2a2e3a);
  border-radius: 4px;
  padding: 5px 10px;
  outline: none;
  /* Phase 22-F-fix (2026-05-24) — 2/3 of the previous size, not
     2/3 of viewport. Was 160/180 (2026-05-20). Now 107/120 ≈ 2/3
     of that — a smaller, tighter input. */
  flex: 0 1 107px;
  max-width: 120px;
}
.forge-bottom-search::placeholder { color: var(--text-3); }
.forge-bottom-search:hover { border-color: var(--gold-soft); }
.forge-bottom-search:focus { border-color: var(--gold); }

/* Timeline scrubber — 4-box layout per John 2026-05-20:
   IN box | slider | OUT box | PRESENT box. All four match the
   height of the zoom-gizmo + search input (single line, 11px
   font, ~24px total height with padding + border). Same dark +
   mono + gold-accent styling for visual consistency. */
.forge-scrub-box {
  pointer-events: auto;
  background: rgba(13, 17, 25, 0.85);
  color: var(--text-2);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  border: 1px solid var(--border, #2a2e3a);
  border-radius: 4px;
  padding: 5px 10px;
  flex: 0 0 auto;
  /* Phase 11 (2026-05-20) — FIXED width. Was min-width:56 which let
     the box jump from ~60px (e.g. "0") to ~90px ("15000 BCE") as the
     user scrubbed, shifting everything next to it. Now the width is
     constant; max content "15000 BCE" (9 chars × ~7px) + 20px padding
     + 2px border ≈ 84px. Use 86px to give "15000 BCE" 1-2px breathing
     room without crowding adjacent UI. */
  width: 86px;
  text-align: center;
  white-space: nowrap;
  box-sizing: border-box;
}
.forge-scrub-box:hover { border-color: var(--gold-soft); }
/* Phase 21R (2026-05-22) — IN / OUT are now <input> elements
   (typable). Match the readout look. Editable affordance: subtle
   gold border + lighter text on hover/focus. */
.forge-scrub-box-editable {
  appearance: none; -webkit-appearance: none;
  outline: none;
  cursor: text;
}
.forge-scrub-box-editable:focus {
  border-color: var(--gold, #d4a55a);
  color: var(--text-0);
  background: rgba(20, 26, 38, 0.92);
}
.forge-scrub-box-editable::selection { background: rgba(212,165,90,0.30); }

/* PRESENT box — slightly emphasized (gold text) to distinguish it
   as the playhead readout vs the IN/OUT range bounds. */
.forge-scrub-present {
  color: var(--gold, #d4a55a);
}
/* Phase 21R (2026-05-22) — in Forge specifically, the PRESENT
   playhead box + the CENTER thumb on the slider are REDUNDANT
   (the wheel filter is driven by IN/OUT alone). Hide them under
   body.view-forge ONLY; JS + DOM stay intact so any future view
   that wants a playhead inherits the wiring. */
body.view-forge #forge-scrub-present     { display: none !important; }
body.view-forge #forge-scrub-center-thumb { display: none !important; }
/* Slider container — same height as the boxes (matches the
   zoom-gizmo + search height). Holds the track + 3 thumbs. */
.forge-scrub-slider {
  pointer-events: auto;
  background: rgba(13, 17, 25, 0.85);
  border: 1px solid var(--border, #2a2e3a);
  border-radius: 4px;
  padding: 5px 10px;
  flex: 0 1 220px;
  max-width: 260px;
  min-width: 140px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  transition: border-color 0.2s ease;
}
.forge-scrub-slider:hover { border-color: var(--gold-soft); }
.forge-scrub-track {
  position: relative;
  width: 100%;
  height: 14px;
}
.forge-scrub-track::before {
  content: "";
  position: absolute;
  left: 0; right: 0;
  top: 50%;
  height: 1px;
  background: var(--border, #2a2e3a);
  transform: translateY(-50%);
}
.forge-scrub-range {
  position: absolute;
  top: 50%;
  height: 2px;
  background: var(--gold-soft, #8a7430);
  transform: translateY(-50%);
  pointer-events: none;
  border-radius: 1px;
}
/* Phase 11 (2026-05-20) — Year-0 reference tick on the slider track.
   A faint grey vertical line, behind the thumbs (lower z), purely
   informational. JS sets `left: %` from dateToFrac(0); CSS keeps it
   1px wide and slightly taller than the track so it reads as a tick. */
.forge-scrub-year-zero {
  position: absolute;
  top: 50%;
  width: 1px;
  height: 10px;
  margin-left: 0;
  margin-top: -5px;
  background: var(--text-3, #6b7280);
  opacity: 0.45;
  pointer-events: none;
  z-index: 0;
}
.forge-scrub-thumb {
  position: absolute;
  top: 50%;
  width: 8px;
  height: 12px;
  margin-left: -4px;
  margin-top: -6px;
  background: var(--gold-soft, #8a7430);
  border-radius: 1px;
  cursor: ew-resize;
  touch-action: none;
}
.forge-scrub-thumb:hover { background: var(--gold, #d4a55a); }
.forge-scrub-center-thumb {
  /* Playhead: a slimmer brighter needle. */
  width: 2px;
  height: 14px;
  margin-left: -1px;
  margin-top: -7px;
  background: var(--gold, #d4a55a);
  cursor: grab;
  border-radius: 0;
}
.forge-scrub-center-thumb:active { cursor: grabbing; }

/* ============================================================
   Phase 13 (2026-05-21) — wire color LEGEND
   ============================================================
   - Wrapper: position-relative parent so the panel anchors to
     the button.
   - Button: same height as the zoom-gizmo and scrub-boxes.
   - Panel: absolutely positioned above the button.
   - Tooltip: secondary explainer popup; positioned by JS to the
     right of the panel; one persistent element, content swaps.
   ============================================================ */
.forge-legend-wrap {
  position: relative;
  flex: 0 0 auto;
  pointer-events: auto;
}
.forge-legend-btn {
  pointer-events: auto;
  background: rgba(13, 17, 25, 0.85);
  color: var(--text-2);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.08em;
  border: 1px solid var(--border, #2a2e3a);
  border-radius: 4px;
  padding: 5px 10px;
  flex: 0 0 auto;
  width: 80px;
  text-align: center;
  white-space: nowrap;
  box-sizing: border-box;
  cursor: pointer;
}
.forge-legend-btn:hover { border-color: var(--gold-soft, #8a7430); color: var(--gold, #d4a55a); }
.forge-legend-btn[aria-expanded="true"] {
  border-color: var(--gold, #d4a55a);
  color: var(--gold, #d4a55a);
}
.forge-legend-panel {
  /* Position above the LEGEND button. JS handles open/close via
     `display`; CSS handles the visual styling. */
  position: absolute;
  bottom: 100%;
  left: 0;
  margin-bottom: 6px;
  background: rgba(13, 17, 25, 0.95);
  border: 1px solid var(--border, #2a2e3a);
  border-radius: 4px;
  padding: 6px 0;
  min-width: 180px;
  box-sizing: border-box;
  z-index: 50;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
}
.forge-legend-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 12px;
  color: var(--text-2);
  cursor: default;
}
.forge-legend-row:hover { background: rgba(212, 165, 90, 0.08); color: var(--text-1, #e5e7eb); }
.forge-legend-swatch {
  display: inline-block;
  width: 14px;
  height: 4px;
  border-radius: 1px;
  flex: 0 0 auto;
}
.forge-legend-name { letter-spacing: 0.04em; }
/* Phase 21AT (2026-05-23) — legend sub-sections (Wire color +
   Source tier) inside the same legend panel. Section caption is
   uppercase mono-small (mirrors the view-settings section style)
   so the two panels share vocabulary. */
.forge-legend-section {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-3, #6b7280);
  padding: 8px 14px 4px;
}
.forge-legend-divider {
  height: 1px;
  margin: 6px 12px 2px;
  background: rgba(212,165,90,0.10);
}
/* Source-tier row — the "swatch" is actually the pill (T1..T5 with
   its color); override the 14×4 bar look so the pill paints its
   own background + text. The pill uses .vs-tier-pill styling so the
   legend reads as the same vocabulary as the side-panel + view-
   settings panels. */
.forge-legend-row--tier .forge-legend-swatch {
  width: auto;
  height: auto;
  padding: 1px 5px;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  font-weight: 600;
  line-height: 1.1;
  border-radius: 3px;
  min-width: 22px;
  text-align: center;
}
/* Phase 21AY (2026-05-23) — interactive toggle rows in the legend.
   Same vocabulary as VIEW's checkbox rows: 14×14 square box that
   fills gold when ON. Buttons reset (no default browser chrome). */
.forge-legend-row--toggle {
  width: 100%;
  background: transparent;
  border: 0;
  text-align: left;
  font: inherit;
  cursor: pointer;
}
.forge-legend-row--toggle .vs-check {
  display: inline-block;
  width: 14px; height: 14px;
  border-radius: 3px;
  border: 1px solid rgba(212,165,90,0.55);
  background: transparent;
  position: relative;
  flex: 0 0 auto;
  transition: background 100ms ease, border-color 100ms ease;
}
.forge-legend-row--toggle.is-on .vs-check {
  background: var(--gold, #d4a55a);
  border-color: var(--gold, #d4a55a);
}
.forge-legend-row--toggle.is-on { color: var(--gold-1, #e8c889); }

/* Phase 22-E (2026-05-24) — keyboard focus state on app-pill menu
   items. Both `:focus` (native browser focus ring) and `.is-focused`
   (JS-added when arrow keys cycle) light up the same gold accent.
   Same hover treatment as the existing nav-hub items. */
.app-pill-menu-item:focus,
.app-pill-menu-item.is-focused {
  outline: none;
  background: rgba(212,165,90,0.14);
  color: var(--gold-1, #e8c889);
}
.app-pill-menu-item:focus .app-pill-menu-icon,
.app-pill-menu-item.is-focused .app-pill-menu-icon {
  color: var(--gold, #d4a55a);
}

/* Political-risk row in the legend — same ⛔ BLACK ALERT vocabulary
   as the side-panel BLACK ALERT chrome. Red top border, ⛔ icon with
   red glow, stronger background tint. */
.forge-legend-row--black-alert {
  border-top: 2px solid rgba(226,91,91,0.65);
  margin-top: 4px;
  background: rgba(226,91,91,0.05);
}
.forge-legend-row--black-alert:hover { background: rgba(226,91,91,0.12); }
.forge-legend-row--black-alert.is-on {
  background: rgba(226,91,91,0.18);
  color: #ffd5d5;
}
.forge-legend-row--black-alert.is-on .vs-check {
  background: #e25b5b;
  border-color: #e25b5b;
}
.forge-legend-row--black-alert .vs-alert-badge {
  font-size: 13px;
  color: #e25b5b;
  text-shadow: 0 0 4px rgba(226,91,91,0.45);
  min-width: 22px;
  text-align: center;
}
.forge-legend-tooltip {
  position: fixed;
  max-width: 280px;
  background: rgba(13, 17, 25, 0.97);
  border: 1px solid var(--border, #2a2e3a);
  border-radius: 4px;
  padding: 8px 12px;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-2);
  z-index: 60;
  pointer-events: none;
  letter-spacing: 0.02em;
}

/* ============================================================
   Phase 14 (2026-05-21) — hover thumbnail CARD
   ============================================================
   Floating card next to the cursor on node hover. Position is
   updated via transform (no left/top thrash). Initial styling is
   scaffolding — iterate after live review.
   ============================================================ */
.forge-hover-card {
  position: fixed;
  top: 0;
  left: 0;
  pointer-events: none;
  width: 220px;
  /* Phase 21AC (2026-05-22) — clamp the card height to the viewport
     so the position-flip logic never has the "neither up nor down
     fits" case that produced the flicker. With max-height set, every
     anchor quadrant always has room; pickAnchor lands stable. */
  max-height: calc(100vh - 24px);
  background: rgba(13, 17, 25, 0.95);
  border: 1px solid var(--border, #2a2e3a);
  border-radius: 4px;
  overflow: hidden;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  z-index: 70;
  will-change: transform, opacity;
  display: flex;
  flex-direction: column;
  /* Phase 24-PRIMITIVE-FIX (2026-05-26): opacity-fade replaces
     display:flex/none toggle so hover-release animates smoothly
     instead of vanishing instantly. Hidden state still has
     pointer-events:none so it can't intercept clicks. */
  opacity: 0;
  transition: opacity 0.14s ease-out;
}
.forge-hover-card.is-shown { opacity: 1; }
.forge-hover-card-thumb {
  width: 100%;
  height: 140px;
  flex: 0 0 140px;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.forge-hover-card-thumb img {
  /* Phase 17B (2026-05-21) — was `display: none` here with JS
     setting `style.display = ''` to reveal. Bug: empty string
     REMOVES the inline override, so CSS `display:none` wins
     again and the image stays hidden. JS now controls display
     explicitly with 'block' / 'none' — leave CSS unspecified
     so it falls back to the user-agent default (inline). */
  max-width: 100%;
  max-height: 100%;
  object-fit: cover;
  width: 100%;
  height: 100%;
}
.forge-hover-card-body {
  padding: 8px 12px;
  /* Phase 21AC — the body takes the remaining vertical space and
     scrolls internally if a node's content overflows. Keeps the
     overall card height stable (= thumb 140 + body ≤ remaining
     viewport - 24 px margin) which is the precondition for the
     stable anchor-quadrant decision. */
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
}
.forge-hover-card-name {
  font-size: 13px;
  color: var(--text-1, #e5e7eb);
  letter-spacing: 0.02em;
}
/* Tradition title (formerly `forge-hover-card-type`). Small caps,
   acts as the "religion title" line just under the name. */
.forge-hover-card-tradition {
  font-size: 10px;
  color: var(--text-3, #6b7280);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-top: 2px;
}
/* Brief description / catchy role (Phase 15). */
.forge-hover-card-desc {
  font-size: 11px;
  color: var(--text-2, #b5b9c5);
  letter-spacing: 0.02em;
  line-height: 1.35;
  margin-top: 8px;
  font-style: italic;
}
/* Connection-counts row — one colored pill per wire bucket. */
/* Side-panel wire rows — Phase 19D upgrade.
   Each wire bucket is now a <details> block: clicking the summary
   expands a list of connected deity titles. Clicking a name in
   the list locks-and-switches the panel to that deity. */
.forge-side-panel-wires {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 10px 0 14px;
}
details.forge-side-panel-wire {
  background: rgba(0, 0, 0, 0.18);
  border: 1px solid var(--border, #2a2e3a);
  border-left: 2px solid var(--bucket-color, #888);
  border-radius: 3px;
}
details.forge-side-panel-wire[open] {
  background: rgba(0, 0, 0, 0.28);
}
.forge-side-panel-wire-summary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  cursor: pointer;
  list-style: none;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--bucket-color, #888);
}
.forge-side-panel-wire-summary::-webkit-details-marker { display: none; }
.forge-side-panel-wire-count {
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}
.forge-side-panel-wire-name {
  font-style: normal;
  color: var(--text-3, #6b7280);
  text-transform: lowercase;
  font-size: 10px;
  letter-spacing: 0.06em;
}
.forge-side-panel-wire-caret {
  margin-left: auto;
  color: var(--text-3, #6b7280);
  font-size: 10px;
  transition: transform 0.15s ease;
}
details.forge-side-panel-wire[open] .forge-side-panel-wire-caret {
  transform: rotate(180deg);
}
.forge-side-panel-wire-list {
  padding: 4px 6px 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* Phase 22-AF (2026-05-24) — belt-and-braces overflow guard.
     John has flagged the right-hand overflow N times. The title's
     ellipsis CSS was already there but wasn't firing because the
     <details> + <div class="...wire-list"> parents weren't
     enforcing horizontal containment. With `min-width: 0` they
     can collapse below their content-size, which is the precondition
     for the flex children (the wire-items) to actually clip. */
  min-width: 0;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  overflow-x: hidden;
}
.forge-side-panel-wire {
  min-width: 0;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  overflow-x: hidden;
}
.forge-side-panel-wire-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  /* Phase 21AU (2026-05-23) — min-width:0 on the flex container so
     a long child title can shrink past its content size, which is
     what allows the title's text-overflow: ellipsis to fire BEFORE
     the trailing tier badge gets pushed past the panel right edge.
     Without this, items with long names like "Enki (Sumerian) / Ea
     (Akkadian)" overflowed the panel and the T1 badge was clipped. */
  min-width: 0;
  background: transparent;
  border: 0;
  padding: 4px 6px;
  text-align: left;
  color: var(--text-2, #b5b9c5);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.02em;
  cursor: pointer;
  border-radius: 2px;
  transition: background 0.12s ease, color 0.12s ease;
}
.forge-side-panel-wire-item:hover {
  background: rgba(212, 165, 90, 0.08);
  color: var(--text-1, #e5e7eb);
}
.forge-side-panel-wire-item-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex: 0 0 auto;
}
.forge-side-panel-wire-item-title {
  /* Phase 22-AF (2026-05-24) — `flex: 1 1 0` (not 1 1 auto) so the
     basis is 0 and the title can shrink all the way down to the
     ellipsis without being pushed by content-size. Same trick as
     the canonical "ellipsis inside flex" pattern. min-width: 0
     stays as the precondition. */
  flex: 1 1 0;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Phase 21AS (2026-05-23) — disclaimer-machine chrome inside the
   wire-item row. Tier pill sits AFTER the title (so the name
   reads first; the tier is a small trailing badge). ⚠ marker
   for T5 / political-risk edges sits BEFORE the title so the
   warning lands in the reader's eye before the claim. */
.forge-side-panel-wire-item-tier {
  flex: 0 0 auto;
  font-size: 8px;
  padding: 1px 4px;
  margin-left: 4px;
  letter-spacing: 0.04em;
}
.forge-side-panel-wire-item-warn {
  flex: 0 0 auto;
  color: #e25b5b;
  font-size: 10px;
  line-height: 1;
  margin-right: 2px;
}
.forge-side-panel-wire-item.is-risky {
  background: rgba(226,91,91,0.04);
}
.forge-side-panel-wire-item.is-risky:hover {
  background: rgba(226,91,91,0.10);
}
/* Phase 21AX (2026-05-23) — CODEX v1.2 — ⛔ BLACK ALERT row chrome.
   The political-risk-flag is ORTHOGONAL to the tier system; this
   class fires on `political_risk_flag: true` regardless of tier.
   Visual escalation co-equal with the soft .is-risky treatment:
   - 4px BLACK left border (high-contrast at scan-level)
   - Stronger red row background (full opacity, not faint)
   - Black ⛔ icon coloring with red glow
   Both .is-risky AND .is-black-alert can co-occur (e.g. Icke is
   both T5 and political-risk); the rules cascade — .is-black-alert
   wins the visual conflict because it's the higher-severity axis. */
.forge-side-panel-wire-item.is-black-alert {
  border-left: 4px solid #000;
  background: rgba(226,91,91,0.10);
  padding-left: 3px;     /* offset the 4px border so content doesn't shift */
}
.forge-side-panel-wire-item.is-black-alert:hover {
  background: rgba(226,91,91,0.20);
}
.forge-side-panel-wire-item-warn--alert {
  color: #000 !important;
  background: #e25b5b;
  border-radius: 2px;
  padding: 1px 3px;
  margin-right: 4px;
  font-weight: 700;
}
/* Phase 21AV (2026-05-23) — cross-folder neighbor row. The
   target is NOT a deity (theme/event/person/etc.) so the row
   isn't clickable on the wheel. Tiny subtype tag after the
   title; the title itself dims slightly to read as secondary;
   cursor flips to default so users don't expect a click. */
.forge-side-panel-wire-item.is-cross-folder {
  cursor: default;
}
.forge-side-panel-wire-item.is-cross-folder .forge-side-panel-wire-item-title {
  color: var(--text-3, #6b7280);
  font-style: italic;
}
.forge-side-panel-wire-item.is-cross-folder:hover {
  background: rgba(255,255,255,0.025);
}
.forge-side-panel-wire-item-subtype {
  flex: 0 0 auto;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 8px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-3, #6b7280);
  padding: 1px 4px;
  margin-left: 4px;
  border-radius: 2px;
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.08);
}

/* ═══════════════════════════════════════════════════════════════
   Phase 21AU (2026-05-23) — Side-panel connection tooltip
   ═══════════════════════════════════════════════════════════════
   Custom tooltip that fires on side-panel connection-row hover
   after a 500ms dwell. Replaces the OS-native title="" tooltip
   (~1.5s delay, ugly OS chrome). Same dark-glass aesthetic as
   the legend tooltip + the hover card. Lives in document.body
   so it can escape the side panel's overflow-hidden clip.
   ═══════════════════════════════════════════════════════════════ */
.forge-side-tip {
  position: fixed;
  z-index: 280;
  max-width: 320px;
  min-width: 200px;
  background: rgba(13, 17, 25, 0.97);
  border: 1px solid var(--border, #2a2e3a);
  border-radius: 6px;
  padding: 8px 10px;
  box-shadow: 0 6px 24px rgba(0,0,0,0.55);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: var(--text-1, #e5e7eb);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  line-height: 1.45;
  letter-spacing: 0.02em;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.12s ease;
  pointer-events: none;
}
.forge-side-tip.is-visible {
  opacity: 1;
  visibility: visible;
}
/* Risky tier — red top border accent so the disclaimer is visually
   pre-announced even before the user reads the caveat. */
.forge-side-tip[data-risky="1"] {
  border-top: 2px solid #e25b5b;
  padding-top: 7px;
}
/* Phase 21AX (2026-05-23) — CODEX v1.2 — political-risk-flag BLACK
   ALERT escalation. Stronger visual treatment than tier-only T5:
   3px BLACK top border (not red), red-tinted background, the body
   leads with the political-risk caveat (handled JS-side). */
.forge-side-tip[data-alert="1"] {
  border-top: 3px solid #000;
  border-left: 3px solid #e25b5b;
  background: rgba(38, 14, 14, 0.97);
  padding-top: 7px;
  padding-left: 9px;
}
.forge-side-tip-risk--alert {
  color: #000 !important;
  background: #e25b5b;
  padding: 4px 6px !important;
  border-radius: 3px;
  margin: -2px -4px 6px -4px !important;
  border-bottom: none !important;
  font-weight: 700 !important;
  letter-spacing: 0.05em !important;
}
.forge-side-tip-risk {
  color: #e25b5b;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 6px;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(226,91,91,0.20);
}
.forge-side-tip-head {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
}
.forge-side-tip-dir {
  color: var(--text-3, #6b7280);
  font-size: 12px;
  flex: 0 0 auto;
}
.forge-side-tip-title {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 600;
  color: var(--gold-1, #e8c889);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.forge-side-tip-row {
  display: flex;
  gap: 8px;
  padding: 2px 0;
  font-size: 10.5px;
}
.forge-side-tip-row .k {
  color: var(--text-3, #6b7280);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 9px;
  min-width: 48px;
  flex: 0 0 auto;
  padding-top: 2px;
}
.forge-side-tip-row .v {
  color: var(--text-2, #b5b9c5);
  flex: 1 1 auto;
  word-break: break-word;
}
.forge-side-tip-notes {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--border, #2a2e3a);
  color: var(--text-2, #b5b9c5);
  font-size: 10.5px;
  font-style: italic;
  font-family: var(--sans, Inter, sans-serif);
  letter-spacing: 0;
  line-height: 1.5;
}
.forge-side-tip-hint {
  margin-top: 8px;
  padding-top: 6px;
  border-top: 1px dashed rgba(255,255,255,0.06);
  color: var(--text-3, #6b7280);
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.10em;
}
/* Phase 21A2 (2026-05-21) — direction arrow LEADS the row per
   John's spec: `[arrow] [color-dot] [name…]`. The arrow now
   sits to the LEFT of the dot, not as a right-trailing
   annotation. The name truncates with an ellipsis so long
   titles never cause horizontal scroll. */
.forge-side-panel-wire-item-dir {
  color: var(--text-3, #6b7280);
  font-size: 11px;
  flex: 0 0 auto;
  margin-left: 0;
  opacity: 0.7;
  min-width: 12px; text-align: center;
}
/* Whole right-side panel must never scroll horizontally — long
   titles, families, dates etc. are truncated at the container
   edge with an ellipsis. */
aside.detail, aside.detail * { max-width: 100%; }
aside.detail { overflow-x: hidden; }

/* Legacy hover-card wires (smaller, simpler — keep the pill style). */
.forge-hover-card-wires {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}
.forge-hover-card-wire {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}
.forge-hover-card-wire-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
}
/* Meta rows — Date, Place. Each is a key on the left + value. */
.forge-hover-card-meta {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.forge-hover-card-meta-row {
  display: flex;
  gap: 8px;
  font-size: 11px;
  color: var(--text-2, #b5b9c5);
  letter-spacing: 0.02em;
}
.forge-hover-card-meta-k {
  flex: 0 0 36px;
  color: var(--text-3, #6b7280);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 10px;
}
.forge-hover-card-meta-v {
  flex: 1 1 auto;
}

/* ============================================================
   Phase 19C (2026-05-21) — Forge deity-inspector with TAB STACK
   ============================================================
   - In Forge view, the global aside.detail is HIDDEN ENTIRELY
     when no deity is locked (no negative empty space).
   - Per-lock floating buttons (.forge-deity-tab) stack at the
     right viewport edge. Clicking one opens the panel for that
     deity; clicking the active one closes it; toggleLock(null)
     clears them all.
   - When the panel is open, the tab column shifts left by the
     panel width so the buttons stay OUTSIDE the panel.
   - Global .detail-toggle is hidden in Forge view (we don't use
     it — our tabs are the way).
   ============================================================ */
/* 2026-06-10 (INCIDENT §4) — the forge-scoped panel hides that lived
   here since Phase 19D/E are DELETED: their behavior (collapsed panel
   fully hidden + zero layout reservation) is now the UNIVERSAL rule
   for every view (see the aside.detail block ~2272). Keeping them
   per-view was the rule-#8 violation that masked the V01 rail on
   ATLAS while every other view exposed it. */

/* Tab stack — fixed at right viewport edge. Shifts left when the
   panel is open so the tabs sit OUTSIDE the panel. */
.forge-deity-tabs {
  position: fixed;
  top: 65px;
  right: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  z-index: 160;             /* above aside.detail (z=150) */
  pointer-events: none;     /* children re-enable */
  transition: right 0.18s ease-out;
}
.forge-deity-tabs.panel-open {
  right: var(--detail-w, 360px);
}
.forge-deity-tab {
  pointer-events: auto;
  width: 28px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  background: rgba(13, 17, 25, 0.92);
  border: 1px solid var(--border, #2a2e3a);
  border-right: 0;
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;
  color: var(--text-2);
  cursor: pointer;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 13px;
  transition: color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
  padding: 0;
}
.forge-deity-tab:hover {
  color: var(--gold, #d4a55a);
  border-color: var(--gold-soft, #8a7430);
}
.forge-deity-tab.is-active {
  color: var(--gold, #d4a55a);
  border-color: var(--gold, #d4a55a);
  background: rgba(13, 17, 25, 0.98);
}
.forge-deity-tab-chevron {
  font-size: 13px;
  line-height: 1;
}
.forge-deity-tab-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: 0 0 auto;
}
/* Phase 19E (2026-05-21) — when the panel is open, the chevron
   is redundant (the panel itself is the open-state indicator).
   Hide chevrons across the WHOLE tab column when .panel-open is
   set, so tabs read as a clean column of color dots. */
/* Phase 21M (2026-05-21) — when the side panel is open, ALL
   tabs keep the SAME WIDTH. Inactive tabs hide their chevron
   via `visibility: hidden` so the column reads as a clean
   stack of equal-sized pills (the chevron's pixel slot is
   still reserved). Active tab keeps a visible chevron so the
   user knows which tab the panel is showing. */
.forge-deity-tabs.panel-open .forge-deity-tab:not(.is-active) .forge-deity-tab-chevron {
  visibility: hidden;
}

/* Pulse animation — added briefly when a new tab is added. */
@keyframes forge-side-panel-pulse {
  0%   { box-shadow: 0 0 0 0   rgba(212, 165, 90, 0.55); }
  50%  { box-shadow: 0 0 0 8px rgba(212, 165, 90, 0.00); }
  100% { box-shadow: 0 0 0 0   rgba(212, 165, 90, 0.00); }
}
.forge-deity-tab.pulsing {
  animation: forge-side-panel-pulse 1.2s ease-out 2;
  color: var(--gold, #d4a55a);
  border-color: var(--gold, #d4a55a);
}

/* Forge content wrapper inside #detail-inner. */
.forge-side-panel-content {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
}
/* 2026-06-10 (INCIDENT §4) — the Phase-19E forge-scoped #detail-inner
   padding override is DELETED: its reason (clearing the V01 chevron's
   38px left gutter) died with the chevron. The base .detail-inner is
   now symmetric for every view. */
.forge-side-panel-aka {
  font-size: 11px;
  color: var(--text-3, #6b7280);
  letter-spacing: 0.04em;
  font-style: italic;
  margin-top: 4px;
}
/* Phase 21X (2026-05-22) — multi-image carousel. Arrows + meta
   strip show only when has-carousel (length > 1) is set on the
   container. Layout: image fills the box; arrows sit absolutely
   on the left + right edges, vertically centered; meta strip
   sits absolutely at the bottom with a gradient backdrop so the
   text reads over the image.
   Phase 21AC (2026-05-22) — square aspect (height matches width
   via aspect-ratio) per John's directive. */
.forge-side-panel-thumb {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  margin-bottom: 14px;
  background: rgba(0, 0, 0, 0.4);
  border-radius: 4px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.forge-side-panel-thumb img {
  max-width: 100%;
  max-height: 100%;
  object-fit: cover;
  width: 100%;
  height: 100%;
}
.forge-side-panel-thumb-prev,
.forge-side-panel-thumb-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 32px; height: 56px;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  border: 0;
  border-radius: 3px;
  font-size: 22px;
  font-family: var(--mono, monospace);
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.18s ease-out, background 0.18s ease-out;
  z-index: 2;
}
.forge-side-panel-thumb-prev { left:  4px; }
.forge-side-panel-thumb-next { right: 4px; }
.forge-side-panel-thumb:hover .forge-side-panel-thumb-prev,
.forge-side-panel-thumb:hover .forge-side-panel-thumb-next {
  opacity: 0.85;
}
.forge-side-panel-thumb-prev:hover,
.forge-side-panel-thumb-next:hover {
  background: rgba(0, 0, 0, 0.70);
  opacity: 1 !important;
}
.forge-side-panel-thumb-meta {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 18px 10px 6px;
  background: linear-gradient(to top, rgba(0,0,0,0.78) 0%, rgba(0,0,0,0.50) 60%, rgba(0,0,0,0) 100%);
  color: var(--text-1, #e5e7eb);
  font-family: var(--sans, Inter, sans-serif);
  font-size: 11px;
  line-height: 1.35;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  gap: 1px;
  z-index: 1;
}
.forge-side-panel-thumb-caption {
  /* Single line, ellipsis if too long. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.forge-side-panel-thumb-attribution {
  color: var(--text-3, #6b7280);
  font-size: 10px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.forge-side-panel-thumb-index {
  color: var(--gold, #d4a55a);
  font-family: var(--mono, monospace);
  font-size: 10px;
  letter-spacing: 0.08em;
  align-self: flex-end;
  margin-top: 2px;
}
.forge-side-panel-header {
  margin-bottom: 10px;
}
.forge-side-panel-name {
  /* Phase 21AC (2026-05-22) — match the canvas node-label font:
     same family + weight + letter-spacing as `.forge-label`. Only
     the size differs (this is a heading, those are inline labels). */
  font-family: var(--forge-font-label, var(--sans));
  font-weight: 500;
  letter-spacing: 0.01em;
  font-size: 18px;
  color: var(--text-0, #f1ede2);
}
.forge-side-panel-tradition {
  font-size: 10px;
  color: var(--text-3, #6b7280);
  letter-spacing: 0.10em;
  text-transform: uppercase;
  margin-top: 4px;
}
.forge-side-panel-desc {
  font-size: 12px;
  color: var(--text-2, #b5b9c5);
  line-height: 1.45;
  margin: 0 0 12px;
  font-style: italic;
}
.forge-side-panel-wires {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 10px 0 14px;
}
.forge-side-panel-wire {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}
.forge-side-panel-wire em {
  font-style: normal;
  color: var(--text-3, #6b7280);
  text-transform: lowercase;
  font-size: 10px;
  letter-spacing: 0.06em;
}
.forge-side-panel-wire-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
}
/* ── Classification provenance (2026-06-02 — John's explicit-why-we-
   categorize directive). Generic over any controlled-vocab field
   surfaced by build_data.py via classification_provenance. Each
   field renders as: label + chips with [tier] badges + visible
   source citation below + (if contested) ⚖ rationale. */
.forge-side-panel-provenance {
  margin: 12px 0;
  padding: 10px 12px;
  border-left: 2px solid var(--family-color, #888);
  background: rgba(255, 255, 255, 0.02);
  border-radius: 0 4px 4px 0;
  font-size: 11px;
}
.forge-side-panel-provenance-label {
  color: var(--text-3, #6b7280);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 9.5px;
  margin-bottom: 6px;
}
.forge-side-panel-provenance-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 6px;
}
/* One row per classification: chip + its own source citation, so the
   chip→source mapping is explicit. 2026-06-02. */
.forge-side-panel-provenance-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 5px;
  flex-wrap: wrap;
}
.forge-side-panel-provenance-row-source {
  font-size: 10px;
  color: var(--text-2, #b5b9c5);
  line-height: 1.4;
  opacity: 0.8;
  flex: 1 1 auto;
  min-width: 0;
}
.forge-side-panel-provenance-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 7px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 3px;
  font-size: 10.5px;
  color: var(--text-1, #d8dbe2);
  /* No cursor:help — the source citation is shown visibly below the
     chips (the ↳ lines), so there's no hidden tooltip to advertise.
     2026-06-02 per John: "why the ? on the cursor that dont show
     anything?" — removed the false-promise cursor. */
}
.forge-side-panel-provenance-chip-tier {
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 1px 4px;
  border-radius: 2px;
  background: rgba(120, 200, 140, 0.18);
  color: #8fd9a8;
}
.forge-side-panel-provenance-chip[data-tier="T2"] .forge-side-panel-provenance-chip-tier {
  background: rgba(200, 180, 100, 0.18);
  color: #e0c878;
}
.forge-side-panel-provenance-chip[data-tier="T3"] .forge-side-panel-provenance-chip-tier {
  background: rgba(220, 140, 80, 0.18);
  color: #e0b078;
}
.forge-side-panel-provenance-chip[data-tier="T4"] .forge-side-panel-provenance-chip-tier {
  background: rgba(220, 90, 90, 0.20);
  color: #e09090;
}
.forge-side-panel-provenance-source {
  color: var(--text-2, #b5b9c5);
  font-size: 10px;
  line-height: 1.4;
  padding: 1px 0 1px 4px;
  opacity: 0.85;
}
.forge-side-panel-provenance-rationale-wrap {
  margin-top: 6px;
}
.forge-side-panel-provenance-rationale-summary {
  cursor: pointer;
  font-size: 10px;
  color: var(--text-3, #6b7280);
  letter-spacing: 0.02em;
  padding: 3px 4px;
  list-style: none;
  user-select: none;
  transition: color 0.15s;
}
.forge-side-panel-provenance-rationale-summary::-webkit-details-marker { display: none; }
.forge-side-panel-provenance-rationale-summary:hover {
  color: var(--text-2, #b5b9c5);
}
.forge-side-panel-provenance-rationale-summary-hint {
  opacity: 0.7;
  font-style: italic;
}
.forge-side-panel-provenance-rationale {
  margin-top: 4px;
  padding: 6px 8px;
  background: rgba(200, 180, 100, 0.05);
  border-left: 2px solid rgba(200, 180, 100, 0.30);
  font-size: 10.5px;
  color: var(--text-2, #b5b9c5);
  line-height: 1.45;
  font-style: italic;
}
.forge-side-panel-provenance--polemical-framing {
  border-left-color: #c4783a;
  background: rgba(196, 120, 58, 0.05);
}
.forge-side-panel-provenance--reclaimed-self-naming {
  border-left-color: #9a7ac4;
  background: rgba(154, 122, 196, 0.05);
}

.forge-side-panel-meta {
  margin: 14px 0;
  display: grid;
  grid-template-columns: 60px 1fr;
  gap: 4px 12px;
  font-size: 11px;
  color: var(--text-2, #b5b9c5);
  letter-spacing: 0.02em;
}
.forge-side-panel-meta dt {
  color: var(--text-3, #6b7280);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 10px;
}
.forge-side-panel-meta dd {
  margin: 0;
}
.forge-side-panel-extract {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border, #2a2e3a);
  font-size: 11px;
  color: var(--text-2, #b5b9c5);
  line-height: 1.5;
}
.forge-side-panel-wikilink {
  display: inline-block;
  margin-top: 14px;
  font-size: 11px;
  color: var(--gold, #d4a55a);
  text-decoration: none;
  letter-spacing: 0.04em;
}
.forge-side-panel-wikilink:hover {
  color: var(--text-1, #e5e7eb);
}
/* Atlas Codex step 5 (2026-05-28) — Open-in-reader CTA for any
   locked doc node whose docNode is claimed by a SCRIPTURE_TEXTS
   entry. More prominent than the inline wikilink because it's
   the primary scripture action; matches the gold-border-on-hover
   chrome of .forge-debug-pin-btn. */
.forge-side-panel-read-btn {
  appearance: none;
  display: block;
  margin-top: 14px;
  padding: 7px 14px;
  background: rgba(212,165,90,0.08);
  border: 1px solid rgba(212,165,90,0.34);
  border-radius: 4px;
  color: var(--gold, #d4a55a);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.forge-side-panel-read-btn:hover {
  background: rgba(212,165,90,0.16);
  border-color: var(--gold, #d4a55a);
  color: var(--gold-1, #e8c889);
}

.forge-stage {
  flex: 1 1 auto;
  position: relative;
  overflow: hidden;
  /* Subtle radial atmosphere so an isolated disk doesn't look like
     it's floating in a void. Pure decoration; the canvas paints on top.
     Phase 6: backdrop is a CSS var (--forge-bg) so the dev panel
     can dial it. Atmosphere strength is also a var. */
  background:
    radial-gradient(ellipse at center,
      rgba(212, 165, 90, calc(var(--forge-atmosphere, 0.025) * 1)) 0%,
      transparent 70%),
    var(--forge-bg, var(--bg-0));
}
.forge-canvas {
  display: block;
  position: absolute;
  inset: 0;
  /* Canvas is a replaced element — without explicit width/height
     it falls back to its intrinsic 300×150 default even with
     inset:0. Pin to 100% so the resize loop's style.width / .height
     overrides can take over once the renderer is up. */
  width: 100%;
  height: 100%;
  /* Interaction affordances. Default arrow at rest (design-app
     feel — the wheel is the subject, not a clickable region);
     `grabbing` shows up only while a drag is in flight, gated by
     the `.is-panning` class the view module toggles. No native
     touch gestures (we own zoom via wheel). */
  cursor: default;
  touch-action: none;
}
.forge-canvas.is-panning { cursor: grabbing; }
.forge-canvas.is-hover-node { cursor: pointer; }

/* Phase 4e — Type-shape glyph overlay.
   One <span> per node, containing an inline <svg> that draws the
   type-shape primitive (◉ deity / ❡ document / ✦ symbol / etc).
   Sized to the disk diameter; positioned over the WebGPU canvas.
   pointer-events: none so it never blocks hover hit-testing on
   the canvas. The SVG `currentColor` is driven by the wrapper
   span's `color` style (set inline at rebuild time to a lighter
   hue of the family color). */
/* 2026-05-20 — DOM glyph overlay retired. Glyphs are now drawn
   in the WebGPU canvas via a texture-atlas instanced quad pass.
   The .forge-glyph CSS rules are gone with the DOM elements. */

/* Phase 4b — Labels overlay.
   DOM <div>s positioned over the canvas. Pointer-events: none so
   the overlay never intercepts cursor → canvas hit-testing. Label
   visibility is JS-driven (focused nodes only); positions are
   sync'd to GPU positions via camera.worldToScreen each frame. */
/* Phase 20 (2026-05-21) — family hulls overlay.
   SVG sits above the canvas, below the labels overlay, so:
     canvas (z-auto) < hulls (z=3) < labels (z=5) < bottom-bar.
   Hulls + labels both pointer-events:none so they never
   intercept hover.
   --family-color is set per group from JS (node.family_color). */
/* Phase 21G (2026-05-21) — BG is now a WORLD OBJECT. Its size
   in world units is declared as a JS constant (BG_WORLD_WIDTH);
   JS sets width / height in pixels each tick = BG_WORLD_WIDTH ×
   camera.scale. The image lives in the same coordinate system
   as the wheel, so it pans + zooms with the wheel automatically.
   CSS only owns the static layer state — fixed positioning at
   the viewport's top-left (JS centres via translate(-50%, -50%)). */
.forge-bg-image {
  position: fixed;
  top: 50%; left: 50%;
  transform-origin: 50% 50%;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  opacity: 0;
  /* Phase 24-PRIMITIVE-FIX (2026-05-26) — width/height removed from
     will-change because they're no longer animated; we use transform:
     scale() instead so all per-frame motion stays on the GPU
     compositor (zero browser layout). */
  will-change: opacity, transform;
}
.forge-hulls-overlay {
  position: absolute; inset: 0;
  pointer-events: none;
  z-index: 3;
  transition: opacity 0.18s ease-out;
  /* CSS opacity (JS sets element.style.opacity per frame for the
     zoom fade); the transition is for the fade-on-fade only. */
}
.forge-hull-poly {
  fill: var(--family-color, #888);
  fill-opacity: 0.05;
  stroke: var(--family-color, #888);
  stroke-opacity: 0.32;
  stroke-width: 1.25;
  stroke-linejoin: round;
}
.forge-hull-label-g {
  /* Wraps a single text element; inherits --family-color. */
}
.forge-hull-label {
  fill: var(--family-color, #888);
  fill-opacity: 0.85;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  /* Phase 20B (2026-05-21) — labels now sit OUTSIDE the wheel rim
     so the cluttered node cloud no longer overlaps them. The
     stroke halo is still helpful for separators / dividers
     crossing the label area. */
  paint-order: stroke fill;
  stroke: rgba(0, 0, 0, 0.7);
  stroke-width: 3px;
  stroke-linejoin: round;
}
/* Phase 20B (2026-05-21) — radial separator lines between adjacent
   families. Drawn at the angular bisector between two families'
   centroids, overshooting both the inner and outer ring radii by
   50 px. The fade across the line endpoints is handled by a
   per-line linearGradient in JS (it sets the gradient endpoint
   coords to match the line, so 0→15% and 85→100% become the soft
   tails on either end). */
.forge-hull-divider {
  /* Phase 21AK (2026-05-23) — width + opacity now driven by the
     Style panel vars so they update live. The `stroke` attribute
     is still set to url(#forge-hull-divgrad-N) in JS (gradient
     reference). The `opacity` here multiplies the gradient alpha,
     giving us a single dimming control without rewriting stops. */
  stroke-width: var(--style-sep-width, 0.5);
  opacity: var(--style-sep-opacity, 1.0);
  fill: none;
}

.forge-labels-overlay {
  position: absolute; inset: 0;
  pointer-events: none;
  /* Above the canvas, below any future toolbar/status chrome. */
  z-index: 5;
}
.forge-label {
  position: absolute;
  /* Phase 24-PRIMITIVE-FIX (2026-05-26): syncLabelPositions writes
     the FULL transform inline (translate3d for GPU compositing
     + the -50%/-100% centering composed). */
  top: 0;
  left: 0;
  font-family: var(--forge-font-label, var(--sans));
  font-size: var(--forge-label-size, 11px);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--forge-label-text, var(--text-0));
  white-space: nowrap;
  /* SAFARI-WORKAROUND (2026-05-26): replaced the 5-shadow halo
     (1 blur + 4 corner offsets) with -webkit-text-stroke. Safari
     paints each text-shadow as a separate text rasterization pass;
     200 labels × 5 shadows = 1000 text rasterizations per repaint.
     -webkit-text-stroke is one GPU-accelerated stroke per character.
     Visually near-identical (1px outline in halo color);
     Blink/Chromium honor -webkit-text-stroke too — both browsers win.
     The user-tunable --forge-label-halo CSS var still drives the
     color via -webkit-text-stroke-color. */
  -webkit-text-stroke: 2px var(--forge-label-halo, var(--bg-0));
  paint-order: stroke fill;
  text-shadow: none;
  /* 2026-05-19 — opacity-driven hide instead of display:none so
     labels ease in/out across focus transitions. JS sets
     `data-visible="1"` on shown labels, opacity follows via the
     transition rule below. */
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease-out;
  /* SAFARI-WORKAROUND (2026-05-26): will-change ONLY on labels
     currently shown — see [data-visible="1"] rule below. Promoting
     all 600+ DOM labels to GPU layers (regardless of visibility)
     creates Safari memory pressure and layer-eviction cliffs.
     Default state: no will-change. Only the ~20-200 visible labels
     at any given moment get layer promotion. */
}
.forge-label[data-visible="1"] {
  opacity: 1;
  will-change: transform;
}
/* (Glyph fade transition removed 2026-05-20 — glyphs are now GPU
   instanced quads with alpha refreshed per frame from nodeStates,
   inheriting the same fade timing as their parent disks.) */

/* ============================================================
   FORGE — chrome cleanup on the parent app shell
   ============================================================
   The Forge view runs in its own pane with its own chrome (status
   strip + bottom bar). The app-shell extras that bleed into the
   pane viewport are hidden here:
   – `#codex-dev-panel` + `#codex-dev-tab` = the legacy Pantheon-V2
     dev panel; its controls only mutate Pantheon V2, not Forge.
   – `<footer>` + `#footer-toggle` = the app-wide vault filter
     (`#filter-search`); its wiring doesn't reach Forge. */
/* 2026-05-19 — hide the app shell view-header in Forge. The
   global .view-header h2 rule renders "FORGE" in big stretched
   serif (text-transform: uppercase + letter-spacing: 0.32em),
   doubling up with the canvas-overlay status strip. Forge owns
   its own chrome via the status strip, so the global header
   isn't needed — same pattern as Transmutation + Scripture
   views already do (lines 2894 + 4258). */
body.view-forge .view-header { display: none; }

/* 2026-05-30 — body.view-forge #codex-dev-panel / #codex-dev-tab
   hide-rules deleted. The panel no longer auto-mounts unless
   ?dev=1 or localStorage['codex-atlas/dev-enabled']==='1' (gated
   in src/js/dev-panel.js per cardinal rule #8). When mounted via
   opt-in, the operator wants it visible on Forge too. Footer +
   #footer-toggle were already deleted from index.html on 2026-05-27. */



/* ════════════════════════════════════════════════════════════
   FORGE FLOOR FX — Phase 21V (2026-05-22)
   ════════════════════════════════════════════════════════════
   When the user zooms out to ~25% gizmo or below, individual deity
   readability is gone — the wheel becomes a constellation. We lean
   into that with three layered effects:

     1. Bloom — soft additive feel via blur + brightness + saturate
                on the canvas (disks become points of light).
     2. Shimmer — slow hue-rotate cycle on the disks (the wheel
                  reads as alive, not static).
     3. Counter-shimmer — hulls hue-rotate the opposite direction
                          so the whole layout breathes color.

   Toggled by JS via body.fx-bloom (forge.js drawFrame computes the
   ramp from camera.scale / fit_scale and toggles the class). The
   class transitions filter values smoothly so the FX fades in/out
   rather than snapping.

   No hit-test impact — these are purely visual filters on the
   rendered output. Performance: GPU-compositor work, no JS cost.
   ════════════════════════════════════════════════════════════ */
body.view-forge .forge-canvas {
  /* Transition is on the FILTER property; the animation overrides
     it once .fx-bloom is set. Smooth fade-in/out at the threshold. */
  transition: filter 0.45s ease-out;
}
/* Phase 21W (2026-05-22) — pushed harder per John's feedback:
   stronger blur (was 0.5-0.9 px → now 2.0-3.5 px), brighter highs
   (1.32 → 1.85 peak), richer saturation (1.45 → 1.75), plus three
   embedded candle-flicker brightness spikes per shimmer cycle.
   Period shortened 6.5s → 5.5s. Each flicker spike is ~3% of the
   cycle (≈165 ms) so it reads as candle-light flicker, NOT strobe. */
/* Phase 21AC (2026-05-22) — HEARTBEAT FX. Replaced the flicker-spike
   shimmer with a single smooth breathing pump per cycle. Disks "rest"
   at the base values (blurred, dim, desaturated) and "pulse" up to
   peak (brighter, sharper, saturated) on each beat. ease-in-out
   smooths the entry + exit so it feels organic, not strobe.
   Period is now a CSS var (--fx-period) so the dev panel slider can
   control rhythm. */
body.view-forge {
  /* Heartbeat rhythm — period of one full pulse. */
  --fx-period:           7.0s;
  /* Disk — rest state (the calm between beats). */
  --fx-blur-base:        20.0px;
  --fx-bright-base:      1.50;
  --fx-sat-base:         1.50;
  /* Disk — pulse state (the brightest moment of the beat). */
  --fx-blur-peak:        20.0px;
  --fx-bright-peak:      2.00;
  --fx-sat-peak:         3.00;
  --fx-hue-peak:         0deg;
  /* Hull — calm counter-phased layer. */
  --fx-hull-bright-peak: 1.30;
  --fx-hull-sat-peak:    1.55;
  --fx-hull-hue-peak:    10deg;
  /* Phase 21AF — per-node hover/click pulse controls. The SIZE
     mult is read by JS to derive pixel size from node radius
     (sizePx = nodeRadiusPx × 2 × pulse-size-mult). Duration is
     read by the CSS animation directly. */
  --fx-pulse-size-mult:  4.0;
  --fx-pulse-duration:   0.8s;
  /* Phase 21AJ+21AK (2026-05-23) — Style-panel vars. Updated
     defaults: ring width 1 → 0.5 (John baseline preference).
     New separator vars (--style-sep-*) apply to BOTH the short
     and converging separator modes (the long-faded mode was
     removed in 21AK). */
  /* Guide rings — single shared color + width + opacity OR per-ring
     colors (inner / mid / outer). The per-ring colors default to the
     same value as the shared ring-color; the Style panel exposes
     them separately so they can be tinted independently. */
  --style-ring-color:        #6f8aaf;
  --style-ring-inner-color:  #6f8aaf;
  --style-ring-mid-color:    #6f8aaf;
  --style-ring-outer-color:  #6f8aaf;
  --style-ring-width:        0.5;
  --style-ring-opacity:      0.5;
  /* Separators — short + converging share width + opacity. The
     converging mode has independent endpoint color + opacity for
     each end (center vs outer). */
  --style-sep-width:         0.5;
  --style-sep-opacity:       0.5;
  --style-conv-center-color: #6f8aaf;
  --style-conv-edge-color:   #6f8aaf;
  --style-conv-center-opacity: 1.0;
  --style-conv-edge-opacity:   0.0;
}
body.view-forge.fx-bloom .forge-canvas {
  filter: blur(var(--fx-blur-base)) brightness(var(--fx-bright-base)) saturate(var(--fx-sat-base));
  /* Phase 21AD (2026-05-22) — symmetric transitions. The 0.45s
     animation-delay lets the `transition: filter` on the base rule
     ramp from "no filter" to the rest state smoothly. Without it,
     the animation starts immediately at its 0% keyframe (=the rest
     state) and snaps the filter, preempting the transition — which
     is what made close→wide zoom feel jumpy while wide→close was
     smooth (the exit had no such preemption). */
  animation: forge-fx-heartbeat var(--fx-period) ease-in-out 0.45s infinite;
  will-change: filter;
}
/* Heartbeat — "lub-dub" with a quick double-pump at the peak so it
   reads as a heartbeat rather than just a sine wave. The two-peaks
   pattern (40% then 50%) is barely perceptible but gives the rhythm
   a living quality. ease-in-out on the parent animation softens it. */
@keyframes forge-fx-heartbeat {
  0%   { filter: blur(var(--fx-blur-base)) brightness(var(--fx-bright-base)) saturate(var(--fx-sat-base)) hue-rotate(0deg); }
  40%  { filter: blur(var(--fx-blur-peak)) brightness(var(--fx-bright-peak)) saturate(var(--fx-sat-peak)) hue-rotate(var(--fx-hue-peak)); }
  /* Tiny dip between the two peaks — the "lub-DUB" inflection. */
  45%  { filter: blur(var(--fx-blur-peak)) brightness(calc(var(--fx-bright-peak) * 0.85)) saturate(var(--fx-sat-peak)) hue-rotate(var(--fx-hue-peak)); }
  55%  { filter: blur(var(--fx-blur-peak)) brightness(var(--fx-bright-peak)) saturate(var(--fx-sat-peak)) hue-rotate(var(--fx-hue-peak)); }
  100% { filter: blur(var(--fx-blur-base)) brightness(var(--fx-bright-base)) saturate(var(--fx-sat-base)) hue-rotate(0deg); }
}

body.view-forge .forge-hulls-overlay {
  transition: filter 0.45s ease-out;
}
body.view-forge.fx-bloom .forge-hulls-overlay {
  filter: brightness(1.12) saturate(1.30);
  /* Matches the canvas animation-delay so disks + hulls start
     pulsing in sync after the entry transition completes. */
  animation: forge-fx-hull-heartbeat var(--fx-period) ease-in-out 0.45s infinite;
  will-change: filter;
}
@keyframes forge-fx-hull-heartbeat {
  0%,   100% { filter: brightness(1.12) saturate(1.30) hue-rotate(0deg); }
  50%        { filter: brightness(var(--fx-hull-bright-peak)) saturate(var(--fx-hull-sat-peak)) hue-rotate(var(--fx-hull-hue-peak)); }
}

/* ════════════════════════════════════════════════════════════
   FORGE FX DEV PANEL — Phase 21AB (2026-05-22)
   ════════════════════════════════════════════════════════════
   Button in the bottom-bar opens a small slider panel for live-
   tuning the floor-FX visual params (blur, brightness, saturate,
   hue, flicker peaks). Sliders write directly to CSS vars on
   body.view-forge (see :root values above). Persisted in LS as
   forge.fxParams.v1.

   Trigger threshold + transition timing are intentionally NOT
   in this panel — only the *look*.
   ════════════════════════════════════════════════════════════ */
.forge-fxpanel-wrap {
  position: relative;
  display: inline-flex; align-items: center;
  pointer-events: auto;
}
/* ════════════════════════════════════════════════════════════
   CANONICAL BOTTOM-BAR BUTTON — site-wide primitive.
   Phase 22-AB-fix4 (2026-05-24) locked in as the ONE class that
   every bottom-bar button MUST use (LIN/LOG/CMP/DENSITY in the
   timeline segment, FX, STYLE, future menus on Board/Map/Star Map,
   etc.). Sister classes (.forge-legend-btn, .forge-zoom-gizmo,
   .forge-scrub-box) exist for historical reasons but duplicate
   these declarations and should be folded back into this class
   in a future cleanup batch.
   Rules (severity-dogma, HOW-WE-WORK.md §5.7):
     - NEW BUTTONS USE THIS CLASS. Never duplicate declarations
       in inline styles or a new sibling class.
     - Active state = [aria-pressed="true"] (rule below).
     - Open state  = [aria-expanded="true"] (rule below).
     - Hover state = :hover.
     - Variants live in app.css as `.forge-fxpanel-btn.foo`, never
       as full forks.
   ════════════════════════════════════════════════════════════ */
.forge-fxpanel-btn {
  /* Phase 21AQ — compact to match LEGEND + VIEW sibling styling. */
  padding: 5px 10px;
  background: rgba(13,17,25,0.78);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 6px;
  color: var(--text-2, #9099a8);
  font-family: var(--mono, "JetBrains Mono", monospace);
  font-size: 11px;
  letter-spacing: 0.08em;
  cursor: pointer;
  pointer-events: auto;
  transition: border-color 120ms ease, color 120ms ease, background 120ms ease;
}
.forge-fxpanel-btn:hover,
.forge-fxpanel-btn[aria-expanded="true"] {
  border-color: var(--gold, #d4a55a);
  color: var(--gold, #d4a55a);
  background: rgba(20,26,38,0.92);
}
/* Phase 22-AB-fix3 (2026-05-24) — `aria-pressed="true"` is the
   canonical active-state modifier for `.forge-fxpanel-btn`. Used by
   the timeline bottom-right toolbar segmented switcher (LIN / LOG /
   LOG-R / CMP) so each segment IS a real `.forge-fxpanel-btn` —
   guaranteeing pixel parity with LEGEND / VIEW / FX / STYLE / #.
   Severity-dogma compliance: NO inline-style duplication. */
.forge-fxpanel-btn[aria-pressed="true"] {
  border-color: var(--gold, #d4a55a);
  color: var(--gold-1, #e8c889);
  background: rgba(212, 165, 90, 0.18);
  font-weight: 600;
}

/* Phase 22-AB-fix4 (2026-05-24) — TIMELINE-SEGMENT IN BOTTOMBAR.
   The bottom-right Timeline controls (LIN/LOG/LOG-R/CMP +
   DENSITY) live INSIDE the canonical `.forge-bottombar` as a
   flex child. `margin-left: auto` pushes it to the right edge of
   the flex row, leaving canonical buttons untouched on the left.
   `.fv-timeline-only` (existing layout-gate class) is already
   styled at app.css ~line 862 to hide outside the Timeline view.
   SEVERITY DOGMA: this is the foundation for ALL future view-
   specific bottom-bar segments. Replicate this pattern for any
   new menus tied to a specific view (Board / Map / Star Map /
   future calendars). One bottombar, one flex row, layout-gated
   children. NEVER spawn `position: absolute` siblings — that's
   how the 2-3px row-drift bug from Phase 22-AA was born. */
.forge-bottombar-right {
  margin-left: auto;       /* pushes this segment to the row's right edge */
  display: inline-flex;
  align-items: center;
  gap: 6px;
  pointer-events: auto;
}

/* ════════════════════════════════════════════════════════════
   TIMELINE FOCUS GROUP — DATE IN / DATE OUT / FOCUS
   Phase 22-AD (2026-05-24). Three more `.forge-fxpanel-btn`
   children that live in `.forge-bottombar-right`. The two inputs
   look identical to the buttons but accept text. The FOCUS button
   reads them and calls `_forge.focusTimelineRange()`.
   ════════════════════════════════════════════════════════════ */
.forge-tl-focus-in,
.forge-tl-focus-out {
  width: 78px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  outline: none;
}
.forge-tl-focus-in::placeholder,
.forge-tl-focus-out::placeholder {
  color: var(--text-3, #6b7280);
  opacity: 0.7;
  text-transform: uppercase;
  letter-spacing: 0.10em;
}
.forge-tl-focus-in:focus,
.forge-tl-focus-out:focus {
  border-color: var(--gold, #d4a55a);
  color: var(--gold-1, #e8c889);
}
.forge-tl-focus-go {
  font-weight: 600;
  color: var(--gold, #d4a55a);
}

/* ════════════════════════════════════════════════════════════
   CALENDAR PICKER — popup attached to the timeline bottombar.
   Phase 22-AE (2026-05-24). Drops UP from the CAL button. Same
   visual family as .forge-fxpanel (FX/Style popovers) so the
   chrome is consistent. Each row is a `.forge-tl-cal-row`
   button — active row gets the gold-tint via [aria-pressed].
   ════════════════════════════════════════════════════════════ */
.forge-fxpanel-btn.forge-tl-cal-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.forge-tl-cal-label { opacity: 0.7; text-transform: uppercase; }
.forge-tl-cal-val   { color: var(--gold, #d4a55a); font-weight: 600; }
.forge-tl-cal-chev  { opacity: 0.6; font-size: 9px; }

.forge-tl-cal-pop {
  position: absolute;
  bottom: 48px;          /* clears bottombar (14 + 24 + 10 gap) */
  right: 14px;
  min-width: 220px;
  padding: 4px;
  background: rgba(13,17,25,0.94);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 8px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 6px 24px rgba(0,0,0,0.45);
  z-index: 235;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.05em;
  color: var(--text-2, #9099a8);
  pointer-events: auto;
  display: none;
}
.forge-tl-cal-pop.is-open { display: block; }

.forge-tl-cal-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  width: 100%;
  padding: 7px 10px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--text-2, #9099a8);
  font-family: inherit;
  font-size: inherit;
  letter-spacing: inherit;
  cursor: pointer;
  text-align: left;
}
.forge-tl-cal-row:hover {
  background: rgba(212, 165, 90, 0.06);
}
.forge-tl-cal-row[aria-pressed="true"] {
  background: rgba(212, 165, 90, 0.12);
  border-color: rgba(212, 165, 90, 0.35);
  color: var(--gold-1, #e8c889);
}
.forge-tl-cal-row-short {
  text-transform: uppercase;
  letter-spacing: 0.10em;
  font-weight: 600;
  color: var(--gold, #d4a55a);
  width: 60px;
  flex: 0 0 auto;
}
.forge-tl-cal-row-label {
  flex: 1 1 auto;
  text-align: right;
  opacity: 0.85;
  text-transform: none;
}

/* Phase 22-AG (2026-05-24) — calendar dwell tooltip. Shows
   500ms after hover on a row in the calendar picker. Same dark
   panel chrome as the picker itself so it reads as a sibling
   surface. Width is fixed so descriptions don't reflow each
   time the user moves between rows. */
.forge-tl-cal-tip {
  width: 280px;
  padding: 10px 12px 12px;
  background: rgba(13, 17, 25, 0.96);
  border: 1px solid rgba(212,165,90,0.30);
  border-radius: 8px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 6px 24px rgba(0,0,0,0.55);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 10.5px;
  line-height: 1.45;
  letter-spacing: 0.02em;
  color: var(--text-2, #9099a8);
  z-index: 240;
  pointer-events: none;       /* tooltip is read-only */
}
.forge-tl-cal-tip-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gold-1, #e8c889);
  margin-bottom: 6px;
}
.forge-tl-cal-tip-body {
  font-size: 10.5px;
  opacity: 0.95;
  color: var(--text-1, #b5b9c5);
}

/* Phase 22-AG (2026-05-24) — secondary epoch pivot label. The
   primary Greg-0 stays gold-bright (`.forge-timeline-year-zero`).
   The secondary calendar-epoch label gets a slightly cooler tone
   so the eye reads Greg-0 as the canonical anchor first. */
.forge-timeline-year-epoch {
  font-style: italic;
}

/* Phase 22-AH (2026-05-25) — cross-folder action popup. Pops up
   when a side-panel wire-item that points to a non-deity target
   is clicked. Offers a "Switch master view" action + dismiss.
   Slot for future actions (Show reference, Copy link, etc.).
   Same dark + gold visual family as the calendar picker. */
.forge-side-cross-pop {
  width: 260px;
  padding: 10px 12px 12px;
  background: rgba(13,17,25,0.96);
  border: 1px solid rgba(212,165,90,0.35);
  border-radius: 8px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 6px 24px rgba(0,0,0,0.55);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  color: var(--text-2, #9099a8);
  z-index: 300;
  pointer-events: auto;
}
.forge-side-cross-pop-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
}
.forge-side-cross-pop-title {
  flex: 1 1 auto;
  font-size: 12px;
  font-weight: 700;
  color: var(--gold-1, #e8c889);
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.forge-side-cross-pop-close {
  flex: 0 0 auto;
  background: transparent;
  border: 0;
  color: var(--text-3, #6b7280);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
}
.forge-side-cross-pop-close:hover { color: var(--gold, #d4a55a); }
.forge-side-cross-pop-sub {
  font-size: 10px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-3, #6b7280);
  margin-bottom: 10px;
}
.forge-side-cross-pop-actions { display: flex; flex-direction: column; gap: 6px; }
.forge-side-cross-pop-action {
  padding: 6px 10px;
  background: rgba(212,165,90,0.12);
  border: 1px solid rgba(212,165,90,0.35);
  border-radius: 6px;
  color: var(--gold-1, #e8c889);
  font-family: inherit;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-align: left;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.forge-side-cross-pop-action:hover {
  background: rgba(212,165,90,0.22);
  border-color: var(--gold, #d4a55a);
}
.forge-side-cross-pop-pending {
  padding: 6px 10px;
  background: rgba(255,255,255,0.03);
  border: 1px dashed rgba(212,165,90,0.20);
  border-radius: 6px;
  color: var(--text-3, #6b7280);
  font-size: 10px;
  font-style: italic;
  letter-spacing: 0.04em;
  text-align: center;
}

/* ════════════════════════════════════════════════════════════
   VERTICAL DENSITY SLIDER — its own primitive
   Phase 22-AD (2026-05-24). Forked out of the bottombar. Always
   visible on Timeline view. Anchored bottom-right above the
   bottombar. Vertical drag = expand/compress band heights.
   ────────────────────────────────────────────────────────────
   Why its own class family (`.forge-tl-vdensity-*`):
   - it has a different SHAPE than bottombar cells (tall, narrow)
   - different INTERACTION (vertical drag vs click)
   - different LIFETIME (persistent, no popover)
   Variants under the SAME canonical look (gold accent on dark
   panel) so it belongs to the visual family even while having
   its own geometry.
   ════════════════════════════════════════════════════════════ */
.forge-tl-vdensity {
  position: absolute;
  right: 14px;
  bottom: 48px;            /* clears the bottombar (14 + 24 + 10 gap) */
  width: 36px;
  height: 188px;           /* +38px for the LOCK toggle row */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 8px 4px;
  background: rgba(13,17,25,0.78);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 6px;
  color: var(--text-2, #9099a8);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  letter-spacing: 0.08em;
  z-index: 6;
  pointer-events: auto;
  user-select: none;
  box-sizing: border-box;
  transition: border-color 120ms ease;
}
.forge-tl-vdensity:hover {
  border-color: var(--gold-soft, rgba(212,165,90,0.45));
}
/* 2026-05-26 — readout is now a <button> sitting BELOW the track
   (where the LOCK toggle used to be). Single click resets density
   to 1.0×. Inherits the dark-pill + gold-border styling the retired
   LOCK button used so the bottom-right control cluster stays
   visually balanced. */
.forge-tl-vdensity-readout {
  margin-top: 6px;
  width: 100%;
  padding: 4px 0;
  background: rgba(13,17,25,0.78);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 4px;
  color: var(--gold, #d4a55a);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-align: center;
  cursor: pointer;
  box-sizing: border-box;
  transition: border-color 120ms ease, color 120ms ease, background 120ms ease;
}
.forge-tl-vdensity-readout:hover {
  border-color: var(--gold-soft, rgba(212,165,90,0.45));
  color: var(--gold-1, #e8c889);
}
.forge-tl-vdensity-readout:active {
  background: rgba(212, 165, 90, 0.18);
}
.forge-tl-vdensity-track {
  flex: 1 1 auto;
  width: 4px;
  margin: 6px 0;
  position: relative;
  background: rgba(212,165,90,0.20);
  border-radius: 3px;
  cursor: ns-resize;
}
.forge-tl-vdensity-thumb {
  position: absolute;
  left: 50%;
  width: 14px;
  height: 14px;
  margin-left: -7px;
  margin-top: -7px;
  border-radius: 50%;
  background: var(--gold, #d4a55a);
  border: 1px solid rgba(20,16,10,0.85);
  box-shadow: 0 1px 3px rgba(0,0,0,0.45);
  cursor: grab;
  touch-action: none;
}
.forge-tl-vdensity-thumb:active { cursor: grabbing; }
.forge-tl-vdensity-label {
  opacity: 0.7;
  text-transform: uppercase;
  text-align: center;
}

/* 2026-05-26 — LOCK toggle styles removed (system retired).
   Vdensity wrapper still needs box-sizing so the readout-button
   respects column width. */
.forge-tl-vdensity > * { box-sizing: border-box; }
.forge-fxpanel {
  position: absolute;
  bottom: 40px;     /* drops upward */
  left: 0;
  width: 280px;
  padding: 10px 14px 12px;
  background: rgba(13,17,25,0.92);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 8px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 6px 24px rgba(0,0,0,0.45);
  z-index: 235;
  display: none;
}
.forge-fxpanel.is-open { display: block; }
.forge-fxpanel-section {
  font-family: var(--mono, monospace);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-3, #6b7280);
  padding: 6px 0 2px;
}
.forge-fxpanel-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 6px;
  padding: 3px 0;
}
.forge-fxpanel-row label {
  font-family: var(--sans, Inter, sans-serif);
  font-size: 11px;
  color: var(--text-1, #e5e7eb);
  display: flex; justify-content: space-between;
  grid-column: 1 / -1;
}
.forge-fxpanel-row label .forge-fxpanel-val {
  color: var(--gold, #d4a55a);
  font-family: var(--mono, monospace);
  font-variant-numeric: tabular-nums;
}
.forge-fxpanel-row input[type="range"] {
  grid-column: 1 / -1;
  width: 100%;
  height: 4px;
  appearance: none; -webkit-appearance: none;
  background: rgba(212,165,90,0.18);
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}
.forge-fxpanel-row input[type="range"]::-webkit-slider-thumb {
  appearance: none; -webkit-appearance: none;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--gold, #d4a55a);
  border: 0;
  cursor: grab;
}
.forge-fxpanel-row input[type="range"]::-moz-range-thumb {
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--gold, #d4a55a);
  border: 0;
  cursor: grab;
}
.forge-fxpanel-divider {
  height: 1px;
  margin: 6px 0;
  background: rgba(212,165,90,0.10);
}
.forge-fxpanel-reset {
  margin-top: 8px;
  width: 100%;
  padding: 6px 10px;
  background: transparent;
  border: 1px solid rgba(212,165,90,0.30);
  border-radius: 4px;
  color: var(--text-2, #9099a8);
  font-family: var(--mono, monospace);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  cursor: pointer;
  transition: border-color 120ms ease, color 120ms ease;
}
.forge-fxpanel-reset:hover {
  border-color: var(--gold, #d4a55a);
  color: var(--gold, #d4a55a);
}

/* ════════════════════════════════════════════════════════════
   FORGE HOVER + CLICK PULSE FX — Phase 21AE (2026-05-22)
   ════════════════════════════════════════════════════════════
   Optional bloom flares triggered by user interaction:
     • Hover flash — short gentle bloom when cursor enters a node
                     (220 ms ease-out, runs ONCE on null → id transition)
     • Click pulse — stronger double-pump bloom on lock-add
                     (420 ms, "lub-DUB" rhythm)

   Both gated by body.fx-pulse-enabled (master toggle from the FX
   panel) AND :not(.fx-bloom) (floor FX has its own filter and only
   one filter per element can be active at a time — the bloom owns
   it at the floor; pulse takes over at close zoom).

   Animation is fire-and-forget: JS adds the class, browser plays
   the keyframes once, JS removes the class after the duration so
   the next trigger can restart the animation cleanly. The
   `void canvas.offsetWidth` reflow trick in JS forces a re-trigger
   on rapid hover-changes.

   Default state: body.fx-pulse-enabled is NOT set on the body.
   The CSS rules below are dead until the user enables the toggle.
   ════════════════════════════════════════════════════════════ */
/* Phase 21AF (2026-05-22) — pulse is now a PER-NODE overlay dot,
   not a canvas-wide filter. The previous version applied the filter
   to .forge-canvas which bloomed every disk (even hidden ones).
   Now: JS positions a single .forge-fx-pulse-dot over the hovered/
   clicked node's screen coordinates, sized to the node radius. The
   bloom only affects that one spot. */
.forge-fx-pulse-dot {
  position: fixed;
  top: 0; left: 0;
  pointer-events: none;
  width:  var(--fx-pulse-size, 80px);
  height: var(--fx-pulse-size, 80px);
  border-radius: 50%;
  background: radial-gradient(
    circle at center,
    var(--fx-pulse-color, #d4a55a) 0%,
    var(--fx-pulse-color, #d4a55a) 18%,
    transparent 65%
  );
  filter: blur(10px);
  z-index: 8;
  opacity: 0;
  transform: translate(-50%, -50%);
  will-change: transform, opacity;
}
body.view-forge.fx-pulse-enabled .forge-fx-pulse-dot.fx-hover-flash {
  animation: forge-fx-pulse-dot-hover var(--fx-pulse-duration, 0.8s) ease-out;
}
body.view-forge.fx-pulse-enabled .forge-fx-pulse-dot.fx-click-pulse {
  animation: forge-fx-pulse-dot-click calc(var(--fx-pulse-duration, 0.8s) * 1.3) ease-out;
}
@keyframes forge-fx-pulse-dot-hover {
  0%   { opacity: 0;    transform: translate(-50%, -50%) scale(0.5); }
  35%  { opacity: 0.9;  transform: translate(-50%, -50%) scale(1.1); }
  65%  { opacity: 0.55; transform: translate(-50%, -50%) scale(1.55); }
  100% { opacity: 0;    transform: translate(-50%, -50%) scale(2.0); }
}
@keyframes forge-fx-pulse-dot-click {
  0%   { opacity: 0;    transform: translate(-50%, -50%) scale(0.4); }
  /* "lub" */
  25%  { opacity: 1.0;  transform: translate(-50%, -50%) scale(1.25); }
  42%  { opacity: 0.5;  transform: translate(-50%, -50%) scale(1.6); }
  /* "DUB" */
  60%  { opacity: 0.95; transform: translate(-50%, -50%) scale(1.4); }
  100% { opacity: 0;    transform: translate(-50%, -50%) scale(2.4); }
}

/* FX panel toggle row (Phase 21AE) — reuses the .vs-check primitive
   for visual consistency with the View panel's layer toggles. */
.forge-fxpanel-toggle {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 6px 0;
  background: transparent;
  border: 0;
  text-align: left;
  font-family: var(--sans, Inter, sans-serif);
  font-size: 12px;
  color: var(--text-1, #e5e7eb);
  cursor: pointer;
  transition: color 90ms ease;
}
.forge-fxpanel-toggle:hover { color: var(--gold-1, #e8c889); }
.forge-fxpanel-toggle .vs-check {
  display: inline-block;
  width: 14px; height: 14px;
  border-radius: 3px;
  border: 1px solid rgba(212,165,90,0.55);
  background: transparent;
  flex: 0 0 auto;
  transition: background 100ms ease, border-color 100ms ease;
}
.forge-fxpanel-toggle.is-on .vs-check {
  background: var(--gold, #d4a55a);
  border-color: var(--gold, #d4a55a);
}
.forge-fxpanel-toggle.is-on { color: var(--gold-1, #e8c889); }

/* Phase 21AH (2026-05-22) — below 15% gizmo the wheel is too
   compressed for individual interaction. Hide every node label
   so the bloom heartbeat owns the visual; hit-testing is
   short-circuited in JS (see hitTestAt). */
body.view-forge.fx-belowfifteen .forge-labels-overlay { display: none !important; }

/* Phase 21AJ (2026-05-23) — right-anchored panels (FX + Style live
   on the right side of the bottom bar now). Override the default
   left:0 with right:0 so the panel extends LEFT from its button
   instead of off-screen to the right. */
.forge-fxpanel--right,
.forge-stylepanel {
  left: auto;
  right: 0;
}

/* Style panel — mirrors the FX panel structurally. */
.forge-stylepanel-wrap {
  position: relative;
  display: inline-flex; align-items: center;
  pointer-events: auto;
}
.forge-stylepanel-btn {
  /* Phase 21AQ — compact to match LEGEND + VIEW + FX sibling styling. */
  padding: 5px 10px;
  background: rgba(13,17,25,0.78);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 6px;
  color: var(--text-2, #9099a8);
  font-family: var(--mono, "JetBrains Mono", monospace);
  font-size: 11px;
  letter-spacing: 0.08em;
  cursor: pointer;
  pointer-events: auto;
  transition: border-color 120ms ease, color 120ms ease, background 120ms ease;
}
.forge-stylepanel-btn:hover,
.forge-stylepanel-btn[aria-expanded="true"] {
  border-color: var(--gold, #d4a55a);
  color: var(--gold, #d4a55a);
  background: rgba(20,26,38,0.92);
}
.forge-stylepanel {
  position: absolute;
  bottom: 40px;
  width: 280px;
  padding: 10px 14px 12px;
  background: rgba(13,17,25,0.92);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 8px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 6px 24px rgba(0,0,0,0.45);
  z-index: 235;
  display: none;
}
.forge-stylepanel.is-open { display: block; }

/* Color-input rows. The native <input type="color"> is small + dark
   on most browsers; this gives it a gold-tinted frame to match the
   rest of the panel. */
.forge-stylepanel-rowcolor {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  padding: 4px 0;
  font-family: var(--sans, Inter, sans-serif);
  font-size: 11px;
  color: var(--text-1, #e5e7eb);
}
.forge-stylepanel-rowcolor input[type="color"] {
  width: 28px; height: 22px;
  padding: 0;
  border: 1px solid rgba(212,165,90,0.35);
  border-radius: 4px;
  background: transparent;
  cursor: pointer;
}

/* Guide ring CSS — binds the stroke style to the Style panel vars.
   Width + opacity are shared across all three rings; colour is
   per-ring (--style-ring-inner-color, -mid-color, -outer-color)
   so each ring can be tinted independently. */
.forge-hull-guide-ring {
  fill: none;
  stroke: var(--style-ring-color, #6f8aaf);
  stroke-opacity: var(--style-ring-opacity, 0.5);
  stroke-width: var(--style-ring-width, 0.5);
}
.forge-hull-guide-ring[data-ring="inner"] { stroke: var(--style-ring-inner-color, var(--style-ring-color, #6f8aaf)); }
.forge-hull-guide-ring[data-ring="mid"]   { stroke: var(--style-ring-mid-color,   var(--style-ring-color, #6f8aaf)); }
.forge-hull-guide-ring[data-ring="outer"] { stroke: var(--style-ring-outer-color, var(--style-ring-color, #6f8aaf)); }

/* ============================================================
 * BOARDS V2 — skeleton step 2 of 10
 * Filed 2026-05-27 per AUDIT/2026-05-28-boards-v2-new-ux-spec.md
 *
 * Mirrors the .forge-pane app-shell contract (respect both rails,
 * fill the rest). Just the pane + an empty stage — NO legacy
 * bottombar / empty-state splash. The chrome the user actually
 * uses is the contextual app-pill (step 4), matching Codex's pill.
 * ============================================================ */
.boards-pane {
  position: absolute;
  top: 0; bottom: 0;
  left:  var(--eff-nav-w);
  right: var(--eff-detail-w);
  background:
    radial-gradient(ellipse at center, rgba(212,165,90,0.04) 0%, transparent 60%),
    var(--bg-0);
  overflow: hidden;
  transition: left var(--t-layout) var(--ease), right var(--t-layout) var(--ease);
  user-select: none;
  -webkit-user-select: none;
  color: var(--text-1, #e6e6e6);
  font: 14px/1.55 -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
}
.boards-shell {
  position: relative;
  width: 100%; height: 100%;
}
.boards-stage {
  position: absolute;
  inset: 0;
  overflow: hidden;
  /* Default cursor = crosshair → left-drag draws a marquee. The
     Figma/Miro convention. Pan mode is opt-in (space-held or
     middle-click drag). */
  cursor: crosshair;
  touch-action: none;        /* let pointermove drive pan instead of browser scroll */
}
.boards-stage.is-pan-mode  { cursor: grab; }
.boards-stage.is-panning   { cursor: grabbing; }

/* Inner div the pan/zoom transform applies to. transform-origin is the
   top-left so coordinates stay simple — card.x/card.y are world-space
   positions, and the stage→world transform handles the rest. */
.boards-world {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  transform-origin: 0 0;
  will-change: transform;
}

/* ── BOARDS empty-state (2026-07-16, alpha "Sealed" loop) ──────
   Shown on an empty board so a first-time tester meets an invitation, not a
   void. Follows the Scripture empty-state pattern (architecture §3): serif
   headline, italic-serif microcopy, mono action buttons. */
.boards-empty {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;          /* clicks pass through to the stage… */
  z-index: 4;
}
.boards-empty-card {
  pointer-events: auto;          /* …except on the card itself */
  width: min(430px, 84%);
  text-align: center;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 32px 34px 26px;
  box-shadow: var(--panel-shadow);
}
.boards-empty-glyph {
  color: var(--gold); font-size: 18px; letter-spacing: 0.4em; text-indent: 0.4em;
}
.boards-empty-title {
  font-family: var(--serif); font-weight: 500; font-size: 22px;
  color: var(--text-0); letter-spacing: 0.02em; margin: 10px 0 0;
}
.boards-empty-sub {
  font-family: var(--serif); font-style: italic; font-size: 13.5px;
  color: var(--text-2); line-height: 1.55; margin: 9px auto 0; max-width: 340px;
}
.boards-empty-actions {
  display: flex; gap: 9px; justify-content: center; margin-top: 20px;
}

/* ── BOARDS "Sealed" toast (save confirmation) ─────────────────
   Fixed-chrome tier (z 50–60). Serif name does the brand work, mono receipt
   the signal work. Glass panel via the --panel-* tokens so it inherits each
   theme's treatment (incl. Mystic's 12px blur). */
.boards-toast {
  position: fixed; left: 50%; bottom: 26px;
  transform: translate(-50%, 12px);
  display: flex; align-items: center; gap: 13px;
  padding: 11px 20px;
  background: var(--panel-bg);
  -webkit-backdrop-filter: var(--panel-blur); backdrop-filter: var(--panel-blur);
  border: 1px solid rgba(212,165,90,0.40);
  border-radius: 10px;
  box-shadow: var(--panel-shadow);
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--t-overlay) var(--ease), transform var(--t-overlay) var(--ease);
  z-index: 60;
}
.boards-toast.is-in { opacity: 1; transform: translate(-50%, 0); }
.boards-toast-glyph { color: var(--gold); font-size: 15px; }
.boards-toast-title { font-family: var(--serif); font-size: 15px; color: var(--text-0); letter-spacing: 0.02em; }
.boards-toast-title em { font-style: italic; color: var(--gold); }
.boards-toast-meta { font-family: var(--mono); font-size: var(--micro); letter-spacing: 0.14em; color: var(--text-3); text-transform: uppercase; }
@media (prefers-reduced-motion: reduce) {
  .boards-toast { transition: opacity 120ms linear; transform: translate(-50%, 0); }
}

/* ── BOARDS unsaved-changes dot on the Save-tree pill ──────────
   Hidden by default; the .has-unsaved class (toggled by boards-controls from
   the boards:dirty-changed event) reveals a soft-glowing gold dot. */
.boards-save-dot {
  display: inline-block; width: 6px; height: 6px; margin-left: 7px;
  border-radius: 50%; background: var(--gold);
  box-shadow: 0 0 7px rgba(212,165,90,0.85);
  opacity: 0; transform: scale(0.5);
  transition: opacity var(--t-micro) var(--ease), transform var(--t-micro) var(--ease);
  vertical-align: middle;
}
.app-pill-boards-save.has-unsaved .boards-save-dot { opacity: 1; transform: scale(1); }

/* Individual card — V2 design 2026-05-28 per John: "all the same
   thumbnail size compact with image and the light information of classes,
   with a drop to expand to more — naturally the side panel is where all
   info then comes." Fixed-width 200px so every card has identical visual
   weight. Thumbnail stripe is fixed 60px tall regardless of image
   availability (fallback type-glyph block). Chevron toggles .is-expanded
   which adds tradition + body excerpt + Open-inspector link. */
.boards-card {
  position: absolute;
  width: 200px;
  background: rgba(13,17,25,0.94);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 8px;
  color: var(--text-0, #e6e6e6);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.01em;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  transition: border-color 100ms ease, box-shadow 100ms ease;
  box-shadow: 0 2px 8px rgba(0,0,0,0.32);
  overflow: hidden;
}
.boards-card:hover {
  border-color: rgba(212,165,90,0.45);
}
.boards-card.is-dragging {
  cursor: grabbing;
  transition: none;
  border-color: rgba(212,165,90,0.65);
  box-shadow: 0 6px 18px rgba(0,0,0,0.5);
  z-index: 10;
}
.boards-card.is-selected {
  border-color: var(--gold, #d4a55a);
  box-shadow: 0 0 0 1px var(--gold, #d4a55a), 0 2px 8px rgba(0,0,0,0.32);
}

/* Thumbnail stripe — fixed dimensions so every card has the same
   visual weight regardless of whether the node has a thumbnail. */
.boards-card-thumb {
  height: 60px;
  background: rgba(0,0,0,0.35);
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid rgba(212,165,90,0.10);
}
.boards-card-thumb img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.boards-card-thumb--fallback {
  background:
    radial-gradient(ellipse at center, rgba(212,165,90,0.10) 0%, rgba(13,17,25,0.6) 70%);
  display: flex;
  align-items: center;
  justify-content: center;
}
.boards-card-glyph {
  color: rgba(212,165,90,0.55);
  font-size: 28px;
  line-height: 1;
}

/* Body — title row + meta line. */
.boards-card-body {
  padding: 8px 10px 9px 10px;
}
.boards-card-title-row {
  display: flex;
  align-items: flex-start;
  gap: 6px;
}
.boards-card-label {
  flex: 1 1 auto;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  line-height: 1.35;
  font-size: 11.5px;
  letter-spacing: 0.01em;
  color: var(--text-0, #e6e6e6);
}
.boards-card-expand {
  flex: 0 0 auto;
  width: 18px; height: 18px;
  margin-top: -2px;
  padding: 0;
  background: transparent;
  border: 0;
  color: rgba(212,165,90,0.45);
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
  transition: color 100ms ease;
}
.boards-card-expand:hover {
  color: var(--gold-1, #e8c889);
}
.boards-card-meta {
  margin-top: 5px;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(212,165,90,0.62);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Expanded panel — hidden by default, slides into view when .is-expanded.
   Adds tradition + 2-line body excerpt + an "Open inspector" link that
   surfaces the side-panel (the deep-detail surface per John). */
.boards-card-expanded {
  display: none;
  padding: 0 10px 10px 10px;
  border-top: 1px solid rgba(212,165,90,0.12);
  margin-top: 0;
}
.boards-card.is-expanded .boards-card-expanded {
  display: block;
}
.boards-card-tradition {
  margin-top: 8px;
  font-size: 9.5px;
  letter-spacing: 0.06em;
  color: rgba(230,230,230,0.65);
  font-style: italic;
}
.boards-card-excerpt {
  margin-top: 6px;
  font-family: var(--sans, "Inter", system-ui, sans-serif);
  font-size: 10.5px;
  line-height: 1.45;
  color: rgba(230,230,230,0.78);
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.boards-card-excerpt--empty {
  color: rgba(230,230,230,0.35);
  font-style: italic;
}
.boards-card-open-inspector {
  margin-top: 8px;
  padding: 4px 10px;
  background: transparent;
  border: 1px solid rgba(212,165,90,0.32);
  border-radius: 5px;
  color: var(--gold, #d4a55a);
  font: inherit;
  font-size: 9.5px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 100ms ease, color 100ms ease;
}
.boards-card-open-inspector:hover {
  background: rgba(212,165,90,0.10);
  color: var(--gold-1, #e8c889);
}

/* ============================================================
 * BOARDS V2 — auto-drawn vault edges (step 6)
 * Filed 2026-05-28 per AUDIT/2026-05-28-boards-v2-new-ux-spec.md
 *
 * SVG layer inside .boards-world, same coordinate space as the
 * cards. The transform-origin: 0 0 on .boards-world makes the SVG
 * pan/zoom for free. SVG sits behind the cards in stacking order
 * (cards have z-index 0+; the SVG is below by document order).
 * ============================================================ */
.boards-edges {
  position: absolute;
  top: 0; left: 0;
  /* Huge viewport so edges can be drawn at any world coordinate
     without overflow clipping. transform-origin: 0 0 lines up the
     SVG (0,0) with the world (0,0). */
  width:  20000px;
  height: 20000px;
  pointer-events: none;
  overflow: visible;
  z-index: 0;
}
/* Per-bucket wire colors — matches the 7 EDGE_BUCKET classes John lives
   with on the Forge wheel. Stroke alpha pushed to ~0.85 so the lines
   actually read on a dark board at any zoom level. */
.boards-edge-line {
  stroke: rgba(156, 163, 175, 0.75);          /* fallback / association — gray */
  stroke-width: 1.5;
  fill: none;
  vector-effect: non-scaling-stroke;
}
.boards-edge-line[data-bucket="transmission"] { stroke: rgba(212, 165,  90, 0.95); stroke-width: 2.0; }   /* gold — the headline */
.boards-edge-line[data-bucket="parallel"]     { stroke: rgba(167, 139, 250, 0.85); stroke-dasharray: 6 4; } /* purple, dashed — convergent */
.boards-edge-line[data-bucket="fusion"]       { stroke: rgba(251, 146,  60, 0.90); stroke-width: 1.8; }   /* orange — syncretism */
.boards-edge-line[data-bucket="attestation"]  { stroke: rgba(134, 239, 172, 0.85); }                       /* green — evidence */
.boards-edge-line[data-bucket="kinship"]      { stroke: rgba(125, 211, 252, 0.85); }                       /* blue — genealogy */
.boards-edge-line[data-bucket="polemic"]      { stroke: rgba(248, 113, 113, 0.90); stroke-width: 1.8; }   /* red — conflict */
.boards-edge-line[data-bucket="association"]  { stroke: rgba(156, 163, 175, 0.55); }                       /* gray — generic */
/* Hide-all toggle from the contextual pill — body class flipped by
   _boardsView.setEdgesVisible(false). */
body.boards-edges-hidden .boards-edges { display: none; }

/* Edges toggle button — pressed = on (default), unpressed = off.
   Matches the codex pill's button-pressed visual conventions. */
.app-pill-boards-edges[aria-pressed="false"] {
  opacity: 0.55;
  text-decoration: line-through;
  text-decoration-color: rgba(212,165,90,0.55);
  text-decoration-thickness: 1px;
}

/* ============================================================
 * BOARDS V2 — card right-click context menu (step 7)
 * Filed 2026-05-28 per AUDIT/2026-05-28-boards-v2-new-ux-spec.md
 * ============================================================ */
.boards-card-menu {
  position: fixed;
  min-width: 240px;
  max-width: 320px;
  padding: 6px 0;
  background: rgba(13,17,25,0.96);
  border: 1px solid rgba(212,165,90,0.32);
  border-radius: 8px;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 10px 32px rgba(0,0,0,0.5);
  z-index: 12000;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  color: var(--text-0, #e6e6e6);
}
.boards-card-menu-header {
  padding: 6px 12px 8px 12px;
  border-bottom: 1px solid rgba(212,165,90,0.18);
  margin-bottom: 4px;
}
.boards-card-menu-title {
  display: block;
  font-weight: 500;
  color: var(--gold-1, #e8c889);
  line-height: 1.3;
  word-break: break-word;
}
.boards-card-menu-id {
  display: block;
  font-size: 9px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(212,165,90,0.45);
  margin-top: 3px;
}
.boards-card-menu-section {
  padding: 8px 12px 4px 12px;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(212,165,90,0.55);
}
.boards-card-menu-item {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 6px 12px;
  background: transparent;
  border: 0;
  text-align: left;
  color: var(--text-0, #e6e6e6);
  font: inherit;
  cursor: pointer;
  transition: background 80ms ease, color 80ms ease;
}
.boards-card-menu-item:hover:not([disabled]) {
  background: rgba(212,165,90,0.10);
  color: var(--gold-1, #e8c889);
}
.boards-card-menu-item[disabled] {
  opacity: 0.35;
  cursor: not-allowed;
}
.bcm-item-label {
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bcm-item-meta {
  flex-shrink: 0;
  font-size: 9px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(212,165,90,0.55);
}
.boards-card-menu-item--path .bcm-item-label {
  white-space: normal;
}
.boards-card-menu-item--danger {
  color: rgba(231, 138, 138, 0.85);
}
.boards-card-menu-item--danger:hover:not([disabled]) {
  background: rgba(196, 74, 90, 0.12);
  color: rgba(255, 168, 168, 0.95);
}
.boards-card-menu-divider {
  height: 1px;
  background: rgba(212,165,90,0.18);
  margin: 4px 6px;
}

/* ============================================================
 * BOARDS V2 — Inspector panel (step 8)
 * Filed 2026-05-28 per AUDIT/2026-05-28-boards-v2-new-ux-spec.md
 *
 * Right-side slide-in panel that shows a full node detail when
 * the user double-clicks a card. V2-native; does NOT reuse the
 * Forge side-panel (too coupled to engine internals).
 * ============================================================ */
.boards-inspector {
  position: fixed;
  top: 0; right: 0;
  width: min(420px, 38vw);
  height: 100vh;
  background: rgba(13,17,25,0.96);
  border-left: 1px solid rgba(212,165,90,0.22);
  box-shadow: -10px 0 32px rgba(0,0,0,0.5);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  z-index: 10000;
  transform: translateX(100%);
  transition: transform 220ms cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  flex-direction: column;
}
body.boards-inspector-open .boards-inspector {
  transform: translateX(0);
}
.boards-inspector[aria-hidden="true"] {
  pointer-events: none;
}
body.boards-inspector-open .boards-inspector[aria-hidden="true"] {
  /* aria-hidden false is set in JS during open; until then,
     pointer-events guard while transform animates in. */
}
.boards-inspector-close {
  position: absolute;
  top: 12px; right: 12px;
  width: 28px; height: 28px;
  background: transparent;
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 6px;
  color: rgba(212,165,90,0.65);
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  z-index: 2;
  transition: color 100ms ease, border-color 100ms ease;
}
.boards-inspector-close:hover {
  color: var(--gold-1, #e8c889);
  border-color: rgba(212,165,90,0.55);
}
.boards-inspector-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 22px 24px 40px 24px;
  scrollbar-width: thin;
}
.boards-inspector-header {
  margin-bottom: 16px;
  padding-right: 36px;
}
.boards-inspector-title {
  font-family: var(--serif, "Cormorant Garamond", Georgia, serif);
  font-size: 22px;
  font-weight: 500;
  color: var(--gold-1, #e8c889);
  line-height: 1.2;
  letter-spacing: 0.01em;
  word-break: break-word;
}
.boards-inspector-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}
.boards-inspector-badge {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(212,165,90,0.65);
  padding: 3px 8px;
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 10px;
}
.boards-inspector-badge--type   { color: var(--gold, #d4a55a); border-color: rgba(212,165,90,0.45); }
.boards-inspector-badge--era    { color: rgba(230,230,230,0.65); }
.boards-inspector-read-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 16px;
  padding: 8px 14px;
  background: rgba(212,165,90,0.10);
  border: 1px solid rgba(212,165,90,0.45);
  border-radius: 6px;
  color: var(--gold-1, #e8c889);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: background 100ms ease, color 100ms ease;
}
.boards-inspector-read-btn:hover {
  background: rgba(212,165,90,0.18);
  color: var(--text-0, #e6e6e6);
}
.boards-inspector-section {
  margin-top: 18px;
  font-family: var(--sans, "Inter", system-ui, sans-serif);
}
.boards-inspector-section-label {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold, #d4a55a);
  margin-bottom: 8px;
}
.boards-inspector-section--body {
  font-size: 13px;
  line-height: 1.65;
  color: rgba(230,230,230,0.88);
}
.boards-inspector-section--body p { margin: 0 0 12px 0; }
.boards-inspector-section--body h2,
.boards-inspector-section--body h3 {
  font-family: var(--serif, "Cormorant Garamond", Georgia, serif);
  font-weight: 500;
  color: var(--text-0, #e6e6e6);
  margin: 18px 0 8px 0;
}
.boards-inspector-section--body h2 { font-size: 16px; }
.boards-inspector-section--body h3 { font-size: 14px; }
.boards-inspector-section--body em { color: var(--gold, #d4a55a); font-style: italic; }
.boards-inspector-section--body strong { color: var(--text-0, #e6e6e6); }
.boards-inspector-section--body a {
  color: var(--gold-1, #e8c889);
  text-decoration: none;
  border-bottom: 1px dotted rgba(212,165,90,0.45);
}
.boards-inspector-pre {
  white-space: pre-wrap;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  color: rgba(230,230,230,0.75);
}
.boards-inspector-empty {
  font-style: italic;
  color: rgba(230,230,230,0.45);
  margin: 0;
}
.boards-inspector-refs {
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: 11px;
  line-height: 1.5;
  color: rgba(230,230,230,0.78);
}
.boards-inspector-refs li {
  padding: 4px 0;
  border-bottom: 1px solid rgba(212,165,90,0.10);
}
.boards-inspector-refs em { color: var(--text-0, #e6e6e6); font-style: italic; }
.boards-inspector-ref-tier {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 8.5px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--gold, #d4a55a);
  border: 1px solid rgba(212,165,90,0.32);
  border-radius: 8px;
}
.boards-inspector-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.boards-inspector-pill {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 10px;
  color: rgba(230,230,230,0.75);
  padding: 3px 9px;
  background: rgba(212,165,90,0.06);
  border: 1px solid rgba(212,165,90,0.18);
  border-radius: 12px;
}

/* ============================================================
 * Wire-bucket TABS in the boards inspector
 * Filed 2026-05-28 — clickable pills toggle their neighbor list
 * (single-open accordion). Mirrors the forge deity panel's
 * `_renderTabs` interaction surface without the wheel-engine
 * dependency (couldn't reuse Forge's tab system; rebuilt as
 * V2-native data-driven HTML).
 * ============================================================ */
.boards-wire-pill {
  /* Override the static <span>.forge-side-panel-wire styles for a
     clickable affordance. */
  background: transparent;
  border: 1px solid transparent;
  cursor: pointer;
  padding: 2px 8px;
  border-radius: 12px;
  transition: background 100ms ease, border-color 100ms ease;
  /* inherit forge-side-panel-wire font/size — those rules already apply */
  font-family: inherit;
  color: inherit;
}
.boards-wire-pill:hover {
  background: rgba(212,165,90,0.08);
  border-color: rgba(212,165,90,0.32);
}
.boards-wire-pill[aria-expanded="true"] {
  background: rgba(212,165,90,0.14);
  border-color: rgba(212,165,90,0.55);
  color: var(--gold-1, #e8c889);
}
.boards-wire-list {
  margin: 6px 0 12px 0;
  padding: 6px 0;
  border-top: 1px solid rgba(212,165,90,0.18);
  border-bottom: 1px solid rgba(212,165,90,0.10);
}
.boards-wire-list-header {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(212,165,90,0.55);
  padding: 4px 0 8px 0;
}
.boards-wire-neighbor {
  display: flex; align-items: center;
  gap: 8px;
  padding: 4px 0;
  transition: background 80ms ease;
}
.boards-wire-neighbor:hover {
  background: rgba(212,165,90,0.04);
}
.boards-wire-neighbor-dir {
  flex: 0 0 auto;
  width: 12px;
  text-align: center;
  color: rgba(212,165,90,0.55);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
}
.boards-wire-neighbor-dot {
  flex: 0 0 auto;
  width: 7px; height: 7px;
  border-radius: 50%;
}
.boards-wire-neighbor-title {
  flex: 1 1 auto;
  background: transparent;
  border: 0;
  text-align: left;
  color: var(--text-0, #e6e6e6);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
  padding: 0;
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color 80ms ease;
}
.boards-wire-neighbor-title:hover {
  color: var(--gold-1, #e8c889);
  text-decoration: underline;
  text-decoration-color: rgba(212,165,90,0.45);
}
.boards-wire-neighbor-type {
  flex: 0 0 auto;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(212,165,90,0.45);
}
.boards-wire-neighbor-add {
  flex: 0 0 auto;
  width: 20px; height: 20px;
  background: transparent;
  border: 1px solid rgba(212,165,90,0.32);
  border-radius: 4px;
  color: var(--gold, #d4a55a);
  font: inherit;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  transition: background 80ms ease, border-color 80ms ease, color 80ms ease;
}
.boards-wire-neighbor-add:hover:not(:disabled) {
  background: rgba(212,165,90,0.16);
  border-color: var(--gold, #d4a55a);
  color: var(--gold-1, #e8c889);
}
.boards-wire-neighbor-add:disabled {
  border-color: rgba(212,165,90,0.18);
  color: rgba(212,165,90,0.45);
  cursor: not-allowed;
}
.boards-wire-neighbor[data-on-board="1"] .boards-wire-neighbor-title {
  color: rgba(230,230,230,0.55);
  font-style: italic;
}

/* ============================================================
 * BOARDS V2 — marquee + multi-card toolbar (step 9 internal /
 * spec step 8: marquee select + multi-card ops)
 * Filed 2026-05-28 per AUDIT/2026-05-28-boards-v2-new-ux-spec.md
 * ============================================================ */
.boards-marquee {
  position: absolute;
  border: 1px solid var(--gold, #d4a55a);
  background: rgba(212,165,90,0.10);
  pointer-events: none;
  z-index: 50;
  border-radius: 2px;
}
.boards-multi-bar {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: rgba(13,17,25,0.94);
  border: 1px solid rgba(212,165,90,0.45);
  border-radius: 10px;
  box-shadow: 0 6px 22px rgba(0,0,0,0.45);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  z-index: 100;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
}
.boards-multi-bar-count {
  color: var(--gold-1, #e8c889);
  padding-right: 6px;
  border-right: 1px solid rgba(212,165,90,0.22);
  letter-spacing: 0.08em;
}
.boards-multi-bar-btn {
  background: transparent;
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 6px;
  padding: 4px 12px;
  color: var(--text-0, #e6e6e6);
  font: inherit;
  cursor: pointer;
  letter-spacing: 0.04em;
  transition: background 100ms ease, color 100ms ease, border-color 100ms ease;
}
.boards-multi-bar-btn:hover {
  background: rgba(212,165,90,0.10);
  color: var(--gold-1, #e8c889);
  border-color: rgba(212,165,90,0.55);
}
.boards-multi-bar-btn--danger { color: rgba(231, 138, 138, 0.85); }
.boards-multi-bar-btn--danger:hover {
  background: rgba(196, 74, 90, 0.14);
  color: rgba(255, 168, 168, 0.95);
  border-color: rgba(231, 138, 138, 0.55);
}
.boards-multi-bar-btn--ghost {
  border-color: rgba(212,165,90,0.10);
  color: rgba(230,230,230,0.55);
}
.boards-multi-bar-btn--ghost:hover {
  color: var(--gold-1, #e8c889);
  border-color: rgba(212,165,90,0.32);
}

/* ============================================================
 * BOARDS V2 — contextual pill (step 4 of 10)
 * Filed 2026-05-28 per AUDIT/2026-05-28-boards-v2-new-ux-spec.md
 *
 * Sibling .app-pill group to .app-pill--codex, lives inside the
 * same .app-pill-wrap, same visual primitive. body-class toggle
 * mirrors the codex pattern: visible only on view-boards.
 * ============================================================ */
.app-pill--boards { margin-left: 8px; display: none; }
body.app-pill-boards-visible .app-pill--boards { display: inline-flex; }
body:not(.view-boards) .app-pill--boards { display: none !important; }

/* Search-picker (Add node ▾) menu — wider than the codex menus,
   custom layout (input + hint + scrolling result list). */
.app-pill-menu--boards-addnode {
  min-width: 340px;
  max-width: 440px;
  padding: 0;
}
.app-pill-menu--boards-investigation {
  min-width: 280px;
  max-width: 360px;
}
.boards-pill-search {
  padding: 10px 12px 6px 12px;
  border-bottom: 1px solid rgba(212,165,90,0.12);
}
.boards-pill-search-input {
  width: 100%;
  padding: 6px 10px;
  background: rgba(0,0,0,0.35);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 6px;
  color: var(--text-0, #e6e6e6);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.02em;
  outline: none;
  transition: border-color 100ms ease;
}
.boards-pill-search-input:focus {
  border-color: rgba(212,165,90,0.55);
}
.boards-pill-search-hint {
  margin-top: 6px;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(212,165,90,0.55);
}
.boards-pill-results {
  max-height: 320px;
  overflow-y: auto;
  padding: 4px 0 6px 0;
}
.boards-pill-result {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 10px;
  padding: 6px 12px;
  background: transparent;
  border: 0;
  text-align: left;
  color: var(--text-0, #e6e6e6);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background 80ms ease, color 80ms ease;
}
.boards-pill-result:hover {
  background: rgba(212,165,90,0.08);
  color: var(--gold-1, #e8c889);
}
.boards-pill-result-title {
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.boards-pill-result-type {
  flex-shrink: 0;
  color: rgba(212,165,90,0.55);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Investigation library placeholder (step 5 wires the real content). */
.boards-pill-placeholder {
  padding: 12px 14px;
}
.boards-pill-placeholder-title {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(212,165,90,0.65);
  margin-bottom: 8px;
}
.boards-pill-placeholder-body {
  font-family: var(--sans, "Inter", system-ui, sans-serif);
  font-size: 12px;
  line-height: 1.55;
  color: rgba(230,230,230,0.75);
}
.boards-pill-placeholder-body em { color: var(--gold, #d4a55a); font-style: normal; }
.boards-pill-placeholder-body strong { color: var(--text-0, #e6e6e6); }

/* ============================================================
 * BOARDS V2 — Investigation Library (step 5)
 * Filed 2026-05-28 per AUDIT/2026-05-28-boards-v2-new-ux-spec.md
 *
 * 4-category dropdown rendered by boards-controls.js
 * buildInvestigationMenu(). Wider than the Add-node picker (the
 * entry titles can be long, the headlines longer). Scrolls
 * internally — max-height bounded so a 100+ entry library never
 * exceeds the viewport.
 * ============================================================ */
.app-pill-menu--boards-investigation {
  min-width: 380px;
  max-width: 480px;
  padding: 0;
}
.boards-lib-scroll {
  max-height: 70vh;
  overflow-y: auto;
  padding: 6px 0;
}
.boards-lib-section-label {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px 6px 14px;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold, #d4a55a);
  border-bottom: 1px solid rgba(212,165,90,0.12);
  margin-bottom: 4px;
}
.boards-lib-section-name { font-weight: 500; }
.boards-lib-section-count {
  color: rgba(212,165,90,0.55);
  font-size: 9px;
}
.boards-lib-subsection-label {
  padding: 8px 14px 4px 14px;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 8.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(212,165,90,0.50);
}
.boards-lib-subsection-count {
  color: rgba(212,165,90,0.35);
  font-size: 8.5px;
}
.boards-lib-entry {
  display: block;
  width: calc(100% - 16px);
  margin: 2px 8px;
  padding: 8px 10px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  text-align: left;
  color: var(--text-0, #e6e6e6);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  cursor: pointer;
  transition: background 80ms ease, border-color 80ms ease;
}
.boards-lib-entry:hover {
  background: rgba(212,165,90,0.06);
  border-color: rgba(212,165,90,0.22);
}
.boards-lib-entry-title {
  font-weight: 500;
  color: var(--text-0, #e6e6e6);
  line-height: 1.35;
}
.boards-lib-entry:hover .boards-lib-entry-title {
  color: var(--gold-1, #e8c889);
}
.boards-lib-entry-headline {
  margin-top: 3px;
  font-family: var(--sans, "Inter", system-ui, sans-serif);
  font-size: 10.5px;
  line-height: 1.45;
  color: rgba(230,230,230,0.62);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.boards-lib-entry-meta {
  margin-top: 4px;
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(212,165,90,0.55);
}
.boards-lib-empty {
  padding: 8px 14px 12px 14px;
  font-family: var(--sans, "Inter", system-ui, sans-serif);
  font-size: 11px;
  line-height: 1.5;
  color: rgba(230,230,230,0.50);
  font-style: italic;
}
.boards-lib-empty strong {
  color: var(--gold, #d4a55a);
  font-style: normal;
}

/* MY BOARDS rows — main entry + ✕ delete button on hover. The row
   is a flex container so the title takes available width and the
   delete sits flush-right. */
.boards-lib-entry-row {
  display: flex;
  align-items: stretch;
  gap: 2px;
  width: calc(100% - 16px);
  margin: 2px 8px;
}
.boards-lib-entry-row.is-current .boards-lib-entry-title {
  color: var(--gold-1, #e8c889);
}
.boards-lib-entry-row .boards-lib-entry--mine {
  flex: 1 1 auto;
  margin: 0;
}
.boards-lib-current-marker {
  color: var(--gold, #d4a55a);
  margin-right: 4px;
}
.boards-lib-entry-delete {
  flex: 0 0 auto;
  width: 28px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  color: rgba(230,230,230,0.32);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 100ms ease, color 100ms ease, background 100ms ease;
}
.boards-lib-entry-row:hover .boards-lib-entry-delete {
  opacity: 1;
}
.boards-lib-entry-delete:hover {
  color: rgba(231, 138, 138, 0.95);
  background: rgba(196, 74, 90, 0.10);
}

/* ============================================================
 * MAP V2 + STAR MAP V2 — skeletons mirroring .boards-pane
 * Filed 2026-05-28 per AUDIT/2026-05-28-legacy-isolation-locked.md
 *
 * Empty V2 stages that replaced the legacy VIEWS.atlas + VIEWS.
 * astrology routes in the master pill. Same app-shell contract
 * as the boards pane (respect both rails, fill the rest); same
 * subtle radial-gradient background. Ready to build into.
 * ============================================================ */
.maps-pane,
.starmap-pane,
.alphabets-pane {
  position: absolute;
  top: 0; bottom: 0;
  left:  var(--eff-nav-w);
  right: var(--eff-detail-w);
  background:
    radial-gradient(ellipse at center, rgba(212,165,90,0.04) 0%, transparent 60%),
    var(--bg-0);
  overflow: hidden;
  transition: left var(--t-layout) var(--ease), right var(--t-layout) var(--ease);
  user-select: none;
  -webkit-user-select: none;
  color: var(--text-1, #e6e6e6);
  font: 14px/1.55 -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
}
.maps-shell,
.starmap-shell {
  position: relative;
  width: 100%; height: 100%;
}
.maps-stage,
.starmap-stage {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

/* ══════════════════════════════════════════════════════════════
   MAP V2 — real MapLibre geographic map (2026-06-13).
   The inner #maps-map is the MapLibre target (MapLibre sets
   position:relative inline, so the fill comes from width/height
   100% within the explicitly-sized .maps-stage). Control + tooltip
   theming mirrors the legacy .atlas-map blocks above so both map
   surfaces share one visual language (cardinal rule #8 — view owns
   its chrome, but reuse the canonical look).
   ══════════════════════════════════════════════════════════════ */
.maps-map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.maps-map .maplibregl-canvas { cursor: grab; }
.maps-map .maplibregl-canvas:active { cursor: grabbing; }
.maps-map .maplibregl-canvas:focus { outline: none; }

/* MapLibre nav + attribution controls — token-palette theming. */
.maps-map .maplibregl-ctrl-group {
  background: var(--bg-1);
  border: 1px solid var(--border);
  box-shadow: 0 8px 18px -10px rgba(0,0,0,0.6);
}
.maps-map .maplibregl-ctrl-group button {
  background: var(--bg-1);
  border-color: var(--border);
  transition: background var(--t-micro) var(--ease);
}
.maps-map .maplibregl-ctrl-group button:hover { background: var(--bg-3); }
.maps-map .maplibregl-ctrl-group button + button { border-top-color: var(--border-soft); }
.maps-map .maplibregl-ctrl-zoom-in span,
.maps-map .maplibregl-ctrl-zoom-out span {
  filter: invert(0.9) sepia(0.15) hue-rotate(20deg) saturate(0.6);
}
.maps-map .maplibregl-ctrl-attrib {
  background: rgba(13,17,25,0.62);
  color: var(--text-3);
  font-family: var(--mono);
  font-size: var(--micro);
}
.maps-map .maplibregl-ctrl-attrib a { color: var(--text-2); }
.maps-map .maplibregl-ctrl-attrib a:hover { color: var(--gold); }
.maps-map .maplibregl-ctrl-attrib-button { background-color: var(--bg-1); }

/* Hover tooltip — a TINY label only (full node content is the inspector).
   The MapLibre Popup wrapper class is .maps-tip (set in maps.js). */
.maplibregl-popup.maps-tip .maplibregl-popup-content {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 7px 10px;
  box-shadow: 0 10px 24px -12px rgba(0,0,0,0.7);
  pointer-events: none;
}
.maplibregl-popup.maps-tip .maplibregl-popup-tip { display: none; }
.maps-tip .maps-tip-title {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-1);
  line-height: 1.3;
}
.maps-tip .maps-tip-meta {
  margin-top: 2px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  color: var(--text-2);
}

/* MAP empty / error state — same idiom as the construction-note it replaced. */
.maps-empty {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
  pointer-events: none;
}
.maps-empty .maps-empty-glyph {
  font-size: 64px;
  line-height: 1;
  color: rgba(212, 175, 110, 0.38);
}
.maps-empty .maps-empty-title {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  color: rgba(232, 226, 214, 0.55);
}
.maps-empty .maps-empty-sub {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.08em;
  line-height: 1.7;
  max-width: 440px;
  color: rgba(232, 226, 214, 0.34);
}

/* ── ALPHABETS V2 — GLYPHS grid + the VERTICAL GENEALOGY page ───
 * (2026-06-10, John-ratified). GLYPHS: flowing grid, scrolls.
 * GENEALOGY: the vertical band-map — svg fills the pane, wheel-zoom
 * + drag-pan own the surface. The engine TIMELINE|Alphabets remains
 * the third class (canonical handoff). */
.alphabets-pane { overflow: auto; }
.alphabets-pane.is-genealogy { overflow: hidden; }
.alphabets-stage {
  position: relative;
  min-height: 100%;
  padding: 58px 18px 28px;            /* clears the floating app-pill */
}
.alphabets-pane.is-genealogy .alphabets-stage {
  position: absolute; inset: 0;
  min-height: 0;
  padding: 0;
}
.alphabets-svg { display: block; width: 100%; height: 100%; cursor: grab; }
.alphabets-svg.is-panning { cursor: grabbing; }
.alphabets-band-line { stroke: rgba(212,165,90,0.14); stroke-width: 1; }
.alphabets-band-label {
  fill: var(--gold, #d4a55a);
  font: 600 10px/1 "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: 0.14em;
  opacity: 0.85;
}
.alphabets-edge { fill: none; stroke-width: 1.25; pointer-events: stroke; }
.alphabets-edge-descent   { stroke: rgba(212,165,90,0.55); }
.alphabets-edge-sibling   { stroke: rgba(160,170,190,0.45); stroke-dasharray: 5 4; }
.alphabets-edge-influence { stroke: rgba(160,170,190,0.35); stroke-dasharray: 1.5 3.5; }
.alphabets-node { cursor: pointer; }
.alphabets-node circle { stroke: rgba(212,165,90,0.85); stroke-width: 1.25; }
.alphabets-node:hover circle { stroke-width: 2.25; }
.alphabets-node-name {
  fill: var(--text-1, #e6e6e6);
  font: 500 11px/1 -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
}
.alphabets-node:hover .alphabets-node-name { fill: var(--gold, #d4a55a); }
.alphabets-node-date {
  fill: rgba(230,230,230,0.45);
  font: 400 9px/1 "JetBrains Mono", ui-monospace, monospace;
}
.alphabets-hint {
  margin-top: 12px;
  color: rgba(230,230,230,0.4);
  font: 400 10.5px/1.5 "JetBrains Mono", ui-monospace, monospace;
}
.alphabets-pane.is-genealogy .alphabets-hint {
  position: absolute;
  left: 16px; right: 16px; bottom: 10px;
  margin: 0;
  pointer-events: none;
}
.alphabets-empty {
  padding: 48px;
  color: rgba(230,230,230,0.5);
  font: 400 13px/1.5 "JetBrains Mono", ui-monospace, monospace;
}

/* GLYPHS class — script chips, letter grid, transmission-chain card */
.alphabets-script-row { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.alphabets-script-chip {
  padding: 4px 11px;
  border: 1px solid rgba(212,165,90,0.28);
  border-radius: 999px;
  background: transparent;
  color: var(--text-2, #b9bec8);
  font: 500 10.5px/1 "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: 0.06em;
  cursor: pointer;
}
.alphabets-script-chip:hover { border-color: var(--gold, #d4a55a); color: var(--text-1, #e6e6e6); }
.alphabets-script-chip.is-active {
  border-color: var(--gold, #d4a55a);
  background: rgba(212,165,90,0.14);
  color: var(--gold, #d4a55a);
}
/* The visible GENEALOGY entry point (2026-06-10 — John couldn't find
 * the class-side path; this chip is the same canonical handoff). */
.alphabets-genealogy-chip {
  border-color: var(--gold, #d4a55a);
  background: rgba(212,165,90,0.18);
  color: var(--gold, #d4a55a);
  font-weight: 600;
}
.alphabets-genealogy-chip:hover { background: rgba(212,165,90,0.3); }
.alphabets-script-sep {
  width: 1px;
  align-self: stretch;
  background: rgba(212,165,90,0.25);
  margin: 0 5px;
}
.alphabets-glyph-note {
  margin: 0 0 12px;
  color: var(--text-2, #b9bec8);
  font: 400 11.5px/1.5 -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
}
.alphabets-glyph-note b { color: var(--gold, #d4a55a); font-weight: 600; }
.alphabets-glyph-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
  gap: 8px;
}
.alphabets-glyph-cell {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 12px 6px 9px;
  border: 1px solid rgba(212,165,90,0.16);
  border-radius: 10px;
  background: rgba(255,255,255,0.015);
  color: var(--text-1, #e6e6e6);
  cursor: pointer;
}
.alphabets-glyph-cell:hover { border-color: rgba(212,165,90,0.55); background: rgba(212,165,90,0.05); }
.alphabets-glyph-cell.is-open { border-color: var(--gold, #d4a55a); background: rgba(212,165,90,0.10); }
.alphabets-glyph-char { font-size: 30px; line-height: 1.15; }
.alphabets-glyph-svg { width: 1em; height: 1em; display: block; overflow: visible; }
.alphabets-glyph-name { font: 500 11px/1.2 -apple-system, BlinkMacSystemFont, system-ui, sans-serif; }
.alphabets-glyph-meaning {
  color: rgba(230,230,230,0.45);
  font: 400 9.5px/1.2 "JetBrains Mono", ui-monospace, monospace;
}
.alphabets-glyph-expanded {
  position: relative;
  display: grid;
  grid-template-columns: minmax(150px, 0.8fr) minmax(260px, 1.6fr) minmax(220px, 1.2fr);
  gap: 18px;
  margin: 0 0 14px;
  padding: 18px 38px 16px 18px;
  border: 1px solid rgba(212,165,90,0.4);
  border-radius: 12px;
  background: rgba(212,165,90,0.05);
}
/* 2026-06-10 — the card now lives INSIDE the letter grid, inserted
 * right after the clicked cell as a full-width row (in-place expand;
 * no scroll-to-top). */
.alphabets-glyph-grid .alphabets-glyph-expanded {
  grid-column: 1 / -1;
  margin: 4px 0 6px;
}
.alphabets-exp-close {
  position: absolute; top: 8px; right: 10px;
  border: none; background: none;
  color: rgba(230,230,230,0.5);
  font-size: 13px; cursor: pointer;
}
.alphabets-exp-close:hover { color: var(--gold, #d4a55a); }
.alphabets-exp-big { font-size: 64px; line-height: 1.1; color: var(--gold, #d4a55a); }
.alphabets-exp-bigsvg { width: 1em; height: 1em; }
.alphabets-exp-name { margin-top: 6px; font: 600 13px/1.35 -apple-system, BlinkMacSystemFont, system-ui, sans-serif; }
.alphabets-exp-gardiner {
  margin-top: 3px;
  color: rgba(230,230,230,0.45);
  font: 400 9.5px/1.4 "JetBrains Mono", ui-monospace, monospace;
}
.alphabets-exp-descs { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 8px; }
.alphabets-exp-desc { font: 400 11px/1.5 -apple-system, BlinkMacSystemFont, system-ui, sans-serif; color: var(--text-2, #b9bec8); }
.alphabets-exp-desc b { color: var(--gold, #d4a55a); font-weight: 600; margin-right: 3px; }
.alphabets-exp-chainlabel, .alphabets-exp-invlabel {
  color: var(--gold, #d4a55a);
  font: 600 9.5px/1 "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: 0.14em;
  margin-bottom: 9px;
}
.alphabets-chain { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; }
.alphabets-chain-step { display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 58px; }
.alphabets-chain-glyph { font-size: 25px; line-height: 1.15; }
.alphabets-chain-label { font: 500 9.5px/1.2 -apple-system, BlinkMacSystemFont, system-ui, sans-serif; }
.alphabets-chain-sub { color: rgba(230,230,230,0.4); font: 400 8.5px/1.2 "JetBrains Mono", ui-monospace, monospace; }
.alphabets-chain-arrow { color: rgba(212,165,90,0.6); font-size: 13px; }
.alphabets-exp-note { margin-top: 11px; color: var(--text-2, #b9bec8); font: 400 11.5px/1.55 -apple-system, BlinkMacSystemFont, system-ui, sans-serif; }
.alphabets-exp-invtext { color: var(--text-1, #e6e6e6); font: 400 11.5px/1.55 -apple-system, BlinkMacSystemFont, system-ui, sans-serif; }
.alphabets-exp-nodes { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 9px; }
.alphabets-exp-node {
  padding: 3px 9px;
  border: 1px solid rgba(212,165,90,0.3);
  border-radius: 999px;
  background: transparent;
  color: var(--text-2, #b9bec8);
  font: 400 9.5px/1.2 "JetBrains Mono", ui-monospace, monospace;
  cursor: pointer;
}
.alphabets-exp-node:hover { border-color: var(--gold, #d4a55a); color: var(--gold, #d4a55a); }

/* 2026-06-16 — script → language → scripture rail (Alphabets glyph view) */
.alphabets-rail { margin: 22px 2px 6px; padding-top: 16px; border-top: 1px solid rgba(255,255,255,0.08); }
.alphabets-rail-head {
  font: 500 10px/1.4 "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-3, #8a8f99); margin-bottom: 13px;
}
.alphabets-rail-arr { color: var(--text-3, #8a8f99); opacity: 0.6; margin: 0 2px; }
.alphabets-rail-codex { color: var(--gold, #d4a55a); }
.alphabets-rail-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 8px 0; border-bottom: 1px solid rgba(255,255,255,0.05);
}
.alphabets-rail-lang {
  flex: 0 0 auto; padding: 4px 11px;
  border: 1px solid rgba(212,165,90,0.5); border-radius: 6px;
  background: rgba(212,165,90,0.06); color: var(--gold, #d4a55a);
  font: 500 12px/1.25 -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  cursor: pointer;
}
.alphabets-rail-lang:hover { background: var(--gold, #d4a55a); color: #0b0d10; }
.alphabets-rail-texts { display: flex; flex-wrap: wrap; gap: 5px; }
.alphabets-rail-text {
  padding: 3px 9px;
  border: 1px solid rgba(255,255,255,0.14); border-radius: 6px;
  background: transparent; color: var(--text-2, #b9bec8);
  font: 400 11px/1.25 -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  cursor: pointer;
}
.alphabets-rail-text:hover { border-color: var(--gold, #d4a55a); color: var(--gold, #d4a55a); }
.alphabets-rail-notexts { color: var(--text-3, #8a8f99); font: 400 11px/1.25 system-ui, sans-serif; opacity: 0.5; }

/* ============================================================
 * Legacy-chrome hide scope — V2 skeleton views
 * Filed 2026-05-28 per AUDIT/2026-05-28-legacy-isolation-locked.md
 *
 * The shared `.view-header` (title + subtitle + view-controls),
 * `aside.detail` (right-rail inspector), `#codex-dev-tab` (Forge
 * dev panel), and the various floating legends + meters live in
 * the V2 shell because Forge + Reader use them. On the new
 * skeleton views (Boards / Map / Star Map) they're dead weight —
 * the contextual app-pill is the only chrome each view should
 * show. Hidden via per-view body-class scope so the slots stay
 * available for any future view that wants them.
 * ============================================================ */
body.view-boards .view-header,
body.view-boards aside.detail,
body.view-boards .legend,
body.view-boards .tier-legend,
body.view-maps .view-header,
body.view-maps .legend,
body.view-maps .tier-legend,
body.view-starmap .view-header,
body.view-starmap aside.detail,
body.view-starmap .legend,
body.view-starmap .tier-legend { display: none !important; }
/* 2026-06-13 — MAP now plots real nodes; clicking one opens the CANONICAL
   aside.detail inspector (window._inspector.show), so it must NOT be hidden
   on view-maps. (It WAS hidden while MAP was a skeleton with no inspector.)
   Only .view-header / .legend / .tier-legend stay hidden — the map doesn't
   use those. STAR MAP is still a skeleton, so it keeps hiding aside.detail. */

/* ════════════════════════════════════════════════════════════════
   FORGE SIDE-PANEL — 2026-05-29 additions
   Action row (between desc and edge buckets), full body markdown
   render (restores V1 content the V2 panel was dropping), refs
   section (V1 had it, V2 was dropping it), body-internal link
   spans.
   ════════════════════════════════════════════════════════════════ */
.forge-side-panel-actions {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin: 0 0 14px;
}
.forge-side-panel-action {
  appearance: none;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px;
  background: rgba(212,165,90,0.06);
  border: 1px solid rgba(212,165,90,0.30);
  border-radius: 4px;
  color: var(--gold, #d4a55a);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 10.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.forge-side-panel-action:hover {
  background: rgba(212,165,90,0.14);
  border-color: rgba(212,165,90,0.55);
  color: #f0c879;
}
.forge-side-panel-action:active { transform: translateY(1px); }
.forge-side-panel-action.is-just-added {
  background: rgba(127,194,139,0.18);
  border-color: rgba(127,194,139,0.55);
  color: #9fd9a8;
}
.forge-side-panel-action-glyph {
  font-size: 13px;
  line-height: 1;
}
.forge-side-panel-action-label {
  letter-spacing: 0.06em;
}

/* Vault body (markdown-rendered). Earlier V2 was dropping this entirely
   and showing only the Wikipedia extract (which was source-truncated,
   producing the "third- and sec…" cut-off John flagged). Restoring
   n.body fixes the cropping at the source. */
.forge-side-panel-body {
  margin: 14px 0 10px;
  padding-top: 14px;
  border-top: 1px solid rgba(212,165,90,0.10);
  color: var(--text-1, #d6d2c4);
  /* 2026-06-10 — prose reads SANS. The content wrapper (line ~7827)
     forces var(--mono) on the whole panel — right for the chrome
     (labels/meta/pills), wrong for long node bodies, which rendered
     as a terminal wall and read as "the old prototype panel" (John).
     Body + refs override back to the app's reading face. */
  font-family: var(--sans, "Inter", -apple-system, sans-serif);
  font-size: 12.5px;
  line-height: 1.62;
}
.forge-side-panel-refs { font-family: var(--sans, "Inter", -apple-system, sans-serif); }
.forge-side-panel-body h1,
.forge-side-panel-body h2,
.forge-side-panel-body h3,
.forge-side-panel-body h4 {
  color: var(--gold, #d4a55a);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 500;
  margin: 14px 0 6px;
}
.forge-side-panel-body h1 { font-size: 12px; }
.forge-side-panel-body h2 { font-size: 11px; }
.forge-side-panel-body p {
  margin: 0 0 10px;
}
.forge-side-panel-body ul,
.forge-side-panel-body ol {
  margin: 0 0 10px;
  padding-left: 22px;
}
.forge-side-panel-body li { margin-bottom: 3px; }
.forge-side-panel-body strong { color: var(--text-0, #f0eee8); }
.forge-side-panel-body em { color: var(--text-1, #d6d2c4); }
.forge-side-panel-body code {
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 11px;
  color: var(--text-0, #f0eee8);
  background: rgba(255,255,255,0.04);
  padding: 0 4px;
  border-radius: 3px;
}
.forge-side-panel-body blockquote {
  border-left: 2px solid rgba(212,165,90,0.30);
  padding: 0 0 0 12px;
  margin: 0 0 10px;
  color: var(--text-2, #b0aa9c);
}
.forge-side-panel-body-link {
  color: var(--gold, #d4a55a);
  cursor: pointer;
  text-decoration: none;
  border-bottom: 1px dashed rgba(212,165,90,0.30);
}
.forge-side-panel-body-link:hover {
  color: #f0c879;
  border-bottom-color: rgba(212,165,90,0.60);
}

.forge-side-panel-section-h {
  margin: 18px 0 8px;
  color: var(--gold, #d4a55a);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 500;
}
.forge-side-panel-refs {
  margin: 0 0 10px;
  padding-left: 22px;
  font-size: 11px;
  color: var(--text-2, #b0aa9c);
  line-height: 1.5;
}
.forge-side-panel-refs li { margin-bottom: 4px; }
.forge-side-panel-refs em { color: var(--text-1, #d6d2c4); }
.forge-side-panel-refs a {
  color: var(--gold, #d4a55a);
  text-decoration: none;
}
.forge-side-panel-refs a:hover { color: #f0c879; }
.forge-side-panel-ref-tier {
  display: inline-block;
  padding: 0 4px;
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
  font-size: 9px;
  color: var(--text-3, #5a5e6a);
  border: 1px solid rgba(212,165,90,0.20);
  border-radius: 3px;
  margin-left: 4px;
  letter-spacing: 0.06em;
}

/* ════════════════════════════════════════════════════════════════
   BOARDS — bottom view-options strip
   ════════════════════════════════════════════════════════════════
   v3: pure container — every interactive cell reuses canonical
   .forge-viewset-* (VIEW button + drop-up panel) and
   .forge-legend-* (wire-bucket rows). Zero forked chrome — Boards
   speaks the exact same vocabulary the Atlas/Forge chart already
   ships. The bottombar itself is just the positioning anchor.
   ════════════════════════════════════════════════════════════════ */
.boards-bottombar {
  position: fixed;
  left: 14px;
  bottom: 14px;
  z-index: 200;
  display: none;
  align-items: stretch;
  gap: 6px;
  pointer-events: auto;
}
body.view-boards .boards-bottombar { display: inline-flex; }
/* Lift the multi-card-selection bar so it doesn't collide with
   the bottombar (bottombar permanent on boards; multi-bar
   appears when ≥1 cards are selected). */
body.view-boards .boards-multi-bar { bottom: 64px; }

/* Right-click context menu on an empty board area. Sits next to
   the cursor; closes on outside-click or Escape. First (and right
   now only) item is "Add node…" — opens the existing Add-node
   search picker. */
.boards-empty-context-menu {
  position: fixed;
  z-index: 380;
  min-width: 180px;
  padding: 4px 0;
  background: rgba(13,17,25,0.96);
  border: 1px solid rgba(212,165,90,0.30);
  border-radius: 6px;
  box-shadow: 0 10px 26px rgba(0,0,0,0.46);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  font-family: var(--mono, "JetBrains Mono", Menlo, monospace);
}
.boards-empty-context-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 14px;
  font-size: 11px;
  color: var(--text-0, #f0eee8);
  cursor: pointer;
  background: transparent;
  border: 0; width: 100%; text-align: left;
}
.boards-empty-context-item:hover {
  background: rgba(212,165,90,0.10);
  color: var(--gold, #d4a55a);
}
.boards-empty-context-glyph {
  color: var(--gold, #d4a55a);
  width: 14px;
  text-align: center;
}

/* ════════════════════════════════════════════════════════════════
   DEV OVERVIEW PANEL — 2026-05-29
   Operator-facing macro view of vault coverage (per-lens + per-family
   counts vs scholarly ballpark baseline). Launched from ✦ user-menu →
   Dev → Overview. Self-contained overlay, reuses canonical theme
   vars (--bg-*, --text-*, --gold, --mono) per SEVERITY DOGMA.
   ════════════════════════════════════════════════════════════════ */
.dev-overview-host {
  position: fixed; inset: 0;
  z-index: 480;            /* above everything but below the trigger ✦ */
  display: none;
}
.dev-overview-host.is-open { display: block; }
.dev-overview-backdrop {
  position: absolute; inset: 0;
  background: rgba(4,6,10,0.78);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.dev-overview-pane {
  position: absolute;
  top: 4vh; bottom: 4vh; left: 4vw; right: 4vw;
  display: flex; flex-direction: column;
  background: var(--bg-1, #0d1119);
  border: 1px solid rgba(212,165,90,0.22);
  border-radius: 12px;
  box-shadow: 0 24px 80px rgba(0,0,0,0.55);
  overflow: hidden;
}
.dev-overview-topbar {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 22px;
  border-bottom: 1px solid rgba(212,165,90,0.14);
  background: var(--bg-2, #141a26);
}
.dev-overview-title {
  display: flex; align-items: baseline; gap: 12px;
  font-family: var(--mono);
}
.dev-overview-title-glyph {
  color: var(--gold);
  font-size: 16px;
  line-height: 1;
}
.dev-overview-title-text {
  color: var(--text-0);
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
.dev-overview-title-hint {
  color: var(--text-3);
  font-size: 10px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
}
.dev-overview-close {
  background: transparent;
  border: 1px solid rgba(212,165,90,0.20);
  color: var(--text-1);
  font-family: var(--mono);
  font-size: 13px;
  width: 30px; height: 30px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 100ms ease, color 100ms ease, border-color 100ms ease;
}
.dev-overview-close:hover {
  color: var(--gold);
  border-color: var(--gold-soft);
  background: rgba(212,165,90,0.06);
}
.dev-overview-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 22px 22px 44px 22px;
  color: var(--text-1);
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.55;
}
.dev-overview-loading,
.dev-overview-error {
  padding: 60px 20px;
  text-align: center;
  color: var(--text-2);
  font-family: var(--mono);
  font-size: 12px;
}
.dev-overview-error h3 { color: var(--gold); margin: 0 0 10px 0; }
.dev-overview-error code { color: var(--text-1); }

.dev-overview-section { margin: 0 0 32px 0; }
.dev-overview-section-h {
  margin: 0 0 14px 0;
  color: var(--gold);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 500;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(212,165,90,0.14);
}
.dev-overview-h-hint {
  color: var(--text-3);
  font-size: 10px;
  letter-spacing: 0.10em;
  text-transform: none;
  margin-left: 8px;
}

/* Summary stat grid */
.dev-overview-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-bottom: 14px;
}
.dev-overview-stat {
  background: var(--bg-2);
  border: 1px solid rgba(212,165,90,0.10);
  border-radius: 8px;
  padding: 14px 16px;
}
.dev-overview-stat-num {
  font-family: var(--mono);
  font-size: 24px;
  font-weight: 500;
  color: var(--text-0);
  line-height: 1.1;
  letter-spacing: 0.01em;
}
.dev-overview-stat-unit {
  font-size: 14px;
  color: var(--text-2);
  margin-left: 2px;
}
.dev-overview-stat-lbl {
  margin-top: 4px;
  font-size: 9.5px;
  color: var(--text-3);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Band-distribution strip */
.dev-overview-band-strip {
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap;
  margin-top: 12px;
  padding: 10px 14px;
  background: var(--bg-2);
  border: 1px solid rgba(212,165,90,0.10);
  border-radius: 8px;
}
.dev-overview-band-strip-pip {
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid;
  font-family: var(--mono);
  font-size: 10.5px;
}
.dev-overview-band-strip-n { font-weight: 500; }
.dev-overview-band-strip-l {
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.85;
}
.dev-overview-band-strip-lbl {
  margin-left: auto;
  color: var(--text-3);
  font-size: 10px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
}

/* Table */
.dev-overview-table-wrap {
  overflow-x: auto;
  border: 1px solid rgba(212,165,90,0.10);
  border-radius: 8px;
  background: var(--bg-2);
}
.dev-overview-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--mono);
  font-size: 11px;
}
.dev-overview-table thead th {
  position: sticky; top: 0;
  background: var(--bg-3, #1c2333);
  color: var(--text-3);
  font-weight: 500;
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid rgba(212,165,90,0.14);
  white-space: nowrap;
}
.dev-overview-table td {
  padding: 9px 12px;
  border-bottom: 1px solid rgba(212,165,90,0.06);
  vertical-align: middle;
}
.dev-overview-table tbody tr:last-child td { border-bottom: 0; }
.dev-overview-row:hover td { background: rgba(212,165,90,0.04); }

.dev-overview-col-num,
.dev-overview-col-pct  { text-align: right; font-variant-numeric: tabular-nums; }
.dev-overview-col-pct  { color: var(--text-0); font-weight: 500; }
.dev-overview-col-base { color: var(--text-2); cursor: help; }
.dev-overview-col-band { width: 1%; white-space: nowrap; }
.dev-overview-col-bar  { width: 22%; min-width: 160px; }
.dev-overview-col-statuses {
  font-size: 10px;
  color: var(--text-3);
  font-family: var(--mono);
}
.dev-overview-cell-main { color: var(--text-0); }
.dev-overview-cell-sub {
  font-size: 9.5px;
  color: var(--text-3);
  margin-top: 2px;
  letter-spacing: 0.04em;
}

/* Progress bar */
.dev-overview-bar {
  position: relative;
  height: 8px;
  background: rgba(255,255,255,0.04);
  border-radius: 4px;
  overflow: hidden;
}
.dev-overview-bar-fill {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: var(--gold-soft);
  border-radius: 4px;
  transition: width 200ms ease;
}
.dev-overview-bar-100 {
  position: absolute;
  /* 100% of baseline at 66.7% width since bar maxes at 150% */
  left: 66.67%;
  top: -2px; bottom: -2px;
  width: 1px;
  background: rgba(255,255,255,0.20);
}
.dev-overview-bar[data-band="anemic"]        .dev-overview-bar-fill { background: #c8554a; }
.dev-overview-bar[data-band="developing"]    .dev-overview-bar-fill { background: #d4a55a; }
.dev-overview-bar[data-band="rich"]          .dev-overview-bar-fill { background: #5fa86a; }
.dev-overview-bar[data-band="over-baseline"] .dev-overview-bar-fill { background: #5e95d9; }

/* Band pill */
.dev-overview-band-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
}
.dev-overview-band-pill[data-band="anemic"],
.dev-overview-band-strip-pip[data-band="anemic"]        { color: #d97a70; border-color: rgba(217,122,112,0.40); background: rgba(217,122,112,0.06); }
.dev-overview-band-pill[data-band="developing"],
.dev-overview-band-strip-pip[data-band="developing"]    { color: #d4a55a; border-color: rgba(212,165,90,0.40); background: rgba(212,165,90,0.06); }
.dev-overview-band-pill[data-band="rich"],
.dev-overview-band-strip-pip[data-band="rich"]          { color: #7fc28b; border-color: rgba(127,194,139,0.40); background: rgba(127,194,139,0.06); }
.dev-overview-band-pill[data-band="over-baseline"],
.dev-overview-band-strip-pip[data-band="over-baseline"] { color: #7fb0e8; border-color: rgba(127,176,232,0.40); background: rgba(127,176,232,0.06); }
.dev-overview-band-pill[data-band="index"],
.dev-overview-band-strip-pip[data-band="index"]         { color: var(--text-3); border-color: rgba(140,140,140,0.30); }

.dev-overview-row--anemic       .dev-overview-col-label .dev-overview-cell-main { color: #f0c2bd; }
.dev-overview-row--over-baseline .dev-overview-col-label .dev-overview-cell-main { color: #c8dffa; }

/* Methodology */
.dev-overview-method-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px;
  background: var(--bg-2);
  border: 1px solid rgba(212,165,90,0.10);
  border-radius: 8px;
  padding: 18px 22px;
}
@media (max-width: 900px) {
  .dev-overview-method-grid { grid-template-columns: 1fr; gap: 18px; }
}
.dev-overview-method h4 {
  margin: 14px 0 6px 0;
  color: var(--gold);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 500;
}
.dev-overview-method h4:first-child { margin-top: 0; }
.dev-overview-method p {
  margin: 0 0 8px 0;
  color: var(--text-1);
  font-size: 11px;
  line-height: 1.6;
}
.dev-overview-band-list,
.dev-overview-caveats {
  list-style: none;
  padding: 0; margin: 0;
}
.dev-overview-band-list li {
  margin-bottom: 6px;
  display: flex; align-items: center; gap: 10px;
}
.dev-overview-band-desc {
  color: var(--text-2);
  font-size: 10.5px;
}
.dev-overview-caveats li {
  position: relative;
  padding-left: 14px;
  margin-bottom: 5px;
  color: var(--text-2);
  font-size: 10.5px;
}
.dev-overview-caveats li::before {
  content: "·";
  position: absolute; left: 4px;
  color: var(--gold-soft);
}
.dev-overview-unmatched {
  margin-top: 18px;
  background: var(--bg-2);
  border: 1px solid rgba(212,165,90,0.10);
  border-radius: 8px;
  padding: 12px 18px;
}
.dev-overview-unmatched summary {
  cursor: pointer;
  color: var(--text-1);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
}
.dev-overview-unmatched-list {
  list-style: none;
  padding: 12px 0 4px 0; margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 4px 18px;
}
.dev-overview-unmatched-list li {
  display: flex; gap: 8px; align-items: baseline;
  padding: 2px 0;
  border-bottom: 1px dotted rgba(212,165,90,0.06);
}
.dev-overview-unmatched-trad {
  flex: 1 1 auto;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--text-1);
  background: transparent;
  padding: 0;
  word-break: break-word;
}
.dev-overview-unmatched-count {
  color: var(--gold-soft);
  font-size: 10px;
  flex: 0 0 auto;
}

.dev-overview-footer {
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid rgba(212,165,90,0.10);
  display: flex; gap: 10px;
  font-family: var(--mono);
  font-size: 9.5px;
  color: var(--text-3);
  letter-spacing: 0.06em;
}
.dev-overview-footer code {
  color: var(--text-1);
  background: rgba(255,255,255,0.03);
  padding: 0 4px;
  border-radius: 3px;
}

/* ══════════════════════════════════════════════════════════════
   CONSTRUCTION NOTE (2026-06-13) — interim surface for not-yet-built
   Sections (MAP, STAR MAP). View-owned: rendered INSIDE the section's
   own pane by its VIEWS.* renderer (rule #8 — no global chrome).
   Deleted with the placeholder when the real build lands.
   ══════════════════════════════════════════════════════════════ */
.construction-note {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
  pointer-events: none;
}
.construction-note .construction-glyph {
  font-size: 64px;
  line-height: 1;
  color: rgba(212, 175, 110, 0.38);
}
.construction-note .construction-title {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  color: rgba(232, 226, 214, 0.55);
}
.construction-note .construction-sub {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.08em;
  line-height: 1.7;
  max-width: 440px;
  color: rgba(232, 226, 214, 0.34);
}

/* ════════════════════════════════════════════════════════════
   THE THRESHOLD — first-run door (2026-07-16, alpha go-online)
   Full-screen overlay OVER the live Forge wheel. Full-screen-modal
   z-tier (100–110, architecture §2). The card is glass (inherits each
   theme's --panel-* tokens) so it frosts the wheel behind it.
   ════════════════════════════════════════════════════════════ */
.threshold {
  position: fixed; inset: 0;
  z-index: 105;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; visibility: hidden;
  transition: opacity var(--t-overlay) var(--ease), visibility 0s linear var(--t-overlay);
}
.threshold.is-open { opacity: 1; visibility: visible; transition: opacity var(--t-overlay) var(--ease); }

.threshold-scrim {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at 50% 46%,
    rgba(7,9,15,0.82) 0%, rgba(7,9,15,0.58) 52%, rgba(7,9,15,0.28) 100%);
  cursor: pointer;
}

.threshold-card {
  position: relative;
  width: min(660px, 88%);
  text-align: center;
  padding: 42px 48px 26px;
  border-radius: 12px;
  background: var(--panel-bg);
  -webkit-backdrop-filter: var(--panel-blur); backdrop-filter: var(--panel-blur);
  border: 1px solid rgba(212,165,90,0.28);
  box-shadow: 0 20px 60px -12px rgba(0,0,0,0.7);
  transform: translateY(8px) scale(0.985);
  transition: transform var(--t-overlay) var(--ease-out-expo);
}
.threshold.is-open .threshold-card { transform: translateY(0) scale(1); }

.threshold-glyph { color: var(--gold); font-size: 19px; letter-spacing: 0.5em; text-indent: 0.5em; }
.threshold-title {
  font-family: var(--serif); font-weight: 500; font-size: 40px; letter-spacing: 0.075em;
  color: var(--text-0); margin: 12px 0 0;
}
.threshold-rule {
  width: 42px; height: 1px; margin: 18px auto;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
}
.threshold-line {
  font-family: var(--serif); font-style: italic; font-size: 16px; line-height: 1.5;
  color: var(--text-1); max-width: 470px; margin: 0 auto;
}
.threshold-stats {
  font-family: var(--mono); font-size: var(--lbl-sm); letter-spacing: 0.2em;
  color: var(--gold-soft); text-transform: uppercase; margin-top: 16px;
}

.threshold-doors {
  display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; margin-top: 26px;
}
@media (max-width: 640px) { .threshold-doors { grid-template-columns: 1fr; } }
.threshold-door {
  text-align: left; cursor: pointer;
  padding: 15px 14px 13px; border-radius: 4px;
  background: rgba(20,26,38,0.55);
  border: 1px solid var(--border);
  transition: border-color var(--t-micro) var(--ease), background var(--t-micro) var(--ease), transform var(--t-micro) var(--ease);
}
.threshold-door:hover {
  border-color: rgba(212,165,90,0.55);
  background: var(--bg-3);
  transform: translateY(-1px);
}
.threshold-door-label {
  display: block;
  font-family: var(--mono); font-size: var(--lbl-md); letter-spacing: 0.14em;
  color: var(--gold); text-transform: uppercase;
}
.threshold-door-copy {
  display: block; margin-top: 6px;
  font-family: var(--serif); font-style: italic; font-size: 12.5px; line-height: 1.45;
  color: var(--text-2);
}
.threshold-door:hover .threshold-door-copy { color: var(--text-1); }

.threshold-exit {
  display: block; margin: 24px auto 0; background: transparent; border: 0; cursor: pointer;
  font-family: var(--mono); font-size: var(--micro); letter-spacing: 0.18em;
  color: var(--text-3); text-transform: uppercase;
  transition: color var(--t-micro) var(--ease);
}
.threshold-exit:hover { color: var(--gold-soft); }

@media (prefers-reduced-motion: reduce) {
  .threshold, .threshold-card { transition: opacity 120ms linear; }
  .threshold-card { transform: none; }
}

/* ════════════════════════════════════════════════════════════
   THE FOLIO — personal page (2026-07-16, alpha go-online)
   Full-screen glass overlay reached from ✦ → Your Folio. Identity card
   (avatar + badge picker + name + seal + theme picker) left, boards shelf
   right. Full-screen-modal z-tier (100–110, architecture §2).
   ════════════════════════════════════════════════════════════ */
.folio {
  position: fixed; inset: 0; z-index: 104;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; visibility: hidden;
  transition: opacity var(--t-overlay) var(--ease), visibility 0s linear var(--t-overlay);
}
.folio.is-open { opacity: 1; visibility: visible; transition: opacity var(--t-overlay) var(--ease); }
.folio-scrim {
  position: absolute; inset: 0; cursor: pointer;
  background: radial-gradient(ellipse at 50% 40%, rgba(7,9,15,0.72), rgba(7,9,15,0.9));
}
.folio-card {
  position: relative;
  width: min(920px, 92%); max-height: 88vh; overflow: hidden;
  display: flex; flex-direction: column;
  border-radius: 12px;
  background: var(--panel-bg);
  -webkit-backdrop-filter: var(--panel-blur); backdrop-filter: var(--panel-blur);
  border: 1px solid rgba(212,165,90,0.24);
  box-shadow: 0 24px 64px -14px rgba(0,0,0,0.72);
  transform: translateY(8px) scale(0.99);
  transition: transform var(--t-overlay) var(--ease-out-expo);
}
.folio.is-open .folio-card { transform: translateY(0) scale(1); }
.folio-topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px; border-bottom: 1px solid var(--border-soft);
  flex-shrink: 0;
}
.folio-brand { font-family: var(--mono); font-size: var(--lbl-sm); letter-spacing: 0.22em; text-transform: uppercase; color: var(--gold-soft); }
.folio-brand-glyph { color: var(--gold); margin-right: 4px; }
.folio-close {
  background: transparent; border: 0; cursor: pointer; color: var(--text-2);
  font-size: 20px; line-height: 1; padding: 2px 6px; border-radius: 3px;
  transition: color var(--t-micro) var(--ease);
}
.folio-close:hover { color: var(--gold); }

.folio-grid {
  display: grid; grid-template-columns: 300px 1fr; gap: 0;
  overflow-y: auto;
}
@media (max-width: 780px) { .folio-grid { grid-template-columns: 1fr; } }

.folio-identity {
  padding: 28px 24px; text-align: center;
  border-right: 1px solid var(--border-soft);
}
@media (max-width: 780px) { .folio-identity { border-right: 0; border-bottom: 1px solid var(--border-soft); } }

.folio-avatar {
  width: 104px; height: 104px; border-radius: 50%;
  margin: 0 auto; position: relative;
  border: 1px solid rgba(212,165,90,0.6);
  padding: 5px;
  box-shadow: 0 0 0 5px rgba(212,165,90,0.12);
}
.folio-avatar-bg {
  position: absolute; inset: 5px; border-radius: 50%; overflow: hidden;
}
.folio-avatar-bg svg { width: 100%; height: 100%; display: block; }
.folio-avatar-initial {
  position: absolute; inset: 5px; display: flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-weight: 500; font-size: 46px; color: #fff;
  text-shadow: 0 1px 8px rgba(0,0,0,0.55);
}
.folio-name-row {
  margin-top: 18px; display: flex; align-items: baseline; gap: 8px; justify-content: center;
}
.folio-name { font-family: var(--serif); font-size: var(--h1-size); font-weight: 500; color: var(--text-0); letter-spacing: 0.02em; }
.folio-name-edit {
  background: transparent; border: 1px solid var(--border); border-radius: 3px; cursor: pointer;
  color: var(--text-3); font-size: 10px; padding: 2px 6px;
  transition: color var(--t-micro) var(--ease), border-color var(--t-micro) var(--ease);
}
.folio-name-edit:hover { color: var(--gold); border-color: rgba(212,165,90,0.45); }

.folio-id-rows { margin-top: 18px; border-top: 1px solid var(--border-soft); }
.folio-id-row {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 8px 2px; border-bottom: 1px solid var(--border-soft); font-family: var(--mono);
}
.folio-id-row .rk { font-size: var(--micro); letter-spacing: 0.18em; color: var(--text-3); text-transform: uppercase; }
.folio-id-row .rv { font-size: var(--lbl-md); color: var(--text-1); letter-spacing: 0.03em; }
.folio-id-row .rv.gold { color: var(--gold); }

.folio-sect { margin-top: 20px; text-align: left; }
.folio-sect-label {
  font-family: var(--mono); font-size: var(--micro); letter-spacing: 0.2em;
  color: var(--text-3); text-transform: uppercase; margin-bottom: 10px;
}
.folio-badge-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.folio-badge-swatch {
  aspect-ratio: 1; border-radius: 50%; overflow: hidden; cursor: pointer; padding: 0;
  border: 1px solid var(--border);
  transition: transform var(--t-micro) var(--ease), box-shadow var(--t-micro) var(--ease);
}
.folio-badge-swatch svg { width: 100%; height: 100%; display: block; }
.folio-badge-swatch:hover { transform: scale(1.08); }
.folio-badge-swatch.is-active { box-shadow: 0 0 0 2px var(--gold); border-color: var(--gold); }

.folio-theme-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.folio-theme-swatch {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  background: transparent; border: 0; cursor: pointer; padding: 4px 0;
}
.folio-theme-chip {
  width: 34px; height: 34px; border-radius: 8px; border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  transition: box-shadow var(--t-micro) var(--ease), transform var(--t-micro) var(--ease);
}
.folio-theme-swatch:hover .folio-theme-chip { transform: scale(1.08); }
.folio-theme-swatch.is-active .folio-theme-chip { box-shadow: 0 0 0 2px var(--gold); }
.folio-theme-dot { width: 10px; height: 10px; border-radius: 50%; }
.folio-theme-name {
  font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-3);
}
.folio-theme-swatch.is-active .folio-theme-name { color: var(--gold); }

.folio-shelf { padding: 24px 26px; min-width: 0; }
.folio-shelf-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.folio-shelf-label { font-family: var(--mono); font-size: var(--lbl-sm); letter-spacing: 0.22em; color: var(--gold-soft); text-transform: uppercase; }
.folio-shelf-count { font-family: var(--mono); font-size: var(--micro); color: var(--text-2); border: 1px solid var(--border); border-radius: 999px; padding: 1px 8px; }

.folio-board-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 560px) { .folio-board-grid { grid-template-columns: 1fr; } }
.folio-board-card {
  text-align: left; cursor: pointer;
  background: var(--bg-1); border: 1px solid var(--border); border-radius: 4px;
  padding: 13px 14px; display: flex; flex-direction: column; gap: 5px;
  transition: border-color var(--t-micro) var(--ease), background var(--t-micro) var(--ease), transform var(--t-micro) var(--ease);
}
.folio-board-card:hover { border-color: rgba(212,165,90,0.5); background: var(--bg-2); transform: translateY(-2px); }
.folio-board-name { font-family: var(--serif); font-size: 15.5px; font-weight: 500; color: var(--text-0); letter-spacing: 0.02em; }
.folio-board-meta { font-family: var(--mono); font-size: var(--micro); letter-spacing: 0.08em; color: var(--text-3); text-transform: uppercase; }

.folio-boards-empty {
  border: 1px dashed var(--border); border-radius: 4px; padding: 22px 20px; text-align: center;
}
.folio-boards-empty p { font-family: var(--serif); font-style: italic; font-size: 13.5px; color: var(--text-2); line-height: 1.55; margin: 0 0 14px; }
.folio-boards-empty em { color: var(--gold); font-style: italic; }

.folio-ghost {
  margin-top: 16px; border: 1px dashed var(--border); border-radius: 4px;
  padding: 12px 16px; display: flex; align-items: baseline; gap: 12px; opacity: 0.5;
}
.folio-ghost-k { font-family: var(--mono); font-size: var(--lbl-sm); letter-spacing: 0.18em; color: var(--text-3); text-transform: uppercase; white-space: nowrap; }
.folio-ghost-c { font-family: var(--serif); font-style: italic; font-size: 12.5px; color: var(--text-3); }

@media (prefers-reduced-motion: reduce) {
  .folio, .folio-card { transition: opacity 120ms linear; }
  .folio-card { transform: none; }
}

/* ============================================================
 * master-pill dropdown — grouped + narrated (2026-07-16)
 * Surface 05 ("A narrated map"). Same 7 targets, same routing —
 * the master menu only gains EXPLORE / STUDY / YOURS headers
 * (reusing .app-pill-menu-section-label) and one italic-serif
 * microcopy line per row. Modifier classes scope the two-line
 * layout so the class menu keeps its compact form. Base row
 * hover / :focus / .is-focused / .is-active states come from the
 * existing .app-pill-menu-item rules (architecture §4).
 * ============================================================ */
.app-pill-menu--narrated {
  min-width: 232px;         /* room for the microcopy line */
}
.app-pill-menu-item--narrated {
  align-items: flex-start;  /* two-line rows top-align */
}
.app-pill-menu-item--narrated .app-pill-menu-check {
  margin-top: 3px;          /* optically centers ● on the label line */
}
.app-pill-menu-text {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.app-pill-menu-copy {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--lbl-md);
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--text-2);
  transition: color var(--t-micro) var(--ease);
}
/* engaged rows (hover / keyboard focus / active view) lift the
   microcopy one text step so the narration reads with the label */
.app-pill-menu-item--narrated:hover .app-pill-menu-copy,
.app-pill-menu-item--narrated:focus .app-pill-menu-copy,
.app-pill-menu-item--narrated.is-focused .app-pill-menu-copy,
.app-pill-menu-item--narrated.is-active .app-pill-menu-copy {
  color: var(--text-1);
}

/* ============================================================
 * ✦ menu identity header (2026-07-16 — surface 05)
 * Top of the account drawer: illuminated-initial avatar in a gold
 * ring + Folio display name (serif) + mono "View folio ↦" link.
 * The whole strip is ONE <button data-action="folio"> — it rides
 * the existing user-menu action router to window._folio.open().
 * Gold rgba steps (0.08 / 0.12 / 0.14) match the existing
 * user-menu / app-pill hover vocabulary — no new color values.
 * ============================================================ */
.user-menu-identity {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 14px;
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
  transition: background var(--t-micro) var(--ease);
}
.user-menu-identity:hover {
  background: rgba(212,165,90,0.08);
}
.user-menu-identity:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: -2px;
  border-radius: 3px;
  background: rgba(212,165,90,0.08);
}
.user-menu-identity:active {
  background: rgba(212,165,90,0.14);
}
.user-menu-identity-avatar {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  border: 1px solid var(--gold);
  box-shadow: 0 0 0 3px rgba(212,165,90,0.12);  /* faint outer ring */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--serif);
  font-size: var(--h3-size);
  line-height: 1;
  color: var(--gold);
}
.user-menu-identity-text {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.user-menu-identity-name {
  font-family: var(--serif);
  font-size: var(--h3-size);
  line-height: 1.2;
  letter-spacing: 0.02em;
  color: var(--text-0);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.user-menu-identity-link {
  font-family: var(--mono);
  font-size: var(--lbl-sm);
  letter-spacing: 0.08em;
  color: var(--text-2);
  transition: color var(--t-micro) var(--ease);
}
.user-menu-identity:hover .user-menu-identity-link,
.user-menu-identity:focus-visible .user-menu-identity-link,
.user-menu-identity:active .user-menu-identity-link {
  color: var(--gold);
}
@media (prefers-reduced-motion: reduce) {
  .user-menu-identity,
  .user-menu-identity-link,
  .app-pill-menu-copy { transition: none; }
}

/* ════════════════════════════════════════════════════════════
   ✦ SIGN-IN — "Enter the Codex" magic-link modal (2026-07-17, Phase B)
   Full-screen-modal z-tier. Glass card inherits the active theme's --panel-*.
   ════════════════════════════════════════════════════════════ */
.signin {
  position: fixed; inset: 0; z-index: 106;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; visibility: hidden;
  transition: opacity var(--t-overlay) var(--ease), visibility 0s linear var(--t-overlay);
}
.signin.is-open { opacity: 1; visibility: visible; transition: opacity var(--t-overlay) var(--ease); }
.signin-scrim {
  position: absolute; inset: 0; cursor: pointer;
  background: radial-gradient(ellipse at 50% 42%, rgba(7,9,15,0.78), rgba(7,9,15,0.92));
}
.signin-card {
  position: relative; width: min(380px, 90%);
  text-align: center; padding: 36px 34px 26px; border-radius: 12px;
  background: var(--panel-bg);
  -webkit-backdrop-filter: var(--panel-blur); backdrop-filter: var(--panel-blur);
  border: 1px solid rgba(212,165,90,0.26);
  box-shadow: 0 22px 60px -14px rgba(0,0,0,0.72);
  transform: translateY(8px) scale(0.99);
  transition: transform var(--t-overlay) var(--ease-out-expo);
}
.signin.is-open .signin-card { transform: translateY(0) scale(1); }
.signin-close {
  position: absolute; top: 12px; right: 14px; background: transparent; border: 0; cursor: pointer;
  color: var(--text-3); font-size: 20px; line-height: 1; padding: 2px 6px; border-radius: 3px;
  transition: color var(--t-micro) var(--ease);
}
.signin-close:hover { color: var(--gold); }
.signin-glyph { color: var(--gold); font-size: 16px; letter-spacing: 0.4em; text-indent: 0.4em; }
.signin-title { font-family: var(--serif); font-weight: 500; font-size: var(--h1-size); letter-spacing: 0.05em; color: var(--text-0); margin: 10px 0 0; }
.signin-copy { font-family: var(--serif); font-style: italic; font-size: 13.5px; line-height: 1.5; color: var(--text-2); margin: 8px auto 0; max-width: 280px; }
.signin-form { margin-top: 22px; display: flex; flex-direction: column; gap: 12px; }
.signin-field {
  width: 100%; background: var(--bg-2); border: 1px solid var(--border); border-radius: 3px;
  padding: 11px 13px; font-family: var(--mono); font-size: var(--lbl-lg); letter-spacing: 0.03em;
  color: var(--text-0); text-align: left;
  transition: border-color var(--t-micro) var(--ease);
}
.signin-field::placeholder { color: var(--text-3); }
.signin-field:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-color: rgba(212,165,90,0.5); }
.signin-btn {
  width: 100%; background: rgba(212,165,90,0.12); border: 1px solid rgba(212,165,90,0.5); border-radius: 3px;
  padding: 11px; font-family: var(--mono); font-size: var(--lbl-md); letter-spacing: 0.2em;
  color: var(--gold); text-transform: uppercase; cursor: pointer;
  transition: background var(--t-micro) var(--ease), color var(--t-micro) var(--ease);
}
.signin-btn:hover { background: rgba(212,165,90,0.2); color: var(--text-0); }
.signin-btn:disabled { opacity: 0.6; cursor: default; }
.signin-error { font-family: var(--mono); font-size: var(--lbl-sm); letter-spacing: 0.04em; color: var(--crimson); min-height: 12px; }
.signin-foot { margin-top: 18px; font-family: var(--mono); font-size: var(--micro); letter-spacing: 0.16em; color: var(--text-3); text-transform: uppercase; }
.signin-sent-glyph { font-size: 26px; color: var(--gold); margin-top: 20px; }
.signin-sent-email { font-family: var(--mono); font-size: var(--lbl-lg); color: var(--text-0); letter-spacing: 0.03em; margin-top: 14px; word-break: break-all; }
.signin-again {
  margin-top: 20px; background: transparent; border: 1px solid var(--border); border-radius: 3px;
  padding: 8px 14px; cursor: pointer;
  font-family: var(--mono); font-size: var(--lbl-sm); letter-spacing: 0.16em; color: var(--text-2); text-transform: uppercase;
  transition: color var(--t-micro) var(--ease), border-color var(--t-micro) var(--ease);
}
.signin-again:hover { color: var(--gold); border-color: rgba(212,165,90,0.45); }
@media (prefers-reduced-motion: reduce) {
  .signin, .signin-card { transition: opacity 120ms linear; }
  .signin-card { transform: none; }
}

/* ── Alpha gate (2026-07-17) — the sign-in wall on real hosts ──
   In gate mode the modal can't be dismissed (no ✕), and the app behind the
   door is blurred + inert until sign-in. localhost is never gated (dev). */
.signin.is-gate .signin-close { display: none; }
body.alpha-gated #svg-wrap,
body.alpha-gated .canvas,
body.alpha-gated #app-pill-wrap,
body.alpha-gated .user-menu-trigger,
body.alpha-gated .forge-bottombar {
  filter: blur(7px);
  pointer-events: none;
  user-select: none;
}
