/* =========================================================================
   RESPONSIVE / TOUCH SYSTEM (single source of truth)
   Body classes are set once in main.js (applyDeviceTier) and kept live on
   resize/orientationchange:
     .is-touch      coarse pointer / touch-capable (any width)
     .is-phone      viewport width <= 640px
     .is-tablet     641px .. 1024px
     .is-mobile     phone OR tablet
     .is-low-power  weak-GPU heuristic (sheds shader cost)
   Scope mobile rules to these body classes (not bare @media) so CSS matches
   the JS branches exactly and the desktop path stays untouched. Matching
   width breakpoints if a media query is ever needed: phone <=640, tablet <=1024.
   ========================================================================= */
:root {
  /* Notch / home-indicator insets (0 on non-notched devices). index.html opts
     in via viewport-fit=cover; docked mobile UI pads against these. */
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
}
html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
  overflow: hidden;
  background: #000;
  color: #ccc;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Arial, sans-serif;
  /* Drag-to-rotate the globe was occasionally grabbing page text. Disable
     text selection at the document level so the canvas drag never picks
     up anything underneath. Text inside actual reading panels re-enables selection locally. */
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
canvas {
  display: block;
  /* Belt-and-braces: the canvas itself is non-selectable too. */
  -webkit-user-select: none;
  user-select: none;
  touch-action: none; /* prevent the browser from grabbing pointer for scroll on touch devices */
}
/* Re-enable text selection where reading content lives, so users can
   still copy dossier text when needed. */
#stories-panel,
#info { -webkit-user-select: text; user-select: text; }
#loading {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  transition: opacity 0.8s ease;
  letter-spacing: 0.18em;
  font-size: 11px;
  text-transform: uppercase;
  color: #555;
}
#loading.hidden { opacity: 0; }
#error {
  position: fixed;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  text-align: center;
  font-size: 13px;
  color: #888;
}

/* =====================================================================
   CONTEXT MENU — right-click on a body to summon a small floating menu.
   Currently a single "Info" item, designed to be extended with more
   actions over time.
   ===================================================================== */
#menu {
  position: fixed;
  display: none;
  min-width: 150px;
  padding: 5px 0;
  background: rgba(12, 14, 20, 0.86);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 6px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.55);
  color: #c8c8c8;
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  user-select: none;
  z-index: 100;
  opacity: 0;
  transform: translateY(-4px) scale(0.98);
  transform-origin: top left;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
#menu.visible {
  display: block;
  opacity: 1;
  transform: translateY(0) scale(1);
}
#menu .item {
  padding: 9px 18px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
#menu .item:hover {
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
}
#menu .target {
  padding: 12px 18px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  margin-bottom: 6px;
}
#menu .target .target-name {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 14px;
  letter-spacing: 0.01em;
  text-transform: none;
  color: #f1f4fa;
  line-height: 1.18;
}
#menu .target .target-tier {
  margin-top: 5px;
  font-size: 9px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(170,180,200,0.62);
}

/* Category items with dot + name + blurb. Earth-Mode right-click only —
 * solar planet menu (Info) keeps the basic .item style above. */
#menu .cat-item {
  display: grid;
  grid-template-columns: 8px 80px 1fr;
  align-items: center;
  gap: 12px;
  padding: 9px 18px;
  letter-spacing: 0;
  text-transform: none;
}
#menu .cat-item:hover { background: rgba(255,255,255,0.06); }
#menu .cat-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: rgba(255,255,255,0.30);
  box-shadow: 0 0 4px rgba(255,255,255,0.14);
}
/* Per-category color tints removed (Franck preference). The base
 * .cat-dot rule above paints every dot in a uniform neutral white. The
 * .cat-dot--power / --money / etc. classes are still rendered on the
 * elements so colors can be reinstated later by re-adding rules here. */
#menu .cat-name {
  font-size: 11.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #e7ebf3;
}
#menu .cat-blurb {
  font-size: 10.5px;
  color: rgba(190,200,218,0.66);
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.35;
}
#menu .cat-item:hover .cat-blurb { color: rgba(220,228,242,0.88); }

/* =====================================================================
   INFO PANEL — selected from the context menu. Lives in the lower-left,
   no chrome, no borders, just letter-spaced text floating over space.
   Earth gets a longer entry; other planets show only key stats.
   Includes a small close × at top-right.
   ===================================================================== */
#info {
  position: fixed;
  left: 36px;
  bottom: 36px;
  width: 260px;
  color: #888;
  pointer-events: none;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.55s ease, transform 0.55s ease;
  user-select: none;
}
#info.visible {
  opacity: 1;
  transform: translateY(0);
}
#info .header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 0 4px;
}
#info .name {
  font-size: 13px;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: #e6e6e6;
  margin: 0;
  font-weight: 400;
}
#info .close {
  pointer-events: auto;
  cursor: pointer;
  background: transparent;
  border: none;
  padding: 8px;
  margin: -8px;
  color: #555;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.2s ease, transform 0.25s ease;
  font-family: inherit;
  line-height: 0;
}
#info .close:hover {
  color: #e6e6e6;
  transform: rotate(90deg);
}
#info .close svg { display: block; }
#info .sub {
  font-size: 9.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #5a5a5a;
  margin: 0 0 20px;
}
#info .rows {
  display: flex;
  flex-direction: column;
  gap: 0;
}
#info .row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 6px 0;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #b0b0b0;
  border-top: 1px solid rgba(255, 255, 255, 0.04);
}
#info .row:last-child {
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}
#info .row .lbl { color: #555; }
#info .quote {
  margin-top: 22px;
  font-size: 11.5px;
  line-height: 1.55;
  color: #9a9a9a;
  letter-spacing: 0.02em;
  font-style: italic;
}
@media (max-width: 480px) {
  #info { left: 20px; bottom: 20px; width: 220px; }
}

/* =====================================================================
   DATE/TIME — top-left timestamp. Quietly anchors the user in real
   time so the live orbital phase has meaning.
   ===================================================================== */
#datetime {
  position: fixed;
  top: 28px;
  left: 32px;
  font-size: 10px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: #5a5a5a;
  user-select: none;
  pointer-events: none;
  font-variant-numeric: tabular-nums;
}

/* =====================================================================
   PLANET LABELS — toggleable name tags floating above each planet.
   Off by default; press L (or use the help overlay to learn how).
   ===================================================================== */
#labels {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  opacity: 0;
  transition: opacity 0.4s ease;
}
#labels.visible { opacity: 1; }
.label {
  position: absolute;
  top: 0;
  left: 0;
  font-size: 9px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(220, 220, 220, 0.6);
  white-space: nowrap;
  /* Default anchor: top-centre. JS positions at the planet's lower edge,
     so the label hangs below it. */
  transform: translate(-50%, 0);
  text-shadow: 0 0 6px rgba(0, 0, 0, 0.85);
  transition: opacity 0.3s ease, color 0.3s ease, font-size 0.3s ease,
              letter-spacing 0.3s ease;
}
/* When the planet is the current focus, the label sits centred on it
   (overlay-style) and reads as a slightly stronger, brighter caption. */
.label.selected {
  transform: translate(-50%, -50%);
  color: rgba(255, 255, 255, 0.92);
  font-size: 11px;
  letter-spacing: 0.36em;
}
/* Arrival flash — a standalone div, fully outside #labels, so it never
   shares opacity context with the label container and causes no flash. */
#arrival-label {
  position: fixed;
  pointer-events: none;
  font-size: 11px;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.92);
  white-space: nowrap;
  transform: translate(-50%, -50%);
  text-shadow: 0 0 6px rgba(0, 0, 0, 0.85);
  opacity: 0;
  transition: opacity 0.35s ease;
  z-index: 10;
}
#arrival-label.visible { opacity: 1; }
#arrival-label.fade-out { opacity: 0; }

/* =====================================================================
   EARTH MODE OVERLAY — country/state names appear under the cursor as
   the user drags over different regions. Faint floating typography,
   no boxes or panels. The card with news content appears anchored to
   the highlighted region's centroid.
   ===================================================================== */
#region-svg {
  position: fixed;
  inset: 0;
  pointer-events: none;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 0.5s ease;
}
#region-svg.visible { opacity: 1; }
#region-svg path {
  fill: rgba(255, 255, 255, 0.04);
  stroke: rgba(255, 255, 255, 0.55);
  stroke-width: 0.9;
  filter: drop-shadow(0 0 6px rgba(140, 200, 255, 0.45));
  transition: fill 0.25s ease;
}
/* In country mode, states/provinces are a hover preview, not the active
   navigation context. The parent country remains visible so right-click
   and the category rail stay true to the selected country until a state
   is explicitly left-clicked. */
#region-svg path.country-context {
  fill: rgba(255, 255, 255, 0.025);
  stroke: rgba(255, 255, 255, 0.50);
  stroke-width: 0.85;
}
#region-svg path.state-preview {
  fill: rgba(190, 225, 255, 0.085);
  stroke: rgba(220, 240, 255, 0.86);
  stroke-width: 1.05;
  filter: drop-shadow(0 0 8px rgba(160, 210, 255, 0.50));
}

/* === ERA SCRUBBER ====================================================
   Bottom-of-screen year slider, revealed only at Earth level when the
   user activates the timeline trigger without a dossier open. Drives
   #era-svg (per-country empire tinting) and #era-panel (the empires-
   of-the-moment list + events around the cursor year).
   ================================================================== */
#era-svg {
  position: fixed;
  inset: 0;
  pointer-events: none;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 0.45s ease;
  z-index: 4;
}
#era-svg.visible { opacity: 0.85; }
#era-svg path {
  fill-opacity: 0.42;
  stroke: rgba(255, 255, 255, 0.18);
  stroke-width: 0.5;
  transition: fill-opacity 0.2s ease, stroke 0.2s ease, stroke-width 0.2s ease;
}
/* Partially-held country: same empire colour but fainter, with a dashed
   outline, so the overlay reads as "part of this country was held" rather
   than claiming the whole modern feature. Placed before the .hovering rules
   so empire-hover highlighting still overrides it. */
#era-svg path.era-path-partial {
  fill-opacity: 0.16;
  stroke: rgba(255, 255, 255, 0.30);
  stroke-width: 0.5;
  stroke-dasharray: 2.5 2.5;
}
/* While the user is hovering an empire in the era panel, dim every
   other country and outline the hovered empire's territory brightly so
   it reads as a single shape on the globe. */
#era-svg.hovering path { fill-opacity: 0.14; }
#era-svg.hovering path.era-path-active {
  fill-opacity: 0.78;
  stroke: rgba(255, 255, 255, 0.95);
  stroke-width: 1.4;
  filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.55));
}

#era-scrubber {
  position: fixed;
  left: 50%;
  bottom: 32px;
  transform: translateX(-50%);
  width: min(960px, 82vw);
  padding: 28px 60px 22px 28px;
  background: linear-gradient(
    180deg,
    rgba(10, 14, 24, 0.82) 0%,
    rgba(6, 10, 18, 0.88) 100%
  );
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 18px;
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
  color: #e6e6e6;
  font-family: inherit;
  z-index: 20;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease, transform 0.5s ease;
}
#era-scrubber.visible {
  opacity: 1;
  pointer-events: auto;
}
#era-scrubber[hidden] { display: none; }

/* Circled close, matching the timeline context card's .tc-close so every
   "exit" control across the app's timelines reads as one family. */
#era-scrubber .es-close {
  position: absolute;
  top: 12px;
  right: 14px;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.55);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  border-radius: 50%;
  font-family: inherit;
  padding: 0;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
#era-scrubber .es-close:hover {
  color: rgba(255, 255, 255, 0.95);
  border-color: rgba(255, 255, 255, 0.32);
  background: rgba(255, 255, 255, 0.05);
}

#era-scrubber .es-bar {
  position: relative;
  height: 70px;
  cursor: pointer;
  touch-action: none;
}

/* Era names floating above the track, centered in each segment. The
   era under the cursor lights up; the others read as subtle context. */
#era-scrubber .es-eras {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 22px;
  pointer-events: none;
}
#era-scrubber .es-era-label {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  font-size: 9.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.32);
  white-space: nowrap;
  transition: color 0.25s ease, text-shadow 0.25s ease;
}
#era-scrubber .es-era-label.active {
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 0 10px rgba(255, 255, 255, 0.35);
}

/* Era period bands — a soft cool→warm ribbon sitting on the track so the
   millennia read as historical periods (deep-past blues → present ambers).
   The era under the cursor brightens; the rest stay quiet context. */
#era-scrubber .es-bands {
  position: absolute;
  top: 32px;                /* centred on the desktop track (top:34px, 2px high) */
  left: 0;
  right: 0;
  height: 6px;
  border-radius: 3px;
  overflow: hidden;
  pointer-events: none;
}
#era-scrubber .es-band {
  position: absolute;
  top: 0;
  bottom: 0;
  opacity: 0.30;
  transition: opacity 0.3s ease;
}
#era-scrubber .es-band.active { opacity: 0.95; }
#era-scrubber .es-band.era-band-0 { background: rgba(110, 128, 205, 0.60); } /* Ancient */
#era-scrubber .es-band.era-band-1 { background: rgba(92, 156, 202, 0.60); }  /* Classical */
#era-scrubber .es-band.era-band-2 { background: rgba(82, 178, 170, 0.60); }  /* Late Antiquity */
#era-scrubber .es-band.era-band-3 { background: rgba(150, 178, 118, 0.60); } /* Medieval */
#era-scrubber .es-band.era-band-4 { background: rgba(214, 176, 102, 0.60); } /* Early Modern */
#era-scrubber .es-band.era-band-5 { background: rgba(218, 136, 94, 0.60); }  /* Modern */

/* The track itself: thin, with a very soft gradient suggesting deep
   past on the left fading toward the present on the right. */
#era-scrubber .es-track {
  position: absolute;
  top: 34px;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0.08) 0%,
    rgba(255, 255, 255, 0.20) 50%,
    rgba(255, 255, 255, 0.36) 100%
  );
  border-radius: 1px;
  pointer-events: none;
}

/* Year ticks + labels below the track. */
#era-scrubber .es-marks {
  position: absolute;
  top: 38px;
  left: 0;
  right: 0;
  height: 32px;
  pointer-events: none;
}
#era-scrubber .es-mark {
  position: absolute;
  top: 0;
  width: 1px;
  height: 6px;
  background: rgba(255, 255, 255, 0.28);
  transform: translateX(-0.5px);
}
#era-scrubber .es-mark-label {
  position: absolute;
  top: 11px;
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  color: rgba(255, 255, 255, 0.45);
  transform: translateX(-50%);
  white-space: nowrap;
  letter-spacing: 0.02em;
}

/* Cursor: thin vertical line spanning the full bar with a year bubble
   floating above. The line and bubble share a soft glow that reads
   even against busy globe imagery. */
#era-scrubber .es-cursor {
  position: absolute;
  top: 20px;
  bottom: 0;
  width: 1.5px;
  margin-left: -0.75px;
  /* Refined position line: a soft, thin marker for orientation across the
     millennia rather than a blazing white bar. Harmonised with the muted
     chip below. */
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.62) 0%,
    rgba(255, 255, 255, 0.34) 60%,
    rgba(255, 255, 255, 0.10) 100%
  );
  box-shadow: 0 0 7px rgba(255, 255, 255, 0.22);
  cursor: ew-resize;
  transition: left 0.08s linear;
  pointer-events: none;
}
/* Year chip: matches the country timeline cursor's discreet dark-glass
   chip (rgba(12,16,26,0.85), muted text, thin border) instead of the old
   loud white box, so both timelines read as one design family. */
#era-scrubber .es-cursor-bubble {
  position: absolute;
  top: -21px;
  left: 50%;
  transform: translateX(-50%);
  padding: 3px 8px;
  background: rgba(12, 16, 26, 0.85);
  color: rgba(255, 255, 255, 0.72);
  font-size: 10px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 5px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.40);
  white-space: nowrap;
  pointer-events: none;
}
#era-scrubber .es-cursor-bubble::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-top-color: rgba(12, 16, 26, 0.85);
}

#era-panel {
  position: fixed;
  top: 84px;
  right: 28px;
  width: 360px;
  max-height: calc(100vh - 220px);
  padding: 22px 22px 18px;
  background: linear-gradient(
    180deg,
    rgba(10, 14, 24, 0.82) 0%,
    rgba(6, 10, 18, 0.88) 100%
  );
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 16px;
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
  color: #e6e6e6;
  font-family: inherit;
  z-index: 20;
  overflow-y: auto;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
#era-panel.visible {
  opacity: 1;
  pointer-events: auto;
}
#era-panel[hidden] { display: none; }
#era-panel::-webkit-scrollbar { width: 6px; }
#era-panel::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.14);
  border-radius: 3px;
}

/* Panel header: small kicker label, then the year set large as the
   visual anchor, with the era name as a quiet subtitle. */
#era-panel .era-panel-head {
  display: flex;
  flex-direction: column;
  margin-bottom: 22px;
  padding-bottom: 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
#era-panel .era-head-kicker {
  font-size: 9.5px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.42);
  margin-bottom: 4px;
}
#era-panel .era-head-year {
  font-size: 32px;
  font-weight: 300;
  letter-spacing: -0.01em;
  color: #fafafa;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
#era-panel .era-head-era {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  margin-top: 6px;
}

#era-panel .era-panel-section {
  margin-bottom: 22px;
}
#era-panel .era-panel-section:last-child { margin-bottom: 0; }
#era-panel .era-panel-section-head {
  font-size: 9.5px;
  letter-spacing: 0.22em;
  color: rgba(255, 255, 255, 0.40);
  text-transform: uppercase;
  margin-bottom: 10px;
}
#era-panel .era-panel-section-head .era-count {
  color: rgba(255, 255, 255, 0.30);
  margin-left: 4px;
  font-weight: 400;
}

/* Empire row: swatch + name + lifespan on the top line, then a thin
   timeline bar showing the empire's full span and the current year's
   position within it. Reads as: "we're early/mid/late in this empire." */
#era-panel .era-emp-item {
  display: grid;
  grid-template-columns: 10px 1fr auto;
  grid-template-rows: auto auto;
  grid-template-areas:
    "swatch name life"
    ". bar bar";
  column-gap: 10px;
  row-gap: 6px;
  padding: 9px 10px;
  border-radius: 8px;
  cursor: pointer;
  margin-bottom: 1px;
  transition: background 0.15s ease;
  line-height: 1.25;
}
#era-panel .era-emp-item:hover {
  background: rgba(255, 255, 255, 0.05);
}
#era-panel .era-emp-swatch {
  grid-area: swatch;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  align-self: center;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.35);
}
#era-panel .era-emp-name {
  grid-area: name;
  font-size: 13px;
  color: #ededed;
  align-self: center;
}
#era-panel .era-emp-life {
  grid-area: life;
  font-size: 10.5px;
  color: rgba(255, 255, 255, 0.42);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  white-space: nowrap;
  align-self: center;
}
#era-panel .era-emp-bar {
  grid-area: bar;
  position: relative;
  height: 3px;
  background: rgba(255, 255, 255, 0.07);
  border-radius: 2px;
}
#era-panel .era-emp-bar-fill {
  position: absolute;
  top: 0;
  bottom: 0;
  border-radius: 2px;
  opacity: 0.78;
}
#era-panel .era-emp-bar-now {
  position: absolute;
  top: 50%;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #fff;
  transform: translate(-50%, -50%);
  box-shadow: 0 0 6px rgba(255, 255, 255, 0.7);
}

/* Event row: empire color dot, year, then the empire name + event
   title stacked. Color dot gives at-a-glance cross-reference to the
   empire list above. */
#era-panel .era-event {
  display: grid;
  grid-template-columns: 8px 50px 1fr;
  align-items: center;
  column-gap: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
  margin-bottom: 1px;
  transition: background 0.15s ease;
}
#era-panel .era-event:hover {
  background: rgba(255, 255, 255, 0.05);
}
#era-panel .era-event-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.35);
}
#era-panel .era-event-year {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.48);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
#era-panel .era-event-body {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
#era-panel .era-event-emp {
  font-size: 9.5px;
  color: rgba(255, 255, 255, 0.50);
  text-transform: uppercase;
  letter-spacing: 0.12em;
}
#era-panel .era-event-title {
  font-size: 12.5px;
  color: #e6e6e6;
  line-height: 1.3;
}
#era-panel .era-empty {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.36);
  font-style: italic;
  padding: 6px 10px;
}
#region-name {
  position: fixed;
  pointer-events: none;
  transform: translate(-50%, -50%);
  color: rgba(255, 255, 255, 0.92);
  font-size: 11px;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  text-shadow: 0 0 8px rgba(0, 0, 0, 0.9);
  opacity: 0;
  transition: opacity 0.35s ease;
  white-space: nowrap;
  z-index: 8;
}
#region-name.visible { opacity: 1; }

/* The old #news-card (small floating panel anchored near the cursor)
   has been removed. Right-click → category now opens the atlas dossier
   scoped to that region. There is a single panel system. */

/* =====================================================================
   CATEGORY RAIL — vertical glass bar pinned to the left edge in Earth
   Mode. Six poetic axes for understanding the world. Click a label to
   open the worldwide dossier panel for that category. The rail itself
   stays out of the way: thin, dim, only crisp on hover/active.
   ===================================================================== */
#category-rail {
  position: fixed;
  left: 34px;
  top: 50%;
  transform: translate(-10px, -50%);
  display: flex;
  flex-direction: column;
  gap: 16px;
  /* No panel chrome — a quiet column of dots floating over the globe.
     Matches the dossier's category dot-switcher (.sp-cs-dot) so the
     navigation language is consistent across the app. */
  padding: 6px 0;
  background: none;
  border: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(.18,.7,.22,1);
  z-index: 10;
  user-select: none;
}
#category-rail.visible {
  opacity: 1;
  /* The container stays click-through; only the .cr-item hit-areas below
     capture events. Otherwise the wide (150px) item boxes would stretch the
     container's bounding box across the globe and the gaps between items
     would swallow clicks meant for the globe. */
  pointer-events: none;
  transform: translate(0, -50%);
}
#category-rail.visible .cr-item { pointer-events: auto; }
/* Each category is a dot; its name appears as a pill on hover (and stays
   visible while active). Mirror of the dossier's .sp-cs-dot, with the
   tip sliding out to the RIGHT since this rail hugs the left edge. */
#category-rail .cr-item {
  position: relative;
  /* The VISIBLE dot stays tiny and discreet, but the clickable/hoverable
     hit-area is much larger so the dot is easy to reach without pixel-
     hunting. The area spans the dot AND the space where its name pill
     appears, so hovering anywhere along the row reveals the label and the
     whole strip is clickable. The dot is rendered by ::before, centered
     vertically and pinned to the left of this wide box. */
  width: 150px;
  height: 16px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  cursor: pointer;
}
#category-rail .cr-item::before {
  content: '';
  /* Pin the small dot to the left of the now-wide hit-area, at the same x
     it occupied when the item was 14px wide (≈ 4.5px from the left edge so
     the 5px dot's center sits ~7px in). */
  margin-left: 4px;
  flex: 0 0 auto;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.32);
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.6);
  transition: background 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
#category-rail .cr-item:hover::before,
#category-rail .cr-item:focus-visible::before {
  background: rgba(255, 255, 255, 0.78);
  transform: scale(1.5);
  box-shadow: 0 0 6px rgba(255, 255, 255, 0.36);
}
#category-rail .cr-item.active::before {
  background: #ffffff;
  transform: scale(1.6);
  box-shadow: 0 0 9px rgba(255, 255, 255, 0.55);
}
#category-rail .cr-item:focus-visible { outline: none; }
/* Name pill — slides out to the right of the dot. */
#category-rail .cr-tip {
  position: absolute;
  left: 18px;
  top: 50%;
  transform: translateY(-50%) translateX(-4px);
  white-space: nowrap;
  padding: 3px 8px;
  font-size: 8.5px;
  letter-spacing: 0.30em;
  text-transform: uppercase;
  color: #f1f4fa;
  background: rgba(15, 18, 26, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 4px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
#category-rail .cr-item:hover .cr-tip,
#category-rail .cr-item:focus-visible .cr-tip,
#category-rail .cr-item.active .cr-tip {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}
/* Stagger the entrance so items glide in one after another. */
#category-rail.visible .cr-item {
  opacity: 0;
  animation: crFade 0.55s cubic-bezier(.18,.7,.22,1) forwards;
}
#category-rail.visible .cr-item:nth-child(1) { animation-delay: 0.05s; }
#category-rail.visible .cr-item:nth-child(2) { animation-delay: 0.12s; }
#category-rail.visible .cr-item:nth-child(3) { animation-delay: 0.19s; }
#category-rail.visible .cr-item:nth-child(4) { animation-delay: 0.26s; }
#category-rail.visible .cr-item:nth-child(5) { animation-delay: 0.33s; }
#category-rail.visible .cr-item:nth-child(6) { animation-delay: 0.40s; }
@keyframes crFade {
  from { opacity: 0; transform: translateX(-10px); }
  to   { opacity: 1; transform: translateX(0); }
}
/* --- Touch: hover can't reveal the rail labels, so on touch devices show
   every category name always and grow the dot + row to a reliable tap target.
   Scoped to body.is-touch so the desktop rail keeps its tight, discreet
   spacing (per the "dots too spaced" feedback). --- */
body.is-touch #category-rail { gap: 10px; }
body.is-touch #category-rail .cr-item { height: 44px; }
body.is-touch #category-rail .cr-item::before {
  width: 7px; height: 7px;
  background: rgba(255, 255, 255, 0.5);
}
body.is-touch #category-rail .cr-tip {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}
/* Phone: leaner than the desktop/tablet rail — hug the edge, smaller labels,
   and tighter vertical spacing so the column reads as a discreet sidebar
   instead of sitting big and central over the globe. Auto-fades when idle (JS
   toggles .cr-idle) and returns on touch. */
body.is-phone #category-rail {
  left: calc(14px + var(--safe-left));
  gap: 3px;
  transition: opacity 0.8s ease;
}
body.is-phone #category-rail.cr-idle { opacity: 0; pointer-events: none; }
/* Tighten the hit area to the (now smaller) labels — the inherited 150px width
   left a wide invisible strip over the globe that stole taps. The longest label
   (PROGRESS) ends ~75px in; 88px covers it with a small tap margin. */
body.is-phone #category-rail .cr-item { width: 88px; height: 34px; }
body.is-phone #category-rail .cr-tip {
  font-size: 7px;
  letter-spacing: 0.2em;
  padding: 2px 6px;
  left: 15px;
  background: rgba(15, 18, 26, 0.6);
  border-color: rgba(255, 255, 255, 0.05);
}
body.is-phone #category-rail .cr-item::before {
  width: 5px; height: 5px;
  background: rgba(255, 255, 255, 0.42);
}

/* =====================================================================
   ATLAS DOSSIER — modal-feel sheet that opens when a category is
   selected in Earth Mode. A full-screen backdrop blurs the globe; the
   panel itself is a translucent dark sheet for regional profile content.
   ===================================================================== */
#stories-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(4, 6, 10, 0.45);
  backdrop-filter: blur(10px) saturate(120%);
  -webkit-backdrop-filter: blur(10px) saturate(120%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease, backdrop-filter 0.5s ease,
              -webkit-backdrop-filter 0.5s ease, background 0.5s ease;
  z-index: 12;
}
#stories-backdrop.visible { opacity: 1; pointer-events: auto; }

#stories-panel {
  position: fixed;
  top: 50%;
  right: 48px;
  transform: translateY(-50%) translateX(20px);
  width: min(520px, 42vw);
  max-height: 78vh;
  display: flex;
  flex-direction: column;
  color: #c8c8c8;
  background: rgba(8, 10, 16, 0.82);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 4px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.65);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease, transform 0.4s ease;
  z-index: 13;
}
#stories-panel.visible {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
  pointer-events: auto;
}
#stories-panel .sp-head {
  padding: 18px 22px 14px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
#stories-panel .sp-cat {
  font-size: 9px;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: #6a6a6a;
}
#stories-panel .sp-title {
  font-size: 14px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: #f0f0f0;
  margin-top: 2px;
}
#stories-panel .sp-close {
  font-size: 16px;
  line-height: 1;
  color: #555;
  cursor: pointer;
  transition: color 0.15s ease;
  /* Native button reset so we can use a real <button> element for
     keyboard / assistive-tech accessibility without losing the
     minimal visual treatment. */
  background: transparent;
  border: 0;
  padding: 4px 6px;
  margin: -4px -6px;
  font: inherit;
  letter-spacing: inherit;
}
#stories-panel .sp-close:hover,
#stories-panel .sp-close:focus-visible { color: #fff; outline: none; }
#stories-panel .sp-close:focus-visible { box-shadow: 0 0 0 1px rgba(255,255,255,0.18); border-radius: 3px; }
/* Editorial description block above the news list. Sits between the
   panel head and the dossier body. Contains: a one-line lede, an optional
   intro paragraph, an optional small key-facts grid, and (at country
   scope) an optional leader portrait + flag. Empty fields collapse so
   the block is invisible when the data isn't filled in yet. */
#stories-panel .sp-context {
  padding: 14px 22px 10px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
#stories-panel .sp-context.empty { display: none; }
#stories-panel .sp-ctx-head {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}
#stories-panel .sp-ctx-portrait {
  width: 56px;
  height: 72px;
  border-radius: 3px;
  object-fit: cover;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  flex: 0 0 auto;
}
#stories-panel .sp-ctx-flag {
  width: 28px;
  height: 18px;
  border-radius: 2px;
  object-fit: cover;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  flex: 0 0 auto;
}
#stories-panel .sp-ctx-text { flex: 1; min-width: 0; }
#stories-panel .sp-ctx-lede {
  font-size: 12px;
  line-height: 1.5;
  color: #d8d8d8;
  letter-spacing: 0.02em;
}
#stories-panel .sp-ctx-intro {
  font-size: 11px;
  line-height: 1.55;
  color: #a8a8a8;
  letter-spacing: 0.02em;
}
#stories-panel .sp-ctx-leader {
  font-size: 9px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: #6a6a6a;
  margin-top: 6px;
}
#stories-panel .sp-ctx-leader .sp-ctx-leader-name { color: #d8d8d8; }
#stories-panel .sp-ctx-facts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 16px;
  margin-top: 4px;
}
#stories-panel .sp-ctx-fact {
  display: flex;
  flex-direction: column;
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #555;
}
#stories-panel .sp-ctx-fact .v {
  margin-top: 2px;
  color: #c4c4c4;
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: none;
}
#stories-panel .sp-ctx-empty-note {
  font-size: 9px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: #444;
}



/* =====================================================================
   ATLAS DOSSIER — deep in-app page opened from a category. The globe
   remains present behind a blurred/dimmed scrim; the dossier is a calm
   side reading surface, not a newsfeed.
   ===================================================================== */
#stories-backdrop.visible {
  background: rgba(2, 4, 9, 0.58);
  backdrop-filter: blur(12px) saturate(105%);
  -webkit-backdrop-filter: blur(12px) saturate(105%);
}
#stories-panel.atlas {
  top: 50%;
  right: 40px;
  width: min(760px, 56vw);
  max-height: 86vh;
  overflow: hidden;
  background: linear-gradient(180deg, rgba(10, 13, 21, 0.90), rgba(5, 7, 12, 0.88));
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 10px;
  box-shadow: 0 34px 100px rgba(0,0,0,0.72), inset 0 1px 0 rgba(255,255,255,0.05);
}
#stories-panel.atlas .sp-head {
  padding: 22px 28px 18px;
  align-items: center;
  border-bottom: 1px solid rgba(255,255,255,0.06);
  /* SOLID opaque fill (panel's top tone) under the subtle sheen, so scrolling
     body text never shows through the pinned header. Stacked above the scroll
     area so it always covers content passing beneath it. */
  background:
    linear-gradient(180deg, rgba(255,255,255,0.035), rgba(255,255,255,0)),
    #0a0d15;
  position: relative;
  z-index: 5;
  flex: 0 0 auto;
}
#stories-panel.atlas .sp-cat {
  color: #7b8799;
  letter-spacing: 0.30em;
}
#stories-panel.atlas .sp-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 30px;
  line-height: 1.12;
  letter-spacing: 0.02em;
  text-transform: none;
  margin-top: 6px;
}
#stories-panel.atlas .sp-close {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255,255,255,0.035);
  border: 1px solid rgba(255,255,255,0.07);
}
#stories-panel.atlas .sp-dossier {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* No top padding: the sticky breadcrumb sits flush against the header and
     provides the top spacing itself, so there is no uncovered strip between
     the header and the breadcrumb for content to show through. */
  padding: 0 28px 30px;
  /* No position:relative here — the back-arrow FAB anchors to
   * #stories-panel (position:fixed) so it stays visible during scroll. */
}
#stories-panel.atlas .sp-dossier::-webkit-scrollbar { width: 7px; }
#stories-panel.atlas .sp-dossier::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,0.10);
  border-radius: 999px;
}
#stories-panel.atlas .sp-context {
  padding: 0;
  border-bottom: none;
  gap: 18px;
}
#stories-panel.atlas .sp-ctx-head {
  gap: 16px;
  padding: 2px 0 4px;
}
#stories-panel.atlas .sp-ctx-lede {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 19px;
  line-height: 1.45;
  color: #f0f2f6;
}
#stories-panel.atlas .sp-ctx-intro {
  font-size: 13px;
  line-height: 1.7;
  color: #b5bdc9;
}
#stories-panel.atlas .sp-ctx-facts {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
#stories-panel.atlas .sp-ctx-fact {
  padding: 12px 14px;
  border: 1px solid rgba(255,255,255,0.07);
  border-radius: 7px;
  background: rgba(255,255,255,0.035);
  min-height: 44px;
}
#stories-panel.atlas .sp-ctx-fact .v {
  color: #e0e5ee;
  font-size: 12px;
  line-height: 1.35;
}
.sp-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  font-size: 10.5px;
  letter-spacing: 0.02em;
  text-transform: none;
  color: #647086;
}
.sp-breadcrumb span { color: #9aa7bb; }
.sp-map-plate {
  position: relative;
  height: 245px;
  overflow: hidden;
  border-radius: 9px;
  margin-bottom: 22px;
  border: 1px solid rgba(255,255,255,0.08);
  background:
    radial-gradient(circle at 70% 20%, rgba(118,165,230,0.17), rgba(118,165,230,0) 42%),
    linear-gradient(135deg, rgba(15,20,32,0.98), rgba(5,7,12,0.98));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.06), 0 18px 44px rgba(0,0,0,0.38);
}
.sp-map-plate svg {
  width: 100%;
  height: 100%;
  display: block;
}
.sp-map-plate .map-grid {
  stroke: rgba(255,255,255,0.065);
  stroke-width: 0.7;
  fill: none;
}
.sp-map-plate .map-context {
  fill: rgba(255,255,255,0.020);
  stroke: rgba(255,255,255,0.12);
  stroke-width: 0.75;
}
.sp-map-plate .map-focus {
  fill: rgba(210,232,255,0.075);
  stroke: rgba(238,247,255,0.86);
  stroke-width: 1.35;
  filter: drop-shadow(0 0 7px rgba(135,190,255,0.45));
}
.sp-map-caption {
  position: absolute;
  left: 18px;
  bottom: 15px;
  font-size: 9px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(225,235,248,0.72);
  text-shadow: 0 0 12px rgba(0,0,0,0.85);
}
.sp-section-title {
  margin: 20px 0 10px;
  font-size: 9px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: #6f7c90;
}
.sp-dossier-note {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid rgba(255,255,255,0.06);
  font-size: 10px;
  line-height: 1.6;
  color: #737f91;
  letter-spacing: 0.04em;
}
@media (max-width: 900px) {
  #stories-panel.atlas {
    right: 18px;
    left: 18px;
    width: auto;
    max-height: 84vh;
  }
  #stories-panel.atlas .sp-title { font-size: 24px; }
  #stories-panel.atlas .sp-ctx-facts { grid-template-columns: 1fr; }
}

