/* ═══════════════════════════════════════════════════════════════════════════
   UFO Player Guide — Zenith Station datapad
   Archives style. The PDF palette is reference only; faction colours are the
   one thing carried over from it.
   ═══════════════════════════════════════════════════════════════════════════ */

/* The credit glyph. unicode-range scopes this font to U+0024 alone, so writing
   a plain "$" in copy renders the galactic credit symbol while digits stay in
   the body font. Must be listed first in any font stack that needs it. */
@font-face {
  font-family: 'Credit';
  src: url('/assets/guide/fonts/credit.woff2') format('woff2');
  unicode-range: U+0024;
  font-display: swap;
}

/* Aurebesh, for in-world flavour text like the version line. */
@font-face {
  font-family: 'Droidobesh';
  src: url('/assets/guide/fonts/droidobesh.woff2') format('woff2');
  font-display: swap;
}

:root {
  --bg: #050d14;
  --glow: #00c8e0;
  --glow2: #00f0c8;
  --accent: #ff6b35;
  --crawl: #ffde59;
  --text: #cfe6ec;
  --text2: #7ec8d8;
  --text3: #4a8fa0;
  --panel: rgba(0, 200, 224, 0.05);
  --line: rgba(0, 200, 224, 0.28);
  --border: #0e3a52;

  /* Overridden per faction page. Placeholder until the real hexes land. */
  --faction: #6fc7b2;

  --page-max: 780px;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  font-family: 'Credit', 'Exo 2', sans-serif;
  background: var(--bg);
  background-image: radial-gradient(ellipse 80% 50% at 50% -10%, rgba(0,200,224,.08), transparent);
  color: var(--text);
  line-height: 1.6;
  font-size: 16.5px;
  overflow-x: hidden;
  min-height: 100vh;
}

/* Scanlines. Sits above content but below chrome. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 60;
  background: repeating-linear-gradient(0deg, rgba(255,255,255,.022) 0 1px, transparent 1px 3px);
}

/* ── ROUTER VIEWPORT ─────────────────────────────────────────────────────── */
/* Pages are absolutely stacked so an outgoing and incoming page can animate
   past each other. Only the current page (and, mid-gesture, its neighbour) is
   ever in the DOM: nothing is pre-rendered alongside. */
#viewport {
  position: relative;
  width: 100%;
  overflow: hidden;
  transition: opacity .19s ease;   /* keep in step with FADE_MS in app.js */
}

/* Page changes crossfade. The scroll reset happens while this is at 0, so it is
   never seen as a jerk to the top of the next page. */
#viewport.dim { opacity: 0; }

.page {
  width: 100%;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 26px 20px 90px;
  will-change: transform;
  min-width: 0;
}

/* Cover and crawl: art pages, so no reading gutter at the top. */
.page-bare { padding-top: 0; padding-bottom: 60px; }

/* The cover art carries the page, so let it break the reading width. */
.page:has(.cover) { max-width: 1200px; padding-left: 0; padding-right: 0; }

/* Long unbroken words (faction names, Orbitron display caps) must never push
   the page wider than the screen. */
.page h1, .page h2, .page h3, .page p, .page li, .page dd { overflow-wrap: break-word; }

.page.leaving {
  position: absolute;
  top: 0; left: 0; right: 0;
  margin: 0 auto;
}

.sliding { transition: transform .34s var(--ease), opacity .34s var(--ease); }
.dragging { transition: none; }

/* ── TYPE ────────────────────────────────────────────────────────────────── */
.term-line {
  font-family: 'Share Tech Mono', monospace;
  color: var(--glow);
  font-size: .78rem;
  letter-spacing: .12em;
  opacity: .75;
  margin-bottom: 14px;
}
.term-line::before { content: "// "; }

h1 {
  font-family: 'Orbitron', sans-serif;
  font-weight: 900;
  text-transform: uppercase;
  /* Exactly the prototype's ramp, so type does not drift from the Mac render. */
  font-size: clamp(1.9rem, 6.4vw, 2.8rem);
  letter-spacing: .06em;
  color: #fff;
  text-shadow: 0 0 14px rgba(0,200,224,.75), 0 0 44px rgba(0,200,224,.35);
  margin-bottom: 6px;
  line-height: 1.14;
}

.sub {
  font-family: 'Share Tech Mono', monospace;
  color: var(--glow);
  font-size: .8rem;
  letter-spacing: .25em;
  text-transform: uppercase;
  opacity: .8;
}

h2 {
  font-family: 'Orbitron', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 1.05rem;
  letter-spacing: .14em;
  color: var(--accent);
  margin: 40px 0 16px;
}

h3 {
  font-family: 'Orbitron', sans-serif;
  font-weight: 500;
  font-size: .95rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--glow);
  margin: 26px 0 8px;
}

