/* ============================================================
   THE GOLDEN MAP — ui.css
   Owns everything inside #ui. Uses only tokens from style.css.
   Warm gold = as engraved (1969) · starlight = modern · alarm = flaws.
   ============================================================ */

/* ---- panel machinery: restrained translate + fade -------------------- */
.gm-panel {
  position: fixed;
  z-index: 20;
  opacity: 0;
  visibility: hidden;
  transform: var(--gm-in, translateY(14px));
  transition:
    opacity 0.6s var(--ease),
    transform 0.6s var(--ease),
    visibility 0s linear 0.6s;
}
.gm-panel.is-on {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}

/* ---- shared sheet chrome ---------------------------------------------- */
/* --pad-* is the sheet's own padding; --tab-bleed is how far the mobile
   header tab must reach sideways to meet the sheet's edges (the rail pads
   its rows individually, so its own box has no side padding to cancel). */
.gm-sheet {
  --pad-y: 1.35rem;
  --pad-x: 1.5rem;
  --tab-bleed: var(--pad-x);
  background: color-mix(in srgb, var(--void-lift) 88%, transparent);
  border: 1px solid var(--gold-faint);
  backdrop-filter: var(--blur-panel);
  -webkit-backdrop-filter: var(--blur-panel);
  padding: var(--pad-y) var(--pad-x);
}
.gm-sheet h2 {
  font-size: var(--step-2);
  line-height: 1.15;
  margin: 0.35em 0 0.4em;
}
.gm-body {
  font-size: 0.98rem;
  color: var(--paper);
  max-width: 60ch;
}
.gm-nowrap { white-space: nowrap; }

/* every expandable section's summary reads as a BUTTON, not a plain label —
   bordered pill, hover glow, with the existing +/− state suffix */
.gm-cover-fig summary,
.gm-drake summary,
.gm-sources summary,
.gm-fine-more summary {
  display: inline-block;
  padding: 0.6em 1em;
  border: 1px solid var(--gold-faint);
  border-radius: 999px;
  background: color-mix(in srgb, var(--void-lift) 88%, transparent);
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.gm-cover-fig summary:hover,
.gm-drake summary:hover,
.gm-sources summary:hover,
.gm-fine-more summary:hover { color: var(--gold-bright); border-color: var(--gold-dim); }

/* mobile-only sheet header tabs (styled inside the ≤900px block) */
.gm-sheet-tab { display: none; }

/* thin engraved scrollbars */
.gm-sheet, .gm-rail-list, .gm-detail-body {
  scrollbar-width: thin;
  scrollbar-color: var(--gold-faint) transparent;
}
.gm-sheet::-webkit-scrollbar, .gm-rail-list::-webkit-scrollbar,
.gm-detail-body::-webkit-scrollbar { width: 4px; }
.gm-sheet::-webkit-scrollbar-thumb,
.gm-rail-list::-webkit-scrollbar-thumb,
.gm-detail-body::-webkit-scrollbar-thumb { background: var(--gold-faint); }

/* key–value rows (detail, crab clock) */
.gm-kv {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1.2em;
  padding: 0.45em 0;
  border-top: 1px solid color-mix(in srgb, var(--gold-faint) 55%, transparent);
}
.gm-k {
  font-family: var(--mono);
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--paper-dim);
}
.gm-v { font-size: 0.8rem; text-align: right; }

/* ---- fine print: footnote-grade secondary text ------------------------
   Plain language leads; the technical provenance lives here. */
.gm-fine {
  display: block;
  font-size: 0.72rem;
  line-height: 1.55;
  color: var(--paper-dim);
  border-top: 1px solid color-mix(in srgb, var(--gold-faint) 55%, transparent);
  margin: 0.55em 0 0 0.6em;
  padding-top: 0.45em;
  max-width: 58ch;
}
/* inside list items the border-left already insets the text */
.gm-list li .gm-fine { margin-left: 0; }

/* longer technical asides collapse behind a disclosure */
.gm-fine-more { margin: 0.8em 0 0 0.6em; }
.gm-fine-more summary {
  cursor: pointer;
  list-style: none;
  font-family: var(--mono);
  font-weight: 500;
  font-size: 0.56rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--gold-dim);
}
.gm-fine-more summary::-webkit-details-marker { display: none; }
.gm-fine-more summary::after { content: ' +'; color: var(--gold-dim); }
.gm-fine-more[open] summary::after { content: ' −'; }
.gm-fine-more summary:hover { color: var(--gold); }
.gm-fine-more .gm-fine { border-top: none; margin-left: 0; padding-top: 0.35em; }

/* ======================================================================
   1. ACT NAV
   ====================================================================== */
#ui .gm-nav { pointer-events: none; }
.gm-nav {
  top: 0; left: 0; right: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 16px;
  --gm-in: translateY(-10px);
}
.gm-nav-row { display: flex; gap: 7px; pointer-events: auto; align-items: stretch; }

/* prev/next act chevrons — quiet ghosts hinting that the arrow keys work.
   align-items: stretch on the row makes them the same height as the act
   buttons; the glyph is a plain ‹ › (no arrow tail), sized to match */