/* Mode hint — discreet caption that shows up when entering Earth Mode */
#mode-banner {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 10px;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  text-align: center;
  text-wrap: balance;
  color: rgba(255, 255, 255, 0.85);
  text-shadow: 0 0 8px rgba(0, 0, 0, 0.9);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.6s ease;
  z-index: 11;
}
#mode-banner.visible { opacity: 1; }

/* Two-tier banner: a prominent state title + a subordinate instruction line.
   Used when the copy is "State — instruction" (e.g. "Earth locked — Double-tap
   …"). Keeps the app's uppercase-tracked voice but gives the hint its own,
   quieter weight so the pair reads as a title card rather than one long run. */
#mode-banner.has-sub {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  letter-spacing: 0;            /* the spans set their own tracking */
}
#mode-banner .mb-title { font-size: 11px; letter-spacing: 0.34em; }
#mode-banner .mb-sub {
  font-size: 10px;
  letter-spacing: 0.16em;
  font-weight: 300;
  opacity: 0.62;
}

/* Phone: the banner is re-laid-out, not ported. Desktop centres it on screen
   (top:50%), which on a phone drops a long caps string straight across the
   globe's lit face in ragged lines. Move it to a calm lower-centre toast zone
   below the globe, tighten the tracking, cap the width and balance the wrap so
   multi-line copy forms neat centred lines clear of the hero. */
body.is-phone #mode-banner {
  top: auto;
  bottom: calc(132px + var(--safe-bottom));
  transform: translateX(-50%);
  max-width: 78vw;
  letter-spacing: 0.22em;
}
body.is-phone #mode-banner .mb-title { font-size: 12px; letter-spacing: 0.26em; }
body.is-phone #mode-banner .mb-sub   { font-size: 10.5px; letter-spacing: 0.13em; }

/* Exit Earth Mode pill — small, top-right */
#exit-earth {
  position: fixed;
  top: 28px;
  right: 24px;
  padding: 7px 14px;
  font-family: inherit;
  font-size: 9.5px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: #aaa;
  background: rgba(12, 14, 20, 0.75);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 999px;
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease, opacity 0.4s ease;
  opacity: 0;
  pointer-events: none;
  z-index: 11;
}
#exit-earth.visible { opacity: 1; pointer-events: auto; }
#exit-earth:hover { color: #fff; border-color: rgba(255, 255, 255, 0.3); }

/* =====================================================================
   HELP — discreet "?" button bottom-right. Hint overlay summoned by
   button or "?" key; auto-shown once on first visit then dismissed.
   ===================================================================== */
#help-btn {
  position: fixed;
  right: 24px;
  bottom: 24px;
  width: 28px;
  height: 28px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 50%;
  background: transparent;
  color: #888;
  font-family: inherit;
  font-size: 11px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
  user-select: none;
}
#help-btn:hover {
  color: #e6e6e6;
  border-color: rgba(255, 255, 255, 0.4);
  transform: scale(1.06);
}
#hint {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.55s ease;
  z-index: 200;
}
#hint.visible {
  opacity: 1;
  pointer-events: auto;
}

/* ---- Quick tour card (the reworked help) ---- */
#hint .tour-card {
  position: relative;
  max-width: 380px;
  width: calc(100vw - 48px);
  background: linear-gradient(180deg, rgba(14,17,26,0.56), rgba(8,10,16,0.66));
  backdrop-filter: blur(26px) saturate(125%);
  -webkit-backdrop-filter: blur(26px) saturate(125%);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 18px;
  padding: 30px 26px 22px;
  box-shadow: 0 30px 80px rgba(0,0,0,0.55);
  color: #e9edf5;
  text-shadow: 0 1px 6px rgba(0,0,0,0.5);
  z-index: 3;
}
/* Spotlight ring around the step's target control; the giant box-shadow dims
   everything else, and #hint goes transparent so only this dims (a real
   spotlight). A beak on the card points at the control. */
#hint.tour-spotting { background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; }
/* Demo step: the tour has driven a live mode in behind the card. Make the
   overlay transparent and click-through so that mode shows clearly and stays
   interactive — only the caption card itself catches taps. */
#hint.tour-demo { background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; pointer-events: none; }
#hint.tour-demo .tour-card {
  pointer-events: auto;
  /* A touch more opaque than the see-through default, so the caption stays
     legible over a bright dossier or globe. */
  background: linear-gradient(180deg, rgba(12,15,23,0.9), rgba(7,9,15,0.94));
}
#hint .tour-spot {
  position: fixed;
  border-radius: 12px;
  border: 2px solid rgba(248,212,140,0.92);
  box-shadow: 0 0 0 9999px rgba(4,6,12,0.66), 0 0 22px rgba(248,212,140,0.55);
  pointer-events: none;
  z-index: 1;
  transition: left 0.3s ease, top 0.3s ease, width 0.3s ease, height 0.3s ease;
}
#hint .tour-card[class*="tour-beak-"]::after {
  content: ''; position: absolute; width: 0; height: 0; border: 10px solid transparent;
}
#hint .tour-beak-down::after  { top: 100%;    left: 50%; transform: translateX(-50%); border-top-color: rgba(11,14,22,0.64); }
#hint .tour-beak-up::after    { bottom: 100%; left: 50%; transform: translateX(-50%); border-bottom-color: rgba(14,17,26,0.58); }
#hint .tour-beak-left::after  { right: 100%;  top: 50%;  transform: translateY(-50%); border-right-color: rgba(13,16,24,0.6); }
#hint .tour-beak-right::after { left: 100%;   top: 50%;  transform: translateY(-50%); border-left-color: rgba(13,16,24,0.6); }

/* ---- First-time gesture hint chip (shown once per gesture context) ---- */
#gesture-hint {
  position: fixed;
  left: 50%;
  bottom: calc(104px + var(--safe-bottom));
  transform: translateX(-50%) translateY(10px);
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 16px;
  border-radius: 999px;
  background: rgba(12,14,20,0.58);
  backdrop-filter: blur(20px) saturate(120%);
  -webkit-backdrop-filter: blur(20px) saturate(120%);
  border: 1px solid rgba(255,255,255,0.12);
  color: rgba(236,238,244,0.94);
  font-size: 12px;
  letter-spacing: 0.03em;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  z-index: 190;
  transition: opacity 0.45s ease, transform 0.45s ease;
  text-shadow: 0 1px 6px rgba(0,0,0,0.5);
}
#gesture-hint.visible { opacity: 1; transform: translateX(-50%) translateY(0); }
#gesture-hint .gh-glyph { font-size: 15px; color: rgba(248,212,140,0.95); }

/* ---- First-run invitation to the guided tour (shown once, then dismissed) ---- */
#tour-invite {
  position: fixed;
  right: 18px;
  bottom: 56px;                 /* clear of the bottom-right "?" button */
  display: flex;
  align-items: center;
  gap: 6px;
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  z-index: 200;
  transition: opacity 0.45s ease, transform 0.45s ease;
}
#tour-invite.visible { opacity: 1; transform: none; pointer-events: auto; }
#tour-invite .ti-open {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 10px 15px;
  border-radius: 999px;
  border: 1px solid rgba(248,212,140,0.45);
  background: rgba(14,17,26,0.72);
  backdrop-filter: blur(20px) saturate(115%);
  -webkit-backdrop-filter: blur(20px) saturate(115%);
  color: #f3dca8;
  font: 13px/1.2 Georgia, 'Times New Roman', serif;
  letter-spacing: 0.2px;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 8px 30px rgba(0,0,0,0.45);
  transition: border-color 0.2s ease, transform 0.2s ease;
}
#tour-invite .ti-open:hover { border-color: rgba(248,212,140,0.85); transform: translateY(-1px); }
#tour-invite .ti-text { color: rgba(236,240,248,0.92); }
#tour-invite .ti-text b { color: #f3dca8; font-weight: 600; }
#tour-invite .ti-spark { font-size: 12px; color: #f3dca8; opacity: 0.9; }
#tour-invite .ti-arrow { color: #f3dca8; }
#tour-invite .ti-close {
  width: 26px; height: 26px;
  border-radius: 50%;
  border: 1px solid rgba(206,215,230,0.22);
  background: rgba(14,17,26,0.72);
  color: rgba(206,215,230,0.7);
  font-size: 14px; line-height: 1; cursor: pointer;
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  transition: color 0.2s ease, border-color 0.2s ease;
}
#tour-invite .ti-close:hover { color: #f3dca8; border-color: rgba(248,212,140,0.5); }
/* On phones, sit centered above the bottom dock instead of in the corner. */
body.is-phone #tour-invite, body.is-mobile #tour-invite {
  left: 50%; right: auto;
  bottom: calc(104px + var(--safe-bottom, 0px));
  transform: translateX(-50%) translateY(8px);
}
body.is-phone #tour-invite.visible, body.is-mobile #tour-invite.visible {
  transform: translateX(-50%);
}

#hint .tour-close {
  position: absolute; top: 13px; right: 13px;
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid rgba(255,255,255,0.12);
  border-radius: 50%; color: rgba(255,255,255,0.6);
  font-size: 18px; line-height: 1; cursor: pointer;
}
#hint .tour-kicker {
  font-size: 9px; letter-spacing: 0.28em; text-transform: uppercase;
  color: rgba(248,212,140,0.75); margin-bottom: 12px;
}
#hint .tour-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 23px; line-height: 1.15; color: #f4f6fb; margin: 0 0 12px;
}
#hint .tour-body {
  font-size: 14px; line-height: 1.55; color: rgba(226,230,238,0.82);
}
#hint .tour-dots {
  display: flex; gap: 6px; justify-content: center; margin: 24px 0 18px;
}
#hint .tour-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: rgba(255,255,255,0.2); transition: background 0.2s ease, transform 0.2s ease;
}
#hint .tour-dot.active { background: rgba(248,212,140,0.9); transform: scale(1.3); }
#hint .tour-nav { display: flex; gap: 12px; }
#hint .tour-nav button {
  flex: 1 1 0;
  padding: 11px 16px;
  border-radius: 10px;
  font-family: inherit; font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease, opacity 0.2s ease;
}
#hint .tour-prev {
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.14);
  color: rgba(255,255,255,0.7);
}
#hint .tour-next {
  background: rgba(248,212,140,0.16);
  border: 1px solid rgba(248,212,140,0.5);
  color: rgba(248,212,140,0.95);
}
#hint .tour-prev:disabled { opacity: 0.3; cursor: default; }
#hint .tour-prev:not(:disabled):hover { background: rgba(255,255,255,0.12); }
#hint .tour-next:hover { background: rgba(248,212,140,0.26); }

#hint .panel {
  display: flex;
  flex-direction: column;
  gap: 22px;
  max-width: 640px;
  padding: 6px 10px;
}
#hint .panel-solar { max-width: 460px; }
#hint .hint-section {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
#hint .hint-section-title {
  font-size: 9px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(180, 196, 222, 0.6);
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}
#hint .hint-grid {
  display: grid;
  grid-template-columns: minmax(120px, auto) 1fr;
  column-gap: 22px;
  row-gap: 10px;
  align-items: baseline;
}
#hint .key {
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #e6e6e6;
  text-align: right;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  justify-content: flex-end;
}
/* Inline icon mirroring the real button SVG for instant recognition. */
#hint .key .hint-ico {
  flex: 0 0 auto;
  color: rgba(232, 240, 252, 0.9);
}
/* Position hint ('top-left', 'bottom-right', etc.) sits beside the icon
   in a quieter weight so the icon reads as the primary identifier. */
#hint .key .hint-pos {
  font-size: 9px;
  letter-spacing: 0.20em;
  text-transform: uppercase;
  color: rgba(170, 180, 200, 0.55);
}
#hint .desc {
  font-size: 10.5px;
  letter-spacing: 0.08em;
  color: rgba(170, 180, 200, 0.78);
  text-align: left;
  text-transform: none;
}
#hint .footer {
  margin-top: 6px;
  text-align: center;
  font-size: 9px;
  letter-spacing: 0.32em;
  color: rgba(255, 255, 255, 0.32);
  text-transform: uppercase;
}


/* =====================================================================
   WORLD / POWER DOSSIER — editorial landing page for Earth mode.
   Uses a real-photo hero treatment and a compact intelligence-layout.
   ===================================================================== */
#stories-panel.atlas .sp-power-page {
  display: flex;
  flex-direction: column;
  gap: 24px;
}
#stories-panel.atlas .sp-power-hero {
  position: relative;
  min-height: 255px;
  overflow: hidden;
  border-radius: 12px;
  border: 1px solid rgba(255,255,255,0.09);
  background:
    linear-gradient(90deg, rgba(3,5,10,0.88), rgba(3,5,10,0.52) 47%, rgba(3,5,10,0.78)),
    url('https://images.unsplash.com/photo-1517502884422-41eaead166d4?auto=format&fit=crop&w=1600&q=80') center center / cover no-repeat,
    linear-gradient(135deg, #111722, #05070c);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 18px 48px rgba(0,0,0,0.42);
  isolation: isolate;
}
#stories-panel.atlas .sp-power-hero::before {
  content: "";
  position: absolute;
  inset: -12px;
  background: inherit;
  filter: blur(2.2px) saturate(85%);
  transform: scale(1.025);
  z-index: -2;
}
#stories-panel.atlas .sp-power-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 18% 18%, rgba(168,194,235,0.16), rgba(168,194,235,0) 38%),
    linear-gradient(180deg, rgba(2,3,8,0.18), rgba(2,3,8,0.78));
  z-index: -1;
}
/* Discreet country flag, pinned to the hero's top-right corner. Small, with a
   soft frame and shadow so it reads as a refined emblem rather than a sticker.
   Sits above the hero's tint layers (which use negative z-index). */
#stories-panel.atlas .sp-power-flag {
  position: absolute;
  top: 16px;
  right: 18px;
  z-index: 2;
  width: 46px;
  height: auto;
  border-radius: 3px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.55), 0 0 0 1px rgba(255,255,255,0.14);
  opacity: 0.92;
}
/* On the no-image header variant, the flag still floats top-right. */
#stories-panel.atlas .sp-power-header-noimg { position: relative; }
#stories-panel.atlas .sp-power-header-noimg .sp-power-flag { top: 2px; right: 2px; }

/* Current-leader ID card at the top of the Key Indicators panel: a small
   portrait beside the role + name. Quiet, contained, never loud. */
#stories-panel.atlas .sp-power-leader {
  display: flex;
  align-items: center;
  gap: 11px;
  padding-bottom: 13px;
  margin-bottom: 13px;
  border-bottom: 1px solid rgba(255,255,255,0.07);
}
#stories-panel.atlas .sp-power-leader-img {
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center top;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.12), 0 3px 10px rgba(0,0,0,0.4);
}
#stories-panel.atlas .sp-power-leader-id { min-width: 0; }
#stories-panel.atlas .sp-power-leader-role {
  font-size: 8.5px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: #697488;
  margin-bottom: 3px;
}
#stories-panel.atlas .sp-power-leader-name {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 15px;
  line-height: 1.15;
  color: #e7ecf4;
}

#stories-panel.atlas .sp-power-hero-content {
  position: absolute;
  left: 26px;
  right: 26px;
  bottom: 24px;
  max-width: 540px;
}
#stories-panel.atlas .sp-power-kicker {
  font-size: 9px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(210,222,240,0.72);
  margin-bottom: 9px;
}
/* Narrative pages (Explore sections, theme hubs, guide chapters) write their
   kicker in sentence case ("The horizon", "How we got here"); render it that
   way to match the title. Country/subject kickers are caps in the data and
   stay as-is. */
#stories-panel.atlas .sp-explore-hero .sp-power-kicker,
#stories-panel.atlas .sp-guide-hero .sp-power-kicker {
  text-transform: none;
  letter-spacing: 0.08em;
  font-size: 10px;
}
#stories-panel.atlas .sp-power-hero-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 24px;
  line-height: 1.18;
  letter-spacing: 0.01em;
  color: #f3f5f9;
  margin-bottom: 10px;
  text-shadow: 0 2px 16px rgba(0,0,0,0.72);
}
#stories-panel.atlas .sp-power-hero-note {
  font-size: 11.5px;
  line-height: 1.55;
  color: rgba(218,225,236,0.86);
  max-width: 500px;
}

/* Hero-less header — used for regions without a hero image (everything
 * except Earth, North America, and the United States). Shows kicker,
 * title, and note in a compact band so the page still has a clear
 * masthead without an image. */
#stories-panel.atlas .sp-power-header-noimg {
  position: relative;
  padding: 22px 26px 20px;
  border-radius: 12px;
  border: 1px solid rgba(255,255,255,0.07);
  background: linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.015));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);
}
#stories-panel.atlas .sp-power-header-noimg .sp-power-hero-title {
  text-shadow: none;
  margin-bottom: 8px;
}
#stories-panel.atlas .sp-power-header-noimg .sp-power-hero-note {
  max-width: 720px;
}
#stories-panel.atlas .sp-power-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(220px, 0.85fr);
  gap: 22px;
  align-items: start;
}
#stories-panel.atlas .sp-power-main {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
#stories-panel.atlas .sp-power-thesis {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 18px;
  line-height: 1.42;
  color: #f1f3f7;
  text-align: justify;
  hyphens: auto;
  -webkit-hyphens: auto;
}
#stories-panel.atlas .sp-power-copy {
  font-size: 12.5px;
  line-height: 1.78;
  color: #b8c1cf;
  text-align: justify;
  hyphens: auto;
  -webkit-hyphens: auto;
}
#stories-panel.atlas .sp-power-copy strong,
#stories-panel.atlas .sp-power-institution strong {
  color: #e5eaf2;
  font-weight: 600;
}
#stories-panel.atlas .sp-power-side {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
#stories-panel.atlas .sp-power-panel {
  border: 1px solid rgba(255,255,255,0.075);
  border-radius: 10px;
  background: rgba(255,255,255,0.033);
  padding: 14px;
}
#stories-panel.atlas .sp-power-panel-title {
  font-size: 9px;
  letter-spacing: 0.30em;
  text-transform: uppercase;
  color: #7d8aa0;
  margin-bottom: 12px;
}
#stories-panel.atlas .sp-power-fact {
  padding: 9px 0;
  border-top: 1px solid rgba(255,255,255,0.055);
}
#stories-panel.atlas .sp-power-fact:first-of-type { border-top: none; padding-top: 0; }
#stories-panel.atlas .sp-power-fact .l {
  display: block;
  font-size: 8.5px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: #697488;
  margin-bottom: 3px;
}
#stories-panel.atlas .sp-power-fact .v {
  display: block;
  font-size: 12px;
  line-height: 1.35;
  color: #dce2ec;
}

/* Consistent country indicator grid: grouped (Core / Economy / Identity /
   Strategic), each a small caps label over tidy key-value rows. Label left and
   muted, value right and bright, so the column reads as a clean reference card
   and identical fields line up across countries. */
#stories-panel.atlas .sp-ind-group { margin-bottom: 14px; }
#stories-panel.atlas .sp-ind-group:last-child { margin-bottom: 0; }
#stories-panel.atlas .sp-ind-group-label {
  font-size: 8px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: #5f6b80;
  margin: 0 0 7px;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(255,255,255,0.07);
}
#stories-panel.atlas .sp-ind-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 0;
}
#stories-panel.atlas .sp-ind-k {
  flex: 0 0 auto;
  font-size: 9.5px;
  letter-spacing: 0.04em;
  color: #7a8499;
}
#stories-panel.atlas .sp-ind-v {
  flex: 1 1 auto;
  text-align: right;
  font-size: 11.5px;
  line-height: 1.3;
  color: #e2e8f2;
}
#stories-panel.atlas .sp-power-section {
  margin-top: 2px;
}
#stories-panel.atlas .sp-power-section-head {
  margin: 0 0 12px;
  font-size: 9px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: #77859b;
}
#stories-panel.atlas .sp-power-institutions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
#stories-panel.atlas .sp-power-institution {
  padding: 13px 14px;
  border-radius: 10px;
  border: 1px solid rgba(255,255,255,0.07);
  background: linear-gradient(180deg, rgba(255,255,255,0.045), rgba(255,255,255,0.025));
  font-size: 11.2px;
  line-height: 1.55;
  color: #aeb8c8;
}
#stories-panel.atlas .sp-power-institution .name {
  display: block;
  margin-bottom: 5px;
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #e3e8f0;
}
#stories-panel.atlas .sp-power-institution .sp-figure-role {
  display: block;
  margin-bottom: 6px;
  font-size: 10.5px;
  font-style: italic;
  color: #c9d2df;
}
#stories-panel.atlas .sp-power-forces {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}
#stories-panel.atlas .sp-power-force {
  min-height: 86px;
  padding: 13px;
  border-radius: 10px;
  border: 1px solid rgba(255,255,255,0.065);
  background: rgba(255,255,255,0.026);
  color: #aab5c6;
  font-size: 11px;
  line-height: 1.5;
}
#stories-panel.atlas .sp-power-force .name {
  display: block;
  margin-bottom: 6px;
  color: #eef2f8;
  font-size: 10px;
  letter-spacing: 0.20em;
  text-transform: uppercase;
}
#stories-panel.atlas .sp-power-source-note {
  padding-top: 12px;
  border-top: 1px solid rgba(255,255,255,0.055);
  color: #6f7a8d;
  font-size: 9.5px;
  line-height: 1.55;
}
@media (max-width: 900px) {
  #stories-panel.atlas .sp-power-grid,
  #stories-panel.atlas .sp-power-institutions,
  #stories-panel.atlas .sp-power-forces { grid-template-columns: 1fr; }
  #stories-panel.atlas .sp-power-hero-title { font-size: 21px; }
}

/* =====================================================================
   BOOT-ERROR OVERLAY — appears only when an uncaught JS error fires.
   Sits above everything; attention-grabbing so silent failures stop
   being silent.
   ===================================================================== */
#boot-error {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(8, 10, 16, 0.86);
  backdrop-filter: blur(10px) saturate(140%);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  z-index: 10000;
  padding: 32px;
  -webkit-user-select: text;
  user-select: text;
}
#boot-error[hidden] { display: none; }
#boot-error .be-card {
  max-width: 720px;
  width: 100%;
  background: #0c0f17;
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 8px;
  padding: 24px 28px 22px;
  box-shadow: 0 24px 80px rgba(0,0,0,0.55);
  color: #cfd2d8;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Arial, sans-serif;
}
#boot-error .be-title {
  font-size: 13px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: #e88;
  margin: 0 0 12px;
}
#boot-error .be-msg {
  font-size: 14px;
  line-height: 1.5;
  color: #f0f0f0;
  margin: 0 0 14px;
}
#boot-error .be-stack {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11px;
  line-height: 1.45;
  color: #9aa0aa;
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.05);
  border-radius: 4px;
  padding: 10px 12px;
  margin: 0 0 14px;
  max-height: 280px;
  overflow: auto;
  white-space: pre-wrap;
}
#boot-error .be-tip {
  font-size: 11.5px;
  letter-spacing: 0.05em;
  color: #888;
  margin: 0;
}


/* =====================================================================
   SEARCH LENS — minimalist magnifying-glass button bottom-right, mirrors
   the help button design language (28px circle, 1px border, transparent
   bg, color #888 → #e6e6e6 on hover). Expands into a horizontal pill
   with a borderless input. No live suggestions — typing + Enter
   navigates to the best match; mismatched queries flash a subtle red.
   ===================================================================== */
#lens-trigger {
  position: fixed;
  right: 60px;
  bottom: 24px;
  width: 28px;
  height: 28px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 50%;
  background: transparent;
  color: #888;
  font-family: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.2s ease, border-color 0.2s ease, transform 0.2s ease, opacity 0.2s ease;
  user-select: none;
  z-index: 90;
  padding: 0;
}
#lens-trigger:hover,
#lens-trigger:focus-visible {
  color: #e6e6e6;
  border-color: rgba(255, 255, 255, 0.4);
  transform: scale(1.06);
  outline: none;
}
#lens-trigger.expanded {
  /* When the panel is open we hide the trigger button and the panel
     itself becomes the visible affordance. */
  opacity: 0;
  pointer-events: none;
}
#lens-trigger[hidden] { display: none; }

#lens-panel {
  position: fixed;
  right: 60px;
  bottom: 24px;
  height: 28px;
  width: 240px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 14px;
  background: transparent;
  display: flex;
  align-items: center;
  padding: 0 14px;
  z-index: 91;
  -webkit-user-select: text;
  user-select: text;
  transition: border-color 0.2s ease;
}
#lens-panel:focus-within { border-color: rgba(255, 255, 255, 0.4); }
#lens-panel[hidden] { display: none; }
#lens-panel .lens-icon {
  flex: 0 0 auto;
  margin-right: 8px;
  color: rgba(255, 255, 255, 0.4);
}
#lens-input {
  flex: 1;
  height: 100%;
  background: transparent;
  border: 0;
  outline: none;
  color: #e6e6e6;
  font-family: inherit;
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  caret-color: #e6e6e6;
}
#lens-input::placeholder {
  color: #6a6a6a;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
#lens-input.miss {
  /* Brief red flash when the user presses Enter on a query with no match. */
  color: #d77;
  animation: lens-shake 0.25s ease;
}

/* =====================================================================
   LENS SUGGESTIONS — live result list. Grows upward from just above
   the lens panel. Deliberately minimal: a short, quiet column of
   labels, never a crowded dropdown.
   ===================================================================== */
#lens-suggestions {
  position: fixed;
  right: 60px;
  /* Sits just above the 28px panel (bottom:24px) with an 8px gap. */
  bottom: 60px;
  width: 240px;
  display: flex;
  flex-direction: column;
  z-index: 91;
  background: rgba(8, 10, 16, 0.82);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 8px;
  padding: 5px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
  user-select: none;
  overflow: hidden;
}
#lens-suggestions[hidden] { display: none; }

#lens-suggestions .ls-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 10px;
  border-radius: 5px;
  cursor: pointer;
  transition: background 0.14s ease;
}
#lens-suggestions .ls-row:hover,
#lens-suggestions .ls-row.sel {
  background: rgba(255, 255, 255, 0.07);
}
#lens-suggestions .ls-label {
  font-size: 11px;
  letter-spacing: 0.10em;
  color: #e8ecf2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#lens-suggestions .ls-row.sel .ls-label { color: #fff; }
#lens-suggestions .ls-kind {
  font-size: 7.5px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: rgba(170, 180, 200, 0.5);
  flex-shrink: 0;
}
#lens-suggestions .ls-row.sel .ls-kind,
#lens-suggestions .ls-row:hover .ls-kind {
  color: rgba(244, 233, 196, 0.8);
}
@keyframes lens-shake {
  0%   { transform: translateX(0); }
  25%  { transform: translateX(-3px); }
  50%  { transform: translateX(3px); }
  75%  { transform: translateX(-2px); }
  100% { transform: translateX(0); }
}

/* =====================================================================
   SUBJECT CARDS — clickable institution/place/event entries inside a
   country or continent's "architecture" list. Visually subtle: a small
   right-arrow appears on the right edge, the entry brightens on hover,
   and the cursor shifts to a pointer. Non-subject entries (descriptive
   text only) stay un-styled.
   ===================================================================== */
#stories-panel.atlas .sp-power-institution.sp-subject-link {
  cursor: pointer;
  position: relative;
  padding-right: 28px;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}
#stories-panel.atlas .sp-power-institution.sp-subject-link:hover,
#stories-panel.atlas .sp-power-institution.sp-subject-link:focus-visible {
  background: rgba(255,255,255,0.04);
  border-color: rgba(255,255,255,0.18);
  color: #f0f0f0;
  outline: none;
}
#stories-panel.atlas .sp-power-institution.sp-subject-link .name {
  color: #e6e6e6;
}
#stories-panel.atlas .sp-power-institution.sp-subject-link:hover .name {
  color: #fff;
}
#stories-panel.atlas .sp-subject-arrow {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 16px;
  line-height: 1;
  color: #555;
  transition: color 0.18s ease, transform 0.18s ease;
}
#stories-panel.atlas .sp-power-institution.sp-subject-link:hover .sp-subject-arrow {
  color: #e6e6e6;
  transform: translateY(-50%) translateX(2px);
}

/* =====================================================================
   BREADCRUMB CRUMBS — segments inside .sp-breadcrumb that carry a
   data-crumb-level attribute are clickable; they fly the camera to
   that level when activated. Current (last) segment stays static.
   ===================================================================== */
#stories-panel .sp-breadcrumb .sp-crumb[data-crumb-level] {
  cursor: pointer;
  transition: color 0.15s ease, text-shadow 0.15s ease;
}
#stories-panel .sp-breadcrumb .sp-crumb[data-crumb-level]:hover,
#stories-panel .sp-breadcrumb .sp-crumb[data-crumb-level]:focus-visible {
  color: #f0f0f0;
  outline: none;
  text-shadow: 0 0 0.5px rgba(255,255,255,0.25);
}
#stories-panel .sp-breadcrumb .sp-crumb-current {
  color: #f0f0f0;
}

/* =====================================================================
   ARCHITECTURE CARDS — minimal: small thumbnail (left) + name + tagline
   (right), with a › arrow indicating clickability. Replaces the older
   text-only block when a row has a thumbnail.
   ===================================================================== */
#stories-panel.atlas .sp-arch-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding-right: 30px; /* room for the › arrow */
}
#stories-panel.atlas .sp-arch-thumb {
  /* The actual image lives on a ::before pseudo-element below so the
     blur stays clipped to the 56x56 frame and the border stays crisp.
     The image URL is passed in as a --thumb-bg custom property by the
     renderer (modules/main.js). */
  flex: 0 0 56px;
  width: 56px;
  height: 56px;
  border-radius: 4px;
  background-color: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.06);
  position: relative;
  overflow: hidden;
  transition: border-color 0.18s ease;
}
#stories-panel.atlas .sp-arch-thumb::before {
  content: '';
  position: absolute;
  /* Negative inset so the blurred edges land outside the visible 56x56
     and overflow:hidden clips them — no soft halo bleeding into the
     card's text or neighbors. */
  inset: -8px;
  background-image: var(--thumb-bg);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  filter: blur(4px) saturate(0.85) brightness(0.95);
}
#stories-panel.atlas .sp-subject-link.sp-arch-card:hover .sp-arch-thumb,
#stories-panel.atlas .sp-subject-link.sp-arch-card:focus-visible .sp-arch-thumb {
  border-color: rgba(255,255,255,0.25);
}
#stories-panel.atlas .sp-arch-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  min-width: 0;
}
#stories-panel.atlas .sp-arch-card .sp-arch-text .name {
  font-size: 11.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #e5eaf2;
}
#stories-panel.atlas .sp-arch-card .sp-arch-desc {
  font-size: 12.5px;
  line-height: 1.5;
  color: #b8c1cf;
}

/* =====================================================================
   FACT FLAGS — clickable country flag chips that appear under specific
   key indicators (UN-SC permanent members, nuclear-armed states).
   ===================================================================== */
#stories-panel.atlas .sp-fact-flags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}
#stories-panel.atlas .sp-fact-flag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 7px 3px 4px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 3px;
  color: #c8cfdb;
  font-family: inherit;
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
#stories-panel.atlas .sp-fact-flag:hover,
#stories-panel.atlas .sp-fact-flag:focus-visible {
  background: rgba(255,255,255,0.08);
  border-color: rgba(255,255,255,0.18);
  color: #f0f0f0;
  outline: none;
}
#stories-panel.atlas .sp-fact-flag img {
  width: 16px;
  height: 11px;
  object-fit: cover;
  border-radius: 1px;
  flex: 0 0 16px;
  background: rgba(255,255,255,0.05);
}

/* =====================================================================
   BACK BUTTON — small ‹ arrow at the top-left of the dossier head.
   Mirrors the close × treatment so they read as a pair.
   ===================================================================== */
#stories-panel .sp-back {
  background: transparent;
  border: 0;
  padding: 4px 8px;
  margin: -4px 8px -4px -4px;
  font: inherit;
  font-size: 22px;
  line-height: 1;
  color: #555;
  cursor: pointer;
  transition: color 0.15s ease, transform 0.2s ease;
}
#stories-panel .sp-back:hover,
#stories-panel .sp-back:focus-visible {
  color: #e6e6e6;
  outline: none;
  transform: translateX(-2px);
}
#stories-panel .sp-back:focus-visible {
  box-shadow: 0 0 0 1px rgba(255,255,255,0.18);
  border-radius: 3px;
}
#stories-panel .sp-back[hidden] { display: none; }

