/* ============================================================
   THE LEDGER — HUD layer for the Proof of Human reading experience.

   Ported from the Remotion chapter-video theme files so the website and the
   films speak one visual language. Those compositions were already DOM + CSS
   + inline SVG, so this is a translation, not a rebuild.

   (Do not write a glob containing a star-slash anywhere in this file: it
   closes the comment early and silently kills the next rule block. That cost
   an hour once already.)

   THREE RULES CARRIED OVER FROM THE FILM WORK — do not quietly break them:

   1. SCRIM THE WHOLE IMAGE, never a box behind text over a picture. A panel
      behind type covers the subject; a full-figure scrim keeps the picture
      readable underneath. Text legibility beats image visibility whenever
      the HUD is carrying the narrative.
   2. NO FREE-FLOATING TEXT. Every HUD line lives inside a panel.
   3. DIM IS RELATIVE, NOT ABSOLUTE. Paul's 2026-07-18 ruling: dim tones tuned
      on a bright workbench plate vanished on dark plates. Everything dim here
      is lifted for legibility while preserving the hierarchy, so the "dead"
      register still reads as dead — it just reads at all.

   PROGRESSIVE BY CONSTRUCTION: the resting state below is the full look. All
   motion is gated behind the .hud-js class, which assets/js/hud.js adds only
   once it can drive it. No JS, old browser, or reduced motion = static HUD,
   nothing hidden.

   Registers are POV, not decoration: the palette shifts with the viewpoint
   character, which is how the films carry interiority without showing faces.
   ============================================================ */

/* ---------------------------------------------------------------
   1. REGISTERS  (values lifted verbatim from the Remotion theme files)
   --------------------------------------------------------------- */

.hud,
[data-register] {
  /* gwen "gloss" is the default: black glass, Honey pink, amber, cyan chrome */
  --hud-bg: #07040a;
  --hud-panel: rgba(14, 8, 18, 0.86);
  --hud-border: rgba(255, 95, 168, 0.20);
  --hud-ink: #eae2ea;
  --hud-ink-dim: #8d7f90;
  --hud-accent: #ff5fa8;
  --hud-accent-dim: rgba(255, 95, 168, 0.55);
  --hud-2: #f0a93c;
  --hud-3: #7fe0ea;
  --hud-ok: #6fce8f;
  --hud-alert: #ff3b47;
  --hud-gold: #c9a24b;

  /* --- the visual taxonomy ------------------------------------------
     Five kinds of non-prose content, each with its own colour AND its own
     icon. The icon is the constant: it never changes between registers, so
     the reader learns the glyph once. The colour is the register, so it can
     keep carrying whose head we are inside.

     The axis is WHO IT IS FOR, not what it looks like:

     AMBER  = addressed to the reader, not observed by any character. System
              copy that orients you from outside the point of view. Location
              tags and civic-system messages both live here. (The Starship
              Troopers / Iain M. Banks interstitial register.)
     CYAN   = her own HUD. Ambient telemetry she reads, and the commands she
              gives it.
     PINK   = someone talking to her privately, inside the lace.
     GREY   = correspondence from outside the lace.
     RED    = broadcast, public, and the only layer with a voice.

     Colour answers "whose layer is this"; the glyph answers "what kind of
     thing is it". That is why two types can share a colour and still never be
     confused: place and system are both amber, readout and command are both
     cyan, and their glyphs keep them apart.
     ------------------------------------------------------------------ */
  --t-place: #f0a93c;
  --t-system: #f0a93c;
  --t-env: #7fe0ea;
  --t-command: #7fe0ea;
  --t-speech: #ff5fa8;
  --t-mail: #9aa3b2;
  --t-cast: #ff3b47;

  /* A physical screen in the room, not an overlay on anyone's vision: an old
     phosphor terminal on someone else's desk. Deliberately outside the
     register system, like the location stamp but for the opposite reason.
     Place is constant because it is authorial; this is constant because it is
     a real light source, and a green screen does not change colour because
     the person reading it does. */
  --t-terminal: #4df08a;
}

[data-register="lust"] {
  /* "The HUD dimmed to a blood-warm monochrome, the world reducing to
     essentials." Gold stays: engagement metrics never leave. */
  --hud-bg: #0a0405;
  --hud-panel: rgba(18, 6, 8, 0.88);
  --hud-border: rgba(255, 59, 71, 0.22);
  --hud-ink: #e8d9d4;
  --hud-ink-dim: #8f7672;
  --hud-accent: #ff3b47;
  --hud-accent-dim: rgba(255, 59, 71, 0.55);
  --hud-2: #e06a4f;
  --hud-3: #e06a4f;
  --hud-ok: #c9a24b;
  --hud-alert: #ff3b47;
  --hud-gold: #c9a24b;

  /* The taxonomy narrows with the register. Types stay separable, but the
     spread collapses toward the kill palette: that reduction is the point. */
  --t-place: #c9a24b;
  --t-env: #e06a4f;
  --t-speech: #ff3b47;
  --t-mail: #8f7672;
  --t-cast: #ff3b47;
}