.gm-nav-arrow {
  display: flex;
  align-items: center;
  padding: 0 0.5em;
  font-family: var(--display);
  font-size: 1.15rem;
  line-height: 1;
  color: var(--gold-dim);
  border: 1px solid transparent;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease), opacity 0.3s var(--ease);
}
.gm-nav-arrow:hover:not(:disabled) { color: var(--gold-bright); border-color: var(--gold-faint); }
.gm-nav-arrow:disabled { opacity: 0.25; cursor: default; }
.gm-act {
  display: flex;
  align-items: center;
  gap: 0.55em;
  padding: 0.5em 0.95em;
  border: 1px solid var(--gold-faint);
  background: color-mix(in srgb, var(--void) 72%, transparent);
  backdrop-filter: var(--blur-chip);
  -webkit-backdrop-filter: var(--blur-chip);
  font-family: var(--display);
  font-size: 0.8rem;
  letter-spacing: 0.09em;
  color: var(--paper-dim);
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.gm-act-n { font-size: 0.66rem; font-weight: 500; letter-spacing: 0.12em; color: var(--gold-dim); }
.gm-act:hover { color: var(--gold-bright); border-color: var(--gold-dim); }
.gm-act.is-current { color: var(--gold-bright); border-color: var(--gold); }
.gm-act.is-current .gm-act-n { color: var(--gold); }
.gm-nav-progress {
  pointer-events: auto;
  width: min(540px, 74vw);
  height: 1px;
  margin-top: 13px;
  background: var(--gold-faint);
}
/* scaleX, not width: animating width relayouts the bar every frame, and this
   one runs on every act change — a transform is composited instead */
.gm-nav-progress i {
  display: block;
  height: 1px;
  width: 100%;
  transform: scaleX(0.2);
  transform-origin: left center;
  background: var(--gold);
  transition: transform 0.9s var(--ease);
}
/* current-act title for compact nav — shown only ≤560px, below the hairline
   so the progress bar never shifts */
.gm-nav-title {
  display: none;
  pointer-events: none;
  margin-top: 7px;
  font-family: var(--display);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-align: center;
  color: var(--gold-bright);
}

/* ======================================================================
   2. TITLE CARD
   ====================================================================== */
#ui .gm-title { pointer-events: none; }
/* Desktop: a left-column masthead — the record and the probe own the right
   side of the frame, with nothing overlapping them. */
.gm-title {
  left: 4.5vw;
  bottom: 12vh;
  z-index: 15;
  width: min(420px, 38vw);
  text-align: left;
  padding: 0;
  --gm-in: translateY(22px);
}
@media (max-width: 900px) {
  /* Phones: back to a compact centered bottom card (the portrait camera
     already lifts the disc above it), with a legibility wash. */
  .gm-title {
    left: 0; right: 0;
    bottom: calc(72px + env(safe-area-inset-bottom, 0px)); /* clears the docked mini player */
    width: auto;
    text-align: center;
    padding: 1.6rem 20px 0.4rem;
    /* stronger wash: the eyebrow can sit over the disc's bottom edge */
    background: radial-gradient(ellipse 52% 128% at 50% 62%,
      color-mix(in srgb, var(--void) 88%, transparent) 0%,
      color-mix(in srgb, var(--void) 62%, transparent) 48%,
      transparent 74%);
  }
}
.gm-title h1 {
  font-size: clamp(2.3rem, 5.4vw, 3.2rem);
  margin: 0.18em 0 0.16em;
  text-shadow: 0 0 44px color-mix(in srgb, var(--gold) 34%, transparent);
}
.gm-tagline {
  margin: 0 0 0.9em;
  font-family: var(--body);
  font-style: italic;
  font-size: clamp(1rem, 1.6vw, 1.2rem);
  letter-spacing: 0.03em;
  color: var(--gold);
}
.gm-hook {
  max-width: 30em;
  margin: 0 0 1.1em;
  font-size: var(--step-0);
  line-height: 1.5;
  color: var(--paper);
}
/* the one-off greeting: a quiet second line under Begin */
.gm-hello {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 0.65em;
  margin-top: 0.85em;
  padding: 0.55em 0.95em;
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--gold-dim);
  border: 1px solid var(--gold-faint);
  border-radius: 999px;
  background: color-mix(in srgb, var(--void-lift) 70%, transparent);
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.gm-hello:hover { color: var(--gold-bright); border-color: var(--gold-dim); }
.gm-hello.is-playing { color: var(--gold); border-color: var(--gold-dim); }
.gm-hello-ic { display: flex; }
.gm-hello-ic svg { width: 9px; height: 9px; fill: currentColor; }
@media (max-width: 900px) { .gm-hello { margin-top: 0.7em; } }
@media (max-width: 900px) { .gm-hook { max-width: 44em; margin: 0 auto 1em; } }
.gm-begin {
  pointer-events: auto;
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--gold);
  padding: 0.9em 1.8em;
  border: 1px solid var(--gold-faint);
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.gm-begin:hover { color: var(--gold-bright); border-color: var(--gold); }

/* ======================================================================
   3. EXPLAINER (left column)
   ====================================================================== */
.gm-left {
  left: 22px;
  top: 96px;
  width: min(430px, calc(100vw - 44px));
  max-height: calc(100vh - 200px);
  overflow-y: auto;
  --gm-in: translateX(-18px);
}
.gm-how {
  list-style: none;
  display: grid;
  gap: 0.8em;
  margin: 1.15em 0 0;
}
.gm-how li {
  font-size: 0.94rem;
  color: var(--paper-dim);
  border-left: 1px solid var(--gold-faint);
  padding-left: 0.95em;
  max-width: 60ch;
}
.gm-how b {
  display: block;
  font-family: var(--mono);
  font-weight: 500;
  font-size: 0.58rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 0.2em;
}

/* the animated binary readout */
.gm-demo {
  margin-top: 1.3em;
  padding-top: 1.05em;
  border-top: 1px solid var(--gold-faint);
}
.gm-demo-ticks {
  margin-top: 0.7em;
  font-size: 0.74rem;
  letter-spacing: 0.1em;
  color: var(--gold-bright);
  min-height: 1.35em;
  white-space: nowrap;
  overflow: hidden;
}
.gm-demo-bits {
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  color: var(--gold-dim);
  min-height: 1.4em;
  white-space: nowrap;
  overflow: hidden;
}
.gm-demo.typing .gm-demo-bits::after {
  content: '▏';
  color: var(--gold);
  animation: gm-caret 0.9s steps(1) infinite;
}
@keyframes gm-caret { 50% { opacity: 0; } }
.gm-demo-result {
  margin-top: 0.55em;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--paper-dim);
  opacity: 0;
  transform: translateY(5px);
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
}
.gm-demo.is-done .gm-demo-result { opacity: 1; transform: none; }