/* =====================================================================
   BREADCRUMB BACK ARROW — small ‹ at the very start of the breadcrumb
   (before "Earth"), shown only when there's a previous page on the
   navigation stack. Replaces the older head-mounted back button.
   ===================================================================== */
/* Back arrow: prominent corner FAB anchored to the hero's top-left.
 * Although it's still rendered as the first child of .sp-breadcrumb,
 * we lift it out of the flex flow with absolute positioning so it
 * floats over the hero / coming-soon frame as a clear navigation
 * anchor. Top offset is chosen to land just inside the hero's top edge
 * (dossier padding-top 24 + breadcrumb height ~22 + breadcrumb margin
 * 16 = ~62, so 56 puts it ~6px proud of the hero corner).
 */
/* Bare-glyph back arrow. The visible footprint is just the chevron;
 * the surrounding 32x32 box is the accessible click target with no
 * background or border. Color tracks the breadcrumb's dim grey, with a
 * brighter hover state and a small horizontal nudge as the affordance.
 */
/* Back arrow: inline flex item inside the breadcrumb. The chevron is
 * an inline SVG (precisely positioned by viewBox), so flex
 * align-items:center on the breadcrumb produces clean optical alignment
 * with the caps text without needing font-specific translate tweaks. */
#stories-panel .sp-breadcrumb .sp-crumb-back {
  position: static;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 14px;
  padding: 0;
  margin: 0 6px 0 -2px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: rgba(218, 226, 240, 0.55);
  cursor: pointer;
  transition: color 0.15s ease, transform 0.18s ease;
}
#stories-panel .sp-breadcrumb .sp-crumb-back svg {
  display: block;
  width: 12px;
  height: 12px;
}
#stories-panel .sp-breadcrumb .sp-crumb-back:hover,
#stories-panel .sp-breadcrumb .sp-crumb-back:focus-visible {
  color: #ffffff;
  transform: translateX(-3px);
  outline: none;
}
#stories-panel .sp-breadcrumb .sp-crumb-back[hidden] { display: none; }
/* Phone: drop the breadcrumb's ‹ back arrow — it's redundant with the main
   back button and routed through a different (rail-stranding) path. The
   breadcrumb segments stay tappable, and the main back button is canonical. */
body.is-phone #stories-panel .sp-breadcrumb .sp-crumb-back { display: none; }
/* The breadcrumb sticks to the top of the dossier scroll area so the
 * back arrow (its first child) stays visible no matter how far the
 * dossier content has scrolled. The slight negative margin counteracts
 * the dossier's padding-top so the sticky pin point matches the
 * breadcrumb's natural top edge. The gradient background obscures
 * content scrolling underneath. */
/* Breadcrumb lives at the top of the scrolling dossier body, below the pinned
   header, and STICKS there: it stays pinned to the top of the scroll area so
   the back arrow is always reachable, even at the bottom of a long page. The
   band is a SOLID opaque fill (not a fade) and full-bleeds to the panel edges,
   so content scrolls cleanly behind it and never shows through. Full-bleed via
   negative side margins that cancel the dossier's 28px horizontal padding. */
#stories-panel.atlas .sp-breadcrumb {
  position: sticky;
  /* Stick flush to the very top of the scroll area. The dossier has no top
     padding, so top:0 lands the band directly beneath the header with NO gap
     strip where content could show through. Negative side margins full-bleed
     it to the panel edges. */
  top: 0;
  z-index: 4;
  margin: 0 -28px 14px;         /* full-bleed sides; flush to the top */
  padding: 16px 28px 12px;      /* the band's own top/bottom spacing */
  background: #0a0d15;          /* opaque; matches the panel's top tone */
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

/* Hide the legacy head-mounted back button if any old DOM still has it. */
#stories-panel .sp-head .sp-back { display: none; }


/* =====================================================================
   PAST / TIMELINE MODE
   Phase 1 styles. Toggle pill in the dossier head, vertical arc timeline,
   and the lineage-to-today closing block.
   ===================================================================== */

/* --- Mode toggle (pill) ------------------------------------------------ */
#stories-panel.atlas .sp-mode-toggle {
  display: inline-flex;
  gap: 0;
  margin: 14px 28px 0 auto; /* right-align under the hero */
  align-self: flex-end;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.09);
  border-radius: 999px;
  padding: 3px;
  width: fit-content;
}
#stories-panel.atlas .sp-mode-btn {
  background: transparent;
  border: 0;
  color: #8a93a3;
  font: inherit;
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  padding: 6px 14px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.16s ease, color 0.16s ease;
}
#stories-panel.atlas .sp-mode-btn:hover {
  color: #d8dde6;
}
#stories-panel.atlas .sp-mode-btn.active {
  background: rgba(255,255,255,0.10);
  color: #f0f2f6;
}
#stories-panel.atlas .sp-mode-btn:focus-visible {
  outline: 1px solid rgba(255,255,255,0.30);
  outline-offset: 1px;
}

/* --- Arc timeline ----------------------------------------------------- */
#stories-panel.atlas .sp-arc-section {
  margin-top: 8px;
}
#stories-panel.atlas .sp-arc {
  position: relative;
  padding-left: 14px;
  margin-top: 4px;
}
/* Vertical rail */
#stories-panel.atlas .sp-arc::before {
  content: '';
  position: absolute;
  left: 4px;
  top: 8px;
  bottom: 8px;
  width: 1px;
  background: linear-gradient(180deg, rgba(255,255,255,0.18), rgba(255,255,255,0.04));
}
#stories-panel.atlas .sp-arc-entry {
  position: relative;
  padding: 10px 0 10px 18px;
  border-top: 1px solid rgba(255,255,255,0.05);
  transition: background 0.18s ease;
}
#stories-panel.atlas .sp-arc-entry:first-of-type { border-top: none; padding-top: 4px; }
/* Dot */
#stories-panel.atlas .sp-arc-entry::before {
  content: '';
  position: absolute;
  left: -3px;
  top: 18px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #c8cfdb;
  box-shadow: 0 0 0 3px rgba(8, 10, 16, 0.95);
}
#stories-panel.atlas .sp-arc-entry:first-of-type::before { top: 12px; }
#stories-panel.atlas .sp-arc-entry-link {
  cursor: pointer;
}
#stories-panel.atlas .sp-arc-entry-link:hover,
#stories-panel.atlas .sp-arc-entry-link:focus-visible {
  background: rgba(255,255,255,0.035);
  outline: none;
}
#stories-panel.atlas .sp-arc-year {
  font-size: 10px;
  letter-spacing: 0.20em;
  text-transform: uppercase;
  color: #7b8799;
  margin-bottom: 3px;
}
#stories-panel.atlas .sp-arc-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 16px;
  line-height: 1.25;
  color: #f0f2f6;
  margin-bottom: 4px;
}
#stories-panel.atlas .sp-arc-summary {
  font-size: 12.5px;
  line-height: 1.55;
  color: #b5bdc9;
}

/* --- Lineage-to-today closing block ----------------------------------- */
#stories-panel.atlas .sp-lineage-to-today {
  margin-top: 18px;
  padding: 18px 20px;
  border-top: 1px solid rgba(255,255,255,0.10);
  border-radius: 4px;
  background: linear-gradient(180deg, rgba(255,255,255,0.025), rgba(255,255,255,0));
}
#stories-panel.atlas .sp-lineage-label {
  font-size: 9.5px;
  letter-spacing: 0.30em;
  text-transform: uppercase;
  color: #7b8799;
  margin-bottom: 8px;
}
#stories-panel.atlas .sp-lineage-body {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 14.5px;
  line-height: 1.6;
  color: #e0e5ee;
}

/* --- Timeline grid (single column, no key_facts sidebar) ------------ */
#stories-panel.atlas .sp-power-grid-timeline {
  display: block;
}



/* =====================================================================
   TIMELINE CINEMATIC MODE
   The bottom-left toggle button (mirrors the lens at bottom-right), the
   bottom timeline strip, the mid-screen context card, and the body-level
   class `cinematic` that toggles backdrop blur and other UI visibility.
   ===================================================================== */

/* --- Toggle button (mirror of #lens-trigger but at bottom-left) ------- */
#timeline-trigger {
  position: fixed;
  left: 60px;
  bottom: 24px;
  width: 28px;
  height: 28px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 50%;
  background: transparent;
  color: #888;
  font-family: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.2s ease, border-color 0.2s ease, transform 0.2s ease, opacity 0.2s ease;
  user-select: none;
  z-index: 90;
  padding: 0;
}
#timeline-trigger.has-timeline {
  color: #cfcfcf;
  border-color: rgba(255, 255, 255, 0.32);
}
#timeline-trigger:hover,
#timeline-trigger:focus-visible {
  color: #e6e6e6;
  border-color: rgba(255, 255, 255, 0.4);
  transform: scale(1.06);
  outline: none;
}
#timeline-trigger.active {
  color: #ff6e5a;
  border-color: rgba(255, 110, 90, 0.55);
}
#timeline-trigger[hidden] { display: none; }

/* --- Body-level mode class -------------------------------------------- */
/* When the body carries `cinematic`, the dossier panel is hidden and the
   backdrop blur is reduced so the globe is the focus. */
body.cinematic #stories-panel,
body.cinematic #stories-backdrop {
  pointer-events: none;
}
body.cinematic #stories-panel {
  opacity: 0;
  transform: translateY(-50%) translateX(20px);
}
body.cinematic #stories-backdrop {
  background: rgba(2, 4, 9, 0.28);
  backdrop-filter: blur(4px) saturate(108%);
  -webkit-backdrop-filter: blur(4px) saturate(108%);
  opacity: 1;
}
body.cinematic #category-rail,
body.cinematic #lens-trigger,
body.cinematic #help-btn,
body.cinematic #exit-earth,
body.cinematic #atlas-index-toggle {
  opacity: 0;
  pointer-events: none;
}
/* News mode (cinematic-now) is an immersive full-screen view too; it's
   translucent, so the browsing chrome behind it would show through. Hide the
   same elements as timeline mode, plus the dossier underneath. */
body.cinematic-now #category-rail,
body.cinematic-now #lens-trigger,
body.cinematic-now #help-btn,
body.cinematic-now #exit-earth,
body.cinematic-now #atlas-index-toggle,
body.cinematic-now #stories-panel,
body.cinematic-now #stories-backdrop {
  opacity: 0;
  pointer-events: none;
}
/* Phone: the dossier/cinematic dimmer was darkening the globe to near-black
   BEFORE the translucent panel even sampled it — so the "see-through" pages
   read as opaque. Make the dimmer barely there so the globe reaches the glass.
   (Must come after the body.cinematic rule above to win the same specificity.) */
body.is-phone #stories-backdrop {
  background: rgba(4, 6, 10, 0.12);
  backdrop-filter: blur(3px) saturate(115%);
  -webkit-backdrop-filter: blur(3px) saturate(115%);
}

/* --- Bottom timeline strip -------------------------------------------- */
#timeline-track {
  position: fixed;
  left: 50%;
  bottom: 32px;
  transform: translateX(-50%) translateY(20px);
  width: min(960px, 82vw);
  background: linear-gradient(
    180deg,
    rgba(10, 14, 24, 0.82) 0%,
    rgba(6, 10, 18, 0.88) 100%
  );
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 18px;
  padding: 14px 26px 16px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease, transform 0.4s ease;
  z-index: 95;
  user-select: none;
}
#timeline-track.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}
#timeline-track[hidden] { display: none; }

#timeline-track .tt-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
  gap: 12px;
}
#timeline-track .tt-subject-title {
  font-size: 9.5px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  /* Give way (ellipsis) rather than push the close button off the edge — long
     empire names (Holy Roman Empire, Kingdom of Kongo) were clipping it. */
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* History deck — previous + next timelines peek from behind the
   current timeline on each side. Designed to read as miniature
   timeline tracks: same glass background, same uppercase letter-
   spaced labels as the global era scrubber, and a faint horizontal
   track-line at the bottom that echoes both the country timeline's
   tt-axis and the era-scrubber's es-track. The peek is unmistakably
   a smaller version of the timeline-track itself. */
#timeline-track .tt-peek {
  position: absolute;
  top: 50%;
  width: 184px;
  padding: 12px 18px 14px;
  background: linear-gradient(
    180deg,
    rgba(10, 14, 24, 0.82) 0%,
    rgba(6, 10, 18, 0.88) 100%
  );
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 14px;
  color: rgba(228, 234, 244, 0.58);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  opacity: 0;
  pointer-events: auto;
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.36);
  z-index: -1;
  transition:
    opacity 0.5s cubic-bezier(.4,0,.2,1),
    transform 0.5s cubic-bezier(.4,0,.2,1),
    color 0.3s ease,
    border-color 0.3s ease;
}
/* A faint horizontal axis line at the bottom of each peek -- the same
   visual idiom as tt-axis on the main timeline and es-track on the
   global era scrubber. This makes the peek read unmistakably as a
   miniature timeline, not just an info card. */
#timeline-track .tt-peek::after {
  content: '';
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 10px;
  height: 1px;
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0.05) 0%,
    rgba(255, 255, 255, 0.20) 50%,
    rgba(255, 255, 255, 0.32) 100%
  );
  border-radius: 0.5px;
  pointer-events: none;
}
#timeline-track .tt-peek[hidden] { display: none; }
/* Peek positions: each peek sits with most of its body OUTSIDE the
   main track on its respective side. The portion that overlaps the
   track is hidden behind it (z-index: -1 + backdrop blur), so only
   the outer edge of the peek shows from the front. Hover gently
   pulls the peek further outward into clearer view -- a "come look
   at me" affordance without overrunning the main timeline. */
#timeline-track .tt-peek-prev {
  left: -148px;
  transform: translateY(-50%) translateX(0) scale(0.92);
}
#timeline-track .tt-peek-next {
  right: -148px;
  transform: translateY(-50%) translateX(0) scale(0.92);
}
#timeline-track .tt-peek.tt-peek-ready { opacity: 0.7; }
#timeline-track .tt-peek:hover {
  opacity: 1;
  color: #ffffff;
  border-color: rgba(248, 212, 140, 0.32);
}
#timeline-track .tt-peek-prev:hover {
  transform: translateY(-50%) translateX(-14px) scale(0.96);
}
#timeline-track .tt-peek-next:hover {
  transform: translateY(-50%) translateX(14px) scale(0.96);
}
/* Meta label — uppercase letter-spaced like the era-scrubber's
   active era label, so the two timeline views share the same
   typographic vocabulary. */
#timeline-track .tt-peek-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 8.5px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.42);
  margin-bottom: 8px;
}
#timeline-track .tt-peek-arrow {
  font-size: 11px;
  line-height: 1;
  color: rgba(255, 255, 255, 0.5);
}
#timeline-track .tt-peek-prev .tt-peek-meta { justify-content: flex-start; }
#timeline-track .tt-peek-next .tt-peek-meta { justify-content: flex-end; }
#timeline-track .tt-peek-name {
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.3;
  color: inherit;
  margin-bottom: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: 0.01em;
}
#timeline-track .tt-peek-next .tt-peek-name { text-align: right; }
#timeline-track .tt-peek-range {
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.36);
  font-variant-numeric: tabular-nums;
}
#timeline-track .tt-peek-next .tt-peek-range { text-align: right; }

/* Character-switch transition. A frozen clone of the current
   timeline is created on click and slides out toward the OPPOSITE
   peek slot (opposite of the click direction). Simultaneously the
   original timeline-track is rebuilt with the new era's content
   and slides IN from the click-direction peek slot to center.
   Both elements are visible at once during the cross, like two
   characters swapping seats. */

/* The clone is a visual twin of the live track during a deck step. It
   KEEPS id="timeline-track", so it inherits the full card look + all the
   id-scoped inner styling (title, axis, dots, leader bands) from the base
   #timeline-track rules -- here we only set the slide + layering. The
   #timeline-track.tt-clone specificity (1,1,0) overrides the base rules
   that now also match the clone. translateY(0) matches the live track's
   resting position so there is no vertical jump when the clone appears. */
#timeline-track.tt-clone {
  z-index: 19;            /* below the live (rebuilt) track at z-index 95 */
  pointer-events: none;
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  transition: transform 0.46s cubic-bezier(.5,.1,.5,1), opacity 0.46s ease-out;
}
/* The card slides horizontally at full size and style (no zoom/morph), so
   it reads as the SAME card moving aside. Inner data stays native-sized. */
#timeline-track.tt-clone.tt-clone-leaving-left {
  transform: translateX(-50%) translateY(0) translateX(-420px);
  opacity: 0;
}
#timeline-track.tt-clone.tt-clone-leaving-right {
  transform: translateX(-50%) translateY(0) translateX(420px);
  opacity: 0;
}

#timeline-track.tt-rotation-instant {
  transition: none !important;
}
#timeline-track.tt-arriving-from-left {
  transform: translateX(-50%) translateY(20px) translateX(-420px);
  opacity: 0;
}
#timeline-track.tt-arriving-from-right {
  transform: translateX(-50%) translateY(20px) translateX(420px);
  opacity: 0;
}

/* Freeze ALL inner-element transforms and transitions during the
   deck step. Without this, the first .tt-event dot gets the active
   class via _ttSetCursorByIndex and scales up to 2.2 with its own
   transition, while the user's mouse may also trigger a :hover
   scale on whichever dot it's near. Both look like "the dots are
   growing during rotation" -- the bug the user reported. By
   locking transform: none and transition: none on .tt-event
   throughout the cross, the dots stay at their native 4x4 px size
   during the motion and only adopt their hover/active states once
   the new track has settled at center. */
#timeline-track.tt-clone .tt-event,
#timeline-track.tt-arriving-from-left .tt-event,
#timeline-track.tt-arriving-from-right .tt-event {
  transform: none !important;
  transition: none !important;
  box-shadow: none !important;
}
/* Actions cluster — layers icon + close, grouped discreetly at the
   right of the meta row so the strip's only prominent text is the
   subject title on the left. */
#timeline-track .tt-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  margin-left: auto;
}
/* Reset-zoom button — hidden until the timeline is zoomed; fades in as a
   quiet icon so the full-range view stays uncluttered. */
#timeline-track .tt-zoom-reset {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  background: transparent;
  border: 1px solid transparent;
  color: rgba(255, 255, 255, 0.40);
  cursor: pointer;
  border-radius: 7px;
  padding: 0;
  opacity: 0;
  pointer-events: none;
  transform: scale(0.85);
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease,
              opacity 0.22s ease, transform 0.22s ease;
}
#timeline-track.tt-zoomed .tt-zoom-reset {
  opacity: 1;
  pointer-events: auto;
  transform: scale(1);
}
#timeline-track .tt-zoom-reset:hover {
  color: rgba(255, 255, 255, 0.90);
  border-color: rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.05);
}
/* Layers control — small icon button that opens a popover menu of
   analytical overlays. User checks one or more layers to reveal ribbons
   above the rail (leaders today; monetary, religion, people, tech to
   follow). Off by default so the timeline reads as one calm rail. */
#timeline-track .tt-layers-control {
  position: relative;
  display: flex;
}
#timeline-track .tt-layers-trigger {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  background: transparent;
  border: 1px solid transparent;
  color: rgba(255, 255, 255, 0.40);
  cursor: pointer;
  border-radius: 7px;
  padding: 0;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
#timeline-track .tt-layers-trigger:hover,
#timeline-track .tt-layers-trigger[aria-expanded="true"] {
  color: rgba(255, 255, 255, 0.90);
  border-color: rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.05);
}
/* Layers sheet: confluence-style panel that slides up from the bottom of
   the timeline area when the layers trigger is clicked. Each lane is one
   of the five civilizational axes plus Religion; lanes are stacked
   horizontally-laid rows. Visual language harmonizes with the confluence
   panel (gold kicker, serif title, dark gradient with backdrop-blur, thin
   inter-row dividers). The trigger button and the data-layer checkbox
   semantics are preserved so the existing JS toggle wiring still works. */
#timeline-track .tt-layers-menu {
  /* Anchored to the viewport (same as #timeline-track itself) so the
     sheet slides up from below and lands over the timeline rail. Using
     fixed instead of absolute avoids being trapped inside the tiny
     .tt-layers-control wrapper around the trigger button. Width and
     bottom match the timeline-track so the panel covers it cleanly. */
  position: fixed;
  bottom: 32px;
  left: 50%;
  transform: translateX(-50%) translateY(calc(100% + 32px));
  width: min(560px, 76vw);
  max-height: 62vh;
  z-index: 130;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.32s ease,
              transform 0.42s cubic-bezier(.22, .8, .25, 1);
}
#timeline-track .tt-layers-menu[hidden] { display: none; }
#timeline-track .tt-layers-menu.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}

#timeline-track .tt-layers-sheet {
  position: relative;
  display: flex;
  flex-direction: column;
  background: linear-gradient(
    180deg,
    rgba(4, 6, 12, 0.96) 0%,
    rgba(4, 6, 12, 0.94) 70%,
    rgba(4, 6, 12, 0.90) 100%
  );
  backdrop-filter: blur(14px) saturate(130%);
  -webkit-backdrop-filter: blur(14px) saturate(130%);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 16px 16px 4px 4px;
  box-shadow: 0 -22px 64px rgba(0, 0, 0, 0.65),
              0 0 0 1px rgba(255, 255, 255, 0.02) inset;
  overflow: hidden;
}

#timeline-track .tt-layers-head {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 14px 22px 11px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
#timeline-track .tt-layers-kicker {
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 9px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(248, 212, 140, 0.7);
  flex: 0 0 auto;
}
#timeline-track .tt-layers-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 15px;
  color: #f1f4fa;
  flex: 1 1 auto;
  line-height: 1.1;
}
#timeline-track .tt-layers-close {
  position: absolute;
  top: 12px;
  right: 14px;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.55);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  border-radius: 50%;
  padding: 0;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
#timeline-track .tt-layers-close:hover {
  color: #fff;
  border-color: rgba(255, 255, 255, 0.34);
  background: rgba(255, 255, 255, 0.06);
}

#timeline-track .tt-layers-lanes {
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
#timeline-track .tt-layers-lanes::-webkit-scrollbar { width: 6px; }
#timeline-track .tt-layers-lanes::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.16);
  border-radius: 3px;
}

#timeline-track .tt-layers-lane {
  display: grid;
  grid-template-columns: 40px 1fr auto;
  align-items: center;
  gap: 13px;
  padding: 10px 22px;
  cursor: pointer;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  transition: background 0.18s ease;
}
#timeline-track .tt-layers-lane:last-child { border-bottom: none; }
#timeline-track .tt-layers-lane:hover {
  background: rgba(255, 255, 255, 0.025);
}

#timeline-track .tt-layers-lane-glyph {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.02);
  color: rgba(248, 212, 140, 0.75);
  flex: 0 0 34px;
  transition: color 0.18s ease, border-color 0.18s ease;
}
#timeline-track .tt-layers-lane:hover .tt-layers-lane-glyph {
  color: rgba(248, 212, 140, 0.95);
  border-color: rgba(248, 212, 140, 0.30);
}

#timeline-track .tt-layers-lane-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
#timeline-track .tt-layers-lane-axis {
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 8.5px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(248, 212, 140, 0.65);
  line-height: 1;
}
#timeline-track .tt-layers-lane-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 13.5px;
  color: #f1f4fa;
  line-height: 1.2;
}
#timeline-track .tt-layers-lane-desc {
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 11px;
  line-height: 1.35;
  color: rgba(220, 226, 238, 0.52);
  margin-top: 1px;
  max-width: 360px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#timeline-track .tt-layers-lane-toggle {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  min-width: 60px;
  flex: 0 0 auto;
}
#timeline-track .tt-layers-lane-toggle input[type="checkbox"] {
  /* Native input hidden visually; styling lives on the track + knob span
     so the click target still works through the label association. */
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
#timeline-track .tt-layers-toggle-track {
  position: relative;
  display: inline-block;
  width: 40px;
  height: 22px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 999px;
  transition: background 0.22s ease, border-color 0.22s ease;
}
#timeline-track .tt-layers-toggle-knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  background: rgba(255, 255, 255, 0.55);
  border-radius: 50%;
  transition: transform 0.26s cubic-bezier(.4, 1.2, .55, 1), background 0.22s ease;
}
#timeline-track .tt-layers-lane input[type="checkbox"]:checked ~ .tt-layers-toggle-track {
  background: rgba(248, 212, 140, 0.55);
  border-color: rgba(248, 212, 140, 0.75);
}
#timeline-track .tt-layers-lane input[type="checkbox"]:checked ~ .tt-layers-toggle-track .tt-layers-toggle-knob {
  transform: translateX(18px);
  background: #f9efd6;
}
#timeline-track .tt-layers-lane:hover .tt-layers-toggle-track {
  border-color: rgba(255, 255, 255, 0.28);
}

#timeline-track .tt-layers-lane-tag {
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 8.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.42);
  border: 1px solid rgba(255, 255, 255, 0.12);
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.02);
}

#timeline-track .tt-layers-lane-soon {
  cursor: default;
}
#timeline-track .tt-layers-lane-soon .tt-layers-lane-title,
#timeline-track .tt-layers-lane-soon .tt-layers-lane-axis {
  color: rgba(255, 255, 255, 0.42);
}
#timeline-track .tt-layers-lane-soon .tt-layers-lane-glyph {
  color: rgba(255, 255, 255, 0.28);
}
#timeline-track .tt-layers-lane-soon:hover .tt-layers-lane-glyph {
  color: rgba(255, 255, 255, 0.40);
  border-color: rgba(255, 255, 255, 0.18);
}

/* Picker footer: shows the running selection count and the Compose CTA
   that commits the chosen lanes into the full-page Composer. */
#timeline-track .tt-layers-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 11px 22px 12px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  background: rgba(0, 0, 0, 0.22);
}
#timeline-track .tt-layers-foot-count {
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(220, 226, 238, 0.45);
}
#timeline-track .tt-layers-foot-n {
  color: rgba(248, 212, 140, 0.85);
  font-variant-numeric: tabular-nums;
}
#timeline-track .tt-layers-foot-compose {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid rgba(248, 212, 140, 0.5);
  background: rgba(248, 212, 140, 0.10);
  color: rgba(248, 212, 140, 0.92);
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}
#timeline-track .tt-layers-foot-compose:hover:not(:disabled) {
  background: rgba(248, 212, 140, 0.22);
  border-color: rgba(248, 212, 140, 0.78);
  transform: translateY(-1px);
}
#timeline-track .tt-layers-foot-compose:disabled {
  opacity: 0.32;
  cursor: not-allowed;
}

/* =====================================================================
   COMPOSER MODE — full-page canvas where the user stacks lanes (axes
   of the current country today; external timelines later) on a shared
   year axis to surface cross-civilization patterns. Mirrors confluence
   aesthetics so the two modes feel like one design family.
   ===================================================================== */
#layers-composer {
  position: fixed;
  inset: 0;
  /* Above the cinematic timeline-track (z 95) so cinematic overlays
     fading out during the suspend transition can't paint over the
     Composer's lane content. */
  z-index: 140;
  display: flex;
  background: linear-gradient(
    100deg,
    rgba(4, 6, 12, 0.97) 0%,
    rgba(4, 6, 12, 0.94) 45%,
    rgba(4, 6, 12, 0.78) 78%,
    rgba(4, 6, 12, 0.58) 100%
  );
  backdrop-filter: blur(6px) saturate(110%);
  -webkit-backdrop-filter: blur(6px) saturate(110%);
  opacity: 0;
  transition: opacity 0.42s ease;
  padding-top: 76px;
}
#layers-composer.visible { opacity: 1; }
#layers-composer[hidden] { display: none; }

#layers-composer .lc-head {
  position: absolute;
  top: 0; left: 0; right: 0;
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 26px 36px;
}
#layers-composer .lc-kicker {
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 9px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(248, 212, 140, 0.7);
  flex: 0 0 auto;
}
#layers-composer .lc-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 17px;
  color: #f1f4fa;
  flex: 1 1 auto;
}
#layers-composer .lc-close {
  position: absolute;
  top: 22px; right: 28px;
  width: 32px; height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid rgba(255,255,255,0.14);
  color: rgba(255,255,255,0.6);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  border-radius: 50%;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
#layers-composer .lc-close:hover {
  color: #fff;
  border-color: rgba(255,255,255,0.34);
  background: rgba(255,255,255,0.06);
}

#layers-composer .lc-stage {
  position: relative;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  margin: 8px 0 0;
  padding: 0 36px 0 56px;
  min-width: 0;
}
/* Touch: the JS pinch/pan/scroll handler owns every gesture inside the stage,
   so disable the browser's own panning/zooming here. The detail panel is a
   sibling of .lc-stage, so it keeps normal scrolling. */
body.is-touch #layers-composer .lc-stage,
body.is-touch #layers-composer .lc-stage * { touch-action: none; }

/* ---- Phone: the header crammed its title UNDER the absolutely-positioned
   actions, and the detail panel was transparent so the lanes/year-axis bled
   through it. ---- */
body.is-phone #layers-composer .lc-head { padding: 13px 14px; gap: 8px; align-items: center; }
body.is-phone #layers-composer .lc-kicker { display: none; }   /* redundant on phone */
body.is-phone #layers-composer .lc-title {
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding-right: 84px;            /* keep the title clear of the actions */
}
body.is-phone #layers-composer .lc-head-actions { top: 11px; right: 12px; gap: 6px; }
/* Phone: the gold pill became a loud gold circle next to the grey × — quiet it
   to a bordered circle that matches the close button, keeping only a soft-gold
   "+" glyph so "add a layer" still reads. */
body.is-phone #layers-composer .lc-add {
  width: 30px; height: 30px;
  padding: 0; gap: 0;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border-color: rgba(255, 255, 255, 0.14);
}
body.is-phone #layers-composer .lc-add:hover {
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(255, 255, 255, 0.30);
  transform: none;
}
body.is-phone #layers-composer .lc-add-plus { font-size: 17px; color: rgba(248, 212, 140, 0.9); }
body.is-phone #layers-composer .lc-add-label { display: none; }   /* icon-only "+" */

/* Per-thumbnail year labels smear into an unreadable cram when dozens of nodes
   stack on one lane. Drop them on phone — the bottom axis gives the time frame,
   and a tap opens the node's exact date. */
body.is-phone #layers-composer .lc-thumb-year { display: none; }

/* Detail: a full-width panel below the header. Translucent over the globe —
   the lanes behind it are hidden while it's open (see .lc-detail-open) so only
   the globe reads through, never the busy rails. */
body.is-phone #layers-composer .lc-detail {
  position: absolute;
  top: calc(50px + var(--safe-top));
  left: 0; right: 0; bottom: 0;
  flex: none; width: auto; max-width: none;
  padding: 14px 20px calc(20px + var(--safe-bottom));
  /* Same glass as the country dossier categories, so every translucent window
     shares one opacity (gradient rgba 0.24 → 0.31, 6px blur, text-shadow). */
  background: linear-gradient(180deg, rgba(13,16,26,0.31), rgba(7,9,15,0.40));
  backdrop-filter: blur(6px) saturate(130%);
  -webkit-backdrop-filter: blur(6px) saturate(130%);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.78);
  z-index: 20;
}
/* While a node detail is open on phone: hide the lanes behind the (now
   translucent) panel, and lighten the composer backdrop so the globe shows. */
body.is-phone #layers-composer.lc-detail-open .lc-stage { display: none; }
body.is-phone #layers-composer.lc-detail-open {
  background: linear-gradient(180deg, rgba(6, 8, 14, 0.34), rgba(4, 6, 12, 0.44));
}

/* Phone layout fixes. Two problems with few lanes: (1) the lanes pinned to the
   top under the header while the axis sat at the screen bottom, leaving a big
   dead gap ("did not cover full screen"); (2) the 52px-wide thumbnails at the
   year-range edges were clipped by the lanes' overflow ("timeline cut off").
   Fix 1: centre the lanes+axis as one block so the axis sits right under the
   lanes and the pair is vertically centred (lanes keep overflow-y for the JS
   scrollTop pan, just no longer stretch). Fix 2: inset BOTH the rails and the
   axis by ~half a thumbnail so the first/last node clears the clip — equal
   insets, so nodes stay aligned over their ticks. */
body.is-phone #layers-composer .lc-stage {
  padding: 0 14px;
  justify-content: center;
}
body.is-phone #layers-composer .lc-lanes {
  flex: 0 1 auto;
  padding: 24px 30px;
}
body.is-phone #layers-composer .lc-axis-rail {
  margin: 0 30px 16px;
}

#layers-composer .lc-lanes {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 24px 0;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
#layers-composer .lc-lanes::-webkit-scrollbar { width: 6px; }
#layers-composer .lc-lanes::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.16);
  border-radius: 3px;
}

#layers-composer .lc-lane {
  position: relative;
  min-height: 88px;
}
#layers-composer .lc-lane-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 14px;
  padding-right: 36px;
}
#layers-composer .lc-lane-axis {
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 9.5px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(248, 212, 140, 0.7);
}
#layers-composer .lc-lane-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 14px;
  color: #eef1f7;
}
#layers-composer .lc-lane-count {
  font-size: 10.5px;
  letter-spacing: 0.08em;
  color: rgba(200, 210, 226, 0.42);
  margin-left: auto;
  font-variant-numeric: tabular-nums;
}
#layers-composer .lc-lane-remove {
  position: absolute;
  top: 0;
  right: 0;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.10);
  color: rgba(255, 255, 255, 0.45);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  border-radius: 50%;
  padding: 0;
  transition: color 0.18s ease, border-color 0.18s ease;
}
#layers-composer .lc-lane-remove:hover {
  color: #fff;
  border-color: rgba(255,255,255,0.34);
}