[data-register="dead"] {
  /* Below the signal floor. Suit-internal telemetry only, and the absence of
     engagement metrics is the point: nobody is watching. */
  --hud-bg: #050607;
  --hud-panel: rgba(8, 12, 12, 0.88);
  --hud-border: rgba(127, 216, 194, 0.22);
  --hud-ink: #e6efea;
  --hud-ink-dim: #aebbb5;
  --hud-accent: #7fd8c2;
  --hud-accent-dim: rgba(150, 210, 196, 0.82);
  --hud-2: #f0a93c;
  --hud-3: #a09cab;
  --hud-ok: #79c97a;
  --hud-alert: #ff5560;
  --hud-gold: #a09cab;

  /* Everything external has gone grey. Only the suit still speaks, so only
     env keeps its colour; nothing is being served to her any more, and speech
     and mail deliberately become indistinguishable because that IS the state.

     Place is the exception, and stays gold in every register. A location tag
     is not part of her HUD: it is the author marking a scene change for the
     reader. That layer is not on the network and does not die with it. */
  --t-place: #c9a24b;
  --t-env: #7fd8c2;
  --t-speech: #a09cab;
  --t-mail: #a09cab;
  --t-cast: #a09cab;
}

/* Each component declares its role once; everything else reads --role. */
.hud-stamp { --role: var(--t-place); }
.hud-system { --role: var(--t-system); }
.hud-panel { --role: var(--t-env); }
.hud-panel.is-command { --role: var(--t-command); }
.hud-thread { --role: var(--t-speech); }
.hud-mail { --role: var(--t-mail); }
.hud-cast { --role: var(--t-cast); }
.hud-term { --role: var(--t-terminal); }

/* ---------------------------------------------------------------
   1b. THE KEY GLYPHS

   Hand-built inline SVG in the markup, inheriting currentColor, per the
   standing rule that technical-SF visuals are drawn in-repo and never
   image-generated. Sized to sit on the kicker's baseline.
   --------------------------------------------------------------- */

.hud-ico {
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
  color: var(--role);
  vertical-align: -1px;
}
.hud-ico path,
.hud-ico circle,
.hud-ico rect { vector-effect: non-scaling-stroke; }

/* The kicker strip: glyph + label, the same shape on every insert type so
   the reader's eye learns one position and then only reads the glyph. */
.hud-kicker {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-data);
  font-size: 10px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--role);
}

/* ---------------------------------------------------------------
   2. READER — the Ledger adaptation of the shared reading column
   --------------------------------------------------------------- */

/* site.css hardcodes EB Garamond on .reader, which is right for Aonaithar
   and wrong here: the Ledger's body face is Inter. */
[data-skin="ledger"] .reader {
  font-family: var(--font-body);
  font-size: 18px;
  line-height: 1.75;
  max-width: 38rem;
}

[data-skin="ledger"] .reader > p:first-of-type::first-letter {
  font-family: var(--skin-display);
  color: var(--hud-accent, var(--color-accent));
}

/* ---------------------------------------------------------------
   3. ADDRESS STAMP — the manuscript's own scene header, made an object
   --------------------------------------------------------------- */

.hud-stamp {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
  margin: 46px 0 30px;
  padding: 12px 16px;
  background: color-mix(in srgb, var(--role) 8%, var(--hud-panel));
  border: 1px solid color-mix(in srgb, var(--role) 34%, transparent);
  border-left: 2px solid var(--role);
  border-radius: 3px;
  font-family: var(--font-data);
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.hud-stamp .hud-ico { margin-right: 2px; }
.hud-stamp .site { color: var(--hud-ink); font-weight: 500; }
.hud-stamp .part { color: var(--hud-ink-dim); }
.hud-stamp .level { color: var(--role); margin-left: auto; letter-spacing: 0.14em; }

/* First stamp on a page sits under the hero, so it needs no top gap. */
.reader > .hud-stamp:first-child { margin-top: 0; }

/* ---------------------------------------------------------------
   3b. SYSTEM MESSAGE — the interstitial register.

   Copy that exists for the reader and is observed by nobody in the scene:
   civic broadcasts, epigraphs, orientation notes. Same amber as the location
   stamp because it belongs to the same layer, but given room to breathe
   because it is read rather than glanced at.
   --------------------------------------------------------------- */

.hud-system {
  margin: 34px 0;
  padding: 18px 20px 20px;
  background: color-mix(in srgb, var(--role) 8%, var(--hud-panel));
  border: 1px solid color-mix(in srgb, var(--role) 32%, transparent);
  border-left: 2px solid var(--role);
  border-radius: 3px;
}

.hud-system .hud-kicker { margin-bottom: 12px; }

.hud-system__title {
  font-family: var(--skin-display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--hud-ink);
  margin: 0 0 4px;
}

.hud-system__meta {
  font-family: var(--font-data);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--hud-ink-dim);
  margin: 0 0 12px;
}

.hud-system__body {
  font-family: var(--font-data);
  font-size: 13px;
  line-height: 1.7;
  color: var(--hud-ink);
}
.hud-system__body p { margin: 0 0 0.85em; }
.hud-system__body p:last-child { margin-bottom: 0; }

/* A labelled sub-block inside a system message (CIVIC HEALTH, TREND SUMMARY). */
.hud-system__body b.sec {
  display: block;
  margin: 1.2em 0 0.35em;
  font-size: 10.5px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--role);
  font-weight: 500;
}
.hud-system__body b.sec:first-child { margin-top: 0; }

/* A system message signs itself off, or cites a reference ("[Further reading:
   ...]"). This had no rule outside the --quote variant, so on the Part One
   opening the reference line rendered identically to body prose. The variant
   below is 0-2-0 and still overrides this 0-1-0 rule whatever the order. */
.hud-system__cite {
  display: block;
  margin-top: 12px;
  font-family: var(--font-data);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--hud-ink-dim);
}

/* An epigraph is a system message that happens to be a quotation. */
.hud-system--quote .hud-system__body { font-family: var(--font-body); font-size: 15px; font-style: italic; }
.hud-system--quote .hud-system__cite {
  display: block;
  margin-top: 10px;
  font-family: var(--font-data);
  font-style: normal;
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--hud-ink-dim);
}