p { margin-bottom: 14px; }
strong { color: #fff; font-weight: 600; }
/* Italics carry no colour of their own: only links are coloured, so emphasis
   never reads as something you can click. */
em { color: inherit; }

/* In-copy links: muted with a dotted underline. */
a {
  color: var(--text2);
  text-decoration: none;
  border-bottom: 1px dotted var(--text3);
}
a:hover { color: var(--glow2); border-bottom-color: var(--glow2); }

/* ── FULL-BLEED STAGES (cover, crawl) ────────────────────────────────────── */
/* These pages are art, not documents: they bleed to the screen edges and centre
   themselves vertically. No negative top margin, which would ride up over the
   kicker line above. */
.stage {
  position: relative;
  margin: 0 -20px;
  padding: 44px 22px 50px;
  overflow: hidden;
  min-height: 68vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.stage-stars {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.stage > *:not(.stage-stars):not(.stage-bg) { position: relative; z-index: 1; }

.stage-dark { background: #01060b; }

/* ── COVER ───────────────────────────────────────────────────────────────── */
.cover { padding: 0; min-height: 0; display: block; margin: 0; }

/* Small print lives here rather than on the welcome page: it's for anyone who
   reads closely, not something a player should have to pass through. */
.fine-print {
  max-width: var(--page-max);
  margin: 30px auto 0;
  padding: 0 20px;
  border-top: 1px solid var(--border);
  padding-top: 16px;
}
.fine-print p {
  font-size: .74rem;
  line-height: 1.62;
  color: var(--text3);
  margin-bottom: 9px;
}
.fine-print p:last-child { margin-bottom: 0; }

.cover-art { position: relative; display: block; }
.cover-art img { display: block; width: 100%; height: auto; }
.cover-art::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(1,6,11,.55) 0%, rgba(1,6,11,.1) 34%, rgba(1,6,11,.25) 72%, var(--bg) 100%);
  pointer-events: none;
}

.cover-text {
  position: absolute;
  top: 5%;
  left: 0; right: 0;
  z-index: 2;
  padding: 0 18px;
  text-align: center;
}

/* Mintie's own title block, with the real display fonts baked in. */
.cover-title-art {
  width: min(84%, 460px);
  height: auto;
  filter: drop-shadow(0 3px 16px rgba(0,0,0,.8));
}

.cover-aurebesh {
  font-family: 'Droidobesh', sans-serif;
  position: absolute;
  right: 16px;
  bottom: 12px;
  z-index: 2;
  font-size: .62rem;
  letter-spacing: .12em;
  color: rgba(255,255,255,.45);
}

/* ── OPENING CRAWL ───────────────────────────────────────────────────────── */
/* Matches the PDF's approach: no 3D rotation, just each block set larger than
   the last so the text appears to recede. Stays fully readable on a phone,
   which a real perspective transform does not. */
.crawl {
  color: var(--crawl);
  font-style: italic;
  font-weight: 600;
  letter-spacing: .01em;
  max-width: 30em;
  margin: 0 auto;
  text-wrap: balance;
}

/* The opening line, above the logo as it appears on film. Pale blue, not the
   crawl's yellow: that contrast is the whole point of the shot. */
.crawl-intro {
  color: #6fc3f7;
  font-size: clamp(.86rem, 3.6vw, 1.08rem);
  line-height: 1.5;
  letter-spacing: .01em;
  max-width: 24em;
  margin: 0 auto 42px;
  text-shadow: 0 0 22px rgba(111,195,247,.3);
}

.crawl .sw-logo {
  width: min(58%, 300px);
  margin: 0 auto 34px;
  display: block;
  filter: drop-shadow(0 0 26px rgba(255,222,89,.28));
}

.crawl-title {
  font-family: 'Orbitron', sans-serif;
  font-style: normal;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .14em;
  font-size: clamp(.8rem, 3.4vw, 1.05rem);
  margin-bottom: 26px;
  text-shadow: 0 0 18px rgba(255,222,89,.3);
}

.crawl p { line-height: 1.62; margin-bottom: 20px; }
.crawl p:last-child { margin-bottom: 0; }
.crawl p:nth-of-type(1) { font-size: clamp(.84rem, 3.4vw, 1rem); }
.crawl p:nth-of-type(2) { font-size: clamp(.96rem, 4.1vw, 1.22rem); }

/* No entrance animation. The PDF crawl is static, and staggering opacity here
   meant the text's visibility depended on an animation clock actually running:
   anything that stalled it left the crawl blank on the page. */

.lede { font-size: 1.05rem; color: #fff; }

/* ── PANELS ──────────────────────────────────────────────────────────────── */
/* Boxed body text runs a notch under prose size everywhere, panels and rank
   cards alike. Labels and chips inside set their own sizes in rem, so they are
   unaffected. */
.panel, .rank { font-size: .92rem; }

.panel {
  position: relative;
  border: 1px solid var(--line);
  background: var(--panel);
  padding: 20px 22px 16px;
  margin: 26px 0;
}
.panel::before, .panel::after { content: ""; position: absolute; width: 14px; height: 14px; }
.panel::before { top: -1px; left: -1px; border-top: 2px solid var(--glow); border-left: 2px solid var(--glow); }
.panel::after { bottom: -1px; right: -1px; border-bottom: 2px solid var(--glow); border-right: 2px solid var(--glow); }

.panel .p-head {
  font-family: 'Share Tech Mono', monospace;
  text-transform: uppercase;
  letter-spacing: .18em;
  font-size: .78rem;
  color: var(--glow);
  margin-bottom: 12px;
}
.panel ul { list-style: none; }
.panel li { padding-left: 18px; position: relative; margin-bottom: 8px; }
.panel li::before {
  content: ">";
  font-family: 'Share Tech Mono', monospace;
  position: absolute; left: 0;
  color: var(--accent);
}
.panel li:last-child { margin-bottom: 0; }

/* Definition-list flavour of the panel, for the game-at-a-glance block. */
.specs { display: grid; gap: 10px; }
.specs div { display: flex; gap: 10px; flex-wrap: wrap; }
.specs dt {
  font-family: 'Share Tech Mono', monospace;
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--glow);
  flex: 0 0 auto;
  padding-top: .18em;
  min-width: 6.5em;
}
.specs dd { flex: 1 1 14em; }   /* size inherits from .panel */

/* ── INSERTS ─────────────────────────────────────────────────────────────── */
/* The "special thing" on each page. Reads as something that showed up rather
   than part of the guide: a card with one chamfered corner, a faint digital
   texture, and a quiet arrival as it scrolls into view. */
.insert {
  position: relative;
  margin: 34px -6px;
  padding: 20px 22px 18px;
  font-size: .92rem;
  background:
    linear-gradient(150deg, rgba(24,52,66,.92), rgba(14,32,42,.94)),
    url('/assets/guide/bg/holo.webp') center/cover no-repeat;
  /* Corner cut off flat, not rounded, per the style spec's cutout panels. */
  clip-path: polygon(0 0, calc(100% - 26px) 0, 100% 26px, 100% 100%, 0 100%);
}

/* Fine transparent lines over the panel: the "glitchy" read, kept quiet. */
.insert::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(0deg, rgba(255,255,255,.035) 0 1px, transparent 1px 4px);
}

.insert-head {
  font-family: 'Share Tech Mono', monospace;
  text-transform: uppercase;
  letter-spacing: .2em;
  font-size: .8rem;
  color: rgba(255,255,255,.47);
  margin-bottom: 12px;
}

.insert p { color: #fff; margin-bottom: 10px; }
.insert p:last-child { margin-bottom: 0; }

/* Scroll reveal. The hidden state is applied only once JS has tagged the
   element, so with no JS the insert is simply visible: nothing depends on an
   observer firing. */
.insert.js-reveal:not(.in) { opacity: 0; transform: translateY(20px); }
.insert.js-reveal { transition: opacity .5s var(--ease), transform .5s var(--ease); }
.insert.js-reveal.in { animation: insert-flicker .5s steps(1) 1; }

@keyframes insert-flicker {
  0%, 100% { opacity: 1; }
  38% { opacity: .72; }
  46% { opacity: 1; }
  58% { opacity: .85; }
}

@media (prefers-reduced-motion: reduce) {
  .insert.js-reveal:not(.in) { opacity: 1; transform: none; }
  .insert.js-reveal.in { animation: none; }
}

/* Redaction bar. Holds no text at all: the hidden words are never written into
   the DOM, so they cannot be recovered from the page source. Width comes from
   --ch, matching the run length in the source document. */
.redact {
  display: inline-block;
  width: calc(var(--ch, 4) * 1ch);
  height: 1em;
  vertical-align: -0.16em;
  /* Solid black. The old slate grey was close to the insert's own background,
     so the bars read as smudges rather than censorship. */
  background: #000;
}

/* ── STEP SECTIONS ───────────────────────────────────────────────────────── */
/* A walkthrough where each step is a whole section rather than one line, as on
   character creation. The number sits in the margin on wide screens and above
   the heading on narrow ones. */
.step-sec { margin: 30px 0; }

.step-sec > .step-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 10px;
}

.step-sec .step-n {
  font-family: 'Share Tech Mono', monospace;
  font-size: .74rem;
  color: var(--glow);
  border: 1px solid var(--line);
  padding: 3px 8px;
  flex: none;
}

.step-sec .step-head h3 { margin: 0; }

/* ── NUMBERED STEPS ──────────────────────────────────────────────────────── */
.steps { list-style: none; counter-reset: step; margin: 16px 0 18px; }
.steps li {
  counter-increment: step;
  position: relative;
  padding-left: 34px;
  margin-bottom: 12px;
}
.steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: .05em;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  font-family: 'Share Tech Mono', monospace;
  font-size: .72rem;
  color: var(--glow);
  border: 1px solid var(--line);
}