#layers-composer .lc-lane-rail {
  position: relative;
  height: 36px;
  margin-bottom: 6px;
}
#layers-composer .lc-lane-rail::before {
  /* Thin horizontal line through the centre of the rail; nodes sit on it. */
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  background: linear-gradient(
    90deg,
    rgba(255,255,255,0.0) 0%,
    rgba(255,255,255,0.12) 8%,
    rgba(255,255,255,0.12) 92%,
    rgba(255,255,255,0.0) 100%
  );
}

/* Year-anchored leader nodes on the Power lane. Color comes from the
   same .leader-* party classes as the country-timeline ribbon so the
   visual language is consistent. */
#layers-composer .lc-node {
  position: absolute;
  top: 50%;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  cursor: pointer;
  border: 1.5px solid rgba(0, 0, 0, 0.55);
  background: rgba(180, 188, 204, 0.85);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.55);
  transition: transform 0.18s cubic-bezier(.2,.7,.2,1), box-shadow 0.18s ease, filter 0.18s ease;
  z-index: 2;
}
#layers-composer .lc-node:hover {
  transform: translate(-50%, -50%) scale(1.35);
  filter: brightness(1.15);
  box-shadow: 0 3px 12px rgba(248, 212, 140, 0.35);
  z-index: 4;
}
#layers-composer .lc-node.is-active {
  transform: translate(-50%, -50%) scale(1.55);
  box-shadow: 0 0 0 3px rgba(248, 212, 140, 0.55),
              0 4px 14px rgba(248, 212, 140, 0.45);
  z-index: 5;
}
/* Party-class colours: mirror the country-timeline ribbon. */
#layers-composer .lc-node.leader-dem      { background: rgba(75,140,225,0.92); }
#layers-composer .lc-node.leader-rep      { background: rgba(220,80,80,0.92); }
#layers-composer .lc-node.leader-left     { background: rgba(210,75,110,0.92); }
#layers-composer .lc-node.leader-right    { background: rgba(95,115,180,0.92); }
#layers-composer .lc-node.leader-lib      { background: rgba(245,180,70,0.92); }
#layers-composer .lc-node.leader-fed      { background: rgba(160,120,200,0.92); }
#layers-composer .lc-node.leader-mil      { background: rgba(125,125,90,0.92); }
#layers-composer .lc-node.leader-royal    { background: rgba(170,115,170,0.92); }
#layers-composer .lc-node.leader-nat      { background: rgba(110,135,110,0.92); }
#layers-composer .lc-node.leader-neutral  { background: rgba(150,158,170,0.85); }

/* =====================================================================
   AXIS LANE STYLES — Money / People / Progress / Planet / Religion
   ===================================================================== */

/* Regime bands (Money, Progress, Religion): horizontal segments that
   span a year range. Each axis gets its own warm-cool tint so users can
   tell lanes apart at a glance. */
#layers-composer .lc-band {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  height: 22px;
  border-radius: 4px;
  cursor: pointer;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.08);
  transition: filter 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
  z-index: 1;
  display: flex;
  align-items: center;
  padding: 0 6px;
  min-width: 4px;
}
#layers-composer .lc-band:hover {
  filter: brightness(1.18);
  border-color: rgba(248, 212, 140, 0.55);
  transform: translateY(-50%) translateY(-1px);
  z-index: 3;
}
#layers-composer .lc-band.is-active {
  box-shadow: 0 0 0 2px rgba(248, 212, 140, 0.55),
              0 4px 12px rgba(248, 212, 140, 0.30);
  border-color: rgba(248, 212, 140, 0.85);
  z-index: 5;
}
#layers-composer .lc-band-label {
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.88);
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}
/* Per-axis band tints. Money = warm green/gold; Progress = cool blue;
   Religion = muted purple. Faces the user as a category cue. */
#layers-composer .lc-band-monetary { background: linear-gradient(180deg, rgba(210, 160, 70, 0.55), rgba(160, 110, 50, 0.55)); }
#layers-composer .lc-band-tech     { background: linear-gradient(180deg, rgba(80, 140, 195, 0.55), rgba(50, 95, 150, 0.55)); }
#layers-composer .lc-band-religion { background: linear-gradient(180deg, rgba(155, 110, 180, 0.55), rgba(110, 75, 140, 0.55)); }

/* Event markers (diamond/circle) — used on all axes that have events.
   Per-axis baseline color + per-type accent for Planet & People. */
#layers-composer .lc-event {
  position: absolute;
  top: 50%;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  transform: translate(-50%, -50%) rotate(0deg);
  cursor: pointer;
  border: 1.5px solid rgba(0, 0, 0, 0.55);
  background: rgba(220, 220, 230, 0.85);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.55);
  transition: transform 0.18s cubic-bezier(.2,.7,.2,1), filter 0.18s ease;
  z-index: 4;
}
#layers-composer .lc-event:hover {
  transform: translate(-50%, -50%) scale(1.4);
  filter: brightness(1.15);
  z-index: 6;
}
#layers-composer .lc-event.is-active {
  transform: translate(-50%, -50%) scale(1.55);
  box-shadow: 0 0 0 3px rgba(248, 212, 140, 0.55),
              0 4px 14px rgba(248, 212, 140, 0.45);
  z-index: 7;
}
/* Money / Progress / Religion events: diamond shape via rotation. */
#layers-composer .lc-event-monetary,
#layers-composer .lc-event-tech,
#layers-composer .lc-event-religion {
  border-radius: 2px;
  transform: translate(-50%, -50%) rotate(45deg);
}
#layers-composer .lc-event-monetary:hover,
#layers-composer .lc-event-tech:hover,
#layers-composer .lc-event-religion:hover {
  transform: translate(-50%, -50%) rotate(45deg) scale(1.4);
}
#layers-composer .lc-event-monetary.is-active,
#layers-composer .lc-event-tech.is-active,
#layers-composer .lc-event-religion.is-active {
  transform: translate(-50%, -50%) rotate(45deg) scale(1.55);
}
#layers-composer .lc-event-monetary { background: rgba(245, 195, 90, 0.95); }
#layers-composer .lc-event-tech     { background: rgba(110, 175, 230, 0.95); }
#layers-composer .lc-event-religion { background: rgba(185, 135, 215, 0.95); }

/* Planet events by type. Earthquake/volcano = warm red, plague/epidemic
   = sickly green, famine/harvest = ochre, flood/climate = blue, heat
   = orange. */
#layers-composer .lc-event-planet                                          { background: rgba(210, 210, 220, 0.88); }
#layers-composer .lc-event-planet.lc-event-type-earthquake,
#layers-composer .lc-event-planet.lc-event-type-volcano                    { background: rgba(220, 90, 70, 0.95); }
#layers-composer .lc-event-planet.lc-event-type-plague,
#layers-composer .lc-event-planet.lc-event-type-epidemic,
#layers-composer .lc-event-planet.lc-event-type-pandemic                   { background: rgba(120, 165, 100, 0.95); }
#layers-composer .lc-event-planet.lc-event-type-famine,
#layers-composer .lc-event-planet.lc-event-type-harvest                    { background: rgba(195, 155, 80, 0.95); }
#layers-composer .lc-event-planet.lc-event-type-flood,
#layers-composer .lc-event-planet.lc-event-type-climate,
#layers-composer .lc-event-planet.lc-event-type-drought                    { background: rgba(110, 175, 215, 0.95); }
#layers-composer .lc-event-planet.lc-event-type-heat                       { background: rgba(235, 145, 80, 0.95); }

/* People events: muted teal default, per-type accents. */
#layers-composer .lc-event-demographic                                     { background: rgba(140, 200, 195, 0.92); }
#layers-composer .lc-event-demographic.lc-event-type-famine                { background: rgba(195, 155, 80, 0.95); }
#layers-composer .lc-event-demographic.lc-event-type-plague,
#layers-composer .lc-event-demographic.lc-event-type-epidemic              { background: rgba(120, 165, 100, 0.95); }
#layers-composer .lc-event-demographic.lc-event-type-war_loss              { background: rgba(180, 90, 90, 0.95); }
#layers-composer .lc-event-demographic.lc-event-type-migration             { background: rgba(130, 170, 220, 0.95); }
#layers-composer .lc-event-demographic.lc-event-type-boom                  { background: rgba(220, 200, 100, 0.95); }
#layers-composer .lc-event-demographic.lc-event-type-policy                { background: rgba(180, 165, 200, 0.92); }

/* People lane: SVG area chart sits behind the event dots and a thin
   line traces the population envelope on top. */
#layers-composer .lc-lane-people .lc-lane-rail { overflow: visible; }
/* Population bar chart: a band of value bars with a thin trend line and
   decluttered numeric labels. Replaces the old vague area curve. */
#layers-composer .lc-people-bars {
  position: absolute;
  left: 0; right: 0;
  top: 0; height: 56px;
  pointer-events: none;
  z-index: 1;
}
#layers-composer .lc-people-trend {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
}
#layers-composer .lc-people-line {
  fill: none;
  stroke: rgba(140, 200, 195, 0.55);
  stroke-width: 1.25;
  vector-effect: non-scaling-stroke;
}
#layers-composer .lc-people-bar {
  position: absolute;
  bottom: 0;
  width: 4px;
  transform: translateX(-50%);
  border-radius: 2px 2px 0 0;
  background: linear-gradient(180deg, rgba(150,210,205,0.85), rgba(110,170,165,0.35));
  pointer-events: auto;
}
#layers-composer .lc-people-vallabel {
  position: absolute;
  transform: translateX(-50%);
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 9px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: rgba(170, 215, 210, 0.85);
  text-shadow: 0 1px 3px rgba(0,0,0,0.8);
  white-space: nowrap;
  pointer-events: none;
}
#layers-composer .lc-people-vallabel.is-latest { color: rgba(190, 230, 225, 1); font-weight: 600; }
#layers-composer .lc-people-vallabel.is-peak { color: rgba(220, 200, 120, 0.95); font-weight: 600; }

/* Band+event lanes get a slightly taller rail to accommodate the bands
   plus the diamond markers above them. */
#layers-composer .lc-lane-bandevt .lc-lane-rail { height: 36px; }
#layers-composer .lc-lane-events .lc-lane-rail { height: 36px; }
/* People lane: 56 (chart) + 8 + 14 (religion strip) + 4 + 14 (ethnic strip) + dots overlay. */
#layers-composer .lc-lane-people .lc-lane-rail { height: 96px; position: relative; }

/* =====================================================================
   ANNOTATED THUMBNAIL EVENT MARKERS (US pilot)
   Framed images alternating above/below the centre rail line, each with
   a leader tick to its exact year and a year label. The image carries
   the at-a-glance meaning a colored dot cannot.
   ===================================================================== */
#layers-composer .lc-lane-thumbs { min-height: 176px; }
#layers-composer .lc-lane-thumbs .lc-lane-rail { height: 154px; overflow: visible; }
#layers-composer .lc-lane-thumbs .lc-lane-rail::after {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 1px;
  background: linear-gradient(90deg,
    rgba(255,255,255,0) 0%, rgba(255,255,255,0.14) 6%,
    rgba(255,255,255,0.14) 94%, rgba(255,255,255,0) 100%);
}
#layers-composer .lc-thumb {
  position: absolute;
  left: 0;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  cursor: pointer;
  z-index: 2;
  width: 52px;
}
#layers-composer .lc-thumb-below { top: 50%; flex-direction: column; }
#layers-composer .lc-thumb-above { bottom: 50%; flex-direction: column-reverse; }
#layers-composer .lc-thumb-tick {
  width: 1px; height: 12px;
  background: rgba(255, 255, 255, 0.28);
  flex: 0 0 auto;
}
#layers-composer .lc-thumb-frame {
  width: 46px; height: 46px;
  border-radius: 8px;
  overflow: hidden;
  border: 1.5px solid rgba(255, 255, 255, 0.20);
  background: rgba(255, 255, 255, 0.05);
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.5);
  flex: 0 0 auto;
  transition: transform 0.18s cubic-bezier(.2,.7,.2,1),
              border-color 0.18s ease, box-shadow 0.18s ease;
}
#layers-composer .lc-thumb-frame img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center top;
  display: block;
}
#layers-composer .lc-thumb-frame.is-empty {
  background: linear-gradient(135deg, rgba(255,255,255,0.08), rgba(255,255,255,0.02));
}
#layers-composer .lc-thumb-year {
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 9px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: rgba(220, 226, 238, 0.6);
  margin: 2px 0;
  flex: 0 0 auto;
  white-space: nowrap;
}
#layers-composer .lc-thumb:hover { z-index: 7; }
#layers-composer .lc-thumb:hover .lc-thumb-frame {
  transform: scale(1.32);
  border-color: rgba(248, 212, 140, 0.7);
  box-shadow: 0 6px 20px rgba(248, 212, 140, 0.4);
}
#layers-composer .lc-thumb:hover .lc-thumb-year { color: rgba(248, 212, 140, 0.95); }
#layers-composer .lc-thumb.is-active { z-index: 8; }
#layers-composer .lc-thumb.is-active .lc-thumb-frame {
  border-color: rgba(248, 212, 140, 0.95);
  box-shadow: 0 0 0 2px rgba(248, 212, 140, 0.6), 0 6px 18px rgba(248, 212, 140, 0.45);
}
/* Type accents on the thumbnail frame (Planet + People events). */
#layers-composer .lc-thumb.lc-event-type-earthquake .lc-thumb-frame,
#layers-composer .lc-thumb.lc-event-type-volcano .lc-thumb-frame { border-color: rgba(220,90,70,0.6); }
#layers-composer .lc-thumb.lc-event-type-plague .lc-thumb-frame,
#layers-composer .lc-thumb.lc-event-type-epidemic .lc-thumb-frame,
#layers-composer .lc-thumb.lc-event-type-pandemic .lc-thumb-frame { border-color: rgba(120,165,100,0.6); }
#layers-composer .lc-thumb.lc-event-type-famine .lc-thumb-frame,
#layers-composer .lc-thumb.lc-event-type-harvest .lc-thumb-frame { border-color: rgba(195,155,80,0.6); }
#layers-composer .lc-thumb.lc-event-type-flood .lc-thumb-frame,
#layers-composer .lc-thumb.lc-event-type-storm .lc-thumb-frame,
#layers-composer .lc-thumb.lc-event-type-climate .lc-thumb-frame { border-color: rgba(110,175,215,0.6); }
#layers-composer .lc-thumb.lc-event-type-heat .lc-thumb-frame,
#layers-composer .lc-thumb.lc-event-type-wildfire .lc-thumb-frame,
#layers-composer .lc-thumb.lc-event-type-drought .lc-thumb-frame { border-color: rgba(235,145,80,0.6); }

/* Power lane thumbnails: party-colored frame border so the red/blue
   pattern survives the switch from dots to portraits. */
#layers-composer .lc-thumb-leaders.leader-rep    .lc-thumb-frame { border-color: rgba(220,80,80,0.85); }
#layers-composer .lc-thumb-leaders.leader-dem    .lc-thumb-frame { border-color: rgba(75,140,225,0.85); }
#layers-composer .lc-thumb-leaders.leader-left   .lc-thumb-frame { border-color: rgba(210,75,110,0.85); }
#layers-composer .lc-thumb-leaders.leader-right  .lc-thumb-frame { border-color: rgba(95,115,180,0.85); }
#layers-composer .lc-thumb-leaders.leader-lib    .lc-thumb-frame { border-color: rgba(245,180,70,0.85); }
#layers-composer .lc-thumb-leaders.leader-fed    .lc-thumb-frame { border-color: rgba(160,120,200,0.85); }
#layers-composer .lc-thumb-leaders.leader-mil    .lc-thumb-frame { border-color: rgba(125,125,90,0.85); }
#layers-composer .lc-thumb-leaders.leader-royal  .lc-thumb-frame { border-color: rgba(170,115,170,0.85); }
#layers-composer .lc-thumb-leaders.leader-nat    .lc-thumb-frame { border-color: rgba(110,135,110,0.85); }
#layers-composer .lc-thumb-leaders.leader-neutral .lc-thumb-frame { border-color: rgba(150,158,170,0.7); }

/* ---- People lane, pilot layout: 3 clean horizontal zones ---------- */
/* Thumbnails on top (single row), population chart in the middle (with
   value labels), composition stripes at the bottom. Avoids the crowding
   of stacking everything on one centre line. */
#layers-composer .lc-lane-people-pilot .lc-lane-rail { height: 196px; overflow: visible; }
#layers-composer .lc-lane-people-pilot .lc-lane-rail::after { display: none; }
/* Pin every event thumbnail to the top band, growing downward (no
   alternation), so they never collide with the chart below. */
#layers-composer .lc-lane-people-pilot .lc-thumb,
#layers-composer .lc-lane-people-pilot .lc-thumb-above,
#layers-composer .lc-lane-people-pilot .lc-thumb-below {
  top: 2px; bottom: auto; flex-direction: column;
}
#layers-composer .lc-lane-people-pilot .lc-thumb-tick { display: none; }
/* Pilot zones: bars band in the middle, single composition stripe below. */
#layers-composer .lc-lane-people-pilot .lc-people-bars { top: 84px; height: 58px; }
#layers-composer .lc-lane-people-pilot .lc-people-composition { top: 152px; }

/* Composition stripe kicker (left label) + dominant-cohort inline label. */
#layers-composer .lc-comp-kicker {
  position: absolute;
  left: -50px;
  top: 50%;
  transform: translateY(-50%);
  width: 46px;
  text-align: right;
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 8.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(200, 210, 226, 0.5);
}
#layers-composer .lc-comp-strip { position: relative; }
#layers-composer .lc-comp-cell { position: relative; overflow: hidden; }
#layers-composer .lc-comp-cell-label {
  position: absolute;
  left: 4px;
  top: 50%;
  transform: translateY(-50%);
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 8.5px;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.8);
  text-shadow: 0 1px 2px rgba(0,0,0,0.7);
  white-space: nowrap;
  pointer-events: none;
}

/* Drag-pan cursor affordance (US pilot, when zoomed). */
#layers-composer.lc-pannable .lc-lanes { cursor: grab; }
#layers-composer.lc-panning .lc-lanes { cursor: grabbing; }
/* Non-pilot People dots sit over the bar band. */
#layers-composer .lc-lane-people .lc-event { top: 28px; }
#layers-composer .lc-lane-people .lc-people-composition {
  position: absolute;
  left: 0;
  right: 0;
  top: 58px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
#layers-composer .lc-comp-strip {
  position: relative;
  height: 12px;
  overflow: hidden;
  border-radius: 2px;
}
#layers-composer .lc-comp-strip::before {
  content: '';
  position: absolute;
  left: -52px;
  top: 50%;
  transform: translateY(-50%);
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 8px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(200, 210, 226, 0.5);
}
#layers-composer .lc-comp-religion::before  { content: 'Faith'; }
#layers-composer .lc-comp-ethnicity::before { content: 'Origin'; }
#layers-composer .lc-comp-period {
  position: absolute;
  top: 0;
  bottom: 0;
  display: flex;
  cursor: pointer;
  border-right: 1px solid rgba(0, 0, 0, 0.35);
  transition: filter 0.16s ease, transform 0.16s ease;
}
#layers-composer .lc-comp-period:hover {
  filter: brightness(1.18);
  transform: translateY(-1px);
}
#layers-composer .lc-comp-cell {
  height: 100%;
  transition: filter 0.16s ease;
}
/* Religion palette */
#layers-composer .lc-comp-cell-catholic            { background: rgba(180, 90, 100, 0.82); }
#layers-composer .lc-comp-cell-protestant          { background: rgba(110, 145, 200, 0.82); }
#layers-composer .lc-comp-cell-jewish              { background: rgba(195, 165, 90, 0.82); }
#layers-composer .lc-comp-cell-muslim              { background: rgba(120, 165, 120, 0.82); }
#layers-composer .lc-comp-cell-secular,
#layers-composer .lc-comp-cell-secular-none        { background: rgba(150, 158, 170, 0.7); }
#layers-composer .lc-comp-cell-pagan,
#layers-composer .lc-comp-cell-pagan-remnant       { background: rgba(105, 130, 80, 0.82); }
/* Ethnicity palette */
#layers-composer .lc-comp-cell-french-metropolitan { background: rgba(110, 145, 200, 0.82); }
#layers-composer .lc-comp-cell-european-immigrant  { background: rgba(155, 180, 215, 0.82); }
#layers-composer .lc-comp-cell-maghrebi            { background: rgba(220, 165, 90, 0.82); }
#layers-composer .lc-comp-cell-sub-saharan-african,
#layers-composer .lc-comp-cell-sub-saharan         { background: rgba(170, 110, 80, 0.82); }
#layers-composer .lc-comp-cell-asian               { background: rgba(210, 155, 105, 0.82); }
#layers-composer .lc-comp-cell-caribbean-overseas,
#layers-composer .lc-comp-cell-caribbean           { background: rgba(140, 175, 165, 0.82); }
/* Catch-all */
#layers-composer .lc-comp-cell-other               { background: rgba(150, 158, 170, 0.6); }

/* Year-axis rail at the bottom: shared X scale for all lanes. The
   draggable focus brush will live here in the next pass. */
#layers-composer .lc-axis-rail {
  position: relative;
  height: 44px;
  margin: 0 0 16px;
  flex: 0 0 auto;
}
#layers-composer .lc-axis-line {
  position: absolute;
  left: 0;
  right: 0;
  top: 12px;
  height: 1px;
  background: rgba(255,255,255,0.12);
}
#layers-composer .lc-axis-ticks {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 100%;
}
#layers-composer .lc-axis-tick {
  position: absolute;
  top: 8px;
  width: 1px;
  height: 8px;
  background: rgba(255,255,255,0.18);
  transform: translateX(-50%);
}
#layers-composer .lc-axis-tick-label {
  position: absolute;
  top: 22px;
  transform: translateX(-50%);
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  color: rgba(200, 210, 226, 0.48);
  white-space: nowrap;
}

/* Header action cluster: + Add layer, Reset zoom, and close × live here
   together so the bottom axis stays clean for year labels. */
#layers-composer .lc-head-actions {
  position: absolute;
  top: 20px;
  right: 28px;
  display: flex;
  align-items: center;
  gap: 10px;
}
#layers-composer .lc-add {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px 7px 10px;
  background: rgba(248, 212, 140, 0.08);
  border: 1px solid rgba(248, 212, 140, 0.42);
  color: rgba(248, 212, 140, 0.92);
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 10.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}
#layers-composer .lc-add:hover {
  background: rgba(248, 212, 140, 0.18);
  border-color: rgba(248, 212, 140, 0.72);
  transform: translateY(-1px);
}
#layers-composer .lc-add-plus {
  font-size: 16px;
  line-height: 1;
  color: rgba(248, 212, 140, 0.95);
}
#layers-composer .lc-reset-zoom {
  display: inline-flex;
  align-items: center;
  padding: 6px 14px;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: rgba(220, 228, 240, 0.65);
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.20em;
  text-transform: uppercase;
  border-radius: 999px;
  cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
#layers-composer .lc-reset-zoom:hover {
  color: #fff;
  border-color: rgba(255, 255, 255, 0.34);
  background: rgba(255, 255, 255, 0.05);
}
#layers-composer .lc-reset-zoom[hidden] { display: none; }

/* Override the original lc-close positioning since it is now inside
   the head-actions flex row (no longer absolute). */
#layers-composer .lc-head-actions .lc-close {
  position: static;
  top: auto;
  right: auto;
}

/* Right-side detail panel. Mirrors the confluence cf-conclusion area:
   gold kicker, serif name, light grey body for the snapshot prose. */
#layers-composer .lc-detail {
  flex: 0 0 360px;
  align-self: stretch;
  padding: 96px 32px 32px 24px;
  max-width: 380px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,0.22) transparent;
}
#layers-composer .lc-detail[hidden] { display: none; }
#layers-composer .lc-detail::-webkit-scrollbar { width: 6px; }
#layers-composer .lc-detail::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,0.18);
  border-radius: 3px;
}
#layers-composer .lc-detail-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 18px;
  padding: 4px 10px 4px 6px;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 14px;
  color: rgba(220, 228, 240, 0.7);
  font-family: inherit;
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
#layers-composer .lc-detail-back:hover {
  color: #fff;
  border-color: rgba(255,255,255,0.34);
  background: rgba(255,255,255,0.05);
}
#layers-composer .lc-detail-kicker {
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 9px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(248, 212, 140, 0.7);
  margin-bottom: 10px;
}
#layers-composer .lc-detail-name {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 22px;
  line-height: 1.22;
  color: #f5f7fb;
  margin-bottom: 6px;
  text-shadow: 0 2px 12px rgba(0,0,0,0.7);
}
#layers-composer .lc-detail-meta {
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: rgba(220, 228, 240, 0.55);
  margin-bottom: 14px;
}
#layers-composer .lc-detail-portrait {
  width: 100%;
  max-width: 220px;
  margin: 0 0 16px;
  border-radius: 10px;
  overflow: hidden;
  background: rgba(255,255,255,0.04);
}
#layers-composer .lc-detail-portrait img {
  width: 100%;
  height: auto;
  display: block;
  object-fit: cover;
  object-position: center top;
}
#layers-composer .lc-detail-body {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 13.5px;
  line-height: 1.66;
  color: rgba(228, 234, 244, 0.92);
  text-shadow: 0 1px 6px rgba(0,0,0,0.6);
}

/* Empty state in lanes panel when no lanes are present (unlikely
   given the Compose CTA requires a selection, but a friendly fallback). */
#layers-composer .lc-empty {
  padding: 60px 24px;
  text-align: center;
  color: rgba(220, 228, 240, 0.5);
  font-family: Georgia, "Times New Roman", serif;
  font-size: 15px;
}

/* Hover portrait card. Identical visual language to the country
   timeline's .tt-leader-portrait. The card pops ABOVE the hovered dot
   by default; when the dot sits near the top of the viewport (e.g.,
   the first lane stacked at the top of the Composer) and the card
   would clip off-screen, JS adds .lc-portrait-below and the card
   flips to appear BELOW the dot instead. */
#layers-composer .lc-portrait {
  position: absolute;
  bottom: calc(100% + 14px);
  left: 0;
  transform: translateX(-50%) translateY(8px) scale(0.96);
  width: 132px;
  padding: 8px 8px 10px;
  background: rgba(12, 16, 26, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 12px;
  box-shadow: 0 18px 46px rgba(0, 0, 0, 0.6);
  opacity: 0;
  pointer-events: none;
  z-index: 8;
  transition: opacity 0.18s ease,
              transform 0.22s cubic-bezier(.2, .7, .2, 1);
}
#layers-composer .lc-portrait.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0) scale(1);
}
#layers-composer .lc-portrait[hidden] { display: none; }
/* Downward beak (default: card is ABOVE the dot). */
#layers-composer .lc-portrait::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: rgba(12, 16, 26, 0.96);
}
/* Flipped variant: card sits BELOW the dot. Beak points up. */
#layers-composer .lc-portrait.lc-portrait-below {
  bottom: auto;
  top: calc(100% + 14px);
}
#layers-composer .lc-portrait.lc-portrait-below::after {
  top: auto;
  bottom: 100%;
  border-top-color: transparent;
  border-bottom-color: rgba(12, 16, 26, 0.96);
}
#layers-composer .lc-portrait-frame {
  width: 116px;
  height: 116px;
  border-radius: 9px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.04);
}
#layers-composer .lc-portrait-frame.is-empty {
  background: linear-gradient(135deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02));
}
#layers-composer .lc-portrait-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
}
#layers-composer .lc-portrait-name {
  margin-top: 7px;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 12px;
  line-height: 1.2;
  color: #f0f2f6;
  text-align: center;
}
#layers-composer .lc-portrait-meta {
  margin-top: 2px;
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 9px;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.45);
  text-align: center;
}
/* Optional summary line for event hover popovers (one-sentence gist
   under the meta line). Hidden when the popover renders a leader. */
#layers-composer .lc-portrait-summary {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  font-family: Georgia, "Times New Roman", serif;
  font-size: 11px;
  line-height: 1.4;
  color: rgba(220, 226, 238, 0.85);
  text-align: left;
}
#layers-composer .lc-portrait-summary:empty { display: none; }
#layers-composer .lc-portrait-body { min-width: 0; }
/* Event preview: a COMPACT horizontal card (small image + text) instead of
   the tall vertical leader portrait. Keeps the popover short so it doesn't
   cover the lanes stacked above/below on a middle lane like Money. */
#layers-composer .lc-portrait.lc-portrait-event {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  width: 250px;
  padding: 9px 11px 10px;
}
#layers-composer .lc-portrait.lc-portrait-event .lc-portrait-frame {
  width: 46px;
  height: 46px;
  border-radius: 7px;
  flex: 0 0 46px;
}
#layers-composer .lc-portrait.lc-portrait-event .lc-portrait-name {
  margin-top: 0;
  text-align: left;
  font-size: 12px;
  line-height: 1.25;
}
#layers-composer .lc-portrait.lc-portrait-event .lc-portrait-meta { text-align: left; }
#layers-composer .lc-portrait.lc-portrait-event .lc-portrait-summary {
  margin-top: 4px;
  padding-top: 4px;
  text-align: left;
  font-size: 10.5px;
  line-height: 1.35;
  /* Clamp to 2 lines so a long event summary can't balloon the card; the
     full text is available on click in the detail panel. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Text-only event card (no image): let the text use the full width. */
#layers-composer .lc-portrait.lc-portrait-event:has(.lc-portrait-frame[style*="display: none"]) {
  width: 232px;
}
/* Slightly wider card when a vertical (leader) card has no image. */
#layers-composer .lc-portrait:not(.lc-portrait-event):has(.lc-portrait-frame[style*="display: none"]) {
  width: 220px;
}
/* Matches the context card's .tc-close exactly so the two "exit timeline"
   buttons read as one consistent control (28px ring to fit the strip header,
   the card uses 30px). flex:0 0 auto keeps it from ever being squeezed. */
#timeline-track .tt-close {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.55);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  margin: 0;
  border-radius: 50%;
  font-family: inherit;
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}
#timeline-track .tt-close:hover {
  color: rgba(255, 255, 255, 0.95);
  border-color: rgba(255, 255, 255, 0.32);
  background: rgba(255, 255, 255, 0.05);
}

/* Leaders ribbon — sits ABOVE the rail and shares its time axis.
   Hidden by default; user reveals via the Leaders chip in .tt-meta.
   Designed thin so several layers (monetary, religion, etc.) can
   stack here without crowding the reading text. */
#timeline-track .tt-leaders {
  position: relative;
  margin: 0 10px 6px 10px;
}
#timeline-track .tt-leaders[hidden] { display: none; }

/* Leader portrait popover — hovering a president/king segment pops his
   portrait above the ribbon. Absolutely positioned within the track;
   left is set in JS to center over the hovered segment (clamped to the
   strip). Rises + fades in for a soft, premium reveal. */
#timeline-track .tt-leader-portrait {
  position: absolute;
  bottom: calc(100% + 14px);
  left: 0;
  transform: translateX(-50%) translateY(8px) scale(0.96);
  width: 132px;
  padding: 8px 8px 10px;
  background: rgba(12, 16, 26, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 12px;
  box-shadow: 0 18px 46px rgba(0, 0, 0, 0.6);
  opacity: 0;
  pointer-events: none;
  z-index: 120;
  transition: opacity 0.2s ease, transform 0.24s cubic-bezier(.2, .7, .2, 1);
}
#timeline-track .tt-leader-portrait.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0) scale(1);
}
#timeline-track .tt-leader-portrait[hidden] { display: none; }
/* A small downward beak anchoring the card to the segment below. */
#timeline-track .tt-leader-portrait::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: rgba(12, 16, 26, 0.96);
}
#timeline-track .tt-lp-frame {
  width: 116px;
  height: 116px;
  border-radius: 9px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.04);
}
#timeline-track .tt-lp-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
}
#timeline-track .tt-lp-name {
  margin-top: 7px;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 12px;
  line-height: 1.2;
  color: #f0f2f6;
  text-align: center;
}
#timeline-track .tt-lp-meta {
  margin-top: 2px;
  font-size: 9px;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.45);
  text-align: center;
}

#timeline-track .tt-leader-track {
  position: relative;
  height: 11px;
  background: rgba(255, 255, 255, 0.022);
  border-radius: 2px;
  overflow: hidden;
}
#timeline-track .tt-leader-seg {
  position: absolute;
  top: 0;
  height: 100%;
  overflow: hidden;
  border-right: 1px solid rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  padding: 0 4px;
  font-size: 9px;
  letter-spacing: 0.01em;
  color: rgba(255, 255, 255, 0.92);
  white-space: nowrap;
  /* Clickable — opens a floating biographical snapshot card on the
     timeline. Cursor signals affordance. */
  cursor: pointer;
  transition: filter 0.18s ease;
}
#timeline-track .tt-leader-seg:hover {
  filter: brightness(1.5);
  z-index: 3;
}
#timeline-track .tt-leader-name {
  text-overflow: ellipsis;
  overflow: hidden;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}
#timeline-track .tt-leader-seg.leader-dem      { background: rgba(60,120,205,0.55); }
#timeline-track .tt-leader-seg.leader-rep      { background: rgba(195,65,65,0.55); }
#timeline-track .tt-leader-seg.leader-left     { background: rgba(180,60,90,0.55); }
#timeline-track .tt-leader-seg.leader-right    { background: rgba(75,95,150,0.55); }
#timeline-track .tt-leader-seg.leader-lib      { background: rgba(220,160,55,0.55); }
#timeline-track .tt-leader-seg.leader-fed      { background: rgba(140,100,180,0.55); }
#timeline-track .tt-leader-seg.leader-mil      { background: rgba(105,105,75,0.6); }
#timeline-track .tt-leader-seg.leader-royal    { background: rgba(150,95,150,0.55); }
#timeline-track .tt-leader-seg.leader-nat      { background: rgba(90,115,90,0.55); }
#timeline-track .tt-leader-seg.leader-neutral  { background: rgba(120,128,140,0.50); }

/* Floating leader-snapshot card. Opened by clicking a segment on the
   .tt-leaders ribbon. Multiple cards can stack — each new one offsets
   up + right from the previous via --stack, so the reader can compare
   two or more leaders side by side. The card matches the leader-portrait
   popover's dark/glass aesthetic but is large enough to host the full
   ~230-word biographical paragraph. */