/* ---------------------------------------------------------------
   4. HUD PANEL + READOUT — telemetry. Silent by design: this is meant
      to be read, which is the whole reason the prose has no narration.
   --------------------------------------------------------------- */

.hud-panel {
  margin: 26px 0;
  padding: 14px 18px;
  background: color-mix(in srgb, var(--role) 6%, var(--hud-panel));
  border: 1px solid color-mix(in srgb, var(--role) 30%, transparent);
  border-left: 2px solid var(--role);
  border-radius: 3px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

/* Corner brackets: the PanelChrome grammar, as pure CSS. */
.hud-panel--chrome { position: relative; }
.hud-panel--chrome::before,
.hud-panel--chrome::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  border: 2px solid var(--role);
  opacity: 0.55;
  pointer-events: none;
}
.hud-panel--chrome::before { top: -1px; right: -1px; border-width: 2px 2px 0 0; border-radius: 0 3px 0 0; }
.hud-panel--chrome::after { bottom: -1px; right: -1px; border-width: 0 2px 2px 0; border-radius: 0 0 3px 0; }

.hud-panel > .hud-kicker { margin-bottom: 9px; }

.hud-readouts { margin: 0; padding: 0; list-style: none; }

/* Label dim and tracked, value bright and tight: the hierarchy is carried
   by letter-spacing as much as by colour. */
.hud-readout {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 4px 18px;
  padding: 6px 0;
  border-bottom: 1px solid var(--hud-border);
  font-family: var(--font-data);
  font-size: 13px;
  line-height: 1.5;
}
.hud-readout:last-child { border-bottom: 0; }

.hud-readout > .lbl {
  color: var(--hud-ink-dim);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-size: 11px;
}
.hud-readout > .val {
  color: var(--hud-ink);
  letter-spacing: 0.04em;
  text-align: right;
  flex: 1 1 auto;
}

/* A readout with no label stays one full-width line rather than being forced
   into a split it does not have. */
.hud-readout.is-single > .val { text-align: left; }

/* Semantic states. Colour means something here; it is never decorative.
   Each also carries a non-colour cue so the meaning survives for readers who
   cannot distinguish them. */
.hud-readout .v-ok { color: var(--hud-ok); }
.hud-readout .v-warn { color: var(--hud-2); }
.hud-readout .v-alert { color: var(--hud-alert); font-weight: 500; }
.hud-readout .v-alert::before { content: "\26A0\FE0E"; margin-right: 7px; opacity: 0.9; }
.hud-readout .v-money { color: var(--hud-gold); }

/* ---------------------------------------------------------------
   5. MESSAGE THREAD — Honey>Gwen and back. A conversation, not telemetry,
      so it reads as a thread rather than a register.
   --------------------------------------------------------------- */

.hud-thread {
  margin: 26px 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.hud-msg {
  max-width: 88%;
  padding: 10px 14px;
  background: color-mix(in srgb, var(--role) 7%, var(--hud-panel));
  border: 1px solid color-mix(in srgb, var(--role) 30%, transparent);
  border-left: 2px solid var(--role);
  border-radius: 3px;
  font-family: var(--font-data);
  font-size: 13px;
  line-height: 1.6;
  color: var(--hud-ink);
}

.hud-msg > .hud-kicker { margin-bottom: 5px; letter-spacing: 0.24em; }

/* Her own replies mirror: outgoing sits right and the accent rail flips with
   it, so an exchange reads as an exchange without needing to be labelled. */
.hud-msg.is-reply {
  align-self: flex-end;
  border-left: 1px solid color-mix(in srgb, var(--role) 30%, transparent);
  border-right: 2px solid var(--role);
}
.hud-msg.is-reply > .hud-kicker { justify-content: flex-end; }

/* ---------------------------------------------------------------
   5b. MAIL — correspondence, not conversation. Asynchronous, from
   outside the lace, and read rather than heard. Its own colour and its
   own glyph so it never reads as Honey talking.
   --------------------------------------------------------------- */

.hud-mail {
  margin: 30px 0;
  background: color-mix(in srgb, var(--role) 7%, var(--hud-panel));
  border: 1px solid color-mix(in srgb, var(--role) 32%, transparent);
  border-left: 2px solid var(--role);
  border-radius: 3px;
  overflow: hidden;
}

.hud-mail__head {
  padding: 11px 16px 10px;
  border-bottom: 1px solid color-mix(in srgb, var(--role) 24%, transparent);
}
.hud-mail__head .hud-kicker { margin-bottom: 7px; }

.hud-mail__meta {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 3px 12px;
  font-family: var(--font-data);
  font-size: 11px;
  line-height: 1.5;
}
.hud-mail__meta dt {
  color: var(--hud-ink-dim);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.hud-mail__meta dd { margin: 0; color: var(--hud-ink); letter-spacing: 0.03em; }

.hud-mail__body {
  padding: 14px 16px;
  font-family: var(--font-data);
  font-size: 13px;
  line-height: 1.7;
  color: var(--hud-ink);
}
.hud-mail__body p { margin: 0 0 0.85em; }
.hud-mail__body p:last-child { margin-bottom: 0; }

/* An invitation is mail with a different job, the way a meeting request and
   an email share an inbox. Same register, its own glyph, and a status. */
.hud-mail--invite .hud-mail__head { border-bottom: 0; padding-bottom: 13px; }
.hud-mail--invite .hud-mail__meta { gap: 5px 12px; }

/* A document is served whole and read top to bottom: terms, notices, the
   things a platform hands you rather than says to you. Mail's register (it
   still comes from outside), a page glyph, and a masthead in place of
   From/To — a document has an issuer and an effective date, not a sender. */
.hud-mail--doc .doc-brand {
  display: block;
  width: 168px;
  height: auto;
  margin: 10px 0 8px;
  mix-blend-mode: screen;
}
.hud-mail--doc .doc-title {
  margin: 0;
  font-family: var(--font-data);
  font-size: 12px;
  line-height: 1.55;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--hud-ink);
}
.hud-mail--doc .doc-sub {
  margin: 4px 0 0;
  font-family: var(--font-data);
  font-size: 12px;
  line-height: 1.55;
  color: var(--hud-ink-dim);
}
.hud-mail--doc .doc-meta {
  margin: 3px 0 0;
  font-family: var(--font-data);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--hud-ink-dim);
}
.hud-mail--doc .doc-h {
  margin: 1.3em 0 0.5em;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--role) 55%, var(--hud-ink));
}
.hud-mail--doc .hud-mail__body p.doc-h:first-child { margin-top: 0; }
.hud-mail--doc .hud-mail__body hr {
  margin: 1.2em 0;
  border: 0;
  border-top: 1px solid color-mix(in srgb, var(--role) 24%, transparent);
}

