/* ============================================================
   AYESTOR — Shared site styles (shell + components)
   Depends on tokens.css (load tokens.css FIRST, then this).
   Shell (header/footer) uses RAW master tokens so it stays
   gold/obsidian on every page regardless of the page skin.
   Page content uses SEMANTIC tokens (--color-*) so it adopts
   the active [data-skin].
   ============================================================ */

*{box-sizing:border-box}
html{scroll-behavior:smooth}
img{display:block;max-width:100%}
a{text-decoration:none;color:var(--color-accent)}
/* 6vw padding is CAPPED at 72px (its value at ~1200px viewport): it sits
   INSIDE the border-box 1180px max-width, so uncapped it starves the content
   area as the viewport grows — on Paul's ultrawide fullscreen (~2600+ CSS px)
   the header lost so much width the nav collided with the brand (7 Jul 2026).
   ≤1200px behaviour is unchanged. */
.wrap{max-width:1180px;margin:0 auto;padding:0 min(6vw,72px)}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}
:focus-visible{outline:2px solid var(--ay-gold);outline-offset:3px}
.skip-link{position:absolute;left:-9999px;top:0;background:var(--ay-gold);color:var(--ay-obsidian);
  padding:10px 16px;border-radius:0 0 8px 0;z-index:100;font-family:var(--font-body);font-weight:600}
.skip-link:focus{left:0}

/* ---------- Header (master shell) ---------- */
header.site{position:sticky;top:0;z-index:50;backdrop-filter:blur(10px);
  background:rgba(11,11,14,.74);border-bottom:1px solid rgba(255,255,255,.08)}
header.site .wrap{display:flex;align-items:center;justify-content:space-between;height:70px}
.brand{display:inline-flex;align-items:center;gap:13px}
.brand img{width:38px;height:38px}
.brand span{font-family:var(--font-display);font-weight:600;font-size:21px;letter-spacing:.16em;color:var(--ay-gold)}
nav.main{display:flex;align-items:center;gap:26px;font-family:var(--font-body)}
nav.main a{color:var(--ay-bone);font-size:13px;letter-spacing:.13em;text-transform:uppercase;opacity:.82;white-space:nowrap}
nav.main a:hover,nav.main a[aria-current="page"]{color:var(--ay-gold-light);opacity:1}
nav.main a.cta{border:1px solid var(--ay-gold);color:var(--ay-gold);padding:8px 16px;border-radius:7px;letter-spacing:.1em}
nav.main a.cta:hover{background:var(--ay-gold);color:var(--ay-obsidian)}

/* ---------- Enhanced dropdown nav (built by assets/js/nav.js) ---------- */
.nav-list{display:flex;align-items:center;gap:26px;list-style:none;margin:0;padding:0}
.nav-item{position:relative}
.nav-item > a{color:var(--ay-bone);font-size:13px;letter-spacing:.13em;text-transform:uppercase;opacity:.82;text-decoration:none;display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
.nav-item > a:hover,.nav-item > a[aria-current="page"]{color:var(--ay-gold-light);opacity:1}
.nav-item.has-sub > a::after{content:"\25BE";font-size:10px;opacity:.7}
.nav-caret{display:none;background:none;border:0;color:inherit;cursor:pointer}
.nav-panel{position:absolute;top:calc(100% + 12px);left:50%;transform:translateX(-50%) translateY(-6px);min-width:250px;
  background:var(--color-surface);border:1px solid var(--color-line);border-radius:12px;padding:8px;
  box-shadow:0 18px 44px rgba(0,0,0,.5);opacity:0;visibility:hidden;transition:opacity .18s ease,transform .18s ease;z-index:60}
.nav-panel::before{content:"";position:absolute;top:-12px;left:0;right:0;height:12px}
.nav-item:hover > .nav-panel,.nav-item:focus-within > .nav-panel,.nav-item.open > .nav-panel{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0)}
.nav-panel ul{list-style:none;margin:0;padding:0}
.nav-panel a{display:block;padding:9px 13px;border-radius:8px;color:var(--ay-bone);font-family:var(--font-body);font-size:12.5px;letter-spacing:.03em;text-transform:none;text-decoration:none;white-space:nowrap;opacity:.86}
.nav-panel a:hover{background:color-mix(in srgb, var(--ay-gold) 14%, transparent);color:var(--ay-gold-light);opacity:1}
.nav-panel a.is-star{color:var(--ay-gold-light)}
.nav-toggle{display:none;background:none;border:0;cursor:pointer;flex-direction:column;gap:5px;padding:6px}
.nav-toggle span{display:block;width:24px;height:2px;background:var(--ay-bone)}

/* Hamburger breakpoint: 980px, NOT 820 — with six top-level items the inline
   nav needs ~950px beside the brand; below that it wraps/overlaps the logo
   (Paul caught this at ~920px on the v1.2.0 draft, 7 Jul 2026). */