#timeline-track .tt-snapcard {
  position: absolute;
  bottom: 160px;
  left: 50%;
  transform: translateX(-50%) translateY(10px) scale(0.97);
  width: 380px;
  max-height: 56vh;
  display: flex;
  flex-direction: column;
  padding: 0;
  background: rgba(10, 14, 22, 0.97);
  border: 1px solid rgba(255, 255, 255, 0.11);
  border-radius: 14px;
  box-shadow: 0 22px 64px rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  opacity: 0;
  pointer-events: auto;
  z-index: calc(140 + var(--stack, 0));
  transition: opacity 0.26s ease,
              transform 0.32s cubic-bezier(.2, .7, .2, 1);
}
#timeline-track .tt-snapcard.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0) scale(1);
}
#timeline-track .tt-snapcard.tt-snapcard-top {
  z-index: calc(180 + var(--stack, 0));
}
#timeline-track .tt-snapcard-close {
  position: absolute;
  top: 6px;
  right: 8px;
  width: 26px;
  height: 26px;
  border: none;
  background: transparent;
  color: rgba(255, 255, 255, 0.55);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  border-radius: 6px;
  z-index: 2;
  transition: background 0.15s ease, color 0.15s ease;
}
#timeline-track .tt-snapcard-close:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}
#timeline-track .tt-snapcard-head {
  display: flex;
  gap: 12px;
  padding: 14px 16px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  align-items: flex-start;
}
/* Gold "watch his story" button on a leader card (only when a video exists). */
#timeline-track .tt-snapcard-video {
  flex: 0 0 auto;
  align-self: center;
  margin-left: auto;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid rgba(248, 212, 140, 0.55);
  background: rgba(248, 212, 140, 0.14);
  color: rgba(248, 212, 140, 0.95);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding-left: 2px; /* optically center the play glyph */
  transition: background 0.15s ease, transform 0.15s ease;
}
#timeline-track .tt-snapcard-video:hover {
  background: rgba(248, 212, 140, 0.26);
  transform: scale(1.06);
}

/* Leader video window: floats on the LEFT of the cinematic stage, mirroring
   the event diaporama on the right. */
.tt-leader-vidwin {
  position: fixed;
  left: 48px;
  top: 6vh;
  width: clamp(340px, 38vw, 760px);
  z-index: 95;
  opacity: 0;
  transform: translateX(-14px);
  transition: opacity 0.35s ease, transform 0.35s ease;
}
.tt-leader-vidwin.visible { opacity: 1; transform: translateX(0); }
.tt-leader-vidwin .tt-lvw-frame {
  position: relative;
  background: linear-gradient(180deg, rgba(10,14,24,0.85) 0%, rgba(6,10,18,0.9) 100%);
  border: 1px solid rgba(255,255,255,0.09);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 28px 70px rgba(0,0,0,0.5);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
}
.tt-leader-vidwin .tt-lvw-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
}
.tt-leader-vidwin .tt-lvw-stage iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
.tt-leader-vidwin .tt-lvw-cap {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 9px 14px 11px;
}
.tt-leader-vidwin .tt-lvw-name {
  font-size: 13px;
  letter-spacing: 0.02em;
  color: rgba(255,255,255,0.92);
}
.tt-leader-vidwin .tt-lvw-sub {
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.5);
}
.tt-leader-vidwin .tt-lvw-close {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.2);
  background: rgba(10,14,24,0.6);
  color: rgba(255,255,255,0.85);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}
.tt-leader-vidwin .tt-lvw-close:hover { background: rgba(255,255,255,0.14); }
#timeline-track .tt-snapcard-portrait {
  flex: 0 0 64px;
  width: 64px;
  height: 64px;
  border-radius: 8px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.04);
}
#timeline-track .tt-snapcard-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
}
#timeline-track .tt-snapcard-portrait-empty {
  background: linear-gradient(135deg, rgba(255,255,255,0.06),
                                       rgba(255,255,255,0.02));
}
#timeline-track .tt-snapcard-id {
  flex: 1 1 auto;
  min-width: 0;
  padding-right: 26px; /* clear the close button */
}
#timeline-track .tt-snapcard-name {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 16px;
  line-height: 1.2;
  color: #f4f5f8;
  font-weight: 600;
}
#timeline-track .tt-snapcard-office {
  margin-top: 4px;
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 10px;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.55);
  text-transform: uppercase;
}
#timeline-track .tt-snapcard-meta {
  margin-top: 6px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 11px;
  color: rgba(255, 255, 255, 0.48);
}
#timeline-track .tt-snapcard-life { color: rgba(255, 255, 255, 0.35); }
#timeline-track .tt-snapcard-body {
  padding: 12px 16px 16px;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 13.5px;
  line-height: 1.62;
  color: rgba(240, 242, 246, 0.92);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,0.25) transparent;
}
#timeline-track .tt-snapcard-body::-webkit-scrollbar { width: 6px; }
#timeline-track .tt-snapcard-body::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,0.18);
  border-radius: 3px;
}

/* Rail — kept compact so the cinematic strip stays slim and several
   layers can stack above it (leaders, monetary, etc.) without
   intruding on the body text. */
#timeline-track .tt-rail {
  position: relative;
  height: 22px;
  padding: 0 10px;
}
/* Wheel-zooms the timeline; grab cursor hints draggable pan when zoomed. */
#timeline-track.tt-zoomed .tt-rail { cursor: grab; }
#timeline-track .tt-rail.tt-panning { cursor: grabbing; }
/* Smooth eased re-layout for zoom reset and cursor-recenter (transient
   class; live zoom/pan stay instant for responsiveness). */
#timeline-track .tt-rail.tt-animate-layout .tt-event,
#timeline-track .tt-rail.tt-animate-layout .tt-cursor {
  transition: left 0.34s cubic-bezier(.4, 0, .2, 1);
}
/* Events scrolled outside the zoom window fade out but stay in the DOM. */
#timeline-track .tt-event.tt-offview {
  opacity: 0;
  pointer-events: none;
}
/* Invisible larger hit/hover target around each 4px dot so the title
   tooltip is easy to summon. Clicks anywhere on the rail already snap to
   the nearest event, so this is purely for hover comfort. */
#timeline-track .tt-event::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 16px;
  height: 18px;
  transform: translate(-50%, -50%);
}
/* When zoomed, label each visible dot with its year (set via
   data-show-year in _ttLayout) so the reader sees which dates are on
   screen. Sits just below the dot; hidden at full view. */
#timeline-track .tt-event[data-show-year]::after {
  content: attr(data-show-year);
  position: absolute;
  top: calc(50% + 8px);
  left: 50%;
  transform: translateX(-50%);
  font-size: 8px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.42);
  white-space: nowrap;
  pointer-events: none;
}
/* The active dot's year label reads a touch brighter. */
#timeline-track .tt-event.active[data-show-year]::after {
  color: rgba(255, 255, 255, 0.7);
}
#timeline-track .tt-axis {
  position: absolute;
  left: 10px;
  right: 10px;
  top: 50%;
  height: 1px;
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0.06) 0%,
    rgba(255, 255, 255, 0.18) 50%,
    rgba(255, 255, 255, 0.30) 100%
  );
  border-radius: 0.5px;
  transform: translateY(-0.5px);
}
#timeline-track .tt-events {
  position: absolute;
  left: 10px;
  right: 10px;
  top: 0;
  bottom: 0;
}
#timeline-track .tt-event {
  position: absolute;
  top: 50%;
  width: 4px;
  height: 4px;
  margin: -2px 0 0 -2px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.45);
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: background 0.22s ease, transform 0.22s ease, box-shadow 0.22s ease;
}
#timeline-track .tt-event:hover {
  background: rgba(255, 255, 255, 0.95);
  transform: scale(1.8);
}
#timeline-track .tt-event.active {
  background: #f59e0b;
  transform: scale(2.2);
  box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.20),
              0 0 8px rgba(245, 158, 11, 0.55);
}

/* Cursor: thin vertical line spanning the rail, with a year bubble
   floating above. Mirrors the era scrubber so both scrubbers share a
   single visual language. The year is read from data-year via attr(). */
#timeline-track .tt-cursor {
  /* The vertical white line is gone; the active event dot is enough of
     a position cue. The cursor element stays as the anchor for the year
     bubble (::before) and arrow (::after), and as the drag target. */
  position: absolute;
  top: 8px;
  bottom: 8px;
  width: 24px;
  margin-left: -12px;
  background: transparent;
  box-shadow: none;
  border-radius: 0;
  border: none;
  cursor: grab;
  z-index: 2;
  transition: left 0.32s cubic-bezier(.4, 0, .2, 1);
}
#timeline-track .tt-cursor.dragging {
  cursor: grabbing;
  transition: none;
}
#timeline-track .tt-cursor:focus-visible {
  outline: none;
  box-shadow: none;
}
#timeline-track .tt-cursor:focus-visible::before {
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45),
              0 0 0 2px rgba(255, 255, 255, 0.65),
              0 0 12px rgba(255, 255, 255, 0.45);
}
#timeline-track .tt-cursor::before {
  content: attr(data-year);
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-bottom: 7px;
  padding: 3px 8px;
  /* Discreet dark-glass chip matching the rest of the UI, instead of the
     loud white box. Muted but legible. */
  background: rgba(12, 16, 26, 0.85);
  color: rgba(255, 255, 255, 0.72);
  font-size: 10px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 5px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.40);
  white-space: nowrap;
  /* Grabbable: pointer events on the pseudo route to the host .tt-cursor,
     so clicking the year chip starts the same drag as the dot. */
  pointer-events: auto;
  cursor: grab;
}
#timeline-track .tt-cursor::after {
  content: '';
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-bottom: 3px;
  border: 4px solid transparent;
  border-top-color: rgba(12, 16, 26, 0.85);
  pointer-events: auto;
  cursor: grab;
}
#timeline-track .tt-cursor.dragging::before,
#timeline-track .tt-cursor.dragging::after { cursor: grabbing; }

/* Year-range subtitle sits next to the subject title in .tt-meta. The
   rail itself is unlabelled — the cursor's own year bubble owns the
   current position; this gives the reader the temporal frame at a
   glance without putting labels on the rail. */
#timeline-track .tt-subject {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex: 0 1 auto;       /* shrinkable so the title can ellipsize, not clip the × */
  min-width: 0;
}
#timeline-track .tt-subject-range {
  font-size: 9px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.18em;
  color: rgba(255, 255, 255, 0.32);
  text-transform: none;
  flex: 0 0 auto;       /* the year range stays whole; the title ellipsizes first */
  white-space: nowrap;
}
#timeline-track .tt-subject-range:empty { display: none; }
/* Phone: drop the redundant " · timeline" word — the strip already IS the
   timeline, and a narrow header has no room for it. */
body.is-phone #timeline-track .tt-kicker-sep { display: none; }
/* Phone: the desktop's airy 0.32em tracking wastes width on a narrow header and
   forced empire names to truncate ("HOLY ROMAN EM…"); tighten it so full names
   fit. */
body.is-phone #timeline-track .tt-subject-title { letter-spacing: 0.16em; font-size: 9px; }
body.is-phone #timeline-track .tt-subject-range { letter-spacing: 0.12em; }

/* --- Context card (left side) ----------------------------------------- */
/* Anchored to the top, not centered, so it can never grow down into the
   timeline strip below. The strip + its layered ribbons occupy the
   lower ~22vh; the card's max-height is capped to leave that clear. */
#timeline-context {
  position: fixed;
  left: 48px;
  top: 9vh;
  transform: translateX(-14px);
  width: min(780px, 52vw);
  max-height: calc(100vh - 9vh - 22vh);
  background: linear-gradient(
    180deg,
    rgba(10, 14, 24, 0.82) 0%,
    rgba(6, 10, 18, 0.88) 100%
  );
  backdrop-filter: blur(22px) saturate(140%);
  -webkit-backdrop-filter: blur(22px) saturate(140%);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 18px;
  padding: 40px 44px 36px;
  box-shadow: 0 28px 70px rgba(0, 0, 0, 0.5);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease, transform 0.4s ease;
  z-index: 94;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
#timeline-context.visible {
  opacity: 1;
  transform: translateX(0);
  pointer-events: auto;
}
#timeline-context[hidden] { display: none; }
/* Text-only moment (no photo or video): let the reading card fill the space the
   diaporama would have taken, instead of leaving the frame empty. */
body.cinematic-text-only #timeline-context {
  width: min(900px, 68vw);
  max-height: calc(100vh - 9vh - 14vh);
}
#timeline-context::-webkit-scrollbar { width: 6px; }
#timeline-context::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.14);
  border-radius: 3px;
}

/* Position indicator floating in the top-right of the card ("4 / 12"),
   driven by data-position set in _ttSetCursorByIndex. */
#timeline-context[data-position]:not([data-position=""])::before {
  content: attr(data-position);
  position: absolute;
  top: 36px;
  right: 60px;
  font-size: 10.5px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.42);
  pointer-events: none;
}

/* Close button — top-right of the context card. Mirrors the timeline-
   track close so users can exit cinematic mode from either surface. */
#timeline-context .tc-close {
  position: absolute;
  top: 26px;
  right: 26px;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.55);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  border-radius: 50%;
  font-family: inherit;
  padding: 0;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
  z-index: 2;
}
#timeline-context .tc-close:hover {
  color: rgba(255, 255, 255, 0.95);
  border-color: rgba(255, 255, 255, 0.32);
  background: rgba(255, 255, 255, 0.05);
}

/* Header: kicker "Arc event" sits above the year, year is large and
   anchors the card, then a thin divider before the title. */
#timeline-context .tc-year {
  position: relative;
  font-size: 30px;
  font-weight: 300;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  color: #fafafa;
  margin-bottom: 0;
  padding: 14px 0 18px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  line-height: 1;
}
#timeline-context .tc-year::before {
  content: 'Arc event';
  display: block;
  margin-bottom: 8px;
  font-size: 9.5px;
  font-weight: normal;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.42);
}
#timeline-context .tc-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 30px;
  line-height: 1.16;
  letter-spacing: -0.005em;
  color: #f3f5f9;
  margin: 22px 0 18px;
}
#timeline-context .tc-summary {
  font-size: 15px;
  line-height: 1.62;
  color: #c8cfdb;
  margin-bottom: 18px;
}
#timeline-context .tc-image {
  position: relative;
  width: 100%;
  height: 380px;
  /* Subtle dark backdrop shows through as letterbox for portrait photos
     while staying invisible for landscape ones that fill the frame. */
  background-color: rgba(0, 0, 0, 0.55);
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.06);
  margin: 18px 0 20px 0;
  overflow: hidden;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
}
#timeline-context .tc-image .tc-image-el {
  display: block;
  width: 100%;
  height: 100%;
  /* contain (not cover) — never crop the photo. Portraits letterbox on
     the sides; landscapes letterbox top/bottom; faces stay visible. */
  object-fit: contain;
  object-position: center;
  transition: opacity 0.45s ease;
}
#timeline-context .tc-image .tc-image-el[src=""],
#timeline-context .tc-image .tc-image-el:not([src]) {
  opacity: 0;
}
#timeline-context .tc-image[hidden] { display: none; }
/* Slide indicator dots, bottom-center of the image area. */
#timeline-context .tc-dots {
  position: absolute;
  left: 50%;
  bottom: 10px;
  transform: translateX(-50%);
  display: flex;
  gap: 6px;
  background: rgba(0,0,0,0.45);
  padding: 5px 10px;
  border-radius: 999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
#timeline-context .tc-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255,255,255,0.35);
  transition: background 0.18s ease, transform 0.18s ease;
}
#timeline-context .tc-dot.active {
  background: #ffffff;
  transform: scale(1.25);
}
/* Slideshow content section: holds image + dots. */
#timeline-context .tc-content {
  /* Long-form narrative paragraphs land in here below summary. */
  font-size: 14.5px;
  line-height: 1.68;
  color: #c0c8d4;
  margin-bottom: 14px;
}
#timeline-context .tc-content p {
  margin: 0 0 12px 0;
}
#timeline-context .tc-content p:last-child { margin-bottom: 0; }


/* --- Tighter layout on narrow screens --------------------------------- */
@media (max-width: 720px) {
  #timeline-context {
    width: 78vw;
    left: 11vw;
    top: auto;
    bottom: 200px;
    transform: translateY(0);
    max-height: 36vh;
  }
  #timeline-context.visible { transform: translateY(0); }
  #timeline-track { width: 92vw; bottom: 14px; }
}


/* Timeline trigger: feedback when clicked with no eligible subject. */
@keyframes traj-trigger-miss {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-2px); }
  40% { transform: translateX(3px); }
  60% { transform: translateX(-2px); }
  80% { transform: translateX(2px); }
}
#timeline-trigger.miss {
  animation: traj-trigger-miss 0.42s ease-in-out;
  border-color: rgba(220, 80, 80, 0.55);
  color: #d66;
}


/* Context-card content swap transition.
   When _ttApplyEntry runs, it adds .tc-swapping for 180ms, swaps text,
   removes the class. The opacity transition produces a soft fade. */
#timeline-context .tc-year,
#timeline-context .tc-title,
#timeline-context .tc-summary,
#timeline-context .tc-content,
#timeline-context .tc-image {
  transition: opacity 0.22s ease;
}
#timeline-context.tc-swapping .tc-year,
#timeline-context.tc-swapping .tc-title,
#timeline-context.tc-swapping .tc-summary,
#timeline-context.tc-swapping .tc-content,
#timeline-context.tc-swapping .tc-image {
  opacity: 0;
}


/* Shift the entire WebGL canvas right in cinematic mode so the globe sits
   off-center and the left side of the screen frees up for the context
   card. Smooth transition both directions. */
canvas {
  transition: transform 0.55s cubic-bezier(.4, 0, .2, 1);
}
/* Dossier open: panel sits on the right, so shift the globe LEFT to give
   it visual breathing room. */
body.dossier-open canvas {
  transform: translateX(-11vw);
}
/* Cinematic mode: card sits on the left, so shift the globe RIGHT.
   This rule is intentionally below body.dossier-open: when both classes
   are present (cinematic always keeps the dossier visible underneath),
   the cinematic shift wins. */
body.cinematic canvas {
  transform: translateX(13vw);
}


/* =====================================================================
   COMING-SOON DOSSIER
   Used for any region/category combo (continent, country, state) that
   hasn't been authored yet. Replaces the legacy banner-on-top-of-world-
   baseline pattern with a calm, minimal frame so the 3D globe stays the
   dominant visual. Voice is intentional, not apologetic.
   ===================================================================== */
#stories-panel.atlas .sp-coming-soon-page {
  display: flex;
  flex-direction: column;
  gap: 22px;
}
#stories-panel.atlas .sp-cs-frame {
  position: relative;
  margin-top: 6px;
  padding: 44px 30px 36px;
  border-radius: 14px;
  border: 1px solid rgba(255,255,255,0.08);
  background:
    radial-gradient(ellipse at 50% -10%, rgba(168,194,235,0.10), rgba(168,194,235,0) 60%),
    linear-gradient(180deg, rgba(255,255,255,0.035), rgba(255,255,255,0.012));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.06), 0 12px 36px rgba(0,0,0,0.32);
  text-align: center;
  overflow: hidden;
}
#stories-panel.atlas .sp-cs-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 100%, rgba(168,194,235,0.05), rgba(168,194,235,0) 55%);
  pointer-events: none;
}
#stories-panel.atlas .sp-cs-rule {
  width: 36px;
  height: 1px;
  margin: 0 auto 22px;
  background: linear-gradient(90deg, rgba(168,194,235,0) 0%, rgba(168,194,235,0.55) 50%, rgba(168,194,235,0) 100%);
}
#stories-panel.atlas .sp-cs-kicker {
  font-size: 9.5px;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: rgba(210,222,240,0.74);
  margin-bottom: 14px;
}
#stories-panel.atlas .sp-cs-headline {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 28px;
  line-height: 1.16;
  letter-spacing: 0.005em;
  color: #f3f5f9;
  margin-bottom: 14px;
  text-shadow: 0 1px 14px rgba(0,0,0,0.55);
}
/* The region's one-glance orienting line, shown even while the tailored
   page is "coming soon" so a country always places itself in the common
   story. Warm serif italic = the soul of the place, distinct from the
   secondary "being authored" note below. */
#stories-panel.atlas .sp-cs-tagline {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 15px;
  font-style: italic;
  line-height: 1.5;
  color: rgba(248, 212, 140, 0.92);
  max-width: 480px;
  margin: 0 auto 16px;
}
/* Story tether — quiet 'Part of the story' link back to the causal thread a
   node belongs to. Styled to recede: a subtle guide, never a banner. */
#stories-panel.atlas .sp-story-tether {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin: 14px 0 2px;
}
#stories-panel.atlas .sp-story-tether .sp-tether-label {
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.32);
}
#stories-panel.atlas .sp-story-tether .sp-tether-link {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 13.5px;
  font-style: italic;
  line-height: 1.3;
  color: rgba(248, 212, 140, 0.82);
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  transition: color 0.18s ease;
}
#stories-panel.atlas .sp-story-tether .sp-tether-link:hover {
  color: rgba(248, 212, 140, 1);
}
#stories-panel.atlas .sp-story-tether .sp-tether-arrow {
  font-style: normal;
  font-size: 12px;
  opacity: 0.65;
  transition: transform 0.18s ease;
}
#stories-panel.atlas .sp-story-tether .sp-tether-link:hover .sp-tether-arrow {
  transform: translateX(2px);
}
/* On the centred coming-soon dossier, centre the tether too. */
#stories-panel.atlas .sp-coming-soon-page .sp-story-tether {
  justify-content: center;
  margin: 2px auto 16px;
}
#stories-panel.atlas .sp-cs-note {
  font-size: 12.5px;
  line-height: 1.65;
  color: rgba(218,225,236,0.78);
  max-width: 460px;
  margin: 0 auto 28px;
}
#stories-panel.atlas .sp-cs-meta {
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 22px;
  padding-top: 18px;
  border-top: 1px solid rgba(255,255,255,0.06);
  width: 100%;
  max-width: 460px;
  margin: 0 auto;
}
#stories-panel.atlas .sp-cs-meta-row {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  font-size: 11px;
  line-height: 1.4;
}
#stories-panel.atlas .sp-cs-meta-row .l {
  color: rgba(168,180,200,0.62);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-size: 9.5px;
}
#stories-panel.atlas .sp-cs-meta-row .v {
  color: #e6ecf6;
  font-weight: 500;
}
@media (max-width: 760px) {
  #stories-panel.atlas .sp-cs-frame { padding: 36px 22px 30px; }
  #stories-panel.atlas .sp-cs-headline { font-size: 24px; }
}


/* =====================================================================
   HINT — mode tag row at the top of the help overlay
   ===================================================================== */
#hint .panel .hint-mode-row {
  grid-column: 1 / -1;
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding-bottom: 12px;
  margin-bottom: 4px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
#hint .panel .hint-mode-tag {
  font-size: 9.5px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: #f4e9c4;
  background: rgba(244, 233, 196, 0.10);
  border: 1px solid rgba(244, 233, 196, 0.22);
  border-radius: 999px;
  padding: 4px 10px;
}
#hint .panel .hint-mode-note {
  font-size: 11px;
  color: rgba(218,225,236,0.74);
  line-height: 1.45;
  flex: 1 1 auto;
}


/* =====================================================================
   PLANET INFO — civilization note (non-Earth bodies)
   Sits between the physical-rows block and the editorial quote, in the
   info panel's lower-left placement. Same font scale as the quote but
   not italic, slightly warmer color so it reads as a state note rather
   than as commentary.
   ===================================================================== */
#info .civilization-note {
  margin-top: 18px;
  padding: 12px 12px;
  font-size: 10.5px;
  line-height: 1.55;
  letter-spacing: 0.02em;
  color: #b8c2d6;
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 4px;
}


/* =====================================================================
   DOSSIER CATEGORY SWITCHER — minimalistic right-edge dot column.
   Five dots, one per category. Click a dot to switch the dossier to
   that category with a smooth fade. Hover shows the category label.
   Lives as a child of #stories-panel, position-absolute on its right
   edge so it floats just outside the dossier scroll area.
   ===================================================================== */
#stories-panel .sp-cat-switch {
  position: absolute;
  /* 14px from the panel right edge — past the 7px webkit scrollbar with
   * a comfortable gap, while still tucked tight against the panel. */
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 0;
  /* No backdrop/border — the dots float on the panel's own glass surface.
   * Cleaner, thinner, and removes the visual conflict with the scrollbar. */
  background: transparent;
  border: 0;
  z-index: 7;
  /* Container is click-through; only the .sp-cs-dot hit-areas capture
   * events. Otherwise the wide (150px) dot boxes would stretch the
   * container leftward over the dossier text and swallow clicks/selection
   * meant for the content beneath them. */
  pointer-events: none;
}
#stories-panel .sp-cat-switch .sp-cs-dot { pointer-events: auto; }
#stories-panel .sp-cs-dot {
  position: relative;
  /* The VISIBLE dot stays tiny and discreet, but the clickable/hoverable
     hit-area is much wider so the dot is easy to reach without pixel-
     hunting. This rail hugs the panel's RIGHT edge and its name pill slides
     out to the LEFT, so the wide box extends leftward and the dot is pinned
     to the box's right edge (rendered by ::before). */
  width: 150px;
  height: 14px;
  border: 0;
  background: transparent;
  padding: 0;
  margin: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
#stories-panel .sp-cs-dot::before {
  content: '';
  /* Pin the small dot to the right of the wide hit-area, at the same x it
     occupied when the box was 12px wide (≈ 3.5px from the right edge so the
     5px dot's center sits ~6px in from the right). */
  margin-right: 3px;
  flex: 0 0 auto;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: rgba(255,255,255,0.32);
  transition: background 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
#stories-panel .sp-cs-dot:hover::before,
#stories-panel .sp-cs-dot:focus-visible::before {
  background: rgba(255,255,255,0.78);
  transform: scale(1.5);
  box-shadow: 0 0 6px rgba(255,255,255,0.36);
}
#stories-panel .sp-cs-dot.active::before {
  background: #ffffff;
  transform: scale(1.6);
  box-shadow: 0 0 9px rgba(255,255,255,0.55);
}
#stories-panel .sp-cs-dot:focus-visible { outline: none; }
/* Tooltip showing the category name on hover, slid out to the LEFT
 * so it stays inside the dossier panel rather than disappearing
 * off the screen edge. */
#stories-panel .sp-cs-tip {
  position: absolute;
  right: 18px;
  top: 50%;
  transform: translateY(-50%) translateX(4px);
  white-space: nowrap;
  padding: 3px 8px;
  font-size: 8.5px;
  letter-spacing: 0.30em;
  text-transform: uppercase;
  color: #f1f4fa;
  background: rgba(15, 18, 26, 0.92);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 4px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
#stories-panel .sp-cs-dot:hover .sp-cs-tip,
#stories-panel .sp-cs-dot:focus-visible .sp-cs-tip {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}
/* --- Touch: the dossier category switcher becomes a horizontal tab bar below
   the header. The desktop vertical hover-dots would overlap the prose once
   labels must be shown permanently (no hover on touch), so on touch we lay the
   categories out as scrollable pill tabs instead. Desktop keeps the discreet
   vertical hover-reveal. Applies to phone AND tablet (both are is-touch). --- */
body.is-touch #stories-panel .sp-cat-switch {
  position: static;
  order: 1;                       /* sequence: header, [tabs], scroll area */
  flex: 0 0 auto;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  gap: 6px;
  transform: none;
  right: auto; top: auto;
  padding: 9px 16px 10px;
  background: #0a0d15;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  overflow-x: auto;
  scrollbar-width: none;
  pointer-events: auto;
  z-index: 5;
}
body.is-touch #stories-panel .sp-cat-switch::-webkit-scrollbar { display: none; }
body.is-touch #stories-panel.atlas .sp-dossier { order: 2; }
body.is-touch #stories-panel .sp-cs-dot {
  width: auto; height: auto;
  flex: 0 0 auto;
  justify-content: center;
  padding: 7px 13px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
}
body.is-touch #stories-panel .sp-cs-dot::before { display: none; }  /* drop the dot glyph */
body.is-touch #stories-panel .sp-cs-tip {
  position: static;
  opacity: 1;
  transform: none;
  background: none;
  border: 0;
  padding: 0;
  color: #9aa6b8;
}
body.is-touch #stories-panel .sp-cs-dot.active { background: rgba(255, 255, 255, 0.13); }
body.is-touch #stories-panel .sp-cs-dot.active .sp-cs-tip { color: #fff; }

/* Smooth fade applied during a category switch. The opacity is set
 * imperatively in JS; this rule just defines the easing curve so the
 * transition feels coordinated with the dot's own scale animation. */
#stories-panel .sp-dossier { transition: opacity 0.20s ease; }


/* =====================================================================
   ATLAS INDEX — content-map navigation menu.
   Three-bar hamburger button below the date/time at top-left, opens a
   slide-out panel listing every authored region and subject.
   ===================================================================== */
#atlas-index-toggle {
  position: fixed;
  top: 58px;
  left: 30px;
  width: 26px;
  height: 22px;
  padding: 4px 4px;
  background: transparent;
  border: 0;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  z-index: 60;
  transition: opacity 0.2s ease;
}
#atlas-index-toggle .bar {
  display: block;
  width: 18px;
  height: 1.5px;
  background: rgba(218, 226, 240, 0.55);
  border-radius: 1px;
  transform-origin: center;
  transition: transform 0.32s cubic-bezier(.6,.1,.2,1),
              opacity 0.22s ease,
              background 0.18s ease;
}
#atlas-index-toggle:hover .bar,
#atlas-index-toggle:focus-visible .bar { background: #ffffff; }
#atlas-index-toggle:focus-visible { outline: none; }
/* Hamburger -> X transformation when the panel is open. The 6.5px y-shift
 * matches the top/bottom bar's distance from center given the toggle's
 * 14px content height. */
#atlas-index-toggle.open .bar:nth-child(1) {
  transform: translateY(6.5px) rotate(45deg);
}
#atlas-index-toggle.open .bar:nth-child(2) {
  opacity: 0;
  transform: scaleX(0);
}
#atlas-index-toggle.open .bar:nth-child(3) {
  transform: translateY(-6.5px) rotate(-45deg);
}

/* Backdrop scrim — click anywhere outside the panel to close. */
#atlas-index-scrim {
  position: fixed;
  inset: 0;
  /* Light touch: just enough tint to lift the panel off the globe and to
     catch a click-anywhere-to-close, without dimming the world heavily. */
  background: rgba(2, 4, 9, 0.18);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.32s ease;
  z-index: 49;
}
#atlas-index-scrim.visible {
  opacity: 1;
  pointer-events: auto;
}

/* The panel itself. Slides in from left edge, glassy. */
#atlas-index {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: min(340px, 86vw);
  background: rgba(8, 10, 16, 0.82);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  border-right: 1px solid rgba(255,255,255,0.06);
  box-shadow: 24px 0 60px rgba(0,0,0,0.55);
  z-index: 55;
  overflow-y: auto;
  transform: translateX(-104%);
  opacity: 0;
  transition: transform 0.36s cubic-bezier(.18,.7,.22,1),
              opacity 0.28s ease;
  padding: 88px 28px 36px;
  color: #c8c8c8;
  user-select: none;
}
#atlas-index.visible {
  transform: translateX(0);
  opacity: 1;
}
#atlas-index::-webkit-scrollbar { width: 7px; }
#atlas-index::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,0.10);
  border-radius: 999px;
}

/* Header */
#atlas-index .ai-head {
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: none;
  color: rgba(170,180,200,0.62);
  padding-bottom: 14px;
  margin-bottom: 16px;
  border-bottom: 1px solid rgba(255,255,255,0.05);
}

/* ============================================================
 * EXPLORE LAUNCHER — four plain rows, one per section, in editorial reading
 * order: Where are we heading? · How we got here · Confluences · Atlas. No
 * boxes, no colour — just the name + a quiet count, dim at rest, warming to
 * gold on hover. Simple and classy, the way the menu started.
 * ============================================================ */
#atlas-index .ai-bars { display: flex; flex-direction: column; }
#atlas-index .ai-bar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  width: 100%;
  text-align: left;
  padding: 13px 2px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(255,255,255,0.05);
  color: rgba(206, 215, 230, 0.82);
  font-family: inherit;
  cursor: pointer;
  transition: color 0.15s ease, transform 0.18s ease;
}
#atlas-index .ai-bar:last-child { border-bottom: 0; }
#atlas-index .ai-bar:hover,
#atlas-index .ai-bar:focus-visible {
  color: #f3dca8;
  transform: translateX(3px);
  outline: none;
}
#atlas-index .ai-bar-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 15px;
  line-height: 1.25;
  letter-spacing: 0.01em;
  color: inherit;
}
#atlas-index .ai-bar-count {
  align-self: center;
  font-size: 9px;
  letter-spacing: 0.16em;
  color: rgba(170, 180, 200, 0.4);
  font-variant-numeric: tabular-nums;
}

/* ---- Explore-page item rows: the per-item entries on the How we got here /
   Confluences pages. Same plain idiom as the launcher — name only, dim to gold
   on hover, a hairline between rows. No boxes, no colour. ---- */
#stories-panel.atlas .sp-ex-pills {
  display: flex;
  flex-direction: column;
  margin-top: 6px;
}
#stories-panel.atlas .sp-ex-pill {
  display: block;
  width: 100%;
  text-align: left;
  padding: 13px 2px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(255,255,255,0.05);
  color: rgba(206, 215, 230, 0.82);
  font-family: inherit;
  cursor: pointer;
  transition: color 0.15s ease, transform 0.18s ease;
}
#stories-panel.atlas .sp-ex-pill:last-child { border-bottom: 0; }
#stories-panel.atlas .sp-ex-pill:hover,
#stories-panel.atlas .sp-ex-pill:focus-visible {
  color: #f3dca8;
  transform: translateX(3px);
  outline: none;
}
#stories-panel.atlas .sp-ex-pill-name {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 15px;
  line-height: 1.3;
  letter-spacing: 0.01em;
  color: inherit;
}
#stories-panel.atlas .sp-ex-pill-confluence .sp-ex-pill-name {
  font-style: italic;
  font-size: 14px;
}