.hud-mail__status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 11px;
  padding: 4px 10px;
  border: 1px solid color-mix(in srgb, var(--role) 40%, transparent);
  border-radius: 999px;
  font-family: var(--font-data);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--hud-ink-dim);
}
.hud-mail__status.is-accepted { color: var(--hud-ok); border-color: color-mix(in srgb, var(--hud-ok) 40%, transparent); }

/* A place chip nested inside another object. It carries the location glyph and
   the location colour wherever it appears, so the reader meets the same mark
   in a second context and the key reinforces itself. */
.hud-chip {
  --role: var(--t-place);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 3px 10px 3px 8px;
  background: color-mix(in srgb, var(--role) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--role) 38%, transparent);
  border-radius: 3px;
  font-family: var(--font-data);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--role);
  white-space: nowrap;
}
.hud-chip .hud-ico { width: 11px; height: 11px; }
.hud-chip .sub { color: var(--hud-ink-dim); letter-spacing: 0.12em; }

/* ---------------------------------------------------------------
   6. BROADCAST INSERT — the in-world feed. The only layer that gets a
      voice, because it is the only layer that lies.
   --------------------------------------------------------------- */

.hud-cast {
  margin: 34px 0;
  background: color-mix(in srgb, var(--role) 7%, var(--hud-panel));
  border: 1px solid color-mix(in srgb, var(--role) 32%, transparent);
  border-left: 2px solid var(--role);
  border-radius: 3px;
  overflow: hidden;
}

.hud-cast__bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  background: rgba(0, 0, 0, 0.45);
  border-bottom: 1px solid color-mix(in srgb, var(--role) 24%, transparent);
  font-family: var(--font-data);
  font-size: 10px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--hud-ink-dim);
}
.hud-cast__live { color: var(--hud-alert); }
.hud-cast__live::before {
  content: "\25CF";
  margin-right: 6px;
}
.hud-cast__body { padding: 15px 18px; font-family: var(--font-data); font-size: 13.5px; line-height: 1.65; }

/* A broadcast opened by /-/broadcast/ carries a masthead rather than the
   status bar, so it needs the same title/meta pair the system panel uses. */
.hud-cast .hud-kicker { display: block; padding: 14px 18px 0; }
.hud-cast__title {
  font-family: var(--skin-display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--hud-ink);
  margin: 8px 0 4px;
  padding: 0 18px;
}
.hud-cast__meta {
  font-family: var(--font-data);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--hud-ink-dim);
  margin: 0;
  padding: 0 18px;
}
.hud-cast__body p { margin: 0 0 0.85em; }
.hud-cast__body p:last-child { margin-bottom: 0; }
/* Production notes ([Anchor Holoform: ...]) are the broadcast's own stage
   directions: present, but never competing with what is being said. */
.hud-cast__note {
  font-family: var(--font-data);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--hud-ink-dim);
  font-style: italic;
}
.hud-cast__body b.sec {
  display: block;
  margin: 1.2em 0 0.35em;
  font-size: 10.5px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--role);
  font-weight: 500;
}
.hud-cast__body b.sec:first-child { margin-top: 0; }

/* ---------- Signage: the city's own voice ----------
   Adverts, AI graffiti, the chanted slogans of the living billboards. Word
   style PINK (Paul, 27 Jul). Deliberately NOT a panel: every boxed component
   here is something a character is reading on an interface, and this is the
   environment shouting at everyone at once, so it is free-standing display
   text. Pink is the speech register, which is what this is. */
.hud-signage {
  --role: var(--t-speech);
  margin: 30px 0;
  text-align: center;
}
.hud-signage p {
  font-family: var(--skin-display);
  font-weight: 600;
  font-size: clamp(15px, 2.6vw, 19px);
  letter-spacing: 0.08em;
  line-height: 1.45;
  color: var(--role);
  margin: 0 0 0.5em;
  text-wrap: balance;
}
.hud-signage p:last-child { margin-bottom: 0; }
.hud-cast__body p { margin: 0 0 0.9em; }
.hud-cast__body p:last-child { margin-bottom: 0; }

/* The emotion-model chyron is already an on-screen text element in the films
   that changes per block, so it can carry the caption line without breaking
   diegesis: accessibility and worldbuilding in the same component. */
.hud-cast__chyron {
  padding: 8px 14px;
  border-top: 1px solid var(--hud-border);
  font-family: var(--font-data);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--hud-ink-dim);
}