/* ── TABLES ──────────────────────────────────────────────────────────────── */
/* Rules tables are reference material people scan on a phone, so below 620px
   each row becomes its own labelled card rather than a sideways scroll. The
   labels come from data-label, generated with the table so they cannot drift
   out of step with the headers. */
.tbl {
  width: 100%;
  border-collapse: collapse;
  margin: 16px 0 18px;
  font-size: .88rem;
}

.tbl th {
  font-family: 'Share Tech Mono', monospace;
  font-size: .68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  /* Neutral rather than cyan: as cyan they competed with the h3 directly above
     each table. The mobile row labels stay cyan, where nothing sits above them. */
  color: rgba(207,230,236,.55);
  text-align: left;
  font-weight: 400;
  padding: 0 10px 8px 0;
  border-bottom: 1px solid var(--line);
  vertical-align: bottom;
}

.tbl td {
  padding: 9px 10px 9px 0;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

.tbl tbody tr:last-child td { border-bottom: none; }
.tbl .cell-v { display: inline; }
.tbl td:first-child { color: #fff; font-weight: 600; }
.tbl td:last-child, .tbl th:last-child { padding-right: 0; }

@media (max-width: 620px) {
  .tbl thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .tbl, .tbl tbody, .tbl tr, .tbl td { display: block; }
  .tbl tr {
    border: 1px solid var(--line);
    background: var(--panel);
    padding: 12px 14px;
    margin-bottom: 10px;
  }
  .tbl td {
    padding: 3px 0;
    border: none;
    display: flex;
    align-items: baseline;
  }
  /* The value is one flex item that wraps inside itself. Letting a cell's inline
     children become flex items in their own right put a cell containing a credit
     symbol on a single non-wrapping line, which ran off the screen, and inserted
     the flex gap after the symbol. */
  .tbl .cell-v { flex: 1 1 auto; min-width: 0; }
  .tbl td::before {
    content: attr(data-label);
    margin-right: 10px;
    flex: 0 0 6.6em;
    font-family: 'Share Tech Mono', monospace;
    font-size: .64rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--glow);
    padding-top: .25em;
  }
  /* First cell is the row's name: give it the whole width as a heading. */
  .tbl td:first-child {
    display: block;
    font-size: .98rem;
    margin-bottom: 7px;
    padding-bottom: 7px;
    border-bottom: 1px solid var(--border);
  }
  .tbl td:first-child::before { content: none; }
  .tbl td:has(> .cell-v:empty) { display: none; }

  /* When the first column is a bare value rather than a name (a rank number,
     say), a lone "1" as the card title means nothing. label-first keeps its
     column name visible and treats it like any other field. */
  .tbl.label-first td:first-child {
    display: flex;
    font-size: inherit;
    margin-bottom: 0;
    padding-bottom: 3px;
    border-bottom: none;
    color: #fff;
  }
  .tbl.label-first td:first-child::before { content: attr(data-label); }
  .tbl.label-first tbody tr:last-child td:first-child { border-bottom: none; }
  /* The desktop rule that strips the last row's bottom border was also stripping
     the rule under that row's card title, so the last card in every table looked
     different from the rest. Put it back here. */
  .tbl tbody tr:last-child td:first-child { border-bottom: 1px solid var(--border); }
}

/* ── DICE ────────────────────────────────────────────────────────────────── */
.die { font-size: .82em; vertical-align: .06em; letter-spacing: .04em; }
.die-diff { color: #b078e8; }        /* difficulty: purple diamonds */
.die-set  { color: #7e8b93; }        /* setback: black squares, lifted to read */

/* ── COLLAPSIBLE DETAIL ──────────────────────────────────────────────────── */
/* The long rules explanations sit behind these so the tables stay scannable. */
details.more {
  border-left: 2px solid var(--line);
  margin: 4px 0 20px;
  padding-left: 14px;
}
/* Set in the colour it used to highlight to on hover, with the hover change
   dropped: the resting state now reads as the interactive thing it is. Hover
   highlights are kept everywhere else. */
details.more > summary {
  font-family: 'Share Tech Mono', monospace;
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--glow2);
  cursor: pointer;
  padding: 4px 0;
  list-style: none;
}
details.more > summary::-webkit-details-marker { display: none; }
details.more > summary::before { content: "+ "; color: var(--accent); }
details.more[open] > summary::before { content: "\2212 "; }
details.more > *:not(summary) { font-size: .9rem; margin-top: 10px; }

/* A reference to a page that isn't built yet. Deliberately unattractive so it
   reads as unavailable rather than as a link someone forgot to style. */
.ref-pending {
  color: #5c6a70;
  background: rgba(255,255,255,.04);
  border-bottom: 1px dashed #5c6a70;
  padding: 0 3px;
  cursor: not-allowed;
  font-style: italic;
}

/* The credit symbol sits tight against its number, so give it a little air.
   A margin rather than a real space, so the amount never breaks across lines. */
.cred { margin-right: .2em; }

/* Discord channel names, set like inline code so they read as a thing you go to
   rather than part of the sentence. Not links. */
.chan {
  font-family: 'Share Tech Mono', monospace;
  font-size: .82em;
  background: rgba(0,200,224,.1);
  border: 1px solid rgba(0,200,224,.22);
  border-radius: 3px;
  padding: .08em .38em;
  color: var(--text);
  white-space: nowrap;
}

/* Footnote asterisk in running text, matching the orange marker on the note. */
.fn-mark { color: var(--accent); font-weight: 600; }

/* Something described but not switched on yet. */
.pending-tag {
  font-family: 'Share Tech Mono', monospace;
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid rgba(255,107,53,.4);
  padding: 1px 6px;
  margin-left: 6px;
  white-space: nowrap;
}

/* Cue that a collapsible can be opened. */
.expand-cue { color: var(--text3); letter-spacing: .04em; }

/* ── BESTIARY ────────────────────────────────────────────────────────────── */
/* Field guide entries. The image lives inside its own entry rather than floating
   centred under a heading, which is what previously made a creature look like it
   belonged to whatever section sat above it. */
.bestiary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(216px, 1fr));
  gap: 14px;
  align-items: start;
  margin: 18px 0 28px;
}