/* Clickable breadcrumb segments (Explore / How we got here / Confluences):
   dim, warming to gold on hover — the same idiom as the rows. */
#stories-panel .sp-breadcrumb .sp-crumb-nav { cursor: pointer; transition: color 0.15s ease; }
#stories-panel .sp-breadcrumb .sp-crumb-nav:hover,
#stories-panel .sp-breadcrumb .sp-crumb-nav:focus-visible { color: #f3dca8; outline: none; }

/* ============================================================
 * EXPLORE CATEGORY PAGES — comprehensive pages opened from the tiles,
 * rendered into #stories-panel. Shared layout primitives + per-page tweaks.
 * ============================================================ */
/* Explore pages render their own hero, so the generic sp-head reads as
   redundant chrome; collapse it to just the floating × control. The page
   below then becomes the only title source. */
#stories-panel.sp-explore .sp-head {
  border-bottom: none;
  padding-top: 0;
  padding-bottom: 0;
  min-height: 0;
}
#stories-panel.sp-explore .sp-head .sp-cat,
#stories-panel.sp-explore .sp-head .sp-title { display: none; }
#stories-panel.sp-explore .sp-head { justify-content: flex-end; padding: 10px 14px 0; }

#stories-panel.atlas .sp-explore-page { padding-top: 6px; }
#stories-panel.atlas .sp-explore-hero { margin-bottom: 22px; }

/* Lens chips reused inside the explore pages — same five-lens palette as
   the drawer rules, scoped to the panel so they apply outside #atlas-index. */
#stories-panel .ai-force-lenses { display: inline-flex; flex-wrap: wrap; gap: 5px; }
#stories-panel .ai-force-lens {
  display: inline-block;
  font-size: 8.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.09);
  color: rgba(228, 234, 244, 0.75);
}
#stories-panel .ai-force-lens-power    { background: rgba(232, 168, 96, 0.10);  border-color: rgba(232, 168, 96, 0.32);  color: rgba(248, 200, 140, 0.92); }
#stories-panel .ai-force-lens-money    { background: rgba(120, 200, 160, 0.09); border-color: rgba(120, 200, 160, 0.30); color: rgba(150, 220, 180, 0.92); }
#stories-panel .ai-force-lens-people   { background: rgba(180, 156, 232, 0.10); border-color: rgba(180, 156, 232, 0.32); color: rgba(206, 188, 246, 0.92); }
#stories-panel .ai-force-lens-planet   { background: rgba(120, 180, 232, 0.10); border-color: rgba(120, 180, 232, 0.30); color: rgba(160, 210, 244, 0.92); }
#stories-panel .ai-force-lens-progress { background: rgba(232, 144, 168, 0.10); border-color: rgba(232, 144, 168, 0.32); color: rgba(244, 184, 200, 0.92); }
#stories-panel .ai-force-updated {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.42);
}
#stories-panel .ai-force-pulse {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: rgba(248, 212, 140, 0.92);
  box-shadow: 0 0 6px rgba(248, 212, 140, 0.6);
  animation: ai-force-pulse 2.4s ease-in-out infinite;
}
#stories-panel.atlas .sp-ex-subhead {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 26px 0 12px;
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif;
  font-size: 15px;
  letter-spacing: 0.01em;
  text-transform: none;
  color: rgba(255,255,255,0.7);
}
#stories-panel.atlas .sp-ex-subhead-count {
  font-family: inherit;
  font-size: 10px;
  letter-spacing: 0.18em;
  color: rgba(255,255,255,0.36);
}
/* Atlas category filter bar: tap a chip to show only that category. */
#stories-panel .sp-atlas-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 6px 0 20px;
}
body.is-phone #stories-panel .sp-atlas-filters {
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  margin-bottom: 14px;
  padding-bottom: 2px;
}
body.is-phone #stories-panel .sp-atlas-filters::-webkit-scrollbar { display: none; }
#stories-panel .sp-atlas-chip {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 6px 13px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,0.12);
  background: rgba(255,255,255,0.03);
  color: rgba(206,215,230,0.78);
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif;
  font-size: 12.5px;
  letter-spacing: 0.01em;
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
#stories-panel .sp-atlas-chip:hover,
#stories-panel .sp-atlas-chip:focus-visible {
  color: #f3dca8;
  border-color: rgba(248,212,140,0.4);
  outline: none;
}
#stories-panel .sp-atlas-chip.active {
  color: #f3dca8;
  border-color: rgba(248,212,140,0.55);
  background: rgba(248,212,140,0.1);
}
#stories-panel .sp-atlas-chip-count {
  font-size: 10px;
  opacity: 0.5;
  font-variant-numeric: tabular-nums;
}

/* ===== "Where are we heading?" — the tracking board ===== */
/* Forces page: intro + one button into the board. */
#stories-panel .sp-forces-enter { margin-top: 22px; }
#stories-panel .tb-enter {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 12px 22px; border-radius: 999px;
  border: 1px solid rgba(248,212,140,0.4); background: rgba(248,212,140,0.08);
  color: #f3dca8; cursor: pointer;
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif;
  font-size: 15px; letter-spacing: 0.01em;
  transition: background 0.18s ease, border-color 0.18s ease;
}
#stories-panel .tb-enter:hover, #stories-panel .tb-enter:focus-visible {
  background: rgba(248,212,140,0.16); border-color: rgba(248,212,140,0.65); outline: none;
}
#stories-panel .tb-enter-arrow { font-size: 16px; }
#stories-panel .sp-forces-enter-note {
  margin-top: 12px; font-size: 12.5px; color: rgba(206,215,230,0.5);
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif;
}

/* Board head */
#stories-panel .sp-trends-board .tb-head { margin: 4px 0 14px; }
#stories-panel .sp-trends-board .tb-kicker {
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif;
  font-size: 22px; color: #ece7da; margin-bottom: 6px;
}
#stories-panel .sp-trends-board .tb-note {
  font-size: 12.5px; line-height: 1.5; color: rgba(206,215,230,0.55); max-width: 560px;
}

/* Board body — lanes on a shared year axis, horizontally scrollable */
#stories-panel .sp-trends-board .tb-board {
  position: relative; margin-top: 10px;
  overflow-x: auto; overflow-y: visible; -webkit-overflow-scrolling: touch;
}
body.is-phone #stories-panel .sp-trends-board .tb-board::-webkit-scrollbar { display: none; }
#stories-panel .sp-trends-board .tb-board-inner { position: relative; }
#stories-panel .sp-trends-board .tb-ruler { display: flex; align-items: center; height: 16px; margin: 0 0 4px; }
#stories-panel .sp-trends-board .tb-tick {
  position: absolute; top: 0; transform: translateX(-50%);
  font-size: 10px; color: rgba(255,255,255,0.32);
  font-variant-numeric: tabular-nums; letter-spacing: 0.04em;
}
#stories-panel .sp-trends-board .tb-lane {
  display: flex; align-items: center;
  height: 62px; border-bottom: 1px solid rgba(255,255,255,0.045);
}
/* The lane name and the ruler's left gutter both pin to the left edge while the
   time axis scrolls under them, so timelines stay labelled and aligned. */
#stories-panel .sp-trends-board .tb-lane-label,
#stories-panel .sp-trends-board .tb-lane-gut {
  flex: 0 0 108px; width: 108px; align-self: stretch;
  position: sticky; left: 0; z-index: 3;
  background: none;   /* sits on the panel like the rest of the page, no block */
}
#stories-panel .sp-trends-board .tb-lane-label {
  display: flex; align-items: center; text-align: left; padding: 0 12px 0 0;
  border: none; color: #e3e0d7; cursor: pointer;
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif;
  font-size: 13px; line-height: 1.25; transition: color 0.16s ease;
}
body.is-phone #stories-panel .sp-trends-board .tb-lane-label,
body.is-phone #stories-panel .sp-trends-board .tb-lane-gut { flex-basis: 88px; width: 88px; }
body.is-phone #stories-panel .sp-trends-board .tb-lane-label { font-size: 12px; }
#stories-panel .sp-trends-board .tb-lane-label:hover,
#stories-panel .sp-trends-board .tb-lane-label:focus-visible { color: #f3dca8; outline: none; }
#stories-panel .sp-trends-board .tb-lane-label-soon { color: rgba(255,255,255,0.32); cursor: default; }
#stories-panel .sp-trends-board .tb-soon {
  font-size: 8.5px; letter-spacing: 0.16em; text-transform: uppercase; color: rgba(255,255,255,0.28);
}
#stories-panel .sp-trends-board .tb-track { position: relative; flex: 1 1 auto; height: 100%; min-width: 0; }
#stories-panel .sp-trends-board .tb-baseline {
  position: absolute; top: 50%; left: 0; right: 0; height: 1px; background: rgba(255,255,255,0.10);
}
#stories-panel .sp-trends-board .tb-track-soon .tb-baseline {
  background: none; border-top: 1px dashed rgba(255,255,255,0.07);
}
#stories-panel .sp-trends-board .tb-dot {
  position: absolute; top: 50%; transform: translate(-50%,-50%);
  width: 34px; height: 34px; border-radius: 50%; padding: 0;
  border: 1px solid rgba(248,212,140,0.45); background: rgba(248,212,140,0.12);
  background-size: cover; background-position: center;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  box-shadow: 0 0 0 3px rgba(5,7,12,0.85);   /* dark halo so close dots stay legible */
  transition: transform 0.16s ease, border-color 0.16s ease;
}
body.is-phone #stories-panel .sp-trends-board .tb-dot { width: 30px; height: 30px; }
#stories-panel .sp-trends-board .tb-dot:hover,
#stories-panel .sp-trends-board .tb-dot:focus-visible {
  transform: translate(-50%,-50%) scale(1.14); border-color: #f3dca8; z-index: 4; outline: none;
}
#stories-panel .sp-trends-board .tb-dot-img { border-color: rgba(248,212,140,0.7); }
#stories-panel .sp-trends-board .tb-dot-yr { font-size: 10px; color: #f3dca8; font-variant-numeric: tabular-nums; }

/* Event window popover */
#tb-pop {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none; transition: opacity 0.2s ease;
}
#tb-pop.visible { opacity: 1; pointer-events: auto; }
#tb-pop .tb-pop-backdrop {
  position: absolute; inset: 0; background: rgba(3,5,9,0.62);
  -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px);
}
#tb-pop .tb-pop-card {
  position: relative; width: calc(100% - 40px); max-width: 520px; max-height: 82vh; overflow: auto;
  padding: 26px 26px 22px; background: rgba(10,13,20,0.97);
  border: 1px solid rgba(248,212,140,0.18); border-radius: 14px;
  box-shadow: 0 24px 60px rgba(0,0,0,0.5);
  transform: translateY(8px); transition: transform 0.2s ease;
}
#tb-pop.visible .tb-pop-card { transform: translateY(0); }
#tb-pop .tb-pop-close {
  position: absolute; top: 12px; right: 14px; width: 30px; height: 30px;
  background: none; border: none; color: rgba(255,255,255,0.5); font-size: 24px; line-height: 1; cursor: pointer;
}
#tb-pop .tb-pop-close:hover { color: #f3dca8; }
#tb-pop .tb-pop-kicker {
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: rgba(248,212,140,0.7); margin-bottom: 8px;
}
#tb-pop .tb-pop-year {
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif;
  font-size: 13px; color: rgba(206,215,230,0.6); font-variant-numeric: tabular-nums;
}
#tb-pop .tb-pop-title {
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif;
  font-size: 21px; line-height: 1.25; color: #ece7da; margin: 2px 0 14px;
}
#tb-pop .tb-pop-media { margin: 0 0 14px; border-radius: 10px; overflow: hidden; }
#tb-pop .tb-pop-media iframe { width: 100%; aspect-ratio: 16 / 9; border: 0; display: block; }
#tb-pop .tb-pop-media-img img { width: 100%; display: block; }
#tb-pop .tb-pop-summary {
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif;
  font-size: 15px; line-height: 1.6; color: #d8d4ca;
}
#tb-pop .tb-pop-content { margin-top: 12px; }
#tb-pop .tb-pop-content p {
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif;
  font-size: 14px; line-height: 1.65; color: rgba(216,212,202,0.85); margin: 0 0 10px;
}
#tb-pop .tb-pop-open {
  margin-top: 8px; display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 18px; border-radius: 999px;
  border: 1px solid rgba(248,212,140,0.4); background: rgba(248,212,140,0.08); color: #f3dca8;
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif; font-size: 13.5px; cursor: pointer;
  transition: background 0.16s ease;
}
#tb-pop .tb-pop-open:hover { background: rgba(248,212,140,0.16); }
#stories-panel.atlas .sp-ex-grid {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
#stories-panel.atlas .sp-ex-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px 18px 14px;
  text-align: left;
  background: linear-gradient(180deg, rgba(20,24,36,0.50), rgba(11,14,22,0.62));
  border: 1px solid rgba(255,255,255,0.07);
  border-radius: 12px;
  color: inherit;
  font-family: inherit;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}
#stories-panel.atlas .sp-ex-card:hover,
#stories-panel.atlas .sp-ex-card:focus-visible {
  background: linear-gradient(180deg, rgba(28,32,46,0.58), rgba(15,18,28,0.7));
  border-color: rgba(248,212,140,0.22);
}
#stories-panel.atlas .sp-ex-card:active { transform: scale(0.99); }
#stories-panel.atlas .sp-ex-card-title {
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif;
  font-size: 17px;
  line-height: 1.22;
  color: #f1ece1;
  font-weight: 500;
}
#stories-panel.atlas .sp-ex-card-stake {
  font-size: 12.5px;
  line-height: 1.5;
  color: rgba(208, 218, 234, 0.74);
  font-style: italic;
}
#stories-panel.atlas .sp-ex-card-intro {
  font-size: 12px;
  line-height: 1.55;
  color: rgba(200, 210, 226, 0.74);
}
#stories-panel.atlas .sp-ex-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 2px;
}
#stories-panel.atlas .sp-ex-card-status {
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.4);
}
/* Force-card extras: latest event row, primary-lens accent. */
#stories-panel.atlas .sp-ex-card-force::before {
  content: '';
  position: absolute;
  left: 0; top: 14px; bottom: 14px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: rgba(255,255,255,0.18);
}
#stories-panel.atlas .sp-ex-card-lens-power::before    { background: linear-gradient(180deg, rgba(232,168,96,0.9), rgba(232,168,96,0.18)); }
#stories-panel.atlas .sp-ex-card-lens-money::before    { background: linear-gradient(180deg, rgba(120,200,160,0.9), rgba(120,200,160,0.18)); }
#stories-panel.atlas .sp-ex-card-lens-people::before   { background: linear-gradient(180deg, rgba(180,156,232,0.9), rgba(180,156,232,0.18)); }
#stories-panel.atlas .sp-ex-card-lens-planet::before   { background: linear-gradient(180deg, rgba(120,180,232,0.9), rgba(120,180,232,0.18)); }
#stories-panel.atlas .sp-ex-card-lens-progress::before { background: linear-gradient(180deg, rgba(232,144,168,0.9), rgba(232,144,168,0.18)); }
#stories-panel.atlas .sp-ex-card-latest {
  display: flex;
  align-items: baseline;
  gap: 9px;
  padding: 7px 10px;
  border-radius: 7px;
  background: rgba(255,255,255,0.025);
  border-left: 2px solid rgba(248,212,140,0.32);
  margin-top: 2px;
}
#stories-panel.atlas .sp-ex-card-latest-label {
  font-size: 8.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.42);
}
#stories-panel.atlas .sp-ex-card-latest-year {
  font-size: 11px;
  letter-spacing: 0.08em;
  color: rgba(255,255,255,0.62);
}
#stories-panel.atlas .sp-ex-card-latest-title {
  flex: 1;
  font-size: 12.5px;
  line-height: 1.4;
  color: rgba(241, 236, 225, 0.92);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Thread cards: stacked question + title in a tighter grid. */
#stories-panel.atlas .sp-ex-thread-grid {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
#stories-panel.atlas .sp-ex-card-thread {
  padding: 13px 16px;
  gap: 4px;
}
#stories-panel.atlas .sp-ex-card-thread-q {
  font-size: 11.5px;
  letter-spacing: 0.005em;
  color: rgba(255,255,255,0.55);
  font-style: italic;
}
#stories-panel.atlas .sp-ex-card-thread-t {
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif;
  font-size: 14.5px;
  line-height: 1.25;
  color: #f1ece1;
}
/* Atlas page: items are a 2-column compact grid; phone breaks to 1. */
#stories-panel.atlas .sp-ex-atlas-group { margin-bottom: 6px; }
#stories-panel.atlas .sp-ex-atlas-items {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 14px;
}
body.is-phone #stories-panel.atlas .sp-ex-atlas-items {
  grid-template-columns: 1fr;
  gap: 2px;
}
#stories-panel.atlas .sp-ex-atlas-item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 4px;
  text-align: left;
  background: transparent;
  border: none;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  color: inherit;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.18s ease;
}
#stories-panel.atlas .sp-ex-atlas-item:hover,
#stories-panel.atlas .sp-ex-atlas-item:focus-visible {
  background: rgba(248,212,140,0.045);
}
#stories-panel.atlas .sp-ex-atlas-name {
  font-size: 13.5px;
  line-height: 1.3;
  color: #e8e5dd;
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#stories-panel.atlas .sp-ex-atlas-span {
  font-size: 9.5px;
  letter-spacing: 0.06em;
  color: rgba(255,255,255,0.4);
  white-space: nowrap;
}

/* ---- Horizon hub: 'Coming soon' timeline stub (not yet authored). Dimmed,
   not tappable, with a quiet tag so the reader knows it is on the way. ---- */
#stories-panel.atlas .sp-ex-card-soon {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(20,24,36,0.28), rgba(11,14,22,0.34));
  border: 1px dashed rgba(255,255,255,0.10);
  opacity: 0.72;
}
#stories-panel.atlas .sp-ex-card-soon .sp-ex-card-title {
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif;
  font-size: 15px;
  color: rgba(226, 232, 242, 0.7);
  font-weight: 500;
}
#stories-panel.atlas .sp-ex-card-soontag {
  flex: 0 0 auto;
  font-size: 8.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(248,212,140,0.6);
  border: 1px solid rgba(248,212,140,0.22);
  border-radius: 999px;
  padding: 3px 9px;
}

/* ---- Horizon hub: the speculative conclusion. A quiet, set-apart block that
   reads as a margin note: what we think is going on, with room to be unsure. */
#stories-panel.atlas .sp-hz-conclusion {
  margin-top: 26px;
  padding: 18px 20px;
  border-radius: 12px;
  border: 1px solid rgba(248,212,140,0.16);
  background: linear-gradient(180deg, rgba(248,212,140,0.05), rgba(248,212,140,0.015));
}
#stories-panel.atlas .sp-hz-conclusion-label {
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(248,212,140,0.7);
  margin-bottom: 10px;
}
#stories-panel.atlas .sp-hz-conclusion-text {
  font-family: 'Source Serif Pro', 'Source Serif 4', Georgia, serif;
  font-size: 14px;
  line-height: 1.6;
  color: rgba(232, 234, 240, 0.9);
  font-style: italic;
}

/* Section cards (How we got here / Where are we heading?): the same elegant
   card as a theme-hub timeline (the 'Scientific Account' design) — gold-edged,
   title + a few lines of framing + a count. Description clamps so cards stay
   even. Reuses the .sp-tlc-* type styles. */
#stories-panel.atlas .sp-section-card {
  gap: 6px;
  border-color: rgba(248, 212, 140, 0.22);
}
#stories-panel.atlas .sp-section-card:hover,
#stories-panel.atlas .sp-section-card:focus-visible {
  background: rgba(248, 212, 140, 0.07);
  border-color: rgba(248, 212, 140, 0.45);
}
#stories-panel.atlas .sp-section-card .sp-tlc-thesis {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Horizon confluence (not woven): a 'soon' lane is dimmed with a quiet tag. */
#thread-confluence .cf-lane-label.cf-lane-soon { opacity: 0.6; }
#thread-confluence .cf-lane-soontag {
  font-size: 8px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(248, 212, 140, 0.6);
  margin-left: 5px;
}
/* A built timeline's name is a link into its full cinematic. */
#thread-confluence .cf-lane-label.cf-lane-link { cursor: pointer; transition: color 0.15s ease; pointer-events: auto; }
#thread-confluence .cf-lane-label.cf-lane-link:hover,
#thread-confluence .cf-lane-label.cf-lane-link:focus-visible { color: rgba(248, 212, 140, 0.95); outline: none; }
/* Lane event dots are tappable for the event detail. */
#thread-confluence .cf-svg .cf-node { cursor: pointer; }
#thread-confluence .cf-svg .cf-node.is-active { stroke: rgba(248,212,140,0.95); stroke-width: 2.5; }

/* Each section header is a small-caps label plus an optional count.
 * Items below are in clean dim typography that brightens on hover. */
#atlas-index .ai-section { margin-bottom: 22px; }
#atlas-index .ai-section-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  text-align: left;
  color: inherit;
  transition: color 0.15s ease;
}
#atlas-index .ai-section-head:hover,
#atlas-index .ai-section-head:focus-visible {
  color: #ffffff;
  outline: none;
}
#atlas-index .ai-section-head .ai-section-title {
  flex: 1 1 auto;
}
#atlas-index .ai-chev {
  flex: 0 0 auto;
  color: rgba(170,180,200,0.55);
  transition: transform 0.24s cubic-bezier(.18,.7,.22,1),
              color 0.18s ease;
}
#atlas-index .ai-section.expanded .ai-chev {
  transform: rotate(180deg);
  color: rgba(218, 226, 240, 0.85);
}
#atlas-index .ai-section-head:hover .ai-chev,
#atlas-index .ai-section-head:focus-visible .ai-chev {
  color: #ffffff;
}
#atlas-index .ai-section-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 13px;
  letter-spacing: 0.04em;
  color: #f1f4fa;
}
#atlas-index .ai-section-count {
  font-size: 9px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(170,180,200,0.50);
}
#atlas-index .ai-list {
  display: flex;
  flex-direction: column;
  gap: 1px;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 0.32s cubic-bezier(.18,.7,.22,1),
              opacity 0.22s ease,
              padding 0.32s cubic-bezier(.18,.7,.22,1);
  padding-top: 0;
  padding-bottom: 0;
}
#atlas-index .ai-section.expanded .ai-list {
  max-height: 1200px;
  opacity: 1;
  padding-top: 4px;
  padding-bottom: 6px;
}
#atlas-index .ai-item {
  display: flex;
  align-items: baseline;
  gap: 9px;
  padding: 6px 0;
  font-size: 11px;
  line-height: 1.35;
  letter-spacing: 0.02em;
  color: rgba(200, 210, 226, 0.78);
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
  transition: color 0.15s ease, transform 0.18s ease;
  width: 100%;
}
#atlas-index .ai-item:hover,
#atlas-index .ai-item:focus-visible {
  color: #ffffff;
  transform: translateX(3px);
  outline: none;
}
#atlas-index .ai-item .ai-bullet {
  color: rgba(170,180,200,0.40);
  font-size: 10px;
  flex: 0 0 auto;
}
#atlas-index .ai-item.has-timeline .ai-bullet {
  color: rgba(225, 195, 130, 0.82);
}
#atlas-index .ai-item .ai-traj {
  margin-left: auto;
  font-size: 8.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(225, 195, 130, 0.70);
  flex: 0 0 auto;
}
#atlas-index .ai-empty {
  padding: 6px 0;
  font-size: 10.5px;
  color: rgba(170,180,200,0.45);
  font-style: italic;
}

/* 'Histories' divider — quiet small-caps label that separates the deep
   timeline catalog from the Now pin + Threads above it. */
#atlas-index .ai-group-label {
  font-size: 8.5px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(170, 180, 200, 0.45);
  margin: 6px 0 14px;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.05);
}

/* Threads 'show more / fewer' — a quiet text toggle under the first four
   threads. Indented to align with the thread text, not the bullets. */
#atlas-index .ai-threads-rest[hidden] { display: none; }
#atlas-index .ai-threads-toggle {
  margin-top: 4px;
  padding: 6px 0 2px;
  background: transparent;
  border: 0;
  cursor: pointer;
  font-family: inherit;
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(150, 180, 230, 0.6);
  text-align: left;
  transition: color 0.16s ease;
}
#atlas-index .ai-threads-toggle:hover,
#atlas-index .ai-threads-toggle:focus-visible {
  color: rgba(190, 210, 250, 0.95);
  outline: none;
}


/* =====================================================================
   ATLAS INDEX — featured pin (Now / live era).
   Sits at the top of the index, above the section list. A small editorial
   tag + serif title + one-line subtitle. Click goes straight to the Now
   timeline dossier.
   ===================================================================== */
#atlas-index .ai-feature {
  margin-bottom: 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid rgba(255,255,255,0.06);
}
#atlas-index .ai-feature-btn {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  column-gap: 12px;
  row-gap: 6px;
  align-items: center;
  width: 100%;
  padding: 12px 14px;
  background: linear-gradient(180deg, rgba(244, 233, 196, 0.06), rgba(244, 233, 196, 0.015));
  border: 1px solid rgba(244, 233, 196, 0.18);
  border-radius: 6px;
  cursor: pointer;
  text-align: left;
  color: inherit;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.2s ease;
}
#atlas-index .ai-feature-btn:hover,
#atlas-index .ai-feature-btn:focus-visible {
  background: linear-gradient(180deg, rgba(244, 233, 196, 0.10), rgba(244, 233, 196, 0.04));
  border-color: rgba(244, 233, 196, 0.32);
  transform: translateX(2px);
  outline: none;
}
#atlas-index .ai-feature-tag {
  grid-row: 1;
  grid-column: 1;
  font-size: 8.5px;
  letter-spacing: 0.30em;
  text-transform: uppercase;
  color: #f4e9c4;
  background: rgba(244, 233, 196, 0.12);
  border: 1px solid rgba(244, 233, 196, 0.28);
  border-radius: 999px;
  padding: 3px 9px;
  align-self: center;
  justify-self: start;
}
#atlas-index .ai-feature-title {
  grid-row: 1;
  grid-column: 2;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 16px;
  letter-spacing: 0.01em;
  color: #f4f6fb;
}
#atlas-index .ai-feature-sub {
  grid-row: 2;
  grid-column: 1 / -1;
  font-size: 10.5px;
  line-height: 1.5;
  color: rgba(200, 210, 226, 0.70);
}

/* Threads section — the causal-narrative entries. Each item leads with
   its QUESTION (the hook) and shows the thread title beneath, so the
   list reads as a set of questions the atlas can answer. */
#atlas-index .ai-thread-item {
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  padding: 9px 8px 11px 8px;
  border-radius: 7px;
  height: auto;
}
#atlas-index .ai-thread-item .ai-thread-q {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 12.5px;
  line-height: 1.32;
  color: #eef1f7;
}
#atlas-index .ai-thread-item .ai-thread-t {
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(180, 196, 222, 0.5);
}
#atlas-index .ai-thread-item:hover,
#atlas-index .ai-thread-item:focus-visible {
  background: rgba(255, 255, 255, 0.05);
}
#atlas-index .ai-thread-item:hover .ai-thread-t,
#atlas-index .ai-thread-item:focus-visible .ai-thread-t {
  color: rgba(190, 206, 232, 0.8);
}

/* ---- 'How we got here' guide section (menu) ------------------------- */
#atlas-index .ai-guide-intro {
  font-size: 11.5px;
  line-height: 1.5;
  color: rgba(180, 196, 222, 0.62);
  padding: 0 8px 8px;
}
#atlas-index .ai-guide-item {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 8px 11px 8px;
  border-radius: 7px;
  height: auto;
}
#atlas-index .ai-guide-item .ai-guide-num {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 1px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10.5px;
  font-weight: 600;
  color: rgba(248, 212, 140, 0.92);
  background: rgba(248, 212, 140, 0.10);
  border: 1px solid rgba(248, 212, 140, 0.28);
}
#atlas-index .ai-guide-item .ai-guide-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
#atlas-index .ai-guide-item .ai-guide-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 13px;
  line-height: 1.3;
  color: #eef1f7;
}
#atlas-index .ai-guide-item .ai-guide-era {
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(180, 196, 222, 0.5);
}
#atlas-index .ai-guide-item .ai-guide-orient {
  font-size: 11.5px;
  line-height: 1.45;
  color: rgba(200, 212, 232, 0.72);
}
#atlas-index .ai-guide-item:hover,
#atlas-index .ai-guide-item:focus-visible {
  background: rgba(248, 212, 140, 0.06);
}
#atlas-index .ai-guide-item:hover .ai-guide-num,
#atlas-index .ai-guide-item:focus-visible .ai-guide-num {
  background: rgba(248, 212, 140, 0.18);
  border-color: rgba(248, 212, 140, 0.45);
}

/* ---- Guide chapter landing (dossier) -------------------------------- */
#stories-panel.atlas .sp-guide-cta {
  margin: 16px 0 6px;
}
#stories-panel.atlas .sp-guide-enter {
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: 100%;
  text-align: left;
  cursor: pointer;
  padding: 13px 16px;
  border-radius: 9px;
  background: rgba(248, 212, 140, 0.08);
  border: 1px solid rgba(248, 212, 140, 0.30);
  position: relative;
  transition: background 0.18s ease, border-color 0.18s ease;
}
#stories-panel.atlas .sp-guide-enter:hover {
  background: rgba(248, 212, 140, 0.13);
  border-color: rgba(248, 212, 140, 0.5);
}
#stories-panel.atlas .sp-guide-enter .sp-guide-enter-label {
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
  color: rgba(248, 212, 140, 0.92);
}
#stories-panel.atlas .sp-guide-enter .sp-guide-enter-sub {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 14px;
  font-style: italic;
  line-height: 1.4;
  color: #eef1f7;
  padding-right: 18px;
}
#stories-panel.atlas .sp-guide-enter .sp-subject-arrow {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: rgba(248, 212, 140, 0.7);
  font-style: normal;
}
#stories-panel.atlas .sp-guide-key-tag {
  display: block;
  font-size: 11.5px;
  line-height: 1.45;
  color: rgba(200, 212, 232, 0.66);
  margin-top: 2px;
}
#stories-panel.atlas .sp-guide-chapnav {
  display: flex;
  gap: 12px;
  margin: 26px 0 6px;
  align-items: stretch;
}
#stories-panel.atlas .sp-guide-navbtn {
  display: flex;
  flex-direction: column;
  gap: 4px;
  cursor: pointer;
  text-align: left;
  padding: 12px 14px;
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  transition: background 0.18s ease, border-color 0.18s ease;
}
#stories-panel.atlas .sp-guide-navbtn:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.16);
}
#stories-panel.atlas .sp-guide-prev { flex: 0 0 34%; }
#stories-panel.atlas .sp-guide-next { flex: 1 1 auto; border-color: rgba(248, 212, 140, 0.22); }
#stories-panel.atlas .sp-guide-next:hover { border-color: rgba(248, 212, 140, 0.45); }
#stories-panel.atlas .sp-guide-navspacer { flex: 0 0 34%; background: none; border: none; }
#stories-panel.atlas .sp-guide-navdir {
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(180, 196, 222, 0.55);
}
#stories-panel.atlas .sp-guide-navtitle {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 13.5px;
  color: #eef1f7;
}
#stories-panel.atlas .sp-guide-next .sp-guide-led {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 12.5px;
  font-style: italic;
  line-height: 1.5;
  color: rgba(248, 212, 140, 0.82);
  margin-bottom: 4px;
}

/* ---- 'How we got here' theme items (menu) --------------------------- */
#atlas-index .ai-theme-item {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 8px 12px 8px;
  border-radius: 7px;
  height: auto;
}
#atlas-index .ai-theme-item .ai-theme-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 auto; }
#atlas-index .ai-theme-item .ai-theme-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 13.5px;
  line-height: 1.3;
  color: #eef1f7;
}
#atlas-index .ai-theme-item .ai-theme-sub {
  font-size: 11px;
  line-height: 1.45;
  color: rgba(200, 212, 232, 0.6);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
#atlas-index .ai-theme-item .ai-theme-status {
  flex: 0 0 auto;
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(248, 212, 140, 0.7);
  margin-top: 2px;
  white-space: nowrap;
}
#atlas-index .ai-theme-item:hover,
#atlas-index .ai-theme-item:focus-visible { background: rgba(248, 212, 140, 0.06); }
#atlas-index .ai-theme-item.ai-theme-stub { opacity: 0.55; }
#atlas-index .ai-theme-item.ai-theme-stub .ai-theme-status { color: rgba(180, 196, 222, 0.5); }

/* ---- 'Where are we heading?' — force items --------------------------
   A force is an arc without an ending. Each row carries: its title, the
   one-line stake, the lens chips it cuts across, and an 'Updated …' stamp
   with a soft live pulse — the visual cue for 'discovering in real time'. */
#atlas-index .ai-force-item {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 5px;
  padding: 13px 14px 12px;
  text-align: left;
  border-radius: 8px;
  background: transparent;
  border: 1px solid transparent;
  transition: background 0.18s ease, border-color 0.18s ease;
}
#atlas-index .ai-force-item:hover,
#atlas-index .ai-force-item:focus-visible {
  background: rgba(248, 212, 140, 0.045);
  border-color: rgba(248, 212, 140, 0.12);
}
#atlas-index .ai-force-title {
  font-size: 14.5px;
  line-height: 1.3;
  color: #f1ece1;
  font-weight: 500;
  letter-spacing: 0.005em;
}
#atlas-index .ai-force-stake {
  font-size: 11.5px;
  line-height: 1.45;
  color: rgba(208, 218, 234, 0.72);
  font-style: italic;
}
#atlas-index .ai-force-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 2px;
  flex-wrap: wrap;
}
#atlas-index .ai-force-lenses { display: inline-flex; flex-wrap: wrap; gap: 5px; }
#atlas-index .ai-force-lens {
  display: inline-block;
  font-size: 8.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 2px 7px 2px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.09);
  color: rgba(228, 234, 244, 0.75);
}
/* Lens-tinted chips — same five-lens palette used elsewhere in the app, so
   a Power/Money/People/Planet/Progress chip reads instantly. */