@media (max-width:980px){
  .nav-toggle{display:flex}
  .nav-list{display:none;position:absolute;top:70px;left:0;right:0;flex-direction:column;align-items:stretch;gap:0;
    background:var(--ay-obsidian, #0b0b0e);border-top:1px solid var(--color-line);border-bottom:1px solid var(--color-line);
    padding:6px 0;max-height:82vh;overflow:auto}
  header.site nav.main.open .nav-list{display:flex}
  .nav-item{padding:0 6vw}
  .nav-item > a{padding:13px 0;font-size:14px}
  .nav-item.has-sub > a::after{display:none}
  .nav-caret{display:flex;align-items:center;justify-content:center;position:absolute;right:5vw;top:6px;width:40px;height:40px;font-size:15px;color:var(--ay-bone)}
  .nav-panel{position:static;transform:none;opacity:1;visibility:visible;display:none;min-width:0;box-shadow:none;border:0;background:transparent;padding:0 0 6px;transition:none}
  /* transform:none MUST be repeated here. The desktop open/hover rule
     `.nav-item.open > .nav-panel{transform:translateX(-50%)...}` is 0-3-0 and
     out-specifies the plain `.nav-panel` reset above (0-1-0), so the mobile
     panel inherited the desktop half-width centring offset and every submenu
     label sat ~148px off the left edge of a 390px screen — invisible, with no
     horizontal scroll to reveal it. Live since the dropdown nav shipped;
     found by the 26 Jul 2026 external audit, fixed v1.5.0.
     If you add another `.nav-item:state > .nav-panel` rule above, reset it here too. */
  .nav-item.open > .nav-panel{display:block;transform:none}
  .nav-panel a{white-space:normal;padding:9px 16px}
}

/* ---------- Footer (master shell) ---------- */
footer.site{background:#08080a;border-top:1px solid rgba(255,255,255,.08);padding:64px 0 30px;font-family:var(--font-body)}
footer.site .cols{display:grid;grid-template-columns:1.4fr 1fr 1fr 1.3fr;gap:32px}
/* min-width:0 is load-bearing, not tidying (31 Jul 2026). An `fr` track's
   automatic minimum is min-content, and a bare <input> reports a min-content
   width from its default size=20 attribute, roughly 202px. Adding the
   newsletter form to the Follow column therefore PINNED that track at 273.5px
   at every viewport and pushed the whole footer 91px past the right edge at
   375px (doc scrollWidth 451 vs 360). min-width:0 on the input alone does NOT
   fix it: that governs flex distribution inside the form, while the grid sizes
   its track from the column div's min-content. The floor has to be released
   here, on the grid item. */
footer.site .cols > div{min-width:0}
footer.site .brand span{font-size:19px}
footer.site p.tag{font-family:var(--font-lore);font-style:italic;color:var(--ay-bone);opacity:.7;margin:16px 0 0;font-size:15px;max-width:34ch}
footer.site h4{font-family:var(--font-data);font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:var(--ay-gold);margin:0 0 14px;opacity:.85}
footer.site ul{list-style:none;margin:0;padding:0}
footer.site li{margin:0 0 10px}
footer.site a{color:var(--ay-bone);opacity:.78;font-size:14px}
footer.site a:hover{opacity:1;color:var(--ay-gold-light)}
/* Footer newsletter (restored 31 Jul 2026 — hidden 20 Jun 2026 pending a
   provider, and Kit has been the provider since 12 Jul). Deliberately raw
   --ay-* tokens, not --color-*: the footer is master-gold chrome on every
   page, including the skinned world pages. The .joinband component above
   is page CONTENT and does take the skin. */
.news{display:flex;gap:8px;margin-top:12px}
.news input{flex:1;min-width:0;background:#111;border:1px solid rgba(255,255,255,.12);border-radius:7px;padding:10px 12px;color:var(--ay-bone);font-family:var(--font-body)}
.news button{background:var(--ay-gold);color:var(--ay-obsidian);border:none;border-radius:7px;padding:10px 18px;font-weight:600;font-family:var(--font-body);cursor:pointer;white-space:nowrap}
.news button:hover{background:var(--ay-gold-light)}
.newsnote{margin:18px 0 0;font-size:14px;line-height:1.5;color:var(--ay-bone);opacity:.78}
.newsfine{margin:9px 0 0;font-family:var(--font-data);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--ay-bone);opacity:.45}
.tbc{font-size:11px;color:var(--ay-gold);opacity:.6}
footer.site .legal{margin-top:46px;padding-top:22px;border-top:1px solid rgba(255,255,255,.08);
  display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px;font-size:12px;color:var(--ay-bone);opacity:.5}

/* ---------- Newsletter band (shared component) ----------
   MOVED HERE 31 Jul 2026 from index.html's page-scoped <style>. The Proof of
   Human book page had used .joinband/.joinform since v1.5.0 with no rules
   behind them anywhere, so its signup — the only conversion point on the
   book's front door — rendered as raw browser default controls: white input
   on a near-black page, grey OS button, left-aligned, no band at all.
   Skin-aware by design: gold/bone are now --color-accent/--color-text, which
   resolve to the identical values on the master shell (so the homepage is
   unchanged) and to cyan/cool-white under [data-skin="ledger"]. The two dark
   background hexes stay literal on purpose — they make the band read as
   slightly raised on every skin, and tokenising them would have shifted the
   approved homepage. ------------------------------------------------------ */
.joinband{border-top:1px solid var(--color-line);text-align:center;
  background:radial-gradient(60% 120% at 50% 0%, color-mix(in srgb, var(--color-accent) 12%, transparent), transparent 70%),linear-gradient(180deg,#101319,#0b0b0e)}
.joinband .wrap{max-width:680px}
.joinband h2{font-family:var(--skin-display);font-weight:600;font-size:clamp(26px,4.6vw,38px);color:var(--color-text);margin:10px 0 12px}
.joinband p{font-family:var(--font-body);font-size:16px;line-height:1.6;color:var(--color-text);opacity:.82;margin:0 auto 26px;max-width:52ch}
.joinform{display:flex;gap:10px;max-width:460px;margin:0 auto;flex-wrap:wrap;justify-content:center}
.joinform input{flex:1;min-width:220px;background:#0d0d11;border:1px solid rgba(255,255,255,.14);border-radius:8px;padding:14px 16px;color:var(--color-text);font-family:var(--font-body)}
.joinform button{background:var(--color-accent);color:var(--ay-obsidian);border:none;border-radius:8px;padding:14px 26px;font-weight:600;font-family:var(--font-body);cursor:pointer}
.joinform button:hover{background:var(--color-accent-2)}
.joinband .fineprint{font-family:var(--font-data);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--color-text);opacity:.5;margin-top:16px}

/* ---------- Buttons ---------- */
.btn{display:inline-flex;align-items:center;gap:9px;font-family:var(--font-body);font-weight:600;
  font-size:14px;letter-spacing:.04em;padding:13px 24px;border-radius:8px;cursor:pointer;transition:transform .2s ease,background .2s ease,color .2s ease}
.btn--accent{background:var(--color-accent);color:#fff;border:1px solid var(--color-accent)}
.btn--accent:hover{transform:translateY(-2px)}
.btn--ghost{background:transparent;color:var(--color-text);border:1px solid var(--color-text-muted)}
.btn--ghost:hover{border-color:var(--color-accent);color:var(--color-accent)}
.btn .ar{transition:transform .25s ease}
.btn:hover .ar{transform:translateX(4px)}

/* ---------- Section frame ---------- */
main{display:block}
section{padding:78px 0}
.sec-head{margin-bottom:34px}
.sec-head.center{text-align:center}
.ey{font-family:var(--font-data);font-size:12px;letter-spacing:.32em;text-transform:uppercase;color:var(--color-accent);opacity:.9}
.sec-head h2{font-family:var(--skin-display);font-weight:600;font-size:clamp(26px,4.6vw,38px);color:var(--color-text);margin:10px 0 0}

/* ---------- Breadcrumb ---------- */
.crumbs{font-family:var(--font-body);font-size:12px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--color-text-muted);padding:18px 0 0}
.crumbs a{color:var(--color-text-muted)}
.crumbs a:hover{color:var(--color-accent)}

/* ---------- Inner page hero (atmospheric, no photo required) ---------- */
.page-hero{position:relative;text-align:center;padding:96px 6vw 76px;overflow:hidden}
.page-hero::before{content:"";position:absolute;inset:0;z-index:0;
  background:
    radial-gradient(60% 70% at 50% 30%, color-mix(in srgb, var(--color-accent) 24%, transparent), transparent 70%),
    linear-gradient(180deg, var(--color-surface), var(--color-ground))}
.page-hero > *{position:relative;z-index:1}
.page-hero .ey{display:block;margin-bottom:14px}
.page-hero h1{font-family:var(--skin-display);font-weight:700;color:var(--color-text);
  font-size:clamp(40px,8vw,84px);letter-spacing:.05em;margin:0}
.page-hero p.lede{font-family:var(--font-lore);font-style:italic;max-width:60ch;margin:20px auto 0;
  font-size:clamp(17px,2.4vw,21px);line-height:1.6;color:var(--color-text);opacity:.85}

/* ---------- Entry cards (hub -> sub-pages) ---------- */
.entries{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:18px}
.entry{position:relative;display:flex;flex-direction:column;border:1px solid var(--color-line);
  border-radius:14px;padding:26px;background:var(--color-surface);transition:transform .3s ease,border-color .3s ease}
.entry[href]:hover{transform:translateY(-5px);border-color:var(--color-accent)}
.entry .k{font-family:var(--font-data);font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--color-accent);opacity:.85}
.entry h3{font-family:var(--skin-display);font-weight:600;font-size:22px;color:var(--color-text);margin:10px 0 8px;overflow-wrap:anywhere}
.entry p{font-family:var(--font-body);font-size:14px;line-height:1.6;color:var(--color-text);opacity:.78;margin:0}
.entry .go{font-family:var(--font-body);font-weight:600;font-size:13px;color:var(--color-accent);margin-top:16px}
/* The arrow glyph inside a .go affordance: same slide as .btn .ar, so cards and
   buttons behave alike (7 Aug 2026 sweep — 43 .ar spans sat inert inside .go). */
.go .ar{display:inline-block;transition:transform .3s ease}
a:hover .go .ar,a:focus-visible .go .ar{transform:translateX(4px)}
.entry .soon{font-family:var(--font-data);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--color-text-muted);margin-top:16px;border:1px solid var(--color-line);border-radius:20px;padding:4px 12px;align-self:flex-start}
.entry.is-soon{opacity:.72}

/* ---------- Lore / prose reading layout ---------- */
.prose{max-width:72ch;margin:0 auto;font-family:var(--skin-body);color:var(--color-text);font-size:19px;line-height:1.8}
.prose p{margin:0 0 1.3em;opacity:.92}
.prose h2{font-family:var(--skin-display);font-weight:600;font-size:30px;color:var(--color-text);margin:2em 0 .6em;opacity:1}
.prose h3{font-family:var(--skin-display);font-weight:600;font-size:22px;color:var(--color-accent);margin:1.6em 0 .5em}
.prose .lead{font-size:23px;line-height:1.6;opacity:1}
/* Lists inside prose (added 31 Jul 2026 for privacy.html; nothing previously
   used .prose ul, so no page changes shape). */
.prose ul{margin:0 0 1.3em;padding-left:1.3em}
.prose li{margin:0 0 .55em;opacity:.92}
.prose li::marker{color:var(--color-accent)}
.prose .dropcap::first-letter{font-family:var(--skin-display);float:left;font-size:4.4em;line-height:.82;
  padding:6px 12px 0 0;color:var(--color-accent)}
.prose blockquote{margin:1.6em 0;padding:6px 0 6px 22px;border-left:3px solid var(--color-accent);
  font-style:italic;color:var(--color-text)}
/* Section text: body copy that lives inside a .wrap section between full-width
   components (card grids, tables, plates). Spans the whole section rather than a
   narrow left-pinned column (Paul's ruling, 7 Aug 2026 — replaces the old inline
   64/72ch lede pattern on those pages). */
.sectext{font-family:var(--font-body);font-size:17px;line-height:1.75;color:var(--color-text);opacity:.85;margin:0 0 26px}

/* .triad works anywhere, not only inside .prose: inside .prose it stays 72ch with the
   text; inside a .wrap section it spans the section (2026-08-07 fix — a bare .triad
   used to render completely unstyled). */
.triad{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px;margin:1.6em 0;font-family:var(--font-body);font-size:15px;line-height:1.6}
.triad div{border:1px solid var(--color-line);border-radius:12px;padding:18px;background:var(--color-surface)}
.triad b{font-family:var(--skin-display);display:block;color:var(--color-accent);font-size:18px;margin-bottom:6px;font-weight:600}

/* ---------- Books ---------- */
.books{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:26px}
.book{display:flex;flex-direction:column;border:1px solid var(--color-line);border-radius:14px;overflow:hidden;background:var(--color-surface)}
.book__cover{aspect-ratio:2/3;background:#0b0b0e;object-fit:cover;width:100%}
.book__body{padding:22px;display:flex;flex-direction:column;flex:1}
.book .part{font-family:var(--font-data);font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--color-accent)}
.book h3{font-family:var(--skin-display);font-weight:600;font-size:24px;color:var(--color-text);margin:8px 0 4px}
.book .sub{font-family:var(--skin-display);font-size:15px;color:var(--color-text);opacity:.7;margin-bottom:12px}
.book p{font-family:var(--font-body);font-size:14px;line-height:1.6;color:var(--color-text);opacity:.82;margin:0 0 18px}
.book .foot{margin-top:auto}
.badge{display:inline-block;font-family:var(--font-data);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  padding:4px 11px;border-radius:20px;margin-bottom:14px}
.badge--live{background:rgba(156,255,87,.14);color:#bdf08a}
.badge--pre{background:rgba(201,162,75,.16);color:var(--ay-gold-light)}
.badge--soon{background:rgba(255,255,255,.07);color:var(--color-text-muted)}

/* ---------- Lore pull / feature quote ---------- */
.lorepull{border-top:1px solid var(--color-line);border-bottom:1px solid var(--color-line);
  background:linear-gradient(180deg,var(--color-surface),var(--color-ground));text-align:center}
.lorepull .wrap{max-width:840px}
.lorepull blockquote{font-family:var(--font-lore);font-style:italic;font-size:clamp(20px,3.4vw,28px);line-height:1.6;color:var(--color-text);margin:0}
.lorepull blockquote b{color:var(--color-accent);font-weight:400;font-style:normal}
.lorepull .src{font-family:var(--font-data);font-size:12px;letter-spacing:.24em;text-transform:uppercase;color:var(--color-accent);opacity:.85;margin-top:22px}

/* ---------- Featured book strip ---------- */
.feature{display:grid;grid-template-columns:auto 1fr;gap:34px;align-items:center;
  border:1px solid var(--color-line);border-radius:16px;padding:30px;background:var(--color-surface)}
.feature img{width:170px;border-radius:8px;box-shadow:0 14px 40px rgba(0,0,0,.5)}
.feature h3{font-family:var(--skin-display);font-weight:600;font-size:26px;color:var(--color-text);margin:6px 0 10px}
.feature p{font-family:var(--font-body);font-size:15px;line-height:1.6;color:var(--color-text);opacity:.82;max-width:48ch;margin:0 0 18px}

.protonote{background:var(--ay-gold);color:var(--ay-obsidian);text-align:center;font-family:var(--font-data);
  font-size:12px;letter-spacing:.14em;text-transform:uppercase;padding:7px}

/* ---------- Inner-page hero with image backdrop (skin-agnostic) ----------
   Adds a photographic backdrop + legibility veil to .page-hero. The photo
   sits at z0, the veil (::before) at z1, the text at z2. Works in any skin
   because the veil tints toward the active --color-ground / --color-accent. */
.page-hero.has-image{padding-top:118px;padding-bottom:98px}
.page-hero.has-image > *{z-index:2}
.page-hero.has-image .ey,.page-hero.has-image h1,.page-hero.has-image .lede{text-shadow:0 2px 20px rgba(0,0,0,.62)}
.page-hero.has-image::before{
  z-index:1;
  background:
    radial-gradient(75% 80% at 50% 26%, color-mix(in srgb, var(--color-accent) 20%, transparent), transparent 72%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--color-ground) 52%, transparent),
      color-mix(in srgb, var(--color-ground) 82%, transparent) 60%,
      var(--color-ground));
}
.page-hero .hero-bg{position:absolute;inset:0;z-index:0;background-size:cover;background-position:center}

/* ---------- Mono ticker (data seasoning; Ledger flavour) ----------
   Blood red (.blood) is reserved for the violence-finance layer only. */
.ticker{display:inline-flex;flex-wrap:wrap;justify-content:center;gap:8px 22px;margin:24px auto 0;
  font-family:var(--font-data);font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--color-text-muted)}