.beast {
  border: 1px solid var(--line);
  background: var(--panel);
  padding: 14px 15px 15px;
  height: 100%;
}

.beast-art {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  height: 132px;
  margin-bottom: 12px;
}
.beast-art img {
  max-width: 100%;
  max-height: 132px;
  width: auto; height: auto;
  filter: drop-shadow(0 0 14px rgba(0,200,224,.3));
}

.beast-name {
  font-family: 'Orbitron', sans-serif;
  font-weight: 500;
  font-size: .82rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--glow);
  margin-bottom: 6px;
}

.beast p { font-size: .86rem; line-height: 1.6; margin: 0; }

/* The one creature the guide singles out before the lists start. */
.beast-feature {
  display: flex;
  gap: 20px;
  align-items: center;
  border: 1px solid var(--line);
  border-left: 3px solid var(--glow);
  background: var(--panel);
  padding: 18px 20px;
  margin: 22px 0 30px;
}
.beast-feature img {
  width: min(38%, 190px);
  height: auto;
  flex: none;
  filter: drop-shadow(0 0 18px rgba(0,200,224,.32));
}
.beast-feature .beast-name { font-size: 1rem; }
@media (max-width: 520px) {
  .beast-feature { flex-direction: column; text-align: center; }
  .beast-feature img { width: min(62%, 200px); }
}

/* Names with no entry of their own yet. */
.beast-listing {
  font-size: .9rem;
  color: var(--text2);
  line-height: 1.7;
}

/* ── LOCATIONS ───────────────────────────────────────────────────────────── */
/* A place with a name, a qualifier, a description, one highlighted entry and a
   run of everything else. Used for the station's levels and Kitta Bay's
   districts, which are the same shape of information. */
.loc {
  border-left: 2px solid var(--line);
  padding: 2px 0 2px 16px;
  margin: 22px 0;
}

.loc-name {
  font-family: 'Orbitron', sans-serif;
  font-weight: 500;
  font-size: .95rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--glow);
}

.loc-meta {
  font-family: 'Share Tech Mono', monospace;
  font-size: .7rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text3);
  margin: 3px 0 9px;
}

.loc > p { margin-bottom: 10px; }
.loc > p:last-child { margin-bottom: 0; }

/* The one thing worth going out of your way for. */
.loc-spot {
  border: 1px solid rgba(255,107,53,.3);
  background: rgba(255,107,53,.06);
  padding: 9px 12px;
  margin: 10px 0;
  font-size: .9rem;
}
.loc-spot::before {
  content: "Spotlight ";
  font-family: 'Share Tech Mono', monospace;
  font-size: .66rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
  display: block;
  margin-bottom: 3px;
}

/* Everything else in the district, run together to stay scannable. */
.loc-also {
  font-size: .86rem;
  color: var(--text2);
  line-height: 1.62;
}
.loc-also b {
  font-family: 'Share Tech Mono', monospace;
  font-size: .66rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text3);
  font-weight: 400;
  display: block;
}

/* A full-width plate for a map or diagram. */
figure.plate { margin: 24px -6px 28px; }
figure.plate img { display: block; width: 100%; height: auto; }
figure.plate figcaption {
  font-family: 'Share Tech Mono', monospace;
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text3);
  margin-top: 8px;
}

/* ── DATAPAD ─────────────────────────────────────────────────────────────── */
/* A handheld device, for in-world documents that are not part of the guide's own
   voice. Built in CSS rather than from the bezel artwork because the content is
   long and variable height: a fixed-aspect image would distort the frame. The
   art in /assets/guide/bg/ stays available if the literal texture is ever wanted.

   This is the one place the PDF's datapad colours are used on purpose: a warm
   near-black screen with cyan text, so the device reads as a different object
   from the pages around it. */