#atlas-index .ai-force-lens-power    { background: rgba(232, 168, 96, 0.10);  border-color: rgba(232, 168, 96, 0.32);  color: rgba(248, 200, 140, 0.92); }
#atlas-index .ai-force-lens-money    { background: rgba(120, 200, 160, 0.09); border-color: rgba(120, 200, 160, 0.30); color: rgba(150, 220, 180, 0.92); }
#atlas-index .ai-force-lens-people   { background: rgba(180, 156, 232, 0.10); border-color: rgba(180, 156, 232, 0.32); color: rgba(206, 188, 246, 0.92); }
#atlas-index .ai-force-lens-planet   { background: rgba(120, 180, 232, 0.10); border-color: rgba(120, 180, 232, 0.30); color: rgba(160, 210, 244, 0.92); }
#atlas-index .ai-force-lens-progress { background: rgba(232, 144, 168, 0.10); border-color: rgba(232, 144, 168, 0.32); color: rgba(244, 184, 200, 0.92); }
/* 'Updated …' stamp with a tiny live pulse: the editorial signal that this
   arc is moving in real time, not a settled history entry. */
#atlas-index .ai-force-updated {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.42);
}
#atlas-index .ai-force-pulse {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: rgba(248, 212, 140, 0.92);
  box-shadow: 0 0 6px rgba(248, 212, 140, 0.6);
  animation: ai-force-pulse 2.4s ease-in-out infinite;
}
@keyframes ai-force-pulse {
  0%, 100% { opacity: 0.55; transform: scale(0.85); }
  50%      { opacity: 1;    transform: scale(1.1); }
}
/* A faint accent rail on the section header so the editorial entry point
   reads as the headline, even when collapsed alongside the others. */
#atlas-index .ai-section-forces .ai-section-head {
  position: relative;
}
#atlas-index .ai-section-forces .ai-section-head::before {
  content: '';
  position: absolute;
  left: 0; top: 8px; bottom: 8px;
  width: 2px;
  border-radius: 0 2px 2px 0;
  background: linear-gradient(180deg, rgba(248, 212, 140, 0.7), rgba(248, 212, 140, 0.15));
}

/* ---- Theme hub: timeline cards -------------------------------------- */
#stories-panel.atlas .sp-timeline-cards { display: flex; flex-direction: column; gap: 12px; }
#stories-panel.atlas .sp-timeline-card {
  display: flex;
  flex-direction: column;
  gap: 5px;
  text-align: left;
  cursor: pointer;
  padding: 14px 16px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(248, 212, 140, 0.22);
  transition: background 0.18s ease, border-color 0.18s ease;
}
#stories-panel.atlas .sp-timeline-card:hover { background: rgba(248, 212, 140, 0.07); border-color: rgba(248, 212, 140, 0.45); }
#stories-panel.atlas .sp-tlc-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
#stories-panel.atlas .sp-tlc-title { font-family: Georgia, "Times New Roman", serif; font-size: 17px; color: #f3f6fb; }
#stories-panel.atlas .sp-tlc-pov {
  font-size: 9px; letter-spacing: 0.16em; text-transform: uppercase; font-weight: 600;
  color: rgba(248, 212, 140, 0.92); border: 1px solid rgba(248, 212, 140, 0.3);
  border-radius: 999px; padding: 2px 8px;
}
#stories-panel.atlas .sp-tlc-span { font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(180, 196, 222, 0.55); }
#stories-panel.atlas .sp-tlc-thesis { font-size: 13px; line-height: 1.55; color: rgba(214, 224, 240, 0.82); }
#stories-panel.atlas .sp-tlc-count { font-size: 10.5px; letter-spacing: 0.06em; color: rgba(248, 212, 140, 0.7); margin-top: 2px; }

/* ---- A single timeline: the followable vertical run of moments ------ */
#stories-panel.atlas .sp-tl-moments {
  list-style: none;
  margin: 18px 0 8px;
  padding: 0 0 0 4px;
  position: relative;
}
#stories-panel.atlas .sp-tl-moment {
  position: relative;
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 14px;
  padding: 0 0 22px 0;
}
/* the vertical spine + the dot on each moment */
#stories-panel.atlas .sp-tl-moment::before {
  content: "";
  position: absolute;
  left: 71px;
  top: 8px;
  bottom: -2px;
  width: 1px;
  background: rgba(248, 212, 140, 0.22);
}
#stories-panel.atlas .sp-tl-moment:last-child::before { display: none; }
#stories-panel.atlas .sp-tl-moment::after {
  content: "";
  position: absolute;
  left: 67px;
  top: 5px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #0b0e16;
  border: 2px solid rgba(248, 212, 140, 0.6);
}
#stories-panel.atlas .sp-tl-year {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: rgba(248, 212, 140, 0.92);
  text-align: right;
  padding-top: 1px;
}
#stories-panel.atlas .sp-tl-body { min-width: 0; padding-left: 6px; }
#stories-panel.atlas .sp-tl-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 15px;
  color: #f3f6fb;
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
}
#stories-panel.atlas .sp-tl-title.sp-subject-link { cursor: pointer; }
#stories-panel.atlas .sp-tl-title.sp-subject-link:hover { color: rgba(248, 212, 140, 0.95); }
#stories-panel.atlas .sp-tl-detail { font-size: 13px; line-height: 1.6; color: rgba(214, 224, 240, 0.82); margin-top: 4px; }
#stories-panel.atlas .sp-crumb-link { background: none; border: 0; padding: 0; cursor: pointer; color: inherit; font: inherit; }
#stories-panel.atlas .sp-crumb-link:hover { color: rgba(248, 212, 140, 0.9); }

/* =====================================================================
   THREAD VIEWER — causal 'how we got here' narrative overlay.
   ===================================================================== */
#thread-viewer-scrim {
  position: fixed;
  inset: 0;
  background: rgba(2, 4, 9, 0.55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  z-index: 58;
  opacity: 0;
  transition: opacity 0.3s ease;
}
#thread-viewer-scrim.visible { opacity: 1; }
#thread-viewer-scrim[hidden] { display: none; }

#thread-viewer {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  width: min(520px, 92vw);
  z-index: 59;
  display: flex;
  pointer-events: none;
}
#thread-viewer[hidden] { display: none; }
#thread-viewer .tv-panel {
  position: relative;
  width: 100%;
  background: rgba(8, 10, 16, 0.92);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  border-right: 1px solid rgba(255, 255, 255, 0.07);
  box-shadow: 28px 0 70px rgba(0, 0, 0, 0.6);
  overflow-y: auto;
  padding: 64px 40px 48px;
  transform: translateX(-104%);
  opacity: 0;
  transition: transform 0.4s cubic-bezier(.18,.7,.22,1), opacity 0.3s ease;
  pointer-events: auto;
}
#thread-viewer.visible .tv-panel {
  transform: translateX(0);
  opacity: 1;
}
#thread-viewer .tv-panel::-webkit-scrollbar { width: 7px; }
#thread-viewer .tv-panel::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.10);
  border-radius: 999px;
}
#thread-viewer .tv-close {
  position: absolute;
  top: 22px;
  right: 22px;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.55);
  font-size: 19px;
  line-height: 1;
  cursor: pointer;
  border-radius: 50%;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
#thread-viewer .tv-close:hover {
  color: #fff;
  border-color: rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.05);
}
#thread-viewer .tv-kicker {
  font-size: 9px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(180, 196, 222, 0.5);
  margin-bottom: 12px;
}
#thread-viewer .tv-q {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 23px;
  line-height: 1.28;
  color: #f3f5f9;
  margin-bottom: 14px;
}
#thread-viewer .tv-summary {
  font-size: 13.5px;
  line-height: 1.6;
  color: rgba(206, 214, 228, 0.78);
  margin-bottom: 10px;
}
#thread-viewer .tv-span {
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.14em;
  color: rgba(180, 196, 222, 0.45);
  margin-bottom: 28px;
}
/* Primary action: enter the confluence (the cinematic stacked-timelines
   view). The snapshot's hero CTA, so it reads gold and prominent. */
#thread-viewer .tv-stack-btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 30px;
  padding: 11px 20px;
  background: rgba(248, 212, 140, 0.12);
  border: 1px solid rgba(248, 212, 140, 0.4);
  border-radius: 24px;
  color: rgba(250, 228, 178, 0.98);
  font-family: inherit;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}
#thread-viewer .tv-stack-btn:hover {
  background: rgba(248, 212, 140, 0.2);
  border-color: rgba(248, 212, 140, 0.65);
  transform: translateY(-1px);
}
/* Woven-timelines chips — the source timelines this thread braids.
   Clicking one opens that single timeline. */
#thread-viewer .tv-weave { margin-bottom: 30px; }
#thread-viewer .tv-weave-label,
#thread-viewer .tv-outcome-label {
  font-size: 9px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(180, 196, 222, 0.5);
  margin-bottom: 12px;
}
#thread-viewer .tv-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
#thread-viewer .tv-chip {
  padding: 7px 13px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 16px;
  color: rgba(214, 222, 236, 0.9);
  font-family: inherit;
  font-size: 11px;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background 0.16s ease, border-color 0.16s ease, color 0.16s ease, transform 0.16s ease;
}
#thread-viewer .tv-chip:hover,
#thread-viewer .tv-chip:focus-visible {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.28);
  color: #fff;
  transform: translateY(-1px);
  outline: none;
}
/* Outcome — where the thread leads. */
#thread-viewer .tv-outcome {
  padding-top: 26px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
#thread-viewer .tv-outcome-text {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 14.5px;
  line-height: 1.62;
  color: rgba(224, 230, 242, 0.92);
}

@media (max-width: 600px) {
  #thread-viewer { width: 100vw; }
  #thread-viewer .tv-panel { padding: 56px 24px 40px; }
  #thread-viewer .tv-q { font-size: 20px; }
}

/* =====================================================================
   THREAD DOSSIER PAGE — threads render in the standard dossier panel
   (same shell as country/subject) with their own hero, key indicators,
   woven-timeline cards, outcome section, and the 'Enter the confluence'
   CTA. Architecture cards reuse .sp-power-institution / .sp-arch-*
   styling for consistency.
   ===================================================================== */
#stories-panel .sp-thread-page .sp-thread-cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 26px 0 10px;
  padding: 12px 22px;
  background: rgba(248, 212, 140, 0.12);
  border: 1px solid rgba(248, 212, 140, 0.40);
  border-radius: 26px;
  color: rgba(252, 230, 178, 0.98);
  font-family: inherit;
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}
#stories-panel .sp-thread-page .sp-thread-cta:hover {
  background: rgba(248, 212, 140, 0.20);
  border-color: rgba(248, 212, 140, 0.66);
  transform: translateY(-1px);
}
#stories-panel .sp-thread-page .sp-thread-card {
  cursor: pointer;
}
#stories-panel .sp-thread-page .sp-thread-outcome-section .sp-power-copy {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 14.5px;
  line-height: 1.62;
  color: rgba(228, 234, 244, 0.92);
}
#stories-panel .sp-thread-page .sp-crumb-sep {
  color: rgba(180, 196, 222, 0.32);
  margin: 0 2px;
}

/* =====================================================================
   CONFLUENCE MODE — the cinematic 'stacked timelines' view of a thread.
   Lanes on the left, the luminous thread weaving between them, the
   conclusion resolving on the right with Earth alive behind it.
   ===================================================================== */
#thread-confluence {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  /* Opaque-dark on the left where the lanes need contrast, fading to
     near-clear on the right so the globe shows through behind the
     conclusion. */
  background: linear-gradient(
    100deg,
    rgba(4, 6, 12, 0.94) 0%,
    rgba(4, 6, 12, 0.88) 45%,
    rgba(4, 6, 12, 0.55) 72%,
    rgba(4, 6, 12, 0.28) 100%
  );
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity 0.45s ease;
  padding-top: 72px;
}
#thread-confluence.visible { opacity: 1; }
#thread-confluence[hidden] { display: none; }

#thread-confluence .cf-head {
  position: absolute;
  top: 0; left: 0; right: 0;
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 26px 36px;
}
#thread-confluence .cf-kicker {
  font-size: 9px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(248, 212, 140, 0.7);
  flex: 0 0 auto;
}
#thread-confluence .cf-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 17px;
  color: #f1f4fa;
  flex: 1 1 auto;
}
#thread-confluence .cf-close {
  position: absolute;
  top: 22px; right: 28px;
  width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border: 1px solid rgba(255,255,255,0.14);
  color: rgba(255,255,255,0.6);
  font-size: 20px; line-height: 1;
  cursor: pointer; border-radius: 50%;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
#thread-confluence .cf-close:hover {
  color: #fff; border-color: rgba(255,255,255,0.34);
  background: rgba(255,255,255,0.06);
}

#thread-confluence .cf-stage {
  position: relative;
  flex: 1 1 auto;
  margin: 8px 0 0 0;
}
#thread-confluence .cf-svg {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
}
#thread-confluence .cf-labels {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
#thread-confluence .cf-lbl {
  position: absolute;
  pointer-events: none;
}
#thread-confluence .cf-lane-label {
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(200, 210, 226, 0.62);
  text-align: right;
  padding-right: 14px;
  line-height: 1;
  /* Centre the label vertically on its `top` value so the lane line
     (drawn at the same y in SVG) runs through the optical middle of
     the text rather than below its baseline. */
  transform: translateY(-50%);
}
#thread-confluence .cf-node-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  transform: translateX(-50%);
  text-align: center;
  /* The labels container is click-through; re-enable clicks on the labels
     themselves so tapping a label selects its node (a big, easy target). */
  pointer-events: auto;
  cursor: pointer;
  transition: top 0.25s cubic-bezier(.2,.7,.2,1);
}
#thread-confluence .cf-node-label:hover .cf-node-name { color: #fff; }
#thread-confluence .cf-node-label .cf-node-year {
  font-size: 9px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  color: rgba(248, 212, 140, 0.85);
}
#thread-confluence .cf-node-label .cf-node-name {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 12px;
  line-height: 1.25;
  color: #eef1f7;
  text-shadow: 0 1px 6px rgba(0,0,0,0.8);
}
#thread-confluence .cf-node {
  cursor: pointer;
  transition: r 0.18s ease;
}
#thread-confluence .cf-svg { pointer-events: auto; }

#thread-confluence .cf-conclusion {
  flex: 0 0 360px;
  align-self: center;
  padding: 0 32px 0 24px;
  max-width: 360px;
  /* Cap to viewport so long node-detail content (with comprehensive
     why fields) scrolls inside the panel instead of overflowing the
     screen. Short outcome content still sits centred. */
  max-height: calc(100vh - 96px);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.22) transparent;
}
#thread-confluence .cf-conclusion::-webkit-scrollbar { width: 6px; }
#thread-confluence .cf-conclusion::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.18);
  border-radius: 3px;
}
#thread-confluence .cf-conclusion::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.32);
}
#thread-confluence .cf-conclusion::-webkit-scrollbar-track { background: transparent; }

/* ---- Phone: the desktop side-by-side (diagram + 360px aside) overlaps on a
   narrow screen — the selected-node detail printed on top of the diagram's
   labels. Stack them instead: diagram on top, outcome below; and when a node
   is selected its detail takes over the screen (diagram hidden) so nothing
   bleeds through. "Back to the outcome" brings the diagram back. ---- */
body.is-phone #thread-confluence {
  flex-direction: column;
  padding-top: calc(58px + var(--safe-top));
  padding-bottom: calc(8px + var(--safe-bottom));
  /* Phone layout stacks lanes over the conclusion (no left-right split), so the
     desktop right-fade just lets whatever is behind (the globe, or the page we
     opened from) bleed through and muddy the text. Use a near-opaque flat dark
     instead so the lanes and the conclusion read cleanly. */
  background: rgba(6, 8, 14, 0.975);
  backdrop-filter: blur(8px) saturate(120%);
  -webkit-backdrop-filter: blur(8px) saturate(120%);
}
body.is-phone #thread-confluence .cf-stage {
  flex: 0 0 auto;
  height: 42vh;
  height: 42dvh;
  margin: 6px 0 0;
}
body.is-phone #thread-confluence .cf-conclusion {
  flex: 1 1 auto;
  width: auto;
  max-width: none;
  max-height: none;
  align-self: stretch;
  padding: 16px 18px calc(10px + var(--safe-bottom));
}
body.is-phone #thread-confluence.cf-detail-open .cf-stage { display: none; }
/* Smaller lane + node labels so they fit the narrower padding the diagram now
   uses on phone (see padL/padR in _renderConfluence). */
body.is-phone #thread-confluence .cf-lane-label { font-size: 8px; letter-spacing: 0.06em; }
body.is-phone #thread-confluence .cf-node-label .cf-node-name { font-size: 11px; line-height: 1.2; }
body.is-phone #thread-confluence .cf-node-label .cf-node-year { font-size: 8px; }

/* Reader prev/next — flip between moments without leaving the detail/event,
   shared by the confluence node detail and the cinematic event card. */
#thread-confluence .cf-conc-nav,
#timeline-context .tc-nav,
#layers-composer .lc-detail-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-top: 30px;
  padding-top: 18px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}
#thread-confluence .cf-conc-nav button,
#timeline-context .tc-nav button,
#layers-composer .lc-detail-nav button {
  flex: 0 0 auto;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: rgba(248, 212, 140, 0.92);
  font-family: inherit;
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 10px 18px;
  border-radius: 9px;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease, opacity 0.2s ease;
}
#thread-confluence .cf-conc-nav button:hover,
#timeline-context .tc-nav button:hover,
#layers-composer .lc-detail-nav button:hover {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.3);
}
#thread-confluence .cf-conc-nav button:disabled,
#timeline-context .tc-nav button:disabled,
#layers-composer .lc-detail-nav button:disabled {
  opacity: 0.28;
  cursor: default;
}
#thread-confluence .cf-conc-kicker {
  font-size: 9px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(248, 212, 140, 0.7);
  margin-bottom: 14px;
}
#thread-confluence .cf-conc-question {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 21px;
  line-height: 1.3;
  color: #f5f7fb;
  margin-bottom: 18px;
  text-shadow: 0 2px 12px rgba(0,0,0,0.7);
}
#thread-confluence .cf-conc-text {
  font-size: 14px;
  line-height: 1.65;
  color: rgba(220, 228, 240, 0.9);
  text-shadow: 0 1px 8px rgba(0,0,0,0.75);
}

/* Node-detail view inside the conclusion panel. Same panel real-estate
   as the outcome — toggled by JS so clicking a dot reveals event detail
   without losing the woven-timelines context. */
#thread-confluence .cf-conc-thread[hidden],
#thread-confluence .cf-conc-node[hidden] { display: none; }
#thread-confluence .cf-conc-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 18px;
  padding: 4px 10px 4px 6px;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 14px;
  color: rgba(220, 228, 240, 0.7);
  font-family: inherit;
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
#thread-confluence .cf-conc-back:hover {
  color: #fff;
  border-color: rgba(255, 255, 255, 0.34);
  background: rgba(255, 255, 255, 0.05);
}
#thread-confluence .cf-conc-node-year {
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.24em;
  color: rgba(248, 212, 140, 0.85);
  margin-bottom: 8px;
}
#thread-confluence .cf-conc-node-label {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 21px;
  line-height: 1.28;
  color: #f5f7fb;
  margin-bottom: 6px;
  text-shadow: 0 2px 12px rgba(0,0,0,0.7);
}
#thread-confluence .cf-conc-node-source {
  font-size: 9px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(200, 210, 226, 0.62);
  margin-bottom: 16px;
}
#thread-confluence .cf-conc-node-image {
  margin-bottom: 16px;
  border-radius: 6px;
  overflow: hidden;
  background: rgba(255,255,255,0.04);
  max-width: 100%;
}
#thread-confluence .cf-conc-node-image img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 200px;
  object-fit: cover;
  object-position: center top;
}
#thread-confluence .cf-conc-node-note {
  font-size: 12px;
  line-height: 1.55;
  color: rgba(200, 210, 226, 0.72);
  margin-bottom: 16px;
  text-shadow: 0 1px 8px rgba(0,0,0,0.7);
}
/* 'Why it propels the chain' — the editorial spine. The substantial
   essay that explains how this node drives the chain toward the
   outcome. Visually most prominent in the node detail panel. */
#thread-confluence .cf-conc-node-why {
  margin-bottom: 18px;
  padding: 16px 18px;
  background: rgba(248, 212, 140, 0.07);
  border-left: 2px solid rgba(248, 212, 140, 0.55);
  border-radius: 0 4px 4px 0;
}
#thread-confluence .cf-conc-node-why[hidden] { display: none; }
#thread-confluence .cf-conc-node-why-label {
  font-size: 9px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(248, 212, 140, 0.85);
  margin-bottom: 10px;
}
#thread-confluence .cf-conc-node-why p {
  font-size: 13.5px;
  line-height: 1.7;
  color: rgba(238, 242, 250, 0.95);
  margin: 0 0 10px 0;
  text-shadow: 0 1px 6px rgba(0,0,0,0.55);
}
#thread-confluence .cf-conc-node-why p:last-child { margin-bottom: 0; }
#thread-confluence .cf-conc-node-event-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 14.5px;
  line-height: 1.3;
  color: #eef1f7;
  margin: 10px 0 6px;
}
#thread-confluence .cf-conc-node-event-summary {
  font-size: 12.5px;
  line-height: 1.55;
  color: rgba(206, 214, 228, 0.8);
  margin-bottom: 10px;
}
#thread-confluence .cf-conc-node-event-para {
  font-size: 12px;
  line-height: 1.62;
  color: rgba(210, 218, 232, 0.75);
  margin: 0;
}

/* Active node dot — when the right panel is showing this node's detail,
   the dot pops with a gold ring so the user sees which point they're on. */
#thread-confluence .cf-node.is-active {
  r: 5;
  stroke: #fff;
  stroke-width: 1.4;
  filter: drop-shadow(0 0 6px rgba(248, 212, 140, 0.8));
}

@media (max-width: 760px) {
  #thread-confluence { flex-direction: column; padding-top: 60px; }
  #thread-confluence .cf-conclusion {
    flex: 0 0 auto; align-self: stretch; max-width: none;
    padding: 16px 28px 28px;
  }
  #thread-confluence .cf-conc-question { font-size: 18px; }
}


/* =====================================================================
   NOW CINEMATIC TRIGGER + CONTEXT PANEL
   ===================================================================== */

/* Trigger button — sits next to #timeline-trigger at bottom-left. */
#now-trigger {
  position: fixed;
  left: 96px;
  bottom: 24px;
  width: 28px;
  height: 28px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 50%;
  background: transparent;
  color: #888;
  font-family: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.2s ease, border-color 0.2s ease, transform 0.2s ease, opacity 0.2s ease;
  user-select: none;
  z-index: 90;
  padding: 0;
}
#now-trigger:hover,
#now-trigger:focus-visible {
  color: #e6e6e6;
  border-color: rgba(255, 255, 255, 0.4);
  transform: scale(1.06);
  outline: none;
}
#now-trigger.active {
  color: #f4e9c4;
  border-color: rgba(244, 233, 196, 0.55);
}
#now-trigger[hidden] { display: none; }

/* ============================================================
 * NEWS CINEMATIC MODE (#news-cinematic)
 *
 * Triggered by the bottom-left #now-trigger. The dossier panel
 * fades away and a 5-card curated-news layout takes over:
 *   - Main article expanded in the centre-left
 *   - 4 preview cards stacked on the right
 *   - Header strip with scope label + timestamp + close
 * Click a preview → it swaps to the main position with a smooth
 * crossfade. Articles are fetched from /api/news.
 * ============================================================ */
#news-cinematic {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: stretch;
  padding: 64px clamp(40px, 6vw, 96px) 56px;
  z-index: 92;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.36s ease;
  user-select: none;
}
#news-cinematic.visible {
  opacity: 1;
  pointer-events: auto;
}
#news-cinematic[hidden] { display: none; }

/* Header: scope + category + timestamp + close */
#news-cinematic .nx-header {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 36px;
  font-size: 10px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(200, 210, 224, 0.78);
}
#news-cinematic .nx-scope-label {
  color: #f3f5f9;
  font-weight: 500;
}
#news-cinematic .nx-cat-label {
  color: #f4e9c4;
}
#news-cinematic .nx-sep {
  color: rgba(200, 210, 224, 0.32);
}
#news-cinematic .nx-timestamp {
  margin-left: auto;
  font-size: 9px;
  color: rgba(170, 180, 200, 0.55);
}
#news-cinematic .nx-close {
  width: 32px;
  height: 28px;
  background: transparent;
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 4px;
  color: rgba(218, 226, 240, 0.74);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
#news-cinematic .nx-close:hover,
#news-cinematic .nx-close:focus-visible {
  color: #fff;
  border-color: rgba(255,255,255,0.40);
  outline: none;
}

/* Body: main article on the left, preview stack on the right */
#news-cinematic .nx-body {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(280px, 0.9fr);
  gap: clamp(28px, 4vw, 56px);
  flex: 1;
  min-height: 0;
}

/* ---- Main expanded article -------------------------------- */
#news-cinematic .nx-main {
  display: flex;
  flex-direction: column;
  background: rgba(8, 10, 16, 0.78);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 10px;
  padding: 40px clamp(28px, 3vw, 48px);
  box-shadow: 0 22px 60px rgba(0,0,0,0.55);
  overflow-y: auto;
  transition: opacity 0.32s ease;
}
#news-cinematic.swapping .nx-main {
  opacity: 0;
}
#news-cinematic .nx-main-image-wrap {
  width: 100%;
  aspect-ratio: 16 / 9;
  margin: -40px clamp(-28px,-3vw,-48px) 28px;
  overflow: hidden;
  border-radius: 10px 10px 0 0;
  background: rgba(0,0,0,0.4);
  /* Prevent the flex column from squishing the image when the long-form
   * expansion text arrives and fills the description slot. Without this,
   * default flex-shrink:1 collapses the image to zero height. */
  flex-shrink: 0;
}
#news-cinematic .nx-main-image-wrap[hidden] { display: none; }
#news-cinematic .nx-main-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity 0.4s ease;
}
#news-cinematic .nx-main-image.loaded { opacity: 1; }

#news-cinematic .nx-main-meta {
  display: flex;
  gap: 16px;
  font-size: 9.5px;
  letter-spacing: 0.30em;
  text-transform: uppercase;
  color: rgba(170, 180, 200, 0.74);
  margin-bottom: 22px;
}
#news-cinematic .nx-main-source {
  color: rgba(244, 233, 196, 0.92);
}
#news-cinematic .nx-main-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: clamp(20px, 2.2vw, 30px);
  line-height: 1.20;
  letter-spacing: 0.005em;
  color: #f3f5f9;
  margin: 0 0 22px;
  font-weight: normal;
}
#news-cinematic .nx-main-framing {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 15px;
  line-height: 1.55;
  color: rgba(244, 233, 196, 0.92);
  margin: 0 0 24px;
  padding-left: 16px;
  border-left: 2px solid rgba(244, 233, 196, 0.30);
}
#news-cinematic .nx-main-description {
  font-size: 13px;
  line-height: 1.70;
  color: rgba(210, 220, 236, 0.82);
  margin: 0 0 32px;
  white-space: pre-wrap;
  transition: color 0.3s ease;
}
#news-cinematic .nx-main-description.is-loading {
  color: rgba(170, 180, 200, 0.55);
  font-style: italic;
}
#news-cinematic .nx-main-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 10px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(190, 210, 240, 0.92);
  text-decoration: none;
  margin-top: auto;
  padding: 10px 0;
  border-top: 1px solid rgba(255,255,255,0.07);
  transition: color 0.15s ease;
}
#news-cinematic .nx-main-link:hover {
  color: #fff;
}

/* ---- Preview stack on the right --------------------------- */
#news-cinematic .nx-previews {
  display: flex;
  flex-direction: column;
  gap: 14px;
  overflow-y: auto;
  padding-right: 4px;
}
#news-cinematic .nx-preview {
  text-align: left;
  background: rgba(8, 10, 16, 0.62);
  backdrop-filter: blur(14px) saturate(130%);
  -webkit-backdrop-filter: blur(14px) saturate(130%);
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 8px;
  padding: 16px 18px;
  cursor: pointer;
  color: rgba(210, 220, 236, 0.82);
  font-family: inherit;
  transition: border-color 0.18s ease, background 0.18s ease, transform 0.18s ease;
}
#news-cinematic .nx-preview:hover,
#news-cinematic .nx-preview:focus-visible {
  border-color: rgba(244, 233, 196, 0.40);
  background: rgba(8, 10, 16, 0.82);
  transform: translateX(-3px);
  outline: none;
}
#news-cinematic .nx-preview.active {
  /* The article currently in the main slot — dimmed so it's
     clear which one is centred. */
  opacity: 0.35;
  pointer-events: none;
}
/* "Load more" button — sits at the foot of the preview stack. Dashed
   border sets it apart from the article cards; gold hover matches them. */
#news-cinematic .nx-load-more {
  text-align: center;
  background: rgba(8, 10, 16, 0.45);
  backdrop-filter: blur(14px) saturate(130%);
  -webkit-backdrop-filter: blur(14px) saturate(130%);
  border: 1px dashed rgba(255,255,255,0.16);
  border-radius: 8px;
  padding: 12px 18px;
  cursor: pointer;
  color: rgba(210, 220, 236, 0.70);
  font-family: inherit;
  font-size: 0.74rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  transition: border-color 0.18s ease, background 0.18s ease, color 0.18s ease;
}
#news-cinematic .nx-load-more:hover,
#news-cinematic .nx-load-more:focus-visible {
  border-color: rgba(244, 233, 196, 0.45);
  background: rgba(8, 10, 16, 0.72);
  color: rgba(244, 233, 196, 0.92);
  outline: none;
}
#news-cinematic .nx-preview-meta {
  display: flex;
  gap: 10px;
  font-size: 8.5px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(170, 180, 200, 0.62);
  margin-bottom: 8px;
}
#news-cinematic .nx-preview-source {
  color: rgba(244, 233, 196, 0.78);
}
#news-cinematic .nx-preview-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 13.5px;
  line-height: 1.35;
  color: #e8edf4;
  margin-bottom: 6px;
  /* Cap at 3 lines */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
#news-cinematic .nx-preview-framing {
  font-size: 11px;
  line-height: 1.50;
  color: rgba(180, 195, 215, 0.65);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---- Loading / empty / error overlays --------------------- */
#news-cinematic .nx-loading,
#news-cinematic .nx-empty,
#news-cinematic .nx-error {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  background: rgba(0,0,0,0.0);
  color: rgba(218, 226, 240, 0.85);
  text-align: center;
  pointer-events: none;
}
#news-cinematic .nx-loading[hidden],
#news-cinematic .nx-empty[hidden],
#news-cinematic .nx-error[hidden] { display: none; }

#news-cinematic .nx-spinner {
  width: 24px;
  height: 24px;
  border: 2px solid rgba(255,255,255,0.12);
  border-top-color: rgba(244, 233, 196, 0.80);
  border-radius: 50%;
  animation: nx-spin 0.9s linear infinite;
}
@keyframes nx-spin {
  to { transform: rotate(360deg); }
}
#news-cinematic .nx-loading span {
  font-size: 11px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(170, 180, 200, 0.74);
}
#news-cinematic .nx-empty-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 18px;
  color: #f3f5f9;
  margin: 0;
}
#news-cinematic .nx-empty-hint {
  font-size: 12px;
  color: rgba(170, 180, 200, 0.62);
  margin: 0;
}
#news-cinematic .nx-error-msg {
  font-size: 13px;
  color: rgba(244, 196, 196, 0.92);
  max-width: 480px;
}

/* Hide the existing dossier and timeline triggers while news mode is on,
   same pattern as body.cinematic for timeline. */
body.cinematic-now #stories-panel,
body.cinematic-now #stories-backdrop,
body.cinematic-now #timeline-trigger,
body.cinematic-now #lens-trigger {
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.32s ease;
}
body.cinematic-now #mode-banner {
  opacity: 0;
  pointer-events: none;
}

/* Responsive: on narrow viewports, stack main + previews vertically */
@media (max-width: 900px) {
  #news-cinematic .nx-body {
    grid-template-columns: 1fr;
  }
  #news-cinematic .nx-previews {
    flex-direction: row;
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: 8px;
    /* Snap one dispatch per swipe instead of a loose continuous scroll. */
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scroll-padding-left: 16px;
  }
  #news-cinematic .nx-preview {
    min-width: 240px;
    flex-shrink: 0;
    scroll-snap-align: start;
  }
  #news-cinematic .nx-load-more {
    flex-shrink: 0;
    white-space: nowrap;
  }
}


/* ============================================================ */
/* Timeline diaporama — top-right slideshow window in cinematic
   mode. Sits to the right of the #timeline-context dossier panel
   on the left, ~half its width. Two image layers crossfade. */
/* ============================================================ */
#timeline-diaporama {
  position: fixed;
  right: 48px;
  top: 6vh;
  /* Responsive across browser widths. clamp() picks a fluid value:
       min  - never go below 360px wide / 280px tall (small laptop)
       pref - 42vw × 52vh (scales smoothly with the viewport)
       max  - cap at 880px × 720px on ultrawide monitors so the
              window never dwarfs the dossier panel.
     The blinking location marker lands in the lower-right quadrant
     below this frame; the camera offset in flyCameraToLatLon's
     cinematic-mode branch is tuned to keep it fully unobscured. */
  width: clamp(360px, 42vw, 880px);
  height: clamp(280px, 52vh, 720px);
  background: linear-gradient(
    180deg,
    rgba(10, 14, 24, 0.82) 0%,
    rgba(6, 10, 18, 0.88) 100%
  );
  backdrop-filter: blur(22px) saturate(140%);
  -webkit-backdrop-filter: blur(22px) saturate(140%);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 18px;
  overflow: hidden;
  box-shadow: 0 28px 70px rgba(0, 0, 0, 0.5);
  opacity: 0;
  pointer-events: none;
  transform: translateX(14px);
  transition: opacity 0.4s ease, transform 0.4s ease;
  z-index: 94;
}
#timeline-diaporama.visible {
  opacity: 1;
  transform: translateX(0);
  pointer-events: auto;
}
#timeline-diaporama[hidden] { display: none; }