/* the annotated cover diagram (Act II disclosure) */
.gm-cover-fig {
  margin-top: 1.2em;
  padding-top: 0.95em;
  border-top: 1px solid var(--gold-faint);
}
.gm-cover-fig summary {
  cursor: pointer;
  list-style: none;
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold);
}
.gm-cover-fig summary::-webkit-details-marker { display: none; }
.gm-cover-fig summary::after { content: ' +'; color: var(--gold-dim); }
.gm-cover-fig[open] summary::after { content: ' −'; }
.gm-cover-fig-body {
  margin-top: 0.7em;
  max-height: 300px;
  overflow-y: auto;
  border: 1px solid var(--gold-faint);
  scrollbar-width: thin;
  scrollbar-color: var(--gold-faint) transparent;
}
.gm-cover-fig-body::-webkit-scrollbar { width: 4px; }
.gm-cover-fig-body::-webkit-scrollbar-thumb { background: var(--gold-faint); }
.gm-cover-fig-body svg { display: block; width: 100%; height: auto; }
.gm-cover-fig-credit {
  margin-top: 0.45em;
  font-size: 0.72rem;
  font-style: italic;
  color: var(--paper-dim);
}

/* ======================================================================
   4. PULSAR RAIL
   ====================================================================== */
.gm-rail {
  left: 22px;
  top: 96px;
  width: min(var(--panel-w), calc(100vw - 44px)); /* same width as the other panels */
  max-height: calc(100vh - 210px);
  display: flex;
  flex-direction: column;
  /* rows and header carry their own side padding, so the box has none */
  --pad-y: 1.1rem;
  --pad-x: 1.1rem;
  --tab-bleed: 0px;
  padding: var(--pad-y) 0 0.4rem;
  --gm-in: translateX(-18px);
}
.gm-rail-head { padding: 0 1.1rem 0.7rem; }
.gm-rail-note { font-size: 0.74rem; font-style: italic; color: var(--paper-dim); }
.gm-pulse-ctl {
  display: flex;
  flex-wrap: wrap; /* three buttons + label must fit a 390px drawer head */
  align-items: baseline;
  gap: 0.35em;
  margin-top: 0.55rem;
}
.gm-pulse-ctl .gm-k { margin-right: 0.2em; }
.gm-pulse-ctl .gm-mode { padding: 0.18em 0.55em; font-size: 0.62rem; }
.gm-rail-list { overflow-y: auto; }
.gm-row {
  display: grid;
  grid-template-columns: 1.7em 1fr auto 14px;
  gap: 0.55em;
  align-items: center;
  width: 100%;
  text-align: left;
  padding: 0.46em 1.1rem;
  border-top: 1px solid color-mix(in srgb, var(--gold-faint) 55%, transparent);
  transition: background 0.25s var(--ease);
}
.gm-row:hover { background: color-mix(in srgb, var(--gold) 7%, transparent); }
.gm-row.is-selected {
  background: color-mix(in srgb, var(--gold) 12%, transparent);
  box-shadow: inset 2px 0 0 var(--gold);
}
.gm-row-n { font-size: 0.6rem; color: var(--gold-dim); }
.gm-row-name { font-size: 0.92rem; color: var(--paper); }
.gm-row-alias { margin-left: 0.45em; font-style: italic; color: var(--gold-bright); }
.gm-row-conf {
  display: block;
  font-family: var(--mono);
  font-weight: 500;
  font-size: 0.54rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--paper-dim);
}
.gm-row-p { font-size: 0.66rem; }
.gm-row-gc .gm-row-name { color: var(--copper); }
.gm-dot {
  width: 5px; height: 5px;
  border-radius: 50%;
  justify-self: center;
  background: var(--gold-dim);
  animation: gm-beat linear infinite;
}
.gm-dot-still { animation: none; background: var(--copper); }
@keyframes gm-beat {
  0%, 4% {
    background: var(--gold-bright);
    box-shadow: 0 0 7px 1px color-mix(in srgb, var(--gold-bright) 65%, transparent);
  }
  9%, 100% { background: var(--gold-dim); box-shadow: none; }
}

/* On phones the rail is a bottom sheet like every other panel — its header
   tab is the open/close control, so there is no floating drawer button. */

/* ======================================================================
   5. DETAIL PANEL
   ====================================================================== */
/* The panel itself never scrolls — the body does, below a fixed header row
   that owns the close button. Nothing ever slides underneath the ✕. */