.ticker span{white-space:nowrap}
.ticker b{font-weight:500;color:var(--color-accent)}
.ticker .up{color:var(--color-accent-2)}
.ticker .blood{color:var(--color-alert)}

/* ---------- Gallery strip (shared component) ---------- */
.gallery{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:14px}
.gallery figure{position:relative;margin:0;border:1px solid var(--color-line);border-radius:12px;overflow:hidden;background:var(--color-surface)}
.gallery a{display:block;color:inherit}
.gallery img{aspect-ratio:16/9;width:100%;object-fit:cover;transition:transform .5s ease}
.gallery a:hover img,.gallery figure:hover img{transform:scale(1.05)}
.gallery figcaption{position:absolute;left:0;right:0;bottom:0;padding:26px 14px 11px;
  font-family:var(--font-data);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--color-text);
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.82))}

/* ---------- Split media + text band (shared component) ---------- */
.split{display:grid;grid-template-columns:1.05fr 1fr;align-items:stretch;
  border:1px solid var(--color-line);border-radius:16px;overflow:hidden;background:var(--color-surface)}
.split + .split{margin-top:20px}
.split__media{position:relative;min-height:300px}
.split__media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.split__body{padding:38px 40px;display:flex;flex-direction:column;justify-content:center}
.split__body .ey{margin-bottom:10px}
.split__body h3{font-family:var(--skin-display);font-weight:600;font-size:clamp(22px,3.2vw,30px);color:var(--color-text);margin:4px 0 12px;overflow-wrap:anywhere}
.split__body p{font-family:var(--font-body);font-size:15px;line-height:1.7;color:var(--color-text);opacity:.85;margin:0 0 18px;max-width:46ch}
.split.is-reverse .split__media{order:2}