/* ---------------------------------------------------------------
   6a. TERMINAL — a physical display, read over someone's shoulder.

   Not her HUD and not the reader's layer: an old phosphor screen on a desk in
   the room. It gets its own ground rather than the register's panel tint,
   because it is emitting its own light.

   Scanlines are allowed here and nowhere else. Over a reading column they
   cost legibility for texture; on a CRT they ARE the object, and this is a
   short bounded block rather than continuous prose.
   --------------------------------------------------------------- */

.hud-term {
  margin: 32px 0;
  background: #030705;
  border: 1px solid color-mix(in srgb, var(--role) 34%, transparent);
  border-left: 2px solid var(--role);
  border-radius: 3px;
  overflow: hidden;
  position: relative;
}

.hud-term__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  border-bottom: 1px solid color-mix(in srgb, var(--role) 24%, transparent);
  background: rgba(77, 240, 138, 0.05);
}

.hud-term__body {
  padding: 15px 16px;
  font-family: var(--font-data);
  font-size: 12.5px;
  line-height: 1.75;
  color: var(--role);
  /* Phosphor bloom: the dark shadow first for legibility, the glow second. */
  text-shadow: 0 0 1px rgba(0, 0, 0, 0.9), 0 0 9px rgba(77, 240, 138, 0.28);
}
.hud-term__body p { margin: 0 0 0.5em; }
.hud-term__body p:last-child { margin-bottom: 0; }

/* The closing line of a run reads as the machine finishing, so it dims. */
.hud-term__body p.term-end { opacity: 0.62; margin-top: 0.9em; }

.hud-term::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    rgba(77, 240, 138, 0.055) 0 1px,
    transparent 1px 3px
  );
}

@media (prefers-reduced-motion: reduce) {
  .hud-term__body { text-shadow: 0 0 1px rgba(0, 0, 0, 0.9); }
}

/* ---------------------------------------------------------------
   6b. THE KEY — the taxonomy, shown to the reader once.

   Teaching the system explicitly costs one small block on the book page and
   saves the reader working it out by inference across five chapters.
   --------------------------------------------------------------- */

.hud-key {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 12px;
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
}

.hud-key > li {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 13px 15px;
  background: color-mix(in srgb, var(--role) 7%, var(--hud-panel));
  border: 1px solid color-mix(in srgb, var(--role) 30%, transparent);
  border-left: 2px solid var(--role);
  border-radius: 3px;
}
.hud-key .hud-ico { width: 15px; height: 15px; margin-top: 2px; }
.hud-key b {
  display: block;
  font-family: var(--font-data);
  font-size: 10.5px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--role);
  margin-bottom: 4px;
}
.hud-key span {
  font-family: var(--font-body);
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--hud-ink);
  opacity: 0.86;
}
.hud-key .k-place { --role: var(--t-place); }
.hud-key .k-system { --role: var(--t-system); }
.hud-key .k-env { --role: var(--t-env); }
.hud-key .k-command { --role: var(--t-command); }
.hud-key .k-speech { --role: var(--t-speech); }
.hud-key .k-mail { --role: var(--t-mail); }
.hud-key .k-cast { --role: var(--t-cast); }
.hud-key .k-terminal { --role: var(--t-terminal); }

/* Types that share a colour are shown as a pair, so the key teaches the
   grouping (whose layer) at the same time as the glyphs (what kind). */
.hud-key__band {
  grid-column: 1 / -1;
  margin: 14px 0 -2px;
  font-family: var(--font-data);
  font-size: 10px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--hud-ink-dim);
}
.hud-key__band:first-child { margin-top: 0; }

/* ---------------------------------------------------------------
   6c. PART FRONT MATTER

   The part page does the job a print part-title spread does: open on the
   reader-facing register, then show the ground before the descent into it.
   --------------------------------------------------------------- */

.partopen { max-width: 44rem; margin: 0 auto; }
.partopen .hud-system { margin: 0 0 20px; }
.partopen .hud-system:last-child { margin-bottom: 0; }

.strata__lede {
  /* Informational register (Paul's ruling, 7 Aug 2026): only BOOK text gets the
     narrow reading measure. Supplementary/orientation text spans its section. */
  margin: 0 0 26px;
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.75;
  color: var(--color-text);
  opacity: 0.84;
}

.strata {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 16px;
}

.strata__card {
  margin: 0;
  border: 1px solid var(--hud-border);
  border-radius: 4px;
  overflow: hidden;
  background: var(--hud-panel);
}
.strata__card img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  /* Scrim, not a panel behind the type: the caption sits below, but the
     plate is still darkened so the set reads as one descent. */
  filter: brightness(0.74) saturate(0.95);
  transition: filter 0.4s ease;
}
.strata__card:hover img { filter: brightness(0.92) saturate(1); }

.strata__card figcaption { padding: 13px 15px 15px; }
.strata__card figcaption b {
  display: block;
  font-family: var(--skin-display);
  font-size: 16px;
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: 3px;
}
.strata__card .addr {
  display: block;
  font-family: var(--font-data);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--t-place);
  margin-bottom: 7px;
}
.strata__card .note {
  display: block;
  font-family: var(--font-body);
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--color-text);
  opacity: 0.8;
}

.strata__more { margin: 24px 0 0; }