.datapad {
  --dp-ink: #7fd3e4;
  position: relative;
  margin: 8px -6px 30px;
  padding: 16px;
  background:
    linear-gradient(160deg, #4a4038 0%, #2b2521 22%, #1d1917 55%, #332b26 100%);
  clip-path: polygon(
    22px 0, calc(100% - 22px) 0, 100% 22px,
    100% calc(100% - 22px), calc(100% - 22px) 100%,
    22px 100%, 0 calc(100% - 22px), 0 22px);
  box-shadow: 0 10px 34px rgba(0,0,0,.55);
}

/* The three status ticks along the top edge of the casing. */
.datapad::before {
  content: "";
  position: absolute;
  top: 6px; left: 50%;
  transform: translateX(-50%);
  width: 26px; height: 4px;
  background: repeating-linear-gradient(90deg, var(--glow) 0 3px, transparent 3px 8px);
  opacity: .8;
}

/* Grip detail on the long edges. */
.datapad::after {
  content: "";
  position: absolute;
  left: 3px; right: 3px; top: 42%;
  height: 46px;
  background:
    repeating-linear-gradient(0deg, rgba(0,0,0,.5) 0 2px, transparent 2px 5px);
  opacity: .5;
  pointer-events: none;
}

.dp-screen {
  position: relative;
  z-index: 1;
  background: #1e1414;
  background-image:
    radial-gradient(ellipse 120% 60% at 50% 0%, rgba(255,150,90,.07), transparent 70%),
    repeating-linear-gradient(0deg, rgba(255,255,255,.028) 0 1px, transparent 1px 3px);
  padding: 26px 22px 30px;
  color: var(--dp-ink);
  font-size: .94rem;
  line-height: 1.66;
  clip-path: polygon(
    14px 0, calc(100% - 14px) 0, 100% 14px,
    100% calc(100% - 14px), calc(100% - 14px) 100%,
    14px 100%, 0 calc(100% - 14px), 0 14px);

  /* The device is a fixed size and the message scrolls inside it, like a real
     handheld, rather than the casing stretching to fit the text. The bottom
     vignette is an inset shadow, so it stays put while the content moves and
     hints that there is more below. */
  height: min(72vh, 760px);
  overflow-y: auto;
  overscroll-behavior: contain;
  box-shadow:
    inset 0 -30px 26px -20px rgba(16,10,10,.96),
    inset 0 0 30px rgba(0,0,0,.7);
  scrollbar-width: thin;
  scrollbar-color: rgba(127,211,228,.35) transparent;
}

/* Opt out where a datapad should size to its content instead. */
.datapad.dp-auto .dp-screen { height: auto; overflow: visible; }

.dp-screen::-webkit-scrollbar { width: 8px; }
.dp-screen::-webkit-scrollbar-track { background: rgba(0,0,0,.35); }
.dp-screen::-webkit-scrollbar-thumb {
  background: rgba(127,211,228,.3);
  border-radius: 4px;
}
.dp-screen::-webkit-scrollbar-thumb:hover { background: rgba(127,211,228,.5); }

.dp-screen p { margin-bottom: 14px; }
.dp-screen p:last-child { margin-bottom: 0; }
.dp-screen strong { color: #fff; }

/* Device logo. A child of the casing rather than the screen, so it stays put
   while the message scrolls underneath it. */
.dp-logo {
  position: absolute;
  top: 36px; right: 40px;
  z-index: 2;
  width: 46px; height: 46px;
  opacity: .9;
  filter: drop-shadow(0 0 10px rgba(0,200,224,.45));
}

.dp-major {
  font-family: 'Orbitron', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: clamp(1.05rem, 4.4vw, 1.45rem);
  color: var(--accent);
  margin-bottom: 2px;
  padding-right: 56px;
}

/* Aurebesh line under each header, as on the PDF page. */
.dp-aurebesh {
  font-family: 'Droidobesh', sans-serif;
  font-size: .9rem;
  letter-spacing: .06em;
  color: var(--glow);
  opacity: .85;
  margin-bottom: 4px;
}

.dp-init {
  font-family: 'Share Tech Mono', monospace;
  font-size: .8rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--glow);
  margin-bottom: 26px;
}

/* ">> SECTION" markers in the message body. */
.dp-sec {
  font-family: 'Orbitron', sans-serif;
  font-weight: 500;
  font-size: .84rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--glow);
  margin: 24px 0 10px;
}
.dp-sec::before { content: ">> "; opacity: .7; }

/* Guide components sitting on a datapad screen. The screen is warm and dark, so
   the page's normal white-with-glow headings and cyan-tinted panels would look
   pasted on; these take the device's own palette instead. */
.dp-screen h2 {
  color: var(--accent);
  font-size: 1rem;
  margin: 34px 0 14px;
}
.dp-screen h3 { color: var(--glow); }
.dp-screen .step-n {
  color: var(--glow);
  border-color: rgba(127,211,228,.3);
}
.dp-screen .step-sec { margin: 24px 0; }

/* Bulleted list on the screen, in the device's ink. */
.dp-list { list-style: none; margin: 14px 0 4px; }
.dp-list li { padding-left: 16px; position: relative; margin-bottom: 9px; }
.dp-list li::before {
  content: ">";
  font-family: 'Share Tech Mono', monospace;
  position: absolute; left: 0;
  color: var(--accent);
}
.dp-list li:last-child { margin-bottom: 0; }

/* An important note, as it looks on a device rather than as the holo card. */
.dp-note {
  border: 1px solid rgba(255,107,53,.5);
  background: rgba(255,107,53,.08);
  padding: 15px 17px 13px;
  margin: 26px 0;
}
.dp-note-head {
  font-family: 'Share Tech Mono', monospace;
  text-transform: uppercase;
  letter-spacing: .2em;
  font-size: .72rem;
  color: var(--accent);
  margin-bottom: 8px;
}
.dp-note p:last-child { margin-bottom: 0; }

.dp-end {
  font-family: 'Orbitron', sans-serif;
  font-weight: 500;
  font-size: .8rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--glow);
  margin-top: 28px;
  padding-top: 14px;
  border-top: 1px solid rgba(127,211,228,.2);
}

/* ── FACTION GRID (index page) ───────────────────────────────────────────── */
.faction-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 12px;
  margin: 26px 0 34px;
}

.faction-tile {
  border: 1px solid var(--line);
  background: var(--panel);
  padding: 18px 12px 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-align: center;
  text-decoration: none;
  transition: border-color .2s, background .2s, transform .2s;
}
.faction-tile:hover {
  border-color: var(--glow);
  background: rgba(0,200,224,.09);
  transform: translateY(-3px);
}

.faction-tile img {
  width: 46px;
  height: 46px;
  object-fit: contain;
  filter: drop-shadow(0 0 10px rgba(0,200,224,.4));
}

.faction-tile span {
  font-family: 'Orbitron', sans-serif;
  font-size: .66rem;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text2);
  line-height: 1.35;
}
.faction-tile:hover span { color: var(--glow2); }

/* ── COMLINK (in-world message) ──────────────────────────────────────────── */
.comlink {
  border: 1px solid var(--line);
  border-left: 3px solid var(--glow);
  background: rgba(0,200,224,.04);
  padding: 14px 18px 12px;
  margin: 20px 0 8px;
  font-size: .9rem;
}
.comlink-head {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
  font-family: 'Share Tech Mono', monospace;
  font-size: .72rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text3);
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
.comlink-head b { color: var(--glow); font-weight: 400; }
.comlink p:last-child { margin-bottom: 0; }
.comlink-link {
  font-family: 'Share Tech Mono', monospace;
  font-size: .76rem;
  color: var(--accent);
  word-break: break-all;
}