/* ---------- Fusion hero glow (Music: gold centre, cyan + ember poles) ----------
   The Music hub lives under the master skin; this glow stages the "collision"
   of the two world accents around the master gold. Raw tokens keep it stable. */
.page-hero.is-fusion::before{
  background:
    radial-gradient(48% 60% at 14% 46%, color-mix(in srgb, var(--led-cyan) 22%, transparent), transparent 60%),
    radial-gradient(48% 60% at 86% 46%, color-mix(in srgb, var(--aon-ember) 26%, transparent), transparent 60%),
    radial-gradient(46% 56% at 50% 36%, color-mix(in srgb, var(--ay-gold) 22%, transparent), transparent 70%),
    linear-gradient(180deg, var(--color-surface), var(--color-ground));
}
.fusion-kicker{font-family:var(--font-data);font-size:clamp(11px,2vw,13px);letter-spacing:.3em;text-transform:uppercase;margin:14px 0 0}
.fusion-kicker .a{color:color-mix(in srgb, var(--aon-ember) 64%, var(--ay-gold-light))}
.fusion-kicker .b{color:var(--led-cyan)}
.fusion-kicker .x{color:var(--ay-gold);opacity:.85;margin:0 .5em}

/* ---------- Release cards (per-track world accent via raw tokens) ----------
   .rel.aon -> ember (Aonaithar), .rel.led -> cyan (Ledger), default -> gold.
   Drives the card topline and the world tag; mirrors the cover-art logic. */