#timeline-diaporama .td-frame {
  position: relative;
  width: 100%;
  height: 100%;
  background-color: rgba(0,0,0,0.6);
}
#timeline-diaporama .td-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover; /* fill the frame; archival photos read better at a
                       generous size, even with light cropping. */
  object-position: center;
  opacity: 0;
  transition: opacity 1.1s ease-in-out;
  user-select: none;
  pointer-events: none;
}
#timeline-diaporama .td-img.td-show { opacity: 1; }

#timeline-diaporama .td-credit {
  position: absolute;
  left: 12px;
  bottom: 12px;
  padding: 4px 9px;
  background: rgba(0,0,0,0.55);
  border-radius: 999px;
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.78);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  max-width: calc(100% - 24px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#timeline-diaporama .td-credit:empty { display: none; }

#timeline-diaporama .td-controls {
  position: absolute;
  right: 10px;
  top: 10px;
  display: flex;
  gap: 6px;
  background: rgba(0,0,0,0.42);
  padding: 4px 6px;
  border-radius: 999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  /* Always faintly visible so users can find the prev/next arrows,
     fully visible on hover. Previously opacity: 0 meant the controls
     were invisible until the mouse entered the frame, and users
     couldn't tell the slideshow was navigable. */
  opacity: 0.55;
  transition: opacity 0.2s ease;
}
#timeline-diaporama:hover .td-controls,
#timeline-diaporama:focus-within .td-controls {
  opacity: 1;
}
#timeline-diaporama .td-controls button {
  background: transparent;
  border: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  color: rgba(255,255,255,0.85);
  font-size: 12px;
  cursor: pointer;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
#timeline-diaporama .td-controls button:hover { color: #fff; background: rgba(255,255,255,0.08); }
#timeline-diaporama .td-controls button[disabled] {
  cursor: not-allowed;
  opacity: 0.4;
}
/* The video button only appears on moments that have a curated video;
   playback happens inline (the diaporama window itself becomes the
   player), never an external redirect. */
#timeline-diaporama .td-video {
  display: none !important;
  border-left: 1px solid rgba(255,255,255,0.18) !important;
  margin-left: 2px;
  border-radius: 0 11px 11px 0 !important;
  padding-left: 6px !important;
}
/* A curated video for this moment lights the button warm gold. */
#timeline-diaporama .td-video.td-has-video {
  display: inline-flex !important;
  color: rgba(248, 212, 140, 0.95) !important;
  background: rgba(248, 212, 140, 0.12) !important;
}
/* While the video plays, the button becomes a stop control. */
#timeline-diaporama .td-video.td-playing {
  color: #fff !important;
  background: rgba(255, 255, 255, 0.16) !important;
}

/* ---- Inline diaporama video: the window itself becomes the player --- */
#timeline-diaporama .td-stage {
  position: absolute;
  inset: 0;
  z-index: 2;            /* above the image layers... */
  background: #000;
  display: none;
}
#timeline-diaporama.td-video-playing .td-stage { display: block; }
#timeline-diaporama .td-stage iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
/* ...but keep the controls above the player so stop / prev / next stay
   clickable while a video is on screen. */
#timeline-diaporama .td-controls { z-index: 3; }

#timeline-diaporama .td-dots {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  display: flex;
  gap: 6px;
  background: rgba(0,0,0,0.45);
  padding: 5px 10px;
  border-radius: 999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
#timeline-diaporama .td-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255,255,255,0.35);
  transition: background 0.18s ease, transform 0.18s ease;
  cursor: pointer;
  border: 0;
  padding: 0;
}
#timeline-diaporama .td-dot.active {
  background: #ffffff;
  transform: scale(1.25);
}

/* Empty state — when the current arc entry has no images yet, hide
   the entire diaporama window. The dossier reads as a single text
   panel until images land via fetch_arc_images.py. */
#timeline-diaporama.td-empty {
  opacity: 0 !important;
  pointer-events: none !important;
  /* Keep .visible class active so the show/hide pipeline isn't disturbed,
     but visually we're invisible until td-empty is removed. */
}

/* When we render the diaporama externally, the inline image inside the
   timeline-context panel is redundant — keep it out of the layout so
   the dossier text gets the full panel. */
#timeline-context .tc-image { display: none !important; }

/* Window stays top-right at every reasonable laptop / desktop size.
   Below 700px (phone-sized) we shrink it but keep it anchored to the
   top so it never collides with the bottom timeline strip. */
@media (max-width: 700px) {
  #timeline-diaporama {
    right: 12px;
    top: 8px;
    width: 44vw;
    height: 28vh;
  }
}

/* In cinematic mode the dossier shares horizontal space with the
   diaporama window. Constrain it to clamp(360-660px / 38vw) so the
   two panels never collide on medium-width viewports. Math:
     diaporama (max 42vw) + dossier (max 38vw) + 96px margins
     = 80vw + 96px, leaves ≥ 20vw of horizontal breathing room
     across all reasonable laptop / desktop sizes. */
body.cinematic #timeline-context {
  width: clamp(360px, 38vw, 660px);
}


/* ============================================================ */
/* Timeline map — bottom-right widget below the diaporama.
   Shows a 2D SVG view of the country containing the current arc
   entry's location. State (if any) is highlighted; a static red
   dot marks the event coordinate. Updates as the timeline moves. */
/* ============================================================ */
#timeline-map {
  position: fixed;
  right: 48px;
  /* Sits ABOVE the bottom timeline rail, BELOW the diaporama. The
     globe's pulsing marker (from showSubjectMarker) lands inside
     this widget's area; the SVG paths are translucent enough that
     the marker shows through. */
  bottom: 14vh;
  width: clamp(360px, 42vw, 880px);
  height: clamp(180px, 28vh, 320px);
  /* Fully transparent panel — country/state outlines float over the
     live globe rendering behind. No backdrop blur, no border, no
     rounded corners — just the geometry, the red dot, and the
     centered label, drawn directly over the globe. */
  background: transparent;
  border: 0;
  border-radius: 0;
  overflow: visible;
  opacity: 0;
  pointer-events: none;
  transform: translateX(14px);
  transition: opacity 0.36s ease, transform 0.36s ease;
  z-index: 94;
  display: flex;
  align-items: center;
  justify-content: center;
}
#timeline-map.visible {
  opacity: 1;
  transform: translateX(0);
  pointer-events: auto;
}
#timeline-map[hidden] { display: none; }
#timeline-map.tm-empty {
  opacity: 0 !important;
  pointer-events: none !important;
}

#timeline-map .tm-svg-wrap {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px;
  box-sizing: border-box;
}
#timeline-map .tm-svg-wrap svg {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
}

#timeline-map .tm-label {
  position: absolute;
  /* Centered at the bottom of the map, no pill background. */
  left: 50%;
  bottom: 8px;
  transform: translateX(-50%);
  padding: 0;
  background: transparent;
  font-size: 10.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.85);
  text-shadow: 0 1px 4px rgba(0,0,0,0.65);
  max-width: 90%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#timeline-map .tm-label:empty { display: none; }

/* Make sure the diaporama doesn't extend so far down that it would
   collide with the map. With diaporama at top:6vh and clamp 280-720
   high, on shorter viewports it could reach into the map area; cap
   it via max-height in cinematic mode. */
body.cinematic #timeline-diaporama {
  max-height: 50vh;
}

@media (max-width: 700px) {
  #timeline-map {
    right: 12px;
    bottom: 16vh;
    width: 44vw;
    height: 22vh;
  }
}

/* =========================================================================
   MOBILE REFLOW (Phase 2) — body-class scoped so desktop is untouched and
   these win over the width-based @media rules above (higher specificity +
   later in the cascade). Heavy reflow targets .is-phone; .is-mobile (phone OR
   tablet) is used where tablets benefit too. Safe-area vars keep docked UI
   clear of notches / home indicators.
   ========================================================================= */

/* --- Bottom action dock (see index.html + setupMobileDock in main.js) ----
   Desktop: display:contents, so each relocated trigger keeps its own fixed
   corner position. Phone: one centered, thumb-reachable row; contextually
   hidden triggers are skipped by flex so the row stays balanced. */
#mobile-dock { display: contents; }
body.is-phone #mobile-dock {
  display: flex;
  position: fixed;
  left: 0; right: 0;
  bottom: calc(10px + var(--safe-bottom));
  justify-content: center;
  align-items: center;
  gap: 16px;
  z-index: 96;
  pointer-events: none;                /* gaps stay click-through to the globe */
}
/* The back button is excluded — it has bespoke collapsible sizing (see
   #mobile-back) so it can animate its width to zero and let the deck re-center. */
body.is-phone #mobile-dock > button:not(#mobile-back) {
  position: static;
  inset: auto;
  transform: none;
  margin: 0;
  width: 46px; height: 46px;           /* comfortable tap targets */
  pointer-events: auto;
}
/* Hide the dock when the Explore drawer is open (it sits above the drawer
   otherwise). #atlas-index precedes #mobile-dock among the body's children. */
body.is-phone #atlas-index.visible ~ #mobile-dock { display: none; }

/* --- Search lens: a compact, contained glass pill centred above the dock. The
   old full-width outlined box read as oversized; this is smaller, refined, and
   carries a magnifier so the placeholder needn't shout across the whole bar. */
body.is-phone #lens-panel {
  left: 50%;
  right: auto;
  transform: translateX(-50%);
  width: min(260px, calc(100vw - 110px));
  bottom: calc(66px + var(--safe-bottom));
  height: 28px;
  border-radius: 14px;
  padding: 0 12px;
  background: rgba(12, 14, 20, 0.46);
  backdrop-filter: blur(20px) saturate(120%);
  -webkit-backdrop-filter: blur(20px) saturate(120%);
  border-color: rgba(255, 255, 255, 0.1);
}
body.is-phone #lens-panel .lens-icon { margin-right: 6px; }
body.is-phone #lens-suggestions {
  left: 50%;
  right: auto;
  transform: translateX(-50%);
  width: min(260px, calc(100vw - 110px));
  bottom: calc(100px + var(--safe-bottom));
  max-height: 46vh;
}
/* Tablet keeps 16px (the safe anti-zoom size). Phone goes smaller (13px) and
   leans on the viewport-scale lock (preventIosInputZoom) to stop the iOS
   focus-zoom, so the search text reads compact rather than oversized. */
body.is-touch #lens-input { font-size: 16px; }
body.is-phone #lens-input { font-size: 13px; }
body.is-phone #lens-input,
body.is-phone #lens-input::placeholder { letter-spacing: 0.08em; }

/* --- Top corners: keep the menu + exit-earth clear of the notch ---------- */
body.is-mobile #atlas-index-toggle {
  top: calc(14px + var(--safe-top));
  left: calc(14px + var(--safe-left));
}
body.is-mobile #exit-earth {
  top: calc(12px + var(--safe-top));
  right: calc(12px + var(--safe-right));
}
/* Phone: the desktop pill (9.5px text at 0.28em tracking) renders oversized —
   the wide tracking alone makes "SOLAR SYSTEM" eat ~half the width. Tighten the
   type, tracking and padding into a compact, refined chip that sits lightly in
   the corner instead of competing with the globe. */
body.is-phone #exit-earth {
  font-size: 8.5px;
  letter-spacing: 0.14em;
  padding: 6px 12px;
  color: rgba(255, 255, 255, 0.6);
}
/* Drawer: a touch wider on phone; clear the notch; lighten blur on weak GPUs. */
body.is-phone #atlas-index {
  box-sizing: border-box;          /* keep padding inside the width (no overflow) */
  width: min(86vw, 360px);
  padding-top: calc(84px + var(--safe-top));
}
body.is-low-power #atlas-index {
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* --- Declutter: the ambient date stamp isn't worth the space on a phone,
   and it would collide with the menu button in the top-left corner. --- */
body.is-phone #datetime { display: none; }

/* =========================================================================
   BOTTOM-SHEET DOSSIER (Phase 3) — on phone the right-anchored atlas card
   becomes a draggable bottom sheet: full-width, rounded top, a drag handle,
   sliding up from the bottom over the existing scrim. Drag the header down to
   dismiss (JS: setupDossierSheet in main.js).
   ========================================================================= */
body.is-phone #stories-panel.atlas {
  top: auto;
  bottom: 0;
  left: 0;
  right: 0;
  width: auto;
  height: 82vh;
  max-height: 82vh;
  border-radius: 18px 18px 0 0;
  border-bottom: 0;
  transform: translateY(100%);
  transition: transform 0.36s cubic-bezier(.22,.72,.2,1), opacity 0.2s ease;
}
body.is-phone #stories-panel.atlas.visible { transform: translateY(0); }
/* While the finger drags the sheet, drop the transition so it tracks 1:1. */
body.is-phone #stories-panel.atlas.sheet-dragging { transition: none; }
/* Grab handle centered at the top edge. */
body.is-phone #stories-panel.atlas::before {
  content: '';
  position: absolute;
  top: 8px; left: 50%;
  transform: translateX(-50%);
  width: 40px; height: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.28);
  z-index: 6;
  pointer-events: none;
}
body.is-phone #stories-panel.atlas .sp-head { padding-top: 22px; }
/* Phone glass: a translucent sheet with the globe softly blurred through it —
   leaning into the confluence's see-through beauty. Lower opacity so the globe
   reads through it; a heavier blur keeps the dense article text legible. */
body.is-phone #stories-panel.atlas {
  background: linear-gradient(180deg, rgba(13,16,26,0.31), rgba(7,9,15,0.40));
  /* LIGHT blur (like the confluence's 2px) so the globe stays recognizable
     through the glass. A heavy blur averages the dark globe into a flat smear
     that just reads as opaque — which is what went wrong before. */
  backdrop-filter: blur(6px) saturate(130%);
  -webkit-backdrop-filter: blur(6px) saturate(130%);
  /* The globe now shows in detail, so a stronger shadow defines the text. */
  text-shadow: 0 1px 8px rgba(0,0,0,0.78);
}
body.is-phone #stories-panel.atlas .sp-head {
  background: linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0)), rgba(11,14,22,0.26);
}
body.is-phone #stories-panel .sp-cat-switch { background: rgba(11,14,22,0.24); }
/* Hide the left rail while a dossier sheet is open on phone. */
body.is-phone.dossier-open #category-rail { display: none; }
/* The dock would sit under the open sheet; relocate it to the top strip and
   keep only the timeline-trigger (shown when a timeline is available for the
   open subject) so the cinematic timeline stays launchable on phone — matching
   desktop, where the trigger is visible alongside the dossier. */
body.is-phone.dossier-open #mobile-dock {
  top: calc(60px + var(--safe-top));
  right: calc(12px + var(--safe-right));
  left: auto;
  bottom: auto;
  justify-content: flex-end;
}
/* Keep the timeline + news triggers reachable as FABs over the open sheet
   (each shows only when eligible for the current scope); hide the rest. */
body.is-phone.dossier-open #mobile-dock > button:not(#timeline-trigger):not(#now-trigger):not(#mobile-back) { display: none; }

/* =========================================================================
   CINEMATIC / TIMELINE MODE (Phase 3, phone) — the desktop layout floats the
   image player and an event card at fixed offsets that overflow a phone. On
   phone, stack vertically: image player on top, event text below it (scrolls),
   timeline strip pinned at the bottom. The small territory map is dropped (it
   competes for space the player already owns).
   ========================================================================= */
body.is-phone.cinematic #mobile-dock { display: none; }   /* strip is the nav here */
/* Heights use dvh (with a vh fallback) so the stack doesn't jump when iOS
   Safari's URL bar shows/hides during a scroll — that shift was the "overlaps
   the strip then retracts when I stop dragging" bug. */
body.is-phone #timeline-diaporama {
  top: calc(8px + var(--safe-top));
  left: 8px; right: 8px; bottom: auto;
  width: auto;
  height: 34vh;
  height: 34dvh;
}
body.is-phone #timeline-context {
  top: calc(34vh + 16px + var(--safe-top));
  top: calc(34dvh + 16px + var(--safe-top));
  left: 8px; right: 8px;
  bottom: calc(104px + var(--safe-bottom));   /* gap above the strip, never overlapping */
  width: auto;
  max-width: none;
  max-height: none;
  padding: 26px 22px 30px;                    /* desktop 44px side padding is too wide here */
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  /* See-through over the globe (confluence-style). LIGHT blur so the globe
     stays recognizable; a stronger shadow defines the text. A heavy blur just
     smears the dark globe into a flat opaque-looking field. */
  background: linear-gradient(180deg, rgba(13,16,26,0.31), rgba(7,9,15,0.40));
  backdrop-filter: blur(6px) saturate(130%);
  -webkit-backdrop-filter: blur(6px) saturate(130%);
  text-shadow: 0 1px 8px rgba(0,0,0,0.78);
}
/* Text-only moment: no diaporama above, so let the reading card rise to fill the
   space (from near the top down to just above the time strip). */
body.is-phone.cinematic-text-only #timeline-context {
  top: calc(10vh + var(--safe-top));
  top: calc(10dvh + var(--safe-top));
  bottom: calc(96px + var(--safe-bottom));
}
body.is-phone #timeline-map { display: none; }
body.is-phone #timeline-track {
  left: 0; right: 0;
  width: auto;
  transform: none;                /* base uses left:50% + translateX(-50%) to center */
  bottom: calc(6px + var(--safe-bottom));
  background: rgba(8, 10, 16, 0.96);   /* opaque so scrolling text never shows through it */
}
/* Leader-bio video window (opens when a ruler is tapped in a timeline): full
   width at the top. Its z-index sits above the event player, so it cleanly
   takes over the top slot while open and reveals the player again on close. */
body.is-phone .tt-leader-vidwin {
  left: 8px; right: 8px;
  width: auto;
  top: calc(8px + var(--safe-top));
  height: 38vh;
}

/* =========================================================================
   NEWS VIEW (cinematic-now) on phone — the dock FABs floated over the header,
   and the desktop padding (64px/40px) cramped a narrow screen.
   ========================================================================= */
body.is-phone.cinematic-now #mobile-dock { display: none; }   /* FABs were over the header */
/* No horizontal padding so the article card spans the full screen width — this
   lets the hero image (its negative side-margins) bleed to both edges. */
body.is-phone #news-cinematic {
  padding: calc(16px + var(--safe-top)) 0 calc(20px + var(--safe-bottom));
}
body.is-phone #news-cinematic .nx-header {
  padding: 0 16px;              /* re-inset the header text (the outer padding is gone) */
  margin-bottom: 16px;
  gap: 8px;
  letter-spacing: 0.2em;        /* desktop 0.32em made "UNITED STATES" too wide */
}
body.is-phone #news-cinematic .nx-main-title { font-size: 22px; line-height: 1.2; }
/* Same see-through glass as the dossier/cinematic — the globe reads through the
   dispatch card. Full width + squared off so the hero image covers the top. */
body.is-phone #news-cinematic .nx-main {
  background: linear-gradient(180deg, rgba(13,16,26,0.31), rgba(7,9,15,0.40));
  backdrop-filter: blur(6px) saturate(130%);
  -webkit-backdrop-filter: blur(6px) saturate(130%);
  text-shadow: 0 1px 8px rgba(0,0,0,0.78);
  border: none;
  border-radius: 0;
}
/* Hero image: full-bleed across the entire top, taller, square corners. The
   inherited negative side-margins (-28px) now reach the screen edges because the
   card is full width; the negative top margin pulls it to the card's top. */
body.is-phone #news-cinematic .nx-main-image-wrap {
  width: auto;                 /* with the -28px side margins, expands to BOTH edges */
  aspect-ratio: 16 / 11;
  border-radius: 0;
  margin-bottom: 22px;
}
/* Phone: news = a max-window article + a small persistent bottom strip you
   swipe to page through stories. The strip is a centred carousel — the current
   dispatch sits in the middle with its neighbours peeking; a JS handler pages
   exactly ONE per swipe and re-centres (no loose horizontal scroll). */
body.is-phone #news-cinematic .nx-previews {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  gap: 10px;
  position: fixed;
  left: 0; right: auto;
  bottom: calc(12px + var(--safe-bottom));
  width: max-content;
  max-width: none;
  margin: 0;
  padding: 0;
  overflow: visible;
  scroll-snap-type: none;
  transform: translateX(0);
  transition: transform 0.34s cubic-bezier(.22,.72,.2,1);
  will-change: transform;
  touch-action: none;
  z-index: 25;
}
body.is-phone #news-cinematic .nx-preview {
  position: relative;
  flex: 0 0 74vw;
  min-width: 0;
  width: auto;
  height: 68px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  padding: 10px 15px;
  border-radius: 13px;
  background: linear-gradient(180deg, rgba(15,18,28,0.62), rgba(9,11,18,0.72));
  border: 1px solid rgba(255,255,255,0.08);
  backdrop-filter: blur(8px) saturate(120%);
  -webkit-backdrop-filter: blur(8px) saturate(120%);
  opacity: 0.42;
  transform: scale(0.94);
  transition: opacity 0.3s ease, transform 0.3s ease, border-color 0.3s ease;
}
/* The card you've browsed to (centred) — brightened, the one a tap would open. */
body.is-phone #news-cinematic .nx-preview.focus {
  opacity: 1;
  transform: scale(1);
  border-color: rgba(255,255,255,0.22);
}
/* The dispatch currently open in the article window — a small gold dot so you
   can see which you're reading while you browse the others. */
body.is-phone #news-cinematic .nx-preview.active::after {
  content: '';
  position: absolute;
  top: 8px; right: 11px;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: rgba(248,212,140,0.95);
  box-shadow: 0 0 6px rgba(248,212,140,0.6);
}
body.is-phone #news-cinematic .nx-preview-image-wrap { display: none; }
body.is-phone #news-cinematic .nx-preview-framing { display: none; }
body.is-phone #news-cinematic .nx-preview-text { min-width: 0; }
body.is-phone #news-cinematic .nx-preview-meta {
  font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase;
  color: rgba(255,255,255,0.5); display: flex; gap: 6px;
}
body.is-phone #news-cinematic .nx-preview-title {
  font-size: 12.5px; line-height: 1.25; color: #eef1f7;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* The article window STOPS above the strip: reserve the strip's zone on the body
   so .nx-main ends cleanly above it (its text no longer bleeds behind the cards). */
body.is-phone #news-cinematic .nx-body { padding-bottom: calc(96px + var(--safe-bottom)); }

/* =========================================================================
   TIMELINE empire navigation on phone — instead of stealing vertical space
   with a separate strip, the timeline BAR ITSELF is the navigator: swipe it
   sideways to step through the chain of empires that ruled this land (one
   swipe = previous/next ruler), exactly like clicking a desktop peek. The
   dossier above keeps its full height. Two supporting pieces of styling:
   (1) make the step's horizontal cross-slide work on the full-width phone
   bar, and (2) reduce the off-screen desktop peek cards to small era-tinted
   chevrons pinned at the bar's edges — a quiet "earlier/later this way" cue.
   ========================================================================= */

/* (1) Phone cross-slide. The desktop clone/arriving transforms centre with
   translateX(-50%); the phone bar is full-width (transform:none), so override
   with plain translateX so the old bar slides fully out and the new slides in. */
body.is-phone #timeline-track.tt-clone { transform: translateX(0); }
body.is-phone #timeline-track.tt-clone.tt-clone-leaving-left  { transform: translateX(-102%); opacity: 0; }
body.is-phone #timeline-track.tt-clone.tt-clone-leaving-right { transform: translateX(102%);  opacity: 0; }
body.is-phone #timeline-track.tt-arriving-from-left  { transform: translateX(-102%); opacity: 0; }
body.is-phone #timeline-track.tt-arriving-from-right { transform: translateX(102%);  opacity: 0; }

/* (2) Edge chevrons. The 184px peek CARDS don't fit a narrow screen (they'd
   poke a sliver in from the side), so strip them to just their ‹ / › arrow,
   tinted with the neighbouring empire's globe colour, pinned at the bar edge.
   They keep the existing click→step wiring, so a tap also works. */
body.is-phone #timeline-track .tt-peek {
  width: auto;
  padding: 0;
  background: none;
  border: none;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  z-index: 3;
}
body.is-phone #timeline-track .tt-peek::after { display: none; }   /* the mini-axis line */
body.is-phone #timeline-track .tt-peek-label,
body.is-phone #timeline-track .tt-peek-name,
body.is-phone #timeline-track .tt-peek-range { display: none; }    /* names/labels — too wide here */
body.is-phone #timeline-track .tt-peek-meta { margin: 0; gap: 0; }
body.is-phone #timeline-track .tt-peek-arrow {
  font-size: 21px;
  line-height: 1;
  color: var(--tt-peek-accent, rgba(248,212,140,0.85));
  text-shadow: 0 1px 6px rgba(0,0,0,0.65);
}
body.is-phone #timeline-track .tt-peek-prev { left: 5px;  right: auto; top: 50%; transform: translateY(-50%); }
body.is-phone #timeline-track .tt-peek-next { right: 5px; left: auto;  top: 50%; transform: translateY(-50%); }
body.is-phone #timeline-track .tt-peek.tt-peek-ready { opacity: 0.55; }

/* =========================================================================
   ERA SCRUBBER (earth-level timeline) on phone — the desktop period-label band
   (ANCIENT / CLASSICAL / LATE ANTIQUITY / ...) can't fit a narrow screen and
   prints on top of itself. Drop it (the current era is already named in the
   panel header) and thin the bar to a lean year-axis + handle.
   ========================================================================= */
body.is-phone #era-scrubber .es-eras { display: none; }
body.is-phone #era-scrubber .es-bar { height: 50px; }
body.is-phone #era-scrubber .es-track { top: 22px; }
body.is-phone #era-scrubber .es-marks { top: 26px; }
/* Bands sit on the phone track (top:22px). */
body.is-phone #era-scrubber .es-bands { top: 20px; }
/* The panel + scrubber carry desktop widths that overflow a narrow phone (the
   panel is right-anchored at 360px, so its left edge falls off-screen; the
   scrubber is centered with translateX(-50%)). Reflow both to full width. */
/* Wrapper is inert by default (desktop, and phone before scrubber) — the panel
   positions itself via its own rules. */
#era-panel-wrap { display: contents; }
/* Phone: the wrapper provides robust top+bottom bounds — browser-computed, so
   they track the iOS URL bar where vh/dvh/svh don't. The panel inside sizes to
   its content but is capped at those bounds (max-height:100% of the wrapper),
   so it ADAPTS to content yet can never reach the scrubber. */
body.is-phone #era-panel-wrap {
  display: flex;
  flex-direction: column;
  position: fixed;
  top: calc(56px + var(--safe-top));
  bottom: calc(116px + var(--safe-bottom));
  left: 8px; right: 8px;
  pointer-events: none;
  z-index: 20;
}
body.is-phone #era-panel {
  position: static;
  top: auto; left: auto; right: auto; bottom: auto;
  width: auto;
  margin: 0;
  max-height: 100%;     /* cap at the wrapper bounds; scrolls when a busy year overflows */
  pointer-events: auto;
  /* Phone glass: match the dossier / timeline / news windows — the globe reads
     through it instead of the opaque desktop slab (which was 0.82–0.88). Light
     6px blur keeps the globe recognizable; the text-shadow holds the dense
     empire/event list legible over it. */
  background: linear-gradient(180deg, rgba(13,16,26,0.31), rgba(7,9,15,0.40));
  backdrop-filter: blur(6px) saturate(130%);
  -webkit-backdrop-filter: blur(6px) saturate(130%);
  text-shadow: 0 1px 8px rgba(0,0,0,0.78);
}
/* The earth-level timeline (era scrubber) is its own mode; hide the browsing
   chrome — the POWER/MONEY rail was showing faintly behind the panel. */
body.scrubber-mode #category-rail,
body.scrubber-mode #lens-trigger,
body.scrubber-mode #help-btn {
  opacity: 0;
  pointer-events: none;
}
body.is-phone #era-scrubber {
  left: 8px; right: 8px;
  width: auto;
  transform: none;
  bottom: calc(8px + var(--safe-bottom));
  padding: 20px 44px 14px 18px;
}
/* The dock sits over the scrubber's year axis; hide it while scrubbing.
   (#era-scrubber precedes #mobile-dock among the body's children.) */
body.is-phone #era-scrubber.visible ~ #mobile-dock { display: none; }

/* =========================================================================
   UNIVERSAL BACK (touch) — a discreet chevron just right of the menu that
   appears whenever there's somewhere to step back (a panel open, or drilled
   into a continent/country/state). A tap fires a synthetic Escape (see
   setupTouchBack in main.js), reusing the desktop step-back stack. Immersive
   modes (cinematic / news / scrubber) carry their own × close, so it's hidden
   there to avoid two back affordances.
   ========================================================================= */
#mobile-back {
  position: fixed;
  /* Tablet default (its dock is display:contents, so the back keeps its own
     fixed corner): bottom-left. Phone overrides this into the deck below. */
  bottom: calc(11px + var(--safe-bottom));
  left: calc(16px + var(--safe-left));
  top: auto;
  width: 46px; height: 46px;
  display: none;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(12, 14, 20, 0.72);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: rgba(232, 232, 232, 0.86);
  cursor: pointer;
  z-index: 96;
  transition: background 0.2s ease, border-color 0.2s ease;
}
body.is-mobile.can-step-back #mobile-back { display: flex; }

/* --- Phone: the back is the LEADING item of the bottom deck, not a detached
   corner button. It lives inside #mobile-dock (see setupMobileDock) and
   collapses its width/margin/opacity (rather than display) so the deck glides
   and re-centers as it appears/disappears. The negative right-margin cancels
   the dock's 16px gap while collapsed so no phantom gap is left behind. --- */
body.is-phone #mobile-back {
  position: static;
  display: flex;
  box-sizing: border-box;       /* width includes border so it collapses to 0 */
  flex: 0 0 auto;
  width: 0; min-width: 0; height: 46px;
  padding: 0;                   /* the button's default padding kept it ~14px */
  margin: 0 -16px 0 0;          /* cancel the dock gap to the next item */
  opacity: 0;
  overflow: hidden;
  pointer-events: none;
  transition: width 0.34s cubic-bezier(.2,.7,.2,1),
              margin 0.34s cubic-bezier(.2,.7,.2,1),
              opacity 0.26s ease,
              background 0.2s ease, border-color 0.2s ease;
}
body.is-phone.can-step-back #mobile-back {
  width: 46px;
  margin: 0;                    /* dock gap now provides the spacing */
  opacity: 1;
  pointer-events: auto;
}
/* In a dossier the deck relocates to the top-right FABs; lift the back out of
   the row to the top-left — level with the news icon, mirroring it, below the
   menu. Fixed so it ignores the relocated row. Covers phone + tablet. */
body.is-mobile.dossier-open #mobile-back {
  position: fixed;
  top: calc(60px + var(--safe-top));
  left: calc(12px + var(--safe-left));
  bottom: auto; right: auto;
  width: 46px;
  margin: 0;
  opacity: 1;
  overflow: visible;
  pointer-events: auto;
}
/* Immersive modes carry their own × close; the dock (and thus the back inside
   it) is already hidden there, but assert it for safety. */
body.cinematic #mobile-back,
body.cinematic-now #mobile-back,
body.scrubber-mode #mobile-back { display: none; }
#mobile-back:active { background: rgba(255, 255, 255, 0.12); }

/* =========================================================================
   DOSSIER = FULL PAGE on phone — bring the category dossier in line with the
   other immersive modes (timeline / news). It used to be an 82vh bottom sheet
   with its navigation scattered to the top corners. Now it fills the screen,
   hides the globe-browsing chrome (menu, Solar-System chip, lens, help) the way
   those modes do, and keeps the standard bottom dock — Back · News · Timeline —
   pinned at the bottom like everywhere else, instead of the corners.
   ========================================================================= */
body.is-phone #stories-panel.atlas {
  top: 0;
  bottom: 0;
  height: 100vh;
  height: 100dvh;
  max-height: none;
  border-radius: 0;
  border: none;
}
body.is-phone #stories-panel.atlas::before { display: none; }   /* no bottom-sheet grab handle on a full page */
body.is-phone #stories-panel.atlas .sp-head { padding-top: calc(16px + var(--safe-top)); }   /* clear the notch */
/* Reserve the bottom dock's band so the dossier's last lines clear the
   Back · News · Timeline bar rather than hiding behind it. */
body.is-phone #stories-panel.atlas .sp-dossier { padding-bottom: calc(84px + var(--safe-bottom)); }
/* Soft fade at the foot of the page so prose dissolves cleanly behind the
   floating dock instead of colliding with it mid-scroll. */
body.is-phone #stories-panel.atlas::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: calc(92px + var(--safe-bottom));
  background: linear-gradient(to top, rgba(7,9,15,0.86) 0%, rgba(7,9,15,0.52) 46%, rgba(7,9,15,0) 100%);
  pointer-events: none;
  z-index: 5;
}

/* Hide the globe-browsing chrome while the full-page dossier is open — same as
   timeline / news mode (and the "menu + Solar System only on the globe" wish). */
body.is-phone.dossier-open #exit-earth,
body.is-phone.dossier-open #atlas-index-toggle,
body.is-phone.dossier-open #lens-trigger,
body.is-phone.dossier-open #help-btn {
  opacity: 0;
  pointer-events: none;
}

/* Keep the dock at the bottom (override the old top-right relocation). */
body.is-phone.dossier-open #mobile-dock {
  top: auto;
  bottom: calc(10px + var(--safe-bottom));
  left: 0; right: 0;
  justify-content: center;
}
/* Keep Back as the leading item of that bottom dock (override the top-left lift). */
body.is-phone.dossier-open #mobile-back {
  position: static;
  inset: auto;
  width: 46px;
  margin: 0;
  opacity: 1;
  overflow: visible;
  pointer-events: auto;
}