/* Prism's invite actually goes somewhere. It must not look like a guide link:
   it keeps the comlink's own orange mono so it reads as part of the message,
   and only the cursor and a faint glow on hover admit that it is clickable.
   Finding it should feel like curiosity, not like following a signpost. */
.comlink-link a {
  color: inherit;
  border-bottom: 1px dotted rgba(255,107,53,.4);
  cursor: pointer;
}
.comlink-link a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
  text-shadow: 0 0 10px rgba(255,107,53,.6);
}

.caption {
  font-size: .82rem;
  color: var(--text3);
  margin-bottom: 20px;
}

/* ── RANK CARDS (faction pages) ──────────────────────────────────────────── */
.rank {
  border: 1px solid var(--line);
  border-left: 3px solid var(--faction);
  background: rgba(255,255,255,.02);
  padding: 16px 18px 10px;
  margin: 16px 0;
}
.rank-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.rank-num {
  font-family: 'Orbitron', sans-serif;
  font-weight: 700; font-size: .9rem;
  letter-spacing: .12em; text-transform: uppercase; color: #fff;
}
.rank-cost {
  font-family: 'Share Tech Mono', monospace;
  font-size: .72rem; letter-spacing: .14em;
  color: var(--faction);
  border: 1px solid var(--line);
  padding: 2px 8px;
}
.rank ul { list-style: none; }
.rank li { padding-left: 20px; position: relative; margin-bottom: 8px; }
.rank li::before { content: "◆"; position: absolute; left: 0; font-size: .6rem; top: .4em; color: var(--faction); }
.passive {
  font-family: 'Share Tech Mono', monospace;
  font-size: .78rem; color: var(--faction); letter-spacing: .08em;
}

/* ── TITLE ROW + EMBLEM ──────────────────────────────────────────────────── */
.title-row { display: flex; align-items: center; gap: 18px; margin-bottom: 30px; }

/* One glow colour for every emblem: the site cyan, same as Lightspire. Per
   faction glows meant dark brand hexes (Bothan's #363636) produced no glow at
   all; a single cyan halo lights every emblem, including the black ones, and
   emblems with cut-out interiors glow through from within. */
.faction-icon {
  width: clamp(64px, 16vw, 96px);
  height: auto;
  flex: none;
  filter: drop-shadow(0 0 16px rgba(0,200,224,.45));
}

/* ── MISC ────────────────────────────────────────────────────────────────── */
.footnote {
  font-family: 'Share Tech Mono', monospace;
  font-size: .74rem;
  color: rgba(207,230,236,.6);
  margin-top: 26px;
  letter-spacing: .05em;
}
.footnote::before { content: "* "; color: var(--accent); }


.aurebesh {
  font-family: 'Droidobesh', sans-serif;
  text-align: center;
  color: rgba(0,200,224,.4);
  font-size: .8rem;
  letter-spacing: .15em;
  margin-top: 46px;
}

/* Call to action into the guide */
.cta {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: 'Share Tech Mono', monospace;
  font-size: .8rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--glow);
  border: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 12px 20px;
  margin-top: 8px;
  transition: background .2s, border-color .2s, color .2s;
}
.cta:hover { background: rgba(0,200,224,.08); border-color: var(--glow); color: var(--glow2); }

/* ── DOWNTIME TERMINAL ───────────────────────────────────────────────────── */
/* The one page in the guide you operate rather than read, so it is allowed to
   look like a console: numbered steps, a hard-edged form, a printout at the
   end. Everything is drawn from the same palette as the rest of the guide, so
   it still reads as a screen on the same datapad. */

/* scroll-margin so that scrolling back to the top of the terminal after picking
   an activity does not park it under the sticky header. */
.dt-app { margin-top: 30px; scroll-margin-top: 72px; }
.dt-nojs { color: var(--accent); }

/* Numbered step marker, with the rule trailing off to the right. */
.dt-step {
  display: flex; align-items: center; gap: 10px;
  font-family: 'Share Tech Mono', monospace;
  font-size: .72rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--text3);
  margin: 30px 0 12px;
}
.dt-step b { color: var(--glow2); font-weight: 400; }
.dt-step::after { content: ""; flex: 1; height: 1px; background: linear-gradient(90deg, var(--line), transparent); }

/* ── form controls ── */
.dt-field { margin-bottom: 14px; }
.dt-field label, .dt-label {
  display: block;
  font-family: 'Share Tech Mono', monospace;
  font-size: .68rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--text3);
  margin-bottom: 5px;
}
.dt-app input[type="text"], .dt-app input[type="number"], .dt-app select, .dt-app textarea {
  width: 100%;
  font-family: 'Credit', 'Exo 2', sans-serif;
  font-size: .95rem;
  color: var(--text);
  background: rgba(0,0,0,.28);
  border: 1px solid var(--border);
  padding: 10px 11px;
  border-radius: 0;
  -webkit-appearance: none;
  appearance: none;
}
.dt-app textarea { resize: vertical; min-height: 62px; line-height: 1.5; }
.dt-app input:focus, .dt-app select:focus, .dt-app textarea:focus {
  outline: none;
  border-color: var(--glow);
  box-shadow: 0 0 0 1px rgba(0,200,224,.28);
}
/* The native arrow is drawn rather than shown, so the control keeps the flat
   cornerless look the rest of the page has. */
.dt-app select {
  padding-right: 32px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--text3) 50%),
    linear-gradient(135deg, var(--text3) 50%, transparent 50%);
  background-position: calc(100% - 17px) 50%, calc(100% - 12px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.dt-hint { font-size: .8rem; color: var(--text3); margin-top: 6px; }

.dt-check { display: flex; align-items: center; flex-wrap: wrap; gap: 9px; }
.dt-check input { width: 17px; height: 17px; accent-color: var(--glow); flex: 0 0 auto; }
.dt-check label { margin-bottom: 0; }
.dt-check .dt-hint { flex-basis: 100%; margin-top: 0; }

.dt-stepper { display: flex; align-items: stretch; gap: 7px; }
.dt-stepper button {
  width: 3rem; flex: 0 0 auto;
  font-family: 'Orbitron', sans-serif; font-size: 1.05rem;
  color: var(--glow);
  background: rgba(0,200,224,.07);
  border: 1px solid var(--border);
  cursor: pointer;
}
.dt-stepper button:hover:not(:disabled) { border-color: var(--glow); background: rgba(0,200,224,.14); }
.dt-stepper button:disabled { opacity: .3; cursor: default; color: var(--text3); }
.dt-stepper output {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 8px;
  font-family: 'Orbitron', sans-serif; font-size: 1.05rem;
  background: rgba(0,0,0,.28);
  border: 1px solid var(--border);
  padding: 8px;
}
.dt-stepper output small {
  font-family: 'Share Tech Mono', monospace;
  font-size: .64rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--text3);
}