.releases{display:grid;grid-template-columns:repeat(auto-fit,minmax(196px,1fr));gap:18px}
.rel{position:relative;border:1px solid var(--color-line);border-radius:14px;overflow:hidden;background:var(--color-surface);--rel:var(--ay-gold);transition:transform .25s ease,border-color .25s ease}
.rel.aon{--rel:var(--aon-ember)}
.rel.led{--rel:var(--led-cyan)}
.is-aon{--rel:var(--aon-ember)}
.is-led{--rel:var(--led-cyan)}
.rel::before{content:"";position:absolute;top:0;left:0;right:0;height:3px;background:var(--rel);z-index:2}
.rel__cover{aspect-ratio:1/1;width:100%;object-fit:cover}
.rel__body{padding:15px 16px 17px;display:flex;flex-direction:column;gap:9px}
.rel__title{font-family:var(--font-display);font-weight:600;font-size:17px;line-height:1.2;color:var(--color-text);margin:0}
.worldtag{align-self:flex-start;font-family:var(--font-data);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
  color:color-mix(in srgb, var(--rel) 80%, var(--color-text));border:1px solid color-mix(in srgb, var(--rel) 52%, transparent);border-radius:20px;padding:3px 10px}
.rel:hover{transform:translateY(-4px);border-color:color-mix(in srgb, var(--rel) 55%, var(--color-line))}
.rel__listen{align-self:flex-start;margin-top:1px;font-family:var(--font-data);font-size:11px;letter-spacing:.12em;text-transform:uppercase;text-decoration:none;color:var(--rel);display:inline-flex;align-items:center;gap:6px}
.rel__listen:hover{color:color-mix(in srgb, var(--rel) 72%, var(--color-text))}
.rel__listen .ar{transition:transform .2s ease}
.rel__listen:hover .ar{transform:translateX(3px)}

/* ---------- Character cast cards (Aonaithar Characters page) ----------
   Portrait card grid; skin-agnostic (adopts the active --color-accent). */
.cast{display:grid;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));gap:20px}
.char{display:flex;flex-direction:column;border:1px solid var(--color-line);border-radius:14px;
  overflow:hidden;background:var(--color-surface);transition:transform .3s ease,border-color .3s ease}