/* ---------------------------------------------------------------
   6d. THE READING STAGE — marginalia

   A physical spread puts the plate on one page and the text on the facing
   one, so the image never interrupts the line you are reading. A single
   centred web column cannot do that: every figure is a full stop.

   So the column stays narrow and the figures move out into the gutter beside
   it, which is otherwise dead space on any desktop monitor. Floats rather
   than grid, because the text has to keep flowing past the figure rather
   than starting a new row beneath it.

   Below the breakpoint there is no gutter to move into, so figures fall back
   inline at full column width. Desktop-first by intent: the reading
   experience is designed for the screen that has the room, and the phone
   gets the honest simplification rather than a squeezed imitation.
   --------------------------------------------------------------- */

.reader-stage {
  max-width: 1500px;
  margin: 0 auto;
  padding: 0 clamp(16px, 4vw, 48px);
}
.reader-stage .reader { max-width: 38rem; margin: 0 auto; }

/* Marginal figures are previews. They are meant to be small enough not to
   compete with the prose and inviting enough to be clicked, at which point
   the lightbox gives the full plate. */
@media (min-width: 1180px) {
  .hud-figure.is-margin {
    width: 250px;
    margin-top: 5px;
    margin-bottom: 22px;
  }
  .hud-figure.is-margin.is-right {
    float: right;
    margin-right: -270px;
    clear: right;
  }
  .hud-figure.is-margin.is-left {
    float: left;
    margin-left: -270px;
    clear: left;
  }
  .hud-figure.is-margin figcaption {
    font-size: 9.5px;
    letter-spacing: 0.14em;
    padding: 8px 11px;
  }
  /* A marginal plate is a preview, so it says so on hover. */
  .hud-figure.is-margin img { transition: filter 0.35s ease; cursor: zoom-in; }
  .hud-figure.is-margin:hover img { filter: brightness(0.82) saturate(1); }

  /* Wider gutters get larger previews. Each tier's pull-out must stay
     inside (viewport - column) / 2 less the scrollbar, or the page scrolls
     sideways: a single 344px offset from 1180px up overflowed every
     laptop-width window between 1180 and 1300. */
  @media (min-width: 1340px) {
    .hud-figure.is-margin { width: 300px; }
    .hud-figure.is-margin.is-right { margin-right: -344px; }
    .hud-figure.is-margin.is-left { margin-left: -344px; }
  }
  @media (min-width: 1500px) {
    .hud-figure.is-margin { width: 340px; }
    .hud-figure.is-margin.is-right { margin-right: -384px; }
    .hud-figure.is-margin.is-left { margin-left: -384px; }
  }
}

/* Nothing may straddle the end of the chapter. */
.reader::after { content: ""; display: block; clear: both; }
.chapter-end { clear: both; }

/* The scene break is the PoH token seal, coloured by where Gwen/LUST stand
   in their PoH journey at that point in the book (green valid, red delisted,
   amber zombie) — the reader's status light between scenes. The marks are
   JPEGs on pure black; screen blending sinks the black into the page so no
   plate edge shows. The typographic ornament is the no-state fallback. */
.chapter-break {
  clear: both;
  margin: 44px 0;
  text-align: center;
  color: var(--hud-accent-dim);
  font-size: 15px;
  letter-spacing: 0.4em;
}
.chapter-break img {
  width: 52px;
  height: 52px;
  margin-inline: auto;   /* the site-wide img reset makes it a block */
  vertical-align: middle;
  mix-blend-mode: screen;
}

/* ---------------------------------------------------------------
   7. SCRIMMED FIGURE — rule 1, as a component.
   --------------------------------------------------------------- */

.hud-figure {
  position: relative;
  margin: 40px 0;
  border: 1px solid var(--hud-border);
  border-radius: 4px;
  overflow: hidden;
  background: var(--hud-bg);
}
.hud-figure img { display: block; width: 100%; height: auto; }

/* The scrim covers the WHOLE image, never just behind the type. */
.hud-figure--scrim img { filter: brightness(0.58) saturate(0.94); }

.hud-figure figcaption {
  padding: 10px 14px;
  font-family: var(--font-data);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--hud-ink-dim);
  border-top: 1px solid var(--hud-border);
}

/* Overlaid caption variant: the layered shadow-then-glow recipe from the
   films, dark shadow first for legibility, colour second for identity. */
.hud-figure--over figcaption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  border-top: 0;
  color: var(--hud-ink);
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.95), 0 0 22px rgba(0, 0, 0, 0.8);
}

/* ---------------------------------------------------------------
   8. MOTION

   There is deliberately no HUD-specific animation driver here.

   assets/js/enhance.js already implements this exact behaviour: it adds .rv
   to known components, an IntersectionObserver adds .in, and site.css
   transitions opacity and transform with a staggered delay. It early-returns
   on prefers-reduced-motion and when IntersectionObserver is missing, so
   nothing is ever hidden without a working driver.

   The HUD components are registered in that selector list rather than
   duplicated here. A separate driver writing per-frame custom properties
   would only earn its place for continuously-valued components (a counter
   that ticks as you read, a scroll-driven gauge). None of those exist yet,
   and building the machinery before the component that needs it would be
   speculative.

   Scanlines are also deliberately absent: over a reading column they cost
   legibility, and legibility beats texture wherever the HUD carries the
   narrative. They belong on figures, if anywhere, and can be added then.
   --------------------------------------------------------------- */

@media print {
  .hud-figure--scrim img { filter: none; }
  .hud-panel, .hud-msg, .hud-stamp, .hud-cast { background: none; }
}

/* ---------------------------------------------------------------
   9. NARROW VIEWPORTS
   --------------------------------------------------------------- */

@media (max-width: 640px) {
  [data-skin="ledger"] .reader { font-size: 17px; }
  .hud-stamp { letter-spacing: 0.16em; font-size: 10px; }
  .hud-stamp .level { margin-left: 0; }
  .hud-readout { font-size: 12px; }
  .hud-msg { max-width: 100%; }
}