.gm-detail {
  right: 22px;
  top: 96px;
  width: min(var(--panel-w), calc(100vw - 44px));
  max-height: calc(100vh - 200px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 30;
  --gm-in: translateX(18px);
}
.gm-close {
  flex: none;
  align-self: flex-end;
  /* tucked toward the panel corner, clear of the text column */
  margin: -0.55rem -0.7rem 0.3rem 0;
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 0.7rem;
  line-height: 1;
  color: var(--paper-dim);
  border: 1px solid var(--gold-faint);
  border-radius: 999px;
  background: color-mix(in srgb, var(--void-lift) 88%, transparent);
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.gm-close:hover { color: var(--gold-bright); border-color: var(--gold-dim); }
.gm-detail-body {
  min-height: 0;
  overflow-y: auto;
  padding-right: 0.35rem; /* text clears the thin scrollbar */
}
.gm-detail-name { font-size: var(--step-2); margin: 0.3em 0 0.05em; }
.gm-detail-sub { font-size: 0.62rem; letter-spacing: 0.12em; color: var(--paper-dim); margin-bottom: 1em; }
.gm-bin-label { display: block; margin: 0.9em 0 0.3em; }
.gm-bin {
  font-size: 0.76rem;
  line-height: 1.75;
  letter-spacing: 0.13em;
  color: var(--gold);
  word-break: break-all;
  margin-bottom: 0.9em;
}
.gm-detail-note {
  font-size: 0.82rem;
  color: var(--paper-dim);
  padding: 0.3em 0 0.5em;
  max-width: 60ch;
}
.gm-detail-story {
  font-size: 0.94rem;
  margin-top: 0.9em;
  padding-top: 0.8em;
  border-top: 1px solid color-mix(in srgb, var(--gold-faint) 55%, transparent);
}
.gm-flaw {
  margin-top: 1em;
  padding: 0.8em 0.95em;
  border: 1px solid color-mix(in srgb, var(--alarm) 45%, transparent);
  color: var(--alarm);
  font-size: 0.88rem;
}
.gm-flaw-label {
  font-size: 0.56rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  margin-bottom: 0.35em;
}

/* ======================================================================
   6. VERDICT PANEL
   ====================================================================== */
.gm-verdict {
  /* the rail is hidden in Act IV, so the panel takes the left margin (same rhythm as .gm-rail) */
  left: 22px;
  top: 96px;
  width: min(430px, calc(100vw - 44px));
  max-height: calc(100vh - 200px);
  overflow-y: auto;
  --gm-in: translateX(-18px);
}
.gm-verdict-lede {
  font-size: var(--step-1);
  color: var(--paper);
  margin-bottom: 0.9em;
}
.gm-verdict-lede em { color: var(--gold-bright); }
.gm-block-h {
  font-size: 0.6rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 1.3em 0 0.5em;
  padding-top: 0.9em;
  border-top: 1px solid var(--gold-faint);
}
.gm-list {
  list-style: none;
  display: grid;
  gap: 0.55em;
}
.gm-list li {
  font-size: 1rem;
  line-height: 1.55;
  color: var(--paper);
  padding-left: 0.95em;
  border-left: 1px solid var(--gold-faint);
  max-width: 60ch;
}
/* the technical asides in the verdict panel read at body-adjacent size —
   0.72rem fine print was genuinely hard to read there */
.gm-list li .gm-fine,
.gm-verdict .gm-fine {
  font-size: 0.83rem;
  line-height: 1.6;
  color: color-mix(in srgb, var(--paper) 82%, var(--paper-dim));
}
.gm-modes-label { display: block; margin: 1.4em 0 0.45em; }
.gm-modes { display: flex; flex-wrap: wrap; gap: 6px; }
.gm-mode {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 0.58rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.65em 0.85em;
  border: 1px solid var(--gold-faint);
  color: var(--paper-dim);
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease), background 0.25s var(--ease);
}
.gm-mode:hover { color: var(--paper); border-color: var(--gold-dim); }
.gm-mode.is-active {
  color: var(--gold-bright);
  border-color: var(--gold);
  background: color-mix(in srgb, var(--gold) 10%, transparent);
}
.gm-mode[data-mode='modern'].is-active {
  color: var(--starlight);
  border-color: var(--starlight-dim);
  background: color-mix(in srgb, var(--starlight) 10%, transparent);
}
.gm-crab {
  margin-top: 1.3em;
  padding: 0.95em 1.05em;
  border: 1px solid var(--gold-faint);
  background: color-mix(in srgb, var(--gold) 4%, transparent);
}
.gm-crab-f { font-size: 0.68rem; color: var(--paper-dim); margin: 0.5em 0 0.4em; }
.gm-crab-line { font-size: 0.9rem; font-style: italic; color: var(--paper-dim); margin-top: 0.6em; }
.gm-crab-line em { color: var(--gold-bright); font-style: normal; }

/* ======================================================================
   7. FINDERS PANEL + 8. SOURCES
   ====================================================================== */
.gm-finders {
  /* right column, same rhythm as .gm-detail — never covers the map.
     While a beacon is selected in Act V the detail panel takes this slot
     and ui.js drops the panel's is-on (restored on deselect). */
  right: 22px;
  top: 96px;
  width: min(var(--panel-w), calc(100vw - 44px));
  max-height: calc(100vh - 200px);
  overflow-y: auto;
  z-index: 25;
  --gm-in: translateX(18px);
}
.gm-finders-intro {
  margin-top: 0.55em;
  font-size: 0.92rem;
  color: var(--paper-dim);
  max-width: 62ch;
}
.gm-finders-intro em { color: var(--gold-bright); font-style: normal; }
.gm-time-row {
  display: flex;
  flex-wrap: wrap; /* in the 400px column the beacons readout wraps under T+ */
  justify-content: space-between;
  gap: 0.2em 1em;
  margin-top: 0.8em;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
}
.gm-tplus { color: var(--gold-bright); }
.gm-beacons { color: var(--paper-dim); }
.gm-slider-wrap { position: relative; margin: 1em 0 1.9em; }
.gm-slider {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  height: 14px;
  background: transparent;
  cursor: pointer;
}
.gm-slider::-webkit-slider-runnable-track {
  height: 2px;
  background: linear-gradient(to right, var(--gold), var(--gold-faint));
}
.gm-slider::-moz-range-track {
  height: 2px;
  background: linear-gradient(to right, var(--gold), var(--gold-faint));
}
.gm-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 13px; height: 13px;
  margin-top: -5.5px;
  border-radius: 50%;
  background: var(--void);
  border: 1px solid var(--gold-bright);
  box-shadow: 0 0 9px color-mix(in srgb, var(--gold-bright) 45%, transparent);
}
.gm-slider::-moz-range-thumb {
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--void);
  border: 1px solid var(--gold-bright);
  box-shadow: 0 0 9px color-mix(in srgb, var(--gold-bright) 45%, transparent);
}
.gm-ticks { position: absolute; left: 0; right: 0; top: 100%; height: 1.2em; }
.gm-tick {
  position: absolute;
  transform: translateX(-50%);
  font-family: var(--mono);
  font-size: 0.54rem;
  letter-spacing: 0.08em;
  color: var(--paper-dim);
  padding-top: 0.45em;
}
.gm-tick::before {
  content: '';
  position: absolute;
  top: -2px;
  left: 50%;
  width: 1px;
  height: 5px;
  background: var(--gold-dim);
}
.gm-era {
  font-size: 0.98rem;
  font-style: italic;
  color: var(--paper);
  min-height: 1.6em;
}
/* the Drake card — same disclosure chrome as Sources */
.gm-drake { margin-top: 1em; border-top: 1px solid var(--gold-faint); padding-top: 0.7em; }
.gm-drake summary {
  cursor: pointer;
  list-style: none;
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold);
}
.gm-drake summary::-webkit-details-marker { display: none; }
.gm-drake summary::after { content: ' +'; color: var(--gold-dim); }
.gm-drake[open] summary::after { content: ' −'; }
.gm-drake .gm-body { margin-top: 0.6em; font-size: 0.92rem; color: var(--paper-dim); }
.gm-drake .gm-body em { color: var(--paper); }
.gm-drake-eq {
  margin: 0.75em 0 0.55em;
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  color: var(--gold);
}
.gm-drake-eq sub { font-size: 0.62em; }
/* the playable Drake equation */
.gm-drake-n {
  margin: 0.9em 0 0.05em;
  font-size: 1rem;
  color: var(--paper-dim);
}
.gm-drake-count { font-size: 1.6rem; color: var(--gold-bright); font-weight: 500; }
.gm-drake-nsub { font-size: 0.78rem; color: var(--paper-dim); margin-bottom: 0.9em; }
.gm-drake-presets { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 1em; }
.gm-drake .gm-mode { text-transform: none; letter-spacing: 0.06em; font-size: 0.68rem; }
.gm-drake-row { margin-bottom: 0.6em; }
.gm-drake-rowhead {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1em;
  margin-bottom: 0.1em;
}
.gm-drake-rowhead label { font-size: 0.76rem; color: var(--paper-dim); }
.gm-drake-rowhead output { font-size: 0.7rem; color: var(--gold); white-space: nowrap; }
.gm-drake-note { border-top: none; margin-left: 0; }
.gm-drake-tie {
  font-size: 0.9rem;
  font-style: italic;
  color: var(--paper-dim);
  padding-top: 0.55em;
  border-top: 1px solid color-mix(in srgb, var(--gold-faint) 55%, transparent);
}
.gm-drake-tie em { color: var(--gold-bright); font-style: normal; }