.char:hover{transform:translateY(-5px);border-color:var(--color-accent)}
a.char{text-decoration:none;color:inherit;cursor:pointer}
a.char .char__img::after{content:"\25B6";position:absolute;right:12px;bottom:12px;width:34px;height:34px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;font-size:11px;padding-left:2px;line-height:1;
  background:rgba(8,9,12,.55);color:#fff;border:1px solid rgba(255,255,255,.55);transition:background .25s ease,color .25s ease,transform .25s ease}
a.char:hover .char__img::after{background:var(--color-accent);color:#08090c;transform:scale(1.08)}
.char__img{position:relative;aspect-ratio:3/4;background:#0b0b0e}
.char__img img{width:100%;height:100%;object-fit:cover;object-position:center top}
.char__body{padding:17px 20px 22px;display:flex;flex-direction:column;flex:1}
.char__k{font-family:var(--font-data);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--color-accent);opacity:.9}
.char h3{font-family:var(--skin-display);font-weight:600;font-size:22px;color:var(--color-text);margin:7px 0 8px}
.char__watch{margin-top:auto;align-self:flex-start;display:inline-flex;align-items:center;gap:8px;text-decoration:none;
  font-family:var(--font-data);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--color-accent);
  padding-top:13px;transition:gap .2s ease}
.char__watch:hover{gap:11px}
.char__watch .play{width:21px;height:21px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid color-mix(in srgb, var(--color-accent) 55%, transparent);font-size:8px;line-height:1;padding-left:1px}

/* ---------- Character profile pages: spoiler note + responsive video embed (reusable) ---------- */
.spoiler-note{display:block;margin:0 0 4px;padding:13px 18px;border:1px solid color-mix(in srgb, var(--color-accent) 40%, var(--color-line));
  border-radius:12px;background:color-mix(in srgb, var(--color-accent) 8%, transparent);font-size:14px;line-height:1.55;
  color:color-mix(in srgb, var(--color-text) 82%, transparent)}
.videoframe{position:relative;width:100%;aspect-ratio:16/9;border-radius:14px;overflow:hidden;border:1px solid var(--color-line);background:#0b0b0e}
.videoframe iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.videoframe video{position:absolute;inset:0;width:100%;height:100%;background:#000}
.lyric{border-left:3px solid var(--color-accent);padding:4px 0 4px 22px;margin:0;font-family:var(--skin-display,var(--font-display));
  font-style:italic;font-size:18px;line-height:1.7;color:color-mix(in srgb, var(--color-text) 92%, transparent)}
.char-prose{display:flow-root}
.fig-l,.fig-r{margin:6px 0 22px;border:1px solid var(--color-line);border-radius:12px;overflow:hidden;background:var(--color-surface)}
.fig-l img,.fig-r img{display:block;width:100%;height:auto}
.fig-l figcaption,.fig-r figcaption{font-family:var(--font-data);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
  color:color-mix(in srgb, var(--color-text) 58%, transparent);padding:9px 13px}
@media(min-width:760px){.fig-r{float:right;width:50%;margin:6px 0 18px 32px}.fig-l{float:left;width:50%;margin:6px 32px 18px 0}}

/* ---------- Listen / narrated page: audio card + cinematic reel ---------- */
.audiocard{max-width:680px;margin:0 auto;border:1px solid color-mix(in srgb, var(--color-accent) 28%, var(--color-line));
  border-radius:16px;background:var(--color-surface);padding:26px 30px 28px;text-align:center}
.audiocard .k{font-family:var(--font-data);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--color-accent)}
.audiocard h3{font-family:var(--skin-display,var(--font-display));font-weight:600;font-size:clamp(22px,3vw,28px);color:var(--color-text);margin:9px 0 5px}
.audiocard .meta{font-size:13px;color:color-mix(in srgb, var(--color-text) 62%, transparent);margin:0}
.audiocard audio{width:100%;margin-top:20px}
.reel{max-width:920px;margin:0 auto;display:flex;flex-direction:column;gap:22px}
.reel figure{margin:0;border:1px solid var(--color-line);border-radius:14px;overflow:hidden;background:var(--color-surface)}
.reel figure img{display:block;width:100%;height:auto}
.reel figcaption{font-family:var(--font-data);font-size:11px;letter-spacing:.12em;text-transform:uppercase;
  color:color-mix(in srgb, var(--color-text) 58%, transparent);padding:10px 14px}

/* ---------- CODEX BAR (built by assets/js/codexbar.js) ----------
   Persistent topic-spine navigation for content pages outside the book:
   the bookbar's sibling, sticky just under the 70px site header. The
   cold-visitor runs (docs/COLD-VISITOR-2026-08-09.md) showed visitors are
   never lost where a persistent position bar exists and lost everywhere
   it isn't. Token-driven so it adopts whichever world skin the page wears.
   JS-off pages simply never get the element. */
.cdxbar{position:sticky;top:70px;z-index:40;background:color-mix(in srgb, var(--color-bg, #0b0b0e) 88%, transparent);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border-bottom:1px solid var(--color-line)}
.cdxbar__in{display:flex;align-items:center;gap:16px;height:44px}
.cdxbar__world{font-family:var(--font-data);font-size:11.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--color-accent);text-decoration:none;white-space:nowrap}
.cdxbar__world:hover{text-decoration:underline;text-underline-offset:3px}
.cdxbar__where{font-family:var(--font-data);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--color-text);opacity:.62;white-space:nowrap;margin-right:auto;overflow:hidden;text-overflow:ellipsis}
.cdxbar__toc{position:relative}
.cdxbar__toc summary{list-style:none;cursor:pointer;font-family:var(--font-data);font-size:11px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--color-text);opacity:.85;border:1px solid var(--color-line);border-radius:7px;
  padding:6px 11px;white-space:nowrap;user-select:none}
.cdxbar__toc summary::-webkit-details-marker{display:none}
.cdxbar__toc summary:hover,.cdxbar__toc[open] summary{color:var(--color-accent);border-color:var(--color-accent);opacity:1}
.cdxbar__panel{position:absolute;right:0;top:calc(100% + 10px);min-width:260px;max-height:min(70vh,520px);overflow-y:auto;
  background:var(--color-surface);border:1px solid var(--color-line);border-radius:12px;padding:12px 14px;
  box-shadow:0 18px 44px rgba(0,0,0,.5);z-index:60}
.cdxbar__spine{font-family:var(--font-data);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--color-accent);margin:12px 0 5px}
.cdxbar__spine:first-child{margin-top:2px}
.cdxbar__pages{list-style:none;margin:0;padding:0}
.cdxbar__pages a{display:block;padding:6px 9px;border-radius:7px;font-family:var(--font-body);font-size:13px;
  color:var(--color-text);opacity:.86;text-decoration:none}
.cdxbar__pages a:hover{background:color-mix(in srgb, var(--color-accent) 12%, transparent);color:var(--color-accent);opacity:1}
.cdxbar__pages a.is-here{color:var(--color-accent);opacity:1;
  background:color-mix(in srgb, var(--color-accent) 9%, transparent)}
.cdxbar__step{display:inline-flex;align-items:center;gap:7px;font-family:var(--font-data);font-size:11px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--color-text);opacity:.75;text-decoration:none;white-space:nowrap}
.cdxbar__step:hover{color:var(--color-accent);opacity:1}
.cdxbar__step.is-off{opacity:.32}
@media (max-width:860px){
  .cdxbar__where{display:none}
  .cdxbar__world{margin-right:auto}
  .cdxbar__in{gap:12px}
  .cdxbar__step .lbl{display:none}
  .cdxbar__step .ar{font-size:14px}
}