/* ---------------------------------------------------------------
   10. THE READER BAR (.bookbar)

   Each book is its own product, and a reader inside it should never
   have to hunt for their place or their next chapter. On reader pages
   (body[data-reader]) the site header stops being sticky and this bar
   takes over the top edge: book title, position, contents, prev/next.
   The contents panel is a native <details>, so the whole bar works
   with JS off; the fixed .readprogress line draws above it (z-60).
   --------------------------------------------------------------- */

[data-reader] header.site { position: static; }

.bookbar {
  position: sticky;
  top: 0;
  z-index: 45;
  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);
}
.bookbar__in { display: flex; align-items: center; gap: 16px; height: 46px; }

.bookbar__book {
  font-family: var(--font-data);
  font-size: 11.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-accent);
  text-decoration: none;
  white-space: nowrap;
}
.bookbar__book:hover { text-decoration: underline; text-underline-offset: 3px; }

.bookbar__where {
  font-family: var(--font-data);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text);
  opacity: 0.62;
  white-space: nowrap;
  margin-right: auto;
}

.bookbar__step {
  font-family: var(--font-data);
  font-size: 11.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text);
  text-decoration: none;
  white-space: nowrap;
  opacity: 0.85;
}
.bookbar__step:hover { color: var(--color-accent); opacity: 1; }
.bookbar__step.is-off { opacity: 0.38; cursor: default; }
.bookbar__step .soon { opacity: 0.8; letter-spacing: 0.06em; }

.bookbar__toc { position: relative; }
.bookbar__toc summary {
  list-style: none;
  cursor: pointer;
  font-family: var(--font-data);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text);
  border: 1px solid var(--color-line);
  border-radius: 999px;
  padding: 5px 14px;
  white-space: nowrap;
}
.bookbar__toc summary::-webkit-details-marker { display: none; }
.bookbar__toc summary:hover,
.bookbar__toc[open] summary { color: var(--color-accent); border-color: var(--color-accent); }

.bookbar__panel {
  position: absolute;
  right: 0;
  top: calc(100% + 10px);
  width: min(340px, 88vw);
  max-height: min(62vh, 500px);
  overflow: auto;
  background: var(--color-bg, #0b0b0e);
  border: 1px solid var(--color-line);
  border-radius: 12px;
  padding: 16px 18px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55);
  z-index: 46;
}

/* The contents panel is right-aligned to .bookbar__toc, which is only ~95px
   wide and stops well short of the bar's right edge (the prev/next controls
   follow it). At 375px that puts a 330px panel at left:-54px, clipped off the
   screen with no horizontal scroll to reach it, so the first characters of
   every chapter title are unreachable. Same failure as the nav submenu, same
   cause: `width: min(340px, 88vw)` caps the WIDTH but says nothing about the
   POSITION. Anchoring to the sticky bar instead keeps it on screen. Breaks
   below ~440px, so this is scoped to 520px with margin to spare rather than
   applied everywhere, which would move the panel on desktop for no reason. */
@media (max-width: 520px) {
  .bookbar__toc { position: static; }
  .bookbar__panel { right: 12px; }
}

.bookbar__part {
  font-family: var(--font-data);
  font-size: 11px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--color-text);
  margin: 14px 0 8px;
}
.bookbar__part:first-child { margin-top: 0; }
.bookbar__part a { color: var(--color-accent); text-decoration: none; }
.bookbar__part a:hover { text-decoration: underline; text-underline-offset: 3px; }
.bookbar__part.is-soon { opacity: 0.45; }
.bookbar__part.is-soon span,
.bookbar__chs .is-soon span {
  font-size: 10px;
  letter-spacing: 0.08em;
  border: 1px solid var(--color-line);
  border-radius: 999px;
  padding: 1px 7px;
  margin-left: 6px;
}

.bookbar__chs { list-style: none; margin: 0 0 4px; padding: 0; }
.bookbar__chs li { margin: 0; }
.bookbar__chs a,
.bookbar__chs .is-soon {
  display: block;
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.45;
  padding: 6px 8px;
  border-radius: 8px;
  color: var(--color-text);
  text-decoration: none;
}
.bookbar__chs b {
  font-family: var(--font-data);
  font-weight: 500;
  font-size: 11px;
  opacity: 0.6;
  margin-right: 7px;
}
.bookbar__chs a:hover { background: color-mix(in srgb, var(--color-accent) 12%, transparent); }
.bookbar__chs a.is-here {
  background: color-mix(in srgb, var(--color-accent) 16%, transparent);
  color: var(--color-accent);
}
.bookbar__chs li.is-soon { opacity: 0.45; }

@media (max-width: 700px) {
  .bookbar__where { display: none; }
  .bookbar__book { margin-right: auto; }
  .bookbar__in { gap: 12px; }
}
@media (max-width: 480px) {
  .bookbar__step .lbl { display: none; }
  .bookbar__step .ar { font-size: 14px; }
}

/* ============================================================
   §11  THE DESCENT  (Part closing page)
   The MAP-02 strata plate is a cross-section with the city on the
   left and roughly a quarter of the frame empty on the right. That
   empty band is the affordance: chapter markers sit in it at the
   altitude their scene actually happens at, so Part One's fall is
   legible as a shape rather than a list. Below 900px the overlay
   stops being an overlay, because a 7-item list cannot share a
   phone screen with a cross-section and stay readable.
   ============================================================ */
.descent { margin: 0; }
.descent__plate { position: relative; }
.descent__plate > img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--color-line);
  border-radius: 3px;
}
.descent figcaption {
  margin-top: 14px;
  font-family: var(--font-data);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  text-align: center;
}