.gm-sources { margin-top: 1em; border-top: 1px solid var(--gold-faint); padding-top: 0.7em; }
.gm-sources summary {
  cursor: pointer;
  list-style: none;
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold);
}
.gm-sources summary::-webkit-details-marker { display: none; }
.gm-sources summary::after { content: ' +'; color: var(--gold-dim); }
.gm-sources[open] summary::after { content: ' −'; }
/* ======================================================================
   THE RECORD PLAYER — a persistent mini dock, bottom-center on every act.
   Gold transport over a hidden SoundCloud widget.
   ====================================================================== */
.gm-mini {
  left: 0; right: 0;
  margin-inline: auto;
  /* as wide as the screen allows — long track titles read whole — while
     always clearing the corner chips flanking the bar */
  width: min(720px, calc(100vw - 360px));
  bottom: 40px;
  z-index: 48;
  --gm-in: translateY(10px);
}
.gm-mini-bar {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 12px;
  border: 1px solid var(--gold-faint);
  border-radius: 14px;
  background: color-mix(in srgb, var(--void-lift) 88%, transparent);
  backdrop-filter: var(--blur-panel);
  -webkit-backdrop-filter: var(--blur-panel);
}
.gm-mini-info { flex: 1; min-width: 0; }
.gm-mini-fly {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 0; right: 0;
  padding: 0.95rem 1.1rem;
  border: 1px solid var(--gold-faint);
  border-radius: 14px;
  background: color-mix(in srgb, var(--void-lift) 92%, transparent);
  backdrop-filter: var(--blur-panel);
  -webkit-backdrop-filter: var(--blur-panel);
}
.gm-mini-fly .gm-fine { border-top: none; margin: 0.7em 0 0; padding-top: 0; }
/* no shouting in the player: mixed case for its heading and playlist chips */
.gm-mini .gm-k,
.gm-mini .gm-mode {
  text-transform: none;
  letter-spacing: 0.06em;
  font-size: 0.68rem;
}
.gm-player-sets { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 0.55em; }
.gm-play-btn {
  flex: none;
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--gold);
  border: 1px solid var(--gold-faint);
  border-radius: 999px;
  background: color-mix(in srgb, var(--void-lift) 88%, transparent);
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.gm-play-btn svg { width: 11px; height: 11px; fill: currentColor; }
.gm-play-btn:hover { color: var(--gold-bright); border-color: var(--gold-dim); }
.gm-play-btn.is-active {
  color: var(--gold-bright);
  border-color: var(--gold-dim);
  background: color-mix(in srgb, var(--gold) 12%, transparent);
}
.gm-pplay { width: 42px; height: 42px; }
.gm-pplay svg { width: 14px; height: 14px; }
.gm-msets { font-size: 0.85rem; line-height: 1; }
/* the standing invitation: a slow golden breath on the play button until
   the first press (stilled under prefers-reduced-motion) */