/* ── setup bar and hour budget ── */
.dt-setup { border: 1px solid var(--line); background: var(--panel); padding: 16px 16px 14px; }
.dt-setup-row { display: flex; gap: 12px; align-items: flex-start; }
.dt-setup-row .dt-field { flex: 1; margin-bottom: 0; }
.dt-setup-row .dt-narrow { flex: 0 0 6.5rem; }

.dt-budget {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 7px;
  margin-top: 14px; padding-top: 12px;
  border-top: 1px solid rgba(14,58,82,.7);
}
.dt-budget-l {
  font-family: 'Share Tech Mono', monospace;
  font-size: .68rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--text3);
}
.dt-budget b { font-family: 'Orbitron', sans-serif; font-size: 1.2rem; color: var(--glow2); }
.dt-budget b.over { color: #e05050; }

/* ── category tabs ── */
.dt-tabs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(5.4rem, 1fr));
  gap: 5px;
  margin-bottom: 12px;
}
.dt-tab {
  font-family: 'Share Tech Mono', monospace;
  font-size: .68rem; letter-spacing: .1em;
  color: var(--text3);
  background: var(--panel);
  border: 1px solid var(--border);
  padding: 11px 4px;
  cursor: pointer;
  transition: color .15s, border-color .15s, background .15s;
}
.dt-tab:hover { color: var(--text2); }
.dt-tab[aria-selected="true"] {
  color: var(--glow);
  border-color: var(--glow);
  background: rgba(0,200,224,.1);
}
/* Roomier tabs once there is width for them. In one desktop row, seven of them
   at the mobile size read as a cramped strip rather than a control. */
@media (min-width: 560px) {
  .dt-tab { padding: 14px 8px; font-size: .72rem; letter-spacing: .12em; }
}

/* A running event takes the orange accent, and carries a lit halo whether or
   not it is the open tab: on a phone it sits alone at the head of its own row
   and cannot be missed, but on desktop all seven sit in one strip, and flat
   orange among six cyan is easy to read past. */
.dt-tab-event {
  color: var(--accent);
  border-color: rgba(255,107,53,.45);
  background: rgba(255,107,53,.05);
  box-shadow: 0 0 14px rgba(255,107,53,.14);
  animation: dt-event-pulse 3.2s ease-in-out infinite;
}
.dt-tab-event:hover { color: #ffaa44; border-color: var(--accent); }
.dt-tab-event[aria-selected="true"] {
  color: #ffaa44;
  border-color: var(--accent);
  background: rgba(255,107,53,.14);
  box-shadow: 0 0 20px rgba(255,107,53,.3), inset 0 0 22px rgba(255,107,53,.1);
  text-shadow: 0 0 12px rgba(255,107,53,.6);
  animation: none;        /* it has arrived; it no longer needs to ask */
}

@keyframes dt-event-pulse {
  0%, 100% { box-shadow: 0 0 10px rgba(255,107,53,.1); }
  50%      { box-shadow: 0 0 20px rgba(255,107,53,.26); }
}

@media (prefers-reduced-motion: reduce) {
  .dt-tab-event { animation: none; }
}

/* The event's one standing line: that this is temporary, and when it ends. */
.dt-notice {
  border: 1px solid rgba(255,107,53,.35);
  border-left: 2px solid var(--accent);
  background: rgba(255,107,53,.06);
  padding: 12px 15px;
  margin-bottom: 12px;
  font-size: .88rem;
  color: var(--text2);
}
.dt-notice b { color: var(--accent); font-weight: 600; }


/* ── activity cards ── */
.dt-cards { display: flex; flex-direction: column; gap: 7px; }
.dt-card {
  display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--panel);
  border: 1px solid var(--border);
  border-left: 2px solid rgba(0,200,224,.3);
  padding: 13px 14px;
  color: inherit;
  font: inherit;
  transition: border-color .15s, background .15s;
}
.dt-card:hover, .dt-card:focus-visible {
  background: rgba(0,200,224,.09);
  border-left-color: var(--glow);
  outline: none;
}
.dt-card-name {
  display: block;
  font-family: 'Orbitron', sans-serif; font-size: .86rem; font-weight: 500;
  color: var(--text);
}
.dt-card-gain { display: block; font-size: .88rem; color: var(--glow2); margin-top: 3px; }
/* 'Credit' has to lead the stack even here: it is scoped to U+0024 alone, so it
   is the only reason a "$" in this row renders as the galactic credit glyph
   rather than a dollar sign. Everything else still falls through to the mono. */
.dt-card-meta {
  display: flex; flex-wrap: wrap; gap: 4px 10px;
  margin-top: 9px;
  font-family: 'Credit', 'Share Tech Mono', monospace;
  font-size: .66rem; letter-spacing: .06em;
  color: var(--text3);
}
/* A leading triangle on every item rather than a separator between them, so the
   spacing stays even however the row wraps. */
.dt-card-meta > span::before { content: "\25B8\00A0"; color: rgba(0,200,224,.45); }
.dt-card-meta > span.roll { color: var(--accent); }
.dt-card-meta > span.roll::before { color: var(--accent); }
/* Costs more hours than the reader has left. Still openable: they may be
   planning next week, or about to buy hours with Time is Credits. */