.descent__marks { list-style: none; margin: 0; padding: 0; }

@media (min-width: 900px) {
  /* The markers live in the plate's empty right-hand quarter. `top` is set
     per item from the --y the builder computes, so the vertical order IS the
     altitude order and the two orbital chapters sit above the crown. */
  .descent__marks {
    position: absolute;
    top: 0;
    right: 0;
    width: 34%;
    height: 100%;
  }
  .descent__mark {
    position: absolute;
    top: var(--y);
    right: 0;
    width: 100%;
    transform: translateY(-50%);
  }
  /* The connector runs left out of the marker toward the section it names.
     Purely decorative: the address text carries the same information. */
  .descent__mark > a::before {
    content: "";
    position: absolute;
    right: 100%;
    top: 50%;
    width: 26px;
    height: 1px;
    background: linear-gradient(to left,
      color-mix(in srgb, var(--color-accent) 70%, transparent), transparent);
  }
  .descent__mark > a::after {
    content: "";
    position: absolute;
    right: calc(100% + 26px);
    top: 50%;
    width: 5px;
    height: 5px;
    margin-top: -2px;
    border-radius: 50%;
    background: var(--color-accent);
    opacity: 0.85;
  }
  .descent__note { display: block; }
}

.descent__mark > a {
  position: relative;
  display: flex;
  gap: 11px;
  align-items: baseline;
  padding: 9px 12px;
  border: 1px solid transparent;
  border-radius: 3px;
  text-decoration: none;
  background: color-mix(in srgb, var(--color-bg, #0b0b0e) 72%, transparent);
  transition: border-color .18s ease, background .18s ease;
}
.descent__mark > a:hover,
.descent__mark > a:focus-visible {
  border-color: color-mix(in srgb, var(--color-accent) 45%, transparent);
  background: color-mix(in srgb, var(--color-accent) 9%, var(--color-bg, #0b0b0e));
}
.descent__n {
  flex: none;
  font-family: var(--font-data);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--color-accent);
}
.descent__body { display: block; }
.descent__body b {
  display: block;
  font-family: var(--skin-display);
  font-size: 15px;
  font-weight: 600;
  color: var(--color-text);
}
.descent__addr {
  display: block;
  margin-top: 2px;
  font-family: var(--font-data);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.descent__note {
  display: none;
  margin-top: 5px;
  font-family: var(--font-body);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--color-text-muted);
}

@media (max-width: 899px) {
  /* Stacked: the plate, then the same seven markers as an ordinary list.
     Order is unchanged, so the descent still reads top to bottom. */
  .descent__marks { margin-top: 18px; display: grid; gap: 8px; }
  .descent__mark { position: static; transform: none; }
  .descent__note { display: block; }
}

/* ============================================================
   §11b  PART-CLOSING BACK-MATTER  (recap, teaser, section sub-ledes)
   Found by the 7 Aug 2026 sitewide sweep: part-01-closing.html shipped
   with .prose-lead / .teaser-cta / .sec-head .lede carrying NO rules
   anywhere — the recap and the Part Two teaser rendered on inherited
   defaults since v1.5.0 (the .joinband failure shape). Styled here in
   the shared sheet so every future part-closing page inherits them.
   Register: informational (wide), per docs/DESIGN-SYSTEM.md — only
   book text gets the narrow measure, and these are site-authored
   back-matter sitting between full-width components.
   ============================================================ */
/* Structural section markers emitted by the part-closing generator; no visual
   rules by design (registered here so the dead-class sweep knows they're owned). */
.descent-sec, .teaser-sec {}
.prose-lead {
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.75;
  color: var(--color-text);
  opacity: 0.85;
  margin: 0 0 18px;
}
.prose-lead:last-child { margin-bottom: 0; }
.teaser-cta {
  font-family: var(--font-data);
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin: 22px 0;
}
.sec-head .lede {
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.7;
  color: var(--color-text);
  opacity: 0.82;
  margin: 10px 0 0;
}

/* ============================================================
   §12  CARD TRIO  (Part closing page, further reading)
   The book pages had no shared card grid: the six-tile hook grids
   on the start-here pages each carry their own page-local <style>
   block. This is the same visual language promoted to the shared
   sheet, so generated pages do not have to inline it.
   ============================================================ */
.cards3 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 18px;
  font-family: var(--font-body);
}
.cards3 .card {
  display: block;
  border: 1px solid var(--color-line);
  border-radius: 12px;
  padding: 20px 22px;
  /* --color-surface is not set in every skin context these pages run under, and
     an unresolved var here silently renders the card transparent: the trio then
     reads as three bare links, which is exactly how it first shipped. */
  background: var(--color-surface, rgba(255, 255, 255, 0.035));
  text-decoration: none;
  transition: border-color .18s ease, transform .18s ease, background .18s ease;
}
.cards3 .card:hover,
.cards3 .card:focus-visible {
  border-color: color-mix(in srgb, var(--color-accent) 55%, transparent);
  background: color-mix(in srgb, var(--color-accent) 9%, rgba(255, 255, 255, 0.035));
  transform: translateY(-2px);
}
.cards3 .card h3 {
  font-family: var(--skin-display, var(--font-display));
  font-weight: 600;
  font-size: 17px;
  color: var(--color-accent);
  margin: 0 0 9px;
}
.cards3 .card p {
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--color-text);
  opacity: 0.82;
  margin: 0;
}
/* The affordance the .item tiles carry, generated rather than authored. */
.cards3 .card h3::after {
  content: " \2192";
  color: var(--color-accent);
  opacity: 0.7;
}