@keyframes gm-invite {
  0%, 100% { border-color: var(--gold-faint); box-shadow: 0 0 0 0 transparent; }
  50% { border-color: var(--gold); box-shadow: 0 0 14px 0 color-mix(in srgb, var(--gold) 30%, transparent); }
}
.gm-pplay.is-invite { animation: gm-invite 2.6s var(--ease) infinite; }
@media (prefers-reduced-motion: reduce) {
  .gm-pplay.is-invite { animation: none; border-color: var(--gold); }
}
.gm-ptitle {
  font-size: 0.74rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  color: var(--paper);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 0.5em;
}
/* before anything has played, the bar carries an invitation, not a track —
   set in the site's italic serif, gold, like the masthead tagline */
.gm-ptitle.is-idle {
  font-family: var(--body);
  font-style: italic;
  font-size: 0.95rem;
  font-weight: 400;
  letter-spacing: 0.03em;
  color: var(--gold);
}

/* track list browser in the flyout */
.gm-tracklist {
  margin-top: 0.75em;
  max-height: min(230px, 34vh);
  overflow-y: auto;
  display: grid;
  gap: 1px;
  scrollbar-width: thin;
  scrollbar-color: var(--gold-faint) transparent;
}
.gm-tracklist::-webkit-scrollbar { width: 4px; }
.gm-tracklist::-webkit-scrollbar-thumb { background: var(--gold-faint); }
.gm-track {
  display: flex;
  align-items: baseline;
  gap: 0.7em;
  padding: 0.38em 0.5em;
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  text-align: left;
  color: var(--paper-dim);
  border: 1px solid transparent;
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease);
}
.gm-track:hover { color: var(--gold-bright); }
.gm-track.is-current {
  color: var(--gold);
  border-color: var(--gold-faint);
  background: color-mix(in srgb, var(--gold) 6%, transparent);
}
.gm-track-n { flex: none; color: var(--gold-dim); }
.gm-track-t { min-width: 0; }
.gm-pbar {
  position: relative;
  height: 3px;
  background: color-mix(in srgb, var(--gold-faint) 65%, transparent);
  cursor: pointer;
}
/* same story as the nav hairline: scaleX composites, width relayouts — and
   this one animates once a second for as long as the record is playing */
.gm-pbar i {
  display: block;
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  background: var(--gold);
  transition: transform 0.25s linear;
}
/* present for the Widget API, parked out of view */
.gm-sc-host { position: absolute; left: -9999px; top: 0; width: 320px; height: 100px; overflow: hidden; }

.gm-sources ul { list-style: none; margin-top: 0.6em; display: grid; gap: 0.3em; }
.gm-sources li { font-size: 0.82rem; }

/* grouped, claim-anchored source list */
.gm-sources-note { border-top: none; margin: 0.6em 0 0.2em; }
.gm-src-h {
  margin-top: 0.9em;
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gold-dim);
}
.gm-sources ul { margin-top: 0.35em; }

/* per-pulsar reference links on the detail card */
.gm-refs { border-top: none; padding-top: 0; margin-top: 0.3em; }
.gm-refs a { color: var(--gold-dim); text-decoration-color: color-mix(in srgb, var(--gold-dim) 50%, transparent); }
.gm-refs a:hover { color: var(--gold-bright); }

/* ?still=1 screenshot mode: only the masthead and the scene */
body.gm-still .gm-nav,
body.gm-still .gm-corner,
body.gm-still .gm-artifact,
body.gm-still .gm-earth-chip,
body.gm-still .gm-tip { display: none !important; }
body.gm-still .gm-title { bottom: 20vh; }
body.gm-still .gm-mini { display: none !important; }

/* colophon — repo + author credit */
.gm-colophon {
  margin-top: 1em;
  padding-top: 0.7em;
  border-top: 1px solid var(--gold-faint);
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gold-dim);
}
.gm-colophon a { color: var(--gold); text-decoration: none; }
.gm-colophon a:hover { color: var(--gold-bright); }

/* ======================================================================
   9. CORNER MARK
   ====================================================================== */
.gm-corner {
  left: 16px;
  bottom: 13px;
  z-index: 12;
  font-size: 0.55rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-dim);
}
.gm-corner a { color: var(--gold); text-decoration: none; }
.gm-corner a:hover { color: var(--gold-bright); }