.dt-card.over { opacity: .45; }
.dt-card-meta > span.over { color: #e05050; }

/* ── detail ── */
.dt-detail-top { display: flex; align-items: center; gap: 12px; margin: 4px 0 16px; }
.dt-back {
  flex: 0 0 auto;
  font-family: 'Share Tech Mono', monospace; font-size: .72rem; letter-spacing: .1em;
  color: var(--text3);
  background: none;
  border: 1px solid var(--border);
  padding: 7px 11px;
  cursor: pointer;
}
.dt-back:hover { color: var(--glow); border-color: var(--glow); }
.dt-detail-title {
  font-family: 'Orbitron', sans-serif; font-size: .98rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: .04em;
  color: var(--glow);
}
.dt-note { font-size: .9rem; color: var(--text2); margin-bottom: 14px; }

.dt-stats { border: 1px solid var(--border); background: var(--panel); padding: 4px 14px; }
.dt-stats > div {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 9px 0;
  font-size: .88rem;
}
.dt-stats > div + div { border-top: 1px solid rgba(14,58,82,.6); }
.dt-stats dt {
  flex: 0 0 auto;
  font-family: 'Share Tech Mono', monospace;
  font-size: .66rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--text3);
}
.dt-stats dd { text-align: right; }
.dt-stats dd.gain { color: var(--glow2); }
.dt-stats dd.roll { color: var(--accent); }
.dt-stats dd.over { color: #e05050; }

/* ── the printout ── */
.dt-out { border: 1px solid var(--line); margin-top: 4px; }
.dt-out-bar {
  display: flex; justify-content: space-between; gap: 12px;
  background: rgba(0,200,224,.08);
  border-bottom: 1px solid var(--border);
  padding: 8px 12px;
  font-family: 'Share Tech Mono', monospace;
  font-size: .64rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--text3);
}
.dt-out pre {
  margin: 0; padding: 14px 12px;
  background: rgba(0,0,0,.28);
  font-family: 'Share Tech Mono', monospace;
  font-size: .78rem; line-height: 1.7;
  color: var(--text2);
  white-space: pre-wrap;
  overflow-wrap: break-word;
}
.dt-copy {
  display: block; width: 100%;
  margin-top: 12px; padding: 15px;
  font-family: 'Share Tech Mono', monospace;
  font-size: .8rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--glow);
  background: rgba(0,200,224,.1);
  border: 1px solid var(--glow);
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.dt-copy:hover { background: rgba(0,200,224,.2); }
.dt-copy.done { color: var(--glow2); border-color: var(--glow2); background: rgba(0,240,200,.14); }
.dt-tail { font-size: .86rem; color: var(--text3); margin-top: 12px; }
.dt-tail b { color: var(--text2); }

@media (max-width: 400px) {
  .dt-setup-row { flex-wrap: wrap; }
  .dt-setup-row .dt-narrow { flex: 1 0 100%; }
}

/* ── CHROME: nav bar, arrows, menu ───────────────────────────────────────── */
.chrome {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px;
  background: rgba(5,13,20,.92);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--border);
}

/* Home, centred on the screen rather than in whatever space the controls leave.
   The arrows are two buttons wide and the menu button is one, so centring the
   logo in the remaining space put it visibly off to one side. Taken out of the
   flow entirely and pinned to the middle instead. */
.chrome { justify-content: space-between; }
.chrome .arrows, .chrome > #burger { flex: 0 0 auto; }

.chrome-home {
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}
.chrome-home img {
  width: 26px;
  height: 26px;
  filter: drop-shadow(0 0 10px rgba(0,200,224,.5));
  transition: filter .2s, transform .2s;
}
.chrome-home:hover img {
  filter: drop-shadow(0 0 16px rgba(0,240,200,.8));
  transform: scale(1.06);
}

.icon-btn {
  background: none; border: 1px solid transparent;
  color: var(--text2);
  font-family: 'Share Tech Mono', monospace;
  font-size: 1rem; line-height: 1;
  padding: 7px 10px;
  cursor: pointer;
  transition: color .2s, border-color .2s, background .2s;
}
.icon-btn:hover:not(:disabled) { color: var(--glow2); border-color: var(--line); background: rgba(0,200,224,.06); }
.icon-btn:disabled { opacity: .25; cursor: default; }
.icon-btn:focus-visible { outline: 1px solid var(--glow); outline-offset: 1px; }

/* Always shown, on touch too. The in-page pager sits at a different height on
   every page because pages differ in length; these stay put in the sticky
   header, so there is one control that never moves. */
.arrows { display: flex; gap: 4px; }

/* Slide-over page list */
#menu {
  position: fixed; inset: 0 0 0 auto;
  width: min(340px, 86vw);
  background: #071522;
  border-left: 1px solid var(--border);
  z-index: 70;
  transform: translateX(100%);
  transition: transform .28s var(--ease);
  overflow-y: auto;
  padding: 18px 0 40px;
}
#menu.open { transform: translateX(0); }

#scrim {
  position: fixed; inset: 0;
  background: rgba(2,8,13,.6);
  z-index: 65;
  opacity: 0; pointer-events: none;
  transition: opacity .28s;
}
#scrim.open { opacity: 1; pointer-events: auto; }

.menu-head {
  font-family: 'Share Tech Mono', monospace;
  font-size: .64rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--text3);
  padding: 10px 20px 12px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 8px;
  display: flex; justify-content: space-between; align-items: center;
}

.menu-link {
  display: flex; align-items: baseline; gap: 10px;
  padding: 9px 20px;
  font-size: .86rem;
  color: var(--text2);
  border: none;
  background: none;
  width: 100%;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
  transition: background .18s, color .18s;
}
.menu-link:hover { background: rgba(0,200,224,.07); color: var(--glow2); }
.menu-link[aria-current="true"] { color: #fff; background: rgba(0,200,224,.1); }
.menu-link[aria-current="true"] .menu-num { color: var(--accent); }

.menu-num {
  font-family: 'Share Tech Mono', monospace;
  font-size: .66rem;
  color: var(--text3);
  flex: none;
  min-width: 1.6em;
}

/* Pages not built yet: shown so the shape of the guide is visible, but inert. */
.menu-link.pending { opacity: .34; cursor: default; }
.menu-link.pending:hover { background: none; color: var(--text2); }
.menu-link.pending::after {
  content: "PENDING";
  font-family: 'Share Tech Mono', monospace;
  font-size: .54rem; letter-spacing: .12em;
  color: var(--accent);
  margin-left: auto;
  align-self: center;
}

.menu-sub { padding-left: 42px; font-size: .8rem; }

/* Bottom pager, the mobile affordance for "there is more this way" */
.pager {
  display: flex; justify-content: space-between; gap: 12px;
  border-top: 1px solid var(--border);
  margin-top: 40px; padding-top: 16px;
  font-family: 'Share Tech Mono', monospace;
  font-size: .68rem; letter-spacing: .1em; text-transform: uppercase;
}
.pager button {
  background: none; border: none; color: var(--text3);
  font: inherit; cursor: pointer; padding: 4px 0;
  max-width: 46%; text-align: left;
}
.pager button:last-child { text-align: right; }
.pager button:hover { color: var(--glow2); }
.pager button:disabled { opacity: 0; cursor: default; }

@media (prefers-reduced-motion: reduce) {
  .sliding, #menu, #scrim { transition-duration: .01ms; }
}