/* ---------- Read-along chapter reader ---------- */
.readprogress{position:fixed;top:0;left:0;height:3px;width:0;background:var(--color-accent);z-index:60;transition:width .12s linear}
.readbar{position:sticky;top:0;z-index:40;background:color-mix(in srgb, var(--color-bg, #0b0b0e) 88%, transparent);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border-top:1px solid var(--color-line);border-bottom:1px solid var(--color-line)}
.readbar .wrap{display:flex;align-items:center;gap:16px;padding:10px 0}
.readbar .rb-label{font-family:var(--font-data);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--color-accent);white-space:nowrap}
.readbar audio{flex:1;min-width:0;height:40px}
.reader{max-width:38rem;margin:0 auto;font-family:var(--font-lore,'EB Garamond',Georgia,serif);font-size:19px;line-height:1.85;
  color:color-mix(in srgb, var(--color-text) 96%, transparent)}
.reader p{margin:0 0 1.4em}
.reader > p:first-of-type::first-letter{float:left;font-family:var(--skin-display);font-weight:700;font-size:3.6em;line-height:.78;padding:5px 12px 0 0;color:var(--color-accent)}
.reader em{font-style:italic}
.chapter-figure{margin:38px 0;border:1px solid var(--color-line);border-radius:14px;overflow:hidden;background:var(--color-surface)}
.chapter-figure img{display:block;width:100%;height:auto}
.chapter-figure figcaption{font-family:var(--font-data);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
  color:color-mix(in srgb, var(--color-text) 56%, transparent);padding:9px 13px}
.chapter-end{text-align:center;margin:48px auto 6px;max-width:38rem}
.chapter-end .orn{color:var(--color-accent);letter-spacing:.6em;font-size:18px;margin-bottom:8px}
.chapter-end h2{font-family:var(--skin-display);font-weight:600;color:var(--color-text);margin:0 0 10px}
.char p{font-family:var(--font-body);font-size:13.5px;line-height:1.62;color:var(--color-text);opacity:.8;margin:0}

/* ---------- Map plates (Maps & Illustrations page) ----------
   Full map kept visible (contain on a dark mat); captioned below. */
.mapfull{max-width:1000px;margin:0 auto;border:1px solid var(--color-line);border-radius:16px;overflow:hidden;background:#0b0b0e}
.mapfull img{width:100%;height:auto;display:block}
.mapfull figcaption{padding:16px 22px;font-family:var(--font-body);font-size:14.5px;line-height:1.65;color:var(--color-text);opacity:.84}
.plates{display:grid;grid-template-columns:repeat(auto-fit,minmax(282px,1fr));gap:18px}
.plate{display:flex;flex-direction:column;margin:0;border:1px solid var(--color-line);border-radius:14px;overflow:hidden;background:var(--color-surface)}
.plate>img{width:100%;height:auto;aspect-ratio:4/3;object-fit:contain;background:#0b0b0e;display:block}
/* Widescreen plates (e.g. the Rezo map suite, 16:9 masters): same card, no letterbox. */
.plates--wide .plate>img{aspect-ratio:16/9}
/* Character turnarounds are full-body 3/4 views at ~941x1672, which is 9:16 to
   within a pixel, so `contain` on this ratio shows the whole figure with no
   letterboxing. The .cast/.char grid crops 3:4 from the top, which is right for
   a face card and wrong here: it cuts a turnaround off at the knees. */
.plates--tall .plate>img{aspect-ratio:9/16}

/* ---------- Duo: one character, two states ----------
   Gwen/LUST and Thera-Luun's public/bio layers are the same person rendered
   twice. The comparison IS the content, so the two plates stay matched in size
   and side by side, and the pair is capped narrow enough that a full-body shot
   does not tower over the prose that explains it. Stays a .plates modifier so
   the lightbox (which selects `.plates .plate > img`) still picks the pair up. */
.plates--duo{grid-template-columns:1fr 1fr;max-width:720px;margin-inline:auto}
@media(max-width:520px){.plates--duo{grid-template-columns:1fr;max-width:330px}}
.plate figcaption{padding:14px 17px 18px}
.plate b{font-family:var(--skin-display);font-weight:600;font-size:16px;color:var(--color-text);display:block;margin-bottom:5px}
.plate figcaption span{font-family:var(--font-body);font-size:13px;line-height:1.55;color:var(--color-text);opacity:.78;display:block}

/* ---------- Timeline (Ledger catalysts / history spine) ---------- */
.timeline{border-left:2px solid var(--color-line);margin:0;padding:2px 0 0 28px;list-style:none}
.timeline li{position:relative;padding:0 0 26px}
.timeline li:last-child{padding-bottom:0}
.timeline li::before{content:"";position:absolute;left:-35px;top:3px;width:11px;height:11px;border-radius:50%;
  background:var(--color-accent);box-shadow:0 0 0 4px var(--color-ground),0 0 12px var(--color-accent)}
.timeline .when{font-family:var(--font-data);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--color-accent)}
.timeline h4{font-family:var(--skin-display);font-weight:600;font-size:18px;color:var(--color-text);margin:3px 0 6px}
.timeline p{font-family:var(--font-body);font-size:14px;line-height:1.62;color:var(--color-text);opacity:.82;margin:0;max-width:64ch}

/* ---------- Star-chart (Ledger corridor map) ---------- */
.starchart{border:1px solid var(--color-line);border-radius:16px;background:
  radial-gradient(120% 140% at 8% 30%, color-mix(in srgb, var(--color-accent) 12%, transparent), transparent 60%),
  var(--color-surface);padding:26px 22px;overflow:hidden}
.starchart svg{width:100%;height:auto;display:block}
.starchart figcaption{font-family:var(--font-data);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--color-text-muted);margin-top:14px;text-align:center}

@media(max-width:980px){
  /* matches the hamburger breakpoint above */
  nav.main{gap:14px}
  /* Hide only the DIRECT static-fallback links on mobile (the no-JS nav).
     Was `nav.main a:not(.cta)` — which also nuked every link inside the
     JS-built .nav-list (specificity 0-2-2 beats .nav-item>a at 0-1-1),
     leaving the hamburger menu EMPTY on mobile. Found 7 Jul 2026 audit. */
  nav.main > a:not(.cta){display:none}
}
@media(max-width:820px){
  footer.site .cols{grid-template-columns:1fr 1fr}
  /* The newsletter form goes full row here. At two columns each track is only
     ~140px at 375px, and an email field that narrow is not usable. */
  footer.site .cols > div:nth-child(4){grid-column:1 / -1}
  .feature{grid-template-columns:1fr;text-align:center}
  .feature img{margin:0 auto}
  .split{grid-template-columns:1fr}
  .split__media{min-height:220px}
  .split.is-reverse .split__media{order:0}
}

/* ============================================================
   POLISH LAYER (7 Jul 2026 audit) — scroll-reveal, lightbox,
   view transitions, mobile-menu motion. All progressive:
   no JS / old browser / reduced motion = current behaviour.
   ============================================================ */

/* ---------- Scroll-reveal (classes added only by enhance.js) ---------- */
.rv{opacity:0;transform:translateY(16px);
  transition:opacity .55s ease var(--rv-d,0s),transform .55s ease var(--rv-d,0s)}
.rv.in{opacity:1;transform:none}
@media print{.rv{opacity:1;transform:none}}

/* ---------- Cross-document view transitions: REMOVED 7 Jul 2026 ----------
   @view-transition{navigation:auto} shipped briefly in the v1.2.0 draft, but
   Paul caught a mid/stuck-transition artifact: the previous page's snapshot
   (its nav "START HERE") composited over the new page's header. The fade is
   not worth an even-occasional broken-looking frame. If reinstated, test on
   heavy pages (the film homepage, the atlas) across Chrome + Safari first. */

/* ---------- Lightbox (native <dialog>, built by enhance.js) ---------- */
.lb-zoom{cursor:zoom-in}
/* Full-viewport by design (19 Jul 2026). It used to cap at min(94vw,1400px)
   and 86vh, which on a large monitor opened a window with the site's nav
   showing through the backdrop — enlarging an image barely enlarged it.
   Now the dialog fills the viewport and the image scales to fit inside it,
   so "expand" means expand. */
dialog.lightbox{width:100vw;max-width:100vw;height:100dvh;max-height:100dvh;padding:0;margin:0;
  background:#050507;border:0;border-radius:0;
  color:var(--color-text);overflow:auto;overscroll-behavior:contain}
dialog.lightbox::backdrop{background:rgba(3,3,5,.94);backdrop-filter:blur(8px)}
/* The stage takes the full height minus the caption strip, so a landscape
   plate uses the whole screen instead of stopping at 86vh. */
dialog.lightbox .lb-stage{display:flex;min-height:calc(100dvh - 46px)}
/* margin:auto centres like flex centering but stays reachable when the
   content overflows and the dialog pans (justify-content:center would not) */
dialog.lightbox .lb-stage img{max-width:100vw;max-height:calc(100dvh - 46px);
  width:auto;height:auto;display:block;margin:auto}
dialog.lightbox .lb-stage .lb-svg{width:min(92vw,1300px);max-width:none;height:auto;padding:20px;margin:auto}
/* (phones: enhance.js sets an inline 880px width on the cloned SVG at
   open-time so the dialog pans — inline style, immune to page CSS) */
dialog.lightbox .lb-cap{margin:0;padding:14px 54px 16px 18px;font-family:var(--font-data);
  font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--color-text-muted);
  text-align:center}
/* Fixed rather than sticky: at full-viewport the dialog scrolls for panning,
   and a sticky close button scrolls away with a tall image. */
dialog.lightbox .lb-close{position:fixed;top:16px;right:16px;width:44px;height:44px;
  border-radius:50%;border:1px solid var(--color-line);background:rgba(6,6,9,.86);color:var(--color-text);
  font-size:16px;cursor:pointer;z-index:2}
dialog.lightbox .lb-close:hover{border-color:var(--color-accent);color:var(--color-accent)}
body:has(dialog.lightbox[open]){overflow:hidden}

/* ---------- Mobile menu motion + scroll lock (matches the 980px hamburger) ---------- */
@media (max-width:980px){
  html.nav-open{overflow:hidden}
  @supports (transition-behavior: allow-discrete){
    .nav-list{opacity:0;transform:translateY(-10px);
      transition:opacity .24s ease,transform .24s ease,display .24s allow-discrete}
    header.site nav.main.open .nav-list{opacity:1;transform:none}
    @starting-style{
      header.site nav.main.open .nav-list{opacity:0;transform:translateY(-10px)}
    }
  }
}