/* ======================================================================
   10. ENGRAVING OVERLAY CHIP — bottom-right mirror of the corner mark.
   Detail panel bottoms out ≥104px above the viewport edge (top 96px +
   max-height 100vh − 200px), but keep the chip small and above it anyway.
   ====================================================================== */
.gm-artifact {
  right: 18px;
  bottom: 18px;
  z-index: 35;
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-dim);
  padding: 0.7em 1.1em;
  border: 1px solid var(--gold-faint);
  border-radius: 999px;
  background: color-mix(in srgb, var(--void-lift) 88%, transparent);
  backdrop-filter: var(--blur-chip);
  -webkit-backdrop-filter: var(--blur-chip);
  --gm-in: translateY(10px);
}
.gm-artifact.is-on {
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease),
    color 0.25s var(--ease), border-color 0.25s var(--ease), background 0.25s var(--ease);
}
.gm-artifact:hover { color: var(--gold-bright); border-color: var(--gold-dim); }
.gm-artifact.is-active {
  color: var(--gold-bright);
  border-color: var(--gold);
  background: color-mix(in srgb, var(--gold) 10%, transparent);
}
/* "you are here" sits just above the engraving chip */
.gm-earth-chip { bottom: 58px; }

/* ======================================================================
   11. HOVER TOOLTIP — floating chip near the cursor, fed by bus 'hover'
   ====================================================================== */
.gm-tip {
  position: fixed;
  z-index: 60;
  pointer-events: none;
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  white-space: nowrap;
  color: var(--gold-bright);
  background: color-mix(in srgb, var(--void) 92%, transparent);
  border: 1px solid var(--gold-faint);
  padding: 0.42em 0.7em;
  opacity: 0;
  transition: opacity 0.15s var(--ease);
}
.gm-tip.is-on { opacity: 1; }

/* ======================================================================
   RESPONSIVE — below 900px EVERY panel is the same bottom sheet: one side
   inset, one width, one header tab, one bottom edge. No hand-tuned offsets
   live here: ui.js measures the real docked player and the real act nav into
   --dock-h / --nav-h, so sheets always sit exactly above the bar (safe area
   included) and the chips exactly below the nav, at any font size.
   ====================================================================== */
@media (max-width: 900px) {
  :root {
    --sheet-x: 10px;    /* side inset — shared by every sheet and the flyout */
    --sheet-gap: 8px;   /* air between a sheet and the docked player */
    --sheet-h: 46vh;    /* the 3D scene always owns the top half */
  }

  .gm-act-t { display: none; }
  .gm-act { padding: 0.5em 0.75em; min-height: 40px; }

  /* ---- Act I masthead: a shorter card leaves the disc room above it ---- */
  .gm-title { bottom: calc(var(--dock-h) + var(--sheet-gap)); }
  .gm-title h1 { font-size: clamp(1.9rem, 5.4vw, 3.2rem); }
  .gm-tagline { font-size: 0.95rem; margin-bottom: 0.7em; }
  .gm-hook { font-size: var(--step--1); }
  .gm-hello { margin-top: 0.55em; padding: 0.5em 0.85em; font-size: 0.58rem; }

  /* ---- one geometry for every sheet ----------------------------------- */
  .gm-left,
  .gm-rail,
  .gm-detail,
  .gm-verdict,
  .gm-finders {
    left: var(--sheet-x);
    right: var(--sheet-x);
    top: auto;
    bottom: calc(var(--dock-h) + var(--sheet-gap));
    width: auto;
    max-height: var(--sheet-h);
    padding-top: 0;          /* the header tab owns the top edge */
    border-radius: 14px;
    z-index: 30;
    --gm-in: translateY(18px); /* they all rise from the dock */
  }
  .gm-rail { overflow: hidden; }  /* the rounded corners clip the row list */
  /* phones scroll by touch: no reserved scrollbar gutter beside the header */
  .gm-left, .gm-verdict, .gm-finders, .gm-detail-body, .gm-rail-list,
  .gm-tracklist { scrollbar-width: none; }
  .gm-left::-webkit-scrollbar, .gm-verdict::-webkit-scrollbar,
  .gm-finders::-webkit-scrollbar, .gm-detail-body::-webkit-scrollbar,
  .gm-rail-list::-webkit-scrollbar, .gm-tracklist::-webkit-scrollbar { display: none; }
  .gm-detail { z-index: 34; }     /* a selection covers the act's own sheet */
  /* a selection owns the sheet slot — the rail steps aside under it */
  body.gm-has-detail .gm-rail { opacity: 0; visibility: hidden; pointer-events: none; }

  /* ---- the header tab: the one control every sheet shares -------------- */
  .gm-sheet-tab {
    display: flex;
    flex: none;
    align-items: center;
    justify-content: space-between;
    gap: 1em;
    position: sticky;   /* stays reachable however far the sheet is scrolled */
    top: 0;
    z-index: 2;
    min-height: 46px;
    /* a <button> sizes to its text, so claim the sheet's full width — content
       box plus the side padding the negative margins reach across */
    width: calc(100% + var(--tab-bleed) * 2);
    margin: 0 calc(-1 * var(--tab-bleed)) 1rem;
    padding: 0.5em var(--pad-x);
    font-size: 0.68rem;
    font-weight: 500;
    letter-spacing: 0.12em;
    text-align: left;
    color: var(--gold);
    background: color-mix(in srgb, var(--void-lift) 94%, transparent);
    border-bottom: 1px solid var(--gold-faint);
    border-radius: 13px 13px 0 0;
  }
  .gm-sheet-tab-ic { flex: none; font-size: 0.78rem; color: var(--gold-dim); }
  .gm-sheet-tab:hover { color: var(--gold-bright); }
  .gm-sheet-tab:hover .gm-sheet-tab-ic { color: var(--gold); }

  /* collapsed: the sheet IS its tab — a slim bar riding over the scene */
  .gm-sheet.sheet-collapsed { padding: 0; }
  .sheet-collapsed > :not(.gm-sheet-tab) { display: none; }
  .sheet-collapsed .gm-sheet-tab {
    width: 100%;   /* no padding left to reach across */
    margin: 0;
    border-bottom: none;
    border-radius: 13px;
  }

  /* pulse-rate chips fit one row */
  .gm-pulse-ctl .gm-mode { font-size: 0.52rem; padding: 0.5em 0.7em; letter-spacing: 0.1em; }

  /* ---- the docked player: full-width, the one square-edged surface ----- */
  .gm-mini { width: auto; bottom: 0; left: 0; right: 0; }
  .gm-mini-bar {
    border-radius: 0;
    border-left: none;
    border-right: none;
    border-bottom: none;
    /* clear the iPhone home indicator */
    padding-bottom: calc(9px + env(safe-area-inset-bottom, 0px));
  }
  .gm-mini-fly {
    left: var(--sheet-x); right: var(--sheet-x);
    bottom: calc(100% + var(--sheet-gap));
    /* never taller than the space between the nav and the bar (landscape) */
    max-height: calc(100vh - var(--dock-h) - var(--nav-h) - 24px);
    overflow-y: auto;
  }

  /* ---- the two scene chips: a top-right stack under the nav ------------ */
  .gm-corner { display: none; }
  .gm-artifact {
    right: var(--sheet-x);
    top: calc(var(--nav-h) + 10px);
    bottom: auto;
    z-index: 39; /* under the nav (40), over the canvas */
    font-size: 0.52rem;
    min-height: 40px;
    display: inline-flex;
    align-items: center;
  }
  .gm-earth-chip { top: calc(var(--nav-h) + 58px); }

  /* the detail sheet's header tab carries the ✕ here */
  .gm-close { display: none; }

  /* tap targets ≥40px */
  .gm-mode { min-height: 40px; }
  .gm-pulse-ctl { align-items: center; }
  .gm-row { min-height: 44px; }
  .gm-begin { min-height: 44px; }
}

/* ======================================================================
   LANDSCAPE PHONES — plenty of width, no height at all. A 46vh bottom sheet
   would leave the scene about 70px to live in, so the sheet becomes a left
   column (still with its header tab, still collapsing to a bar) and the map
   keeps the right of the frame. Same components, different axis.
   ====================================================================== */
@media (max-width: 900px) and (max-height: 520px) and (orientation: landscape) {
  .gm-left,
  .gm-rail,
  .gm-detail,
  .gm-verdict,
  .gm-finders {
    right: auto;
    width: min(var(--panel-w), 48vw);
    top: calc(var(--nav-h) + 6px);
    max-height: none;
    --gm-in: translateX(-14px);
  }
  .gm-sheet.sheet-collapsed { top: auto; } /* collapsed: just the bar, at the foot */

  /* the two chips share one row — stacked, the lower one reached the sheet */
  .gm-earth-chip {
    top: calc(var(--nav-h) + 10px);
    right: calc(var(--sheet-x) + 137px);
  }

  /* Act I masthead becomes a left column too, like the desktop composition */
  .gm-title {
    left: var(--sheet-x); right: auto;
    width: min(430px, 52vw);
    text-align: left;
    padding: 0;
    background: none;
  }
  .gm-title h1 { font-size: 2rem; }
  .gm-hook { margin: 0 0 0.8em; font-size: 0.8rem; }
  .gm-title .eyebrow { display: none; } /* two lines the card cannot spare here */
}

/* ======================================================================
   SHORT PORTRAIT PHONES (SE-class, ≤700px tall) — the scene scales with the
   viewport but the masthead's type does not, so on a short screen the card
   grew into the disc. Compress the card; the framing then clears it again.
   ====================================================================== */
@media (max-width: 900px) and (max-height: 700px) and (orientation: portrait) {
  .gm-title { padding-top: 1rem; }
  .gm-title .eyebrow { display: none; }
  .gm-title h1 { font-size: 1.7rem; margin: 0 0 0.1em; }
  .gm-tagline { font-size: 0.85rem; margin-bottom: 0.5em; }
  .gm-hook { font-size: 0.8rem; margin-bottom: 0.8em; }
  .gm-begin { padding: 0.7em 1.4em; }
  .gm-hello { margin-top: 0.45em; }
}

/* ======================================================================
   COMPACT NAV — small portrait phones: numerals only, current-act title
   beneath the progress hairline (so the hairline itself never moves)
   ====================================================================== */
@media (max-width: 560px) {
  .gm-nav { padding-top: 12px; }
  .gm-nav-row { gap: 6px; }
  .gm-act { min-width: 44px; min-height: 44px; justify-content: center; }
  .gm-nav-title { display: block; }

  /* Act I: smaller type so the disc has room */
  .gm-title h1 { font-size: clamp(2rem, 5.4vw, 3.2rem); }
  .gm-hook { font-size: 0.92rem; }
}

/* ======================================================================
   REDUCED MOTION — style.css already collapses durations; also stop loops
   ====================================================================== */
@media (prefers-reduced-motion: reduce) {
  .gm-dot { animation: none; background: var(--gold); }
  .gm-demo.typing .gm-demo-bits::after { animation: none; }
}
