/* ═══════════════════════════════════════════════════════════
   VIA — Ancient World Explorer  |  style.css
   ═══════════════════════════════════════════════════════════ */

/* ── RESET & BASE ── */
*, *::before, *::after { margin:0; padding:0; box-sizing:border-box; }

:root {
  --gold:       #d4a853;
  --gold-dim:   rgba(212,168,83,0.45);
  --gold-faint: rgba(212,168,83,0.12);
  --ink:        #110a00;
  --ink-panel:  rgba(10,5,0,0.97);
  --parchment:  #f0e6d3;
  --text-muted: rgba(240,230,211,0.55);
  --text-body:  rgba(240,230,211,0.78);
  --border:     rgba(212,168,83,0.22);
  /* Colorblind-safe quest palette: amber / blue / purple, no red-green pair.
     Tiers are ALSO shape-coded on the map (circle / diamond / triangle) so
     they're distinguishable without relying on color at all. */
  --quest-photo:    #ff9e2c;
  --quest-location: #2b8cde;
  --quest-text:     #b15ad6;
  --panel-width: 380px;

  /* ── TYPE SCALE ──────────────────────────────────────────────────────
     One documented ramp. Every `font-size` references a token below — no
     raw px in declarations (grep guard in the Rams refine). Steps are keyed
     to their pixel value for self-documentation. The four former half-pixel
     orphans (8.5/10.5/11.5/12.5) were snapped to the nearest whole step
     (sub-0.5px, imperceptible). Rough usage: 8–10 map micro-labels &
     captions · 11–13 UI/body text · 14–19 subheads/labels · 20+ modal &
     hero display glyphs. (Aggressive display-size consolidation was left
     for a designer pass — these steps are documented, not yet merged.) */
  --fs-8: 8px;   --fs-9: 9px;   --fs-10: 10px; --fs-11: 11px; --fs-12: 12px;
  --fs-13: 13px; --fs-14: 14px; --fs-15: 15px; --fs-16: 16px; --fs-17: 17px;
  --fs-18: 18px; --fs-19: 19px; --fs-20: 20px; --fs-22: 22px; --fs-23: 23px;
  --fs-24: 24px; --fs-26: 26px; --fs-28: 28px; --fs-34: 34px; --fs-38: 38px;
  --fs-40: 40px; --fs-42: 42px; --fs-44: 44px;
}

body {
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  background: var(--ink);
  color: var(--parchment);
  overflow: hidden;
  height: 100dvh;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Keyboard focus ring — gold against ink, only on keyboard navigation. */
:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 2px;
}

/* ── MAP ── */
#map {
  position: fixed;
  inset: 0;
  z-index: 1;
}

/* Ancient-mode floor: a keyless sepia-tinted CARTO light_all base that ALWAYS
   renders, with the Stamen (Stadia Maps) layer stacked on top of it (see
   js/basemap.js). The sepia tint makes the CARTO base fit the ancient view when
   it shows through — i.e. wherever the Stamen layer above fails to authenticate
   or load. The .ancient-sepia-floor class is set on the CARTO base in basemap.js. */
.ancient-sepia-floor {
  filter: sepia(0.5) saturate(0.85);
}

/* Banner element is left in the DOM for backwards compatibility but is now
   never shown — the layered fallback design makes it unnecessary. */
#dare-fallback-banner { display: none !important; }

/* ── TOP BAR ── */
#topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 900;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px 30px;
  background: linear-gradient(to bottom, rgba(10,5,0,0.94) 0%, transparent 100%);
  pointer-events: none;
}

#app-brand { pointer-events: all; }

#app-title {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-28);
  font-weight: 700;
  letter-spacing: 6px;
  color: var(--gold);
  text-shadow: 0 1px 18px rgba(17,10,0,0.85), 0 0 24px rgba(212,168,83,0.32);
  line-height: 1;
}

#app-subtitle {
  font-size: var(--fs-12);
  letter-spacing: 2.4px;
  color: rgba(240,230,211,0.92);
  text-transform: uppercase;
  margin-top: 5px;
  text-shadow: 0 1px 12px rgba(10,5,0,0.95);
}

#topbar-search {
  position: absolute;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  width: min(420px, calc(100vw - 360px));
  pointer-events: all;
}

#site-search-input {
  width: 100%;
  height: 42px;
  padding: 0 15px;
  border-radius: 999px;
  border: 1px solid rgba(212,168,83,0.4);   /* match the control chips' gold outline */
  background: rgba(10,5,0,0.9);
  color: var(--parchment);
  font-family: 'Inter', sans-serif;
  font-size: var(--fs-14);
  outline: none;
  box-shadow: 0 10px 24px rgba(0,0,0,0.2);
}

#site-search-input::placeholder {
  color: rgba(240,230,211,0.45);
}

#site-search-input:focus {
  border-color: rgba(212,168,83,0.55);
  background: rgba(10,5,0,0.96);
}

#site-search-results {
  display: none;
  margin-top: 8px;
  max-height: min(360px, calc(100dvh - 140px));
  overflow-y: auto;
  background: rgba(10,5,0,0.96);
  border: 1px solid rgba(212,168,83,0.24);
  border-radius: 14px;
  box-shadow: 0 18px 44px rgba(0,0,0,0.42);
}

#site-search-results.open { display: block; }

.site-search-group-label {
  padding: 10px 14px 6px;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-9);
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: rgba(212,168,83,0.68);
}

.site-search-result {
  width: 100%;
  border: 0;
  border-top: 1px solid rgba(212,168,83,0.12);
  background: transparent;
  color: inherit;
  text-align: left;
  padding: 12px 14px;
  cursor: pointer;
  display: grid;
  gap: 4px;
}

.site-search-result:first-child,
.site-search-empty:first-child {
  border-top: 0;
}

.site-search-result:hover,
.site-search-result:focus-visible,
.site-search-result.active {
  background: rgba(212,168,83,0.12);
}

.site-search-name {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-12);
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--parchment);
}

.site-search-meta {
  font-size: var(--fs-12);
  line-height: 1.4;
  color: var(--text-body);
}

.site-search-match {
  color: rgba(212,168,83,0.9);
}

.site-search-empty {
  padding: 13px 14px;
  font-size: var(--fs-12);
  color: var(--text-muted);
}

/* ── ERA TOGGLE ── */
#era-toggle-wrap {
  position: fixed;
  top: 116px;            /* just below the VIA block (title + Choose-your-world) */
  left: 18px;
  z-index: 905;
  pointer-events: none;
}

/* Desktop "nearest secondary road" hover readout — names the faint Itiner-e
   canvas line under the cursor so you can tell what's tappable. Follows the
   cursor; never intercepts pointer events. */
#road-hover-readout {
  position: fixed;
  z-index: 1200;
  pointer-events: none;
  background: rgba(10,5,0,0.92);
  color: var(--gold);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 3px 8px;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-11);
  letter-spacing: 0.5px;
  white-space: nowrap;
  max-width: 280px;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  transition: opacity 0.12s;
}
#road-hover-readout.show { opacity: 1; }

#era-toggle {
  pointer-events: all;
  display: flex;
  align-items: center;
  background: rgba(10,5,0,0.88);
  /* Shared subtle gold outline (0.4) — matches the Roman Roads / Sites chips so
     every control reads as one family. */
  border: 1px solid rgba(212,168,83,0.4);
  border-radius: 30px;
  padding: 3px;
}

.era-btn {
  padding: 7px 18px;
  border-radius: 25px;
  border: none;
  cursor: pointer;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  letter-spacing: 2px;
  font-weight: 600;
  transition: all 0.3s;
  background: transparent;
  color: rgba(212,168,83,0.82);
}

.era-btn.active {
  background: linear-gradient(135deg, var(--gold), #b8893a);
  color: var(--ink);
  box-shadow: 0 2px 10px rgba(212,168,83,0.3);
}

.era-btn:not(.active):hover { color: var(--gold); }

/* ── MODE TABS (top-level experience switch) ── */
#mode-tabs {
  position: fixed;
  top: 76px;
  left: 18px;
  z-index: 906;                 /* above era toggle (905); below transient overlays */
  display: flex;
  gap: 0;
  padding: 3px;
  background: rgba(10,5,0,0.9);
  border: 1px solid rgba(212,168,83,0.4);
  border-radius: 5px;
  box-shadow: 0 4px 18px rgba(0,0,0,0.4);
  pointer-events: auto;
}
.mode-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 164px;
  border: none;
  background: transparent;
  color: rgba(212,168,83,0.82);
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  letter-spacing: 1.2px;
  font-weight: 600;
  padding: 8px 15px;
  border-radius: 3px;
  cursor: pointer;
  white-space: nowrap;
  transition: color .2s, background .2s;
}
.mode-tab:not(.active):hover { color: var(--gold); }
.mode-tab.active {
  color: var(--ink);
  background: linear-gradient(135deg, var(--gold), #b8893a);
  box-shadow: 0 2px 10px rgba(212,168,83,0.3);
}
.mode-tab-glyph { font-size: var(--fs-13); line-height: 1; }
#mode-alexander .mode-tab-glyph { font-family: 'Cinzel', serif; font-weight: 700; }

/* ── MODE CHROME SWAP ── */
/* The Alexander chip/legend-row is redundant with the tab — hide it always. */
#btn-alexander, #legend-alexander-toggle { display: none !important; }
/* Alexander mode hides Roman-only controls + the Roman legend block. The Detail
   slider (site-density curation) is a Roman concept with no campaign meaning —
   hide both the control and its mobile dock button. */
body.mode-alexander #btn-roads,
body.mode-alexander #btn-sites,
body.mode-alexander #btn-names,
body.mode-alexander #detail-control,
body.mode-alexander #dock-curation,
body.mode-alexander #dock-quest,
body.mode-alexander #roman-legend { display: none; }
/* Campaign legend: hidden by default, shown only in Alexander mode. */
#campaign-legend { display: none; }
body.mode-alexander #campaign-legend { display: block; }

/* ── PER-PAGE MODE NAVIGATION ──
   The deployed experiences stay separate for payload focus, but their sibling
   links render as one persistent two-tab control. */
#mode-crosslink {
  position: fixed;
  top: 76px;
  left: 18px;
  z-index: 906;
  display: none;
  align-items: stretch;
  padding: 3px;
  background: rgba(10,5,0,0.92);
  border: 1px solid rgba(212,168,83,0.45);
  border-radius: 5px;
  box-shadow: 0 4px 18px rgba(0,0,0,0.4);
}
/* World selection now lives on the welcome splash + the brand's "⇄ <world>"
   switch line, so the on-map mode selector is retired everywhere: the tab pair
   and the sibling cross-links never render. (Elements + lock JS are kept so the
   per-page lock still drives chrome/welcome variant.) */
#mode-tabs,
#mode-crosslink { display: none !important; }

/* ── PHASE 3: split-unlock subtractions ──
   On the Roman-locked page the Alexander layer chip + legend row are dead
   controls (no Alexander layer to toggle). Hidden here; kept for ?lock=none
   dual-mode dev. */
body.lock-roman #btn-alexander,
body.lock-roman #legend-alexander-toggle { display: none; }

/* Topbar Key button: mobile-only (folded up from the old dock). Desktop keeps
   the always-open legend, so it stays hidden there. Shown in the ≤640px block. */
#topbar-key { display: none; }
.mode-cross {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 164px;
  padding: 8px 15px;
  border-radius: 3px;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  font-weight: 600;
  letter-spacing: 1.2px;
  color: rgba(240,230,211,0.78);
  text-decoration: none;
  background: transparent;
  transition: background 0.15s ease, color 0.15s ease;
}
.mode-cross:hover { color: var(--gold); background: rgba(212,168,83,0.1); }
.mode-cross.active,
body.lock-roman .mode-cross.to-roman,
body.lock-alexander .mode-cross.to-alexander {
  color: var(--ink);
  background: linear-gradient(135deg, #e0b562, #b98532);
  box-shadow: 0 2px 10px rgba(212,168,83,0.28);
  pointer-events: none;
}

/* Welcome-modal copy variants: one per experience, selected by the lock. Default
   (unlocked dev) shows the dual variant; a locked page shows only its own. */
#welcome-body .wb-variant { display: none; }
#welcome-body .wb-dual { display: block; }
body.lock-roman #welcome-body .wb-dual,
body.lock-alexander #welcome-body .wb-dual { display: none; }
body.lock-roman #welcome-body .wb-roman { display: block; }
body.lock-alexander #welcome-body .wb-alexander { display: block; }
.welcome-cross-link {
  display: inline-block; margin-top: 14px;
  color: var(--gold); text-decoration: none;
  font-size: var(--fs-14); border-bottom: 1px solid rgba(212,168,83,0.4);
  padding-bottom: 1px;
}
.welcome-cross-link:hover { border-bottom-color: var(--gold); }

/* Campaign phase key — the NUMBER is the primary channel (colorblind-safe);
   the color fill is a secondary reinforcement. */
.phase-row { gap: 8px; }
.phase-num {
  flex-shrink: 0;
  width: 17px; height: 17px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  font-weight: 700;
  color: var(--parchment, #f2eadb);
  background: var(--pc, #8f7cc3);
  box-shadow: 0 0 0 1px rgba(240,230,211,0.18);
}
.phase-yrs {
  margin-left: auto;
  color: var(--text-muted, #b8aa91);
  font-size: var(--fs-10);
  letter-spacing: 0.3px;
}

/* Interactive campaign legend — rows are tap-to-spotlight filters. */
#campaign-legend .phase-row,
#campaign-legend .cert-row { cursor: pointer; border-radius: 5px; transition: background .15s; }
#campaign-legend .phase-row:hover,
#campaign-legend .cert-row:hover { background: rgba(240,230,211,0.06); }
/* Selected row: bright gold rail + faint fill — the ROW's own colorblind-safe
   "this is the one lit on the map" cue (luminance, not hue). */
#campaign-legend .phase-row.active,
#campaign-legend .cert-row.active {
  background: rgba(212,168,83,0.16);
  box-shadow: inset 3px 0 0 var(--gold, #d4a853);
}
#campaign-legend .phase-row.active .phase-num { box-shadow: 0 0 0 2px var(--gold, #d4a853); }

/* ── Alexander guided journey ───────────────────────────────
   The journey rail + phase pills live at the top of the info panel and only
   show on .alexander-panel; the launcher floats over the map when no stop is
   open. Prev/Next walk the ordered stops; the pills jump between phases. */
#journey-rail,
#journey-phases { display: none; }
#info-panel.alexander-panel #journey-rail { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
#info-panel.alexander-panel #journey-phases { display: flex; }

#journey-rail .journey-nav {
  flex: 0 0 auto;
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-24); line-height: 1;
  color: var(--gold, #d4a853);
  background: rgba(212,168,83,0.08);
  border: 1px solid rgba(212,168,83,0.38);
  border-radius: 999px;
  cursor: pointer;
  transition: background .15s, opacity .15s;
}
#journey-rail .journey-nav:hover { background: rgba(212,168,83,0.16); }
#journey-rail .journey-nav:disabled { opacity: 0.28; cursor: default; }
#journey-pos { flex: 1 1 auto; text-align: center; min-width: 0; }
#journey-count {
  font-family: 'Cinzel', serif; font-weight: 600;
  font-size: var(--fs-13); letter-spacing: 1px;
  color: rgba(240,230,211,0.92);
}
#journey-phase-label {
  font-size: var(--fs-11); letter-spacing: 0.4px;
  color: rgba(212,168,83,0.75); margin-top: 2px;
}

#journey-phases {
  gap: 6px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  margin-bottom: 14px;
  padding-bottom: 2px;
}
#journey-phases::-webkit-scrollbar { display: none; }
.journey-phase-pill {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 10px 5px 5px;
  background: rgba(20,12,2,0.6);
  border: 1px solid rgba(212,168,83,0.22);
  border-radius: 999px;
  color: rgba(240,230,211,0.78);
  cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}
.journey-phase-pill .jpp-num {
  flex: 0 0 auto;
  width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: 'Cinzel', serif; font-weight: 700; font-size: var(--fs-11);
  color: #110a00; background: var(--pc, #8f7cc3);
  border-radius: 999px;
}
.journey-phase-pill .jpp-label {
  font-size: var(--fs-11); letter-spacing: 0.3px; white-space: nowrap;
}
.journey-phase-pill:hover { border-color: rgba(212,168,83,0.5); color: rgba(240,230,211,0.95); }
.journey-phase-pill.active {
  background: rgba(212,168,83,0.14);
  border-color: var(--gold, #d4a853);
  color: rgba(240,230,211,0.98);
}
.journey-phase-pill.active .jpp-num { box-shadow: 0 0 0 2px var(--gold, #d4a853); }

/* Floating launcher — the calm "enter the journey" affordance over the map. */
#journey-launch { display: none; }
#journey-launch.journey-launch-show {
  display: inline-flex; align-items: center; gap: 9px;
  position: fixed;
  left: 50%; transform: translateX(-50%);
  bottom: 26px;
  z-index: 958;
  padding: 12px 22px;
  font-family: 'Cinzel', serif; font-weight: 600;
  font-size: var(--fs-14); letter-spacing: 1px;
  color: #110a00;
  background: linear-gradient(180deg, #e6c983 0%, #d4a853 100%);
  border: 1px solid rgba(212,168,83,0.6);
  border-radius: 999px;
  box-shadow: 0 6px 22px rgba(0,0,0,0.42), 0 0 0 4px rgba(212,168,83,0.14);
  cursor: pointer;
}
#journey-launch .jl-icon { font-size: var(--fs-11); }

.legend-sub {
  display: block;
  font-size: var(--fs-8);
  letter-spacing: 0.4px;
  color: rgba(184,170,145,0.7);
  margin-top: 1px;
  text-transform: none;
}
/* Clear-highlights control. Kept permanently in the layout (visibility toggled,
   not display) so lighting the first phase doesn't reflow the panel and shove the
   rows out from under the cursor — it only becomes visible/clickable when
   something is lit. */
.legend-clear {
  display: block;
  visibility: hidden;
  width: 100%;
  margin-top: 6px;
  padding: 5px 8px;
  background: rgba(212,168,83,0.1);
  border: 1px solid rgba(212,168,83,0.3);
  border-radius: 5px;
  color: var(--gold, #d4a853);
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  letter-spacing: 0.5px;
  cursor: pointer;
  transition: background .15s;
}
.legend-clear.show { visibility: visible; }
.legend-clear:hover { background: rgba(212,168,83,0.2); }

/* Search/focus BEACON on a campaign stop — a persistent bright dot + an
   expanding white ring. Pure luminance + motion, so a searched place is findable
   regardless of colour vision. Rendered via a divIcon marker (iconSize 0,0), so
   both children centre on the map point. */
.alex-beacon { background: none; border: none; }
/* Colorblind-first locator. Detection can't rely on hue (red-green vision) OR on
   a single luminance — a white-only beacon vanishes on the light satellite/sepia
   basemap. So every element is DUAL-TONE: a dark ring wrapped around a white ring,
   which guarantees a high-contrast edge on any background, light or dark. The dot
   also carries a PERSISTENT halo (not just the fading pulse) so there is always a
   visible mark between pulse sweeps. */
.alex-beacon-dot {
  position: absolute;
  width: 16px; height: 16px;
  margin: -8px 0 0 -8px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid #140a00;
  box-shadow:
    0 0 0 3px rgba(20,10,0,0.92),
    0 0 0 5px rgba(255,255,255,0.98),
    0 0 16px 5px rgba(255,255,255,0.85);
  pointer-events: none;
}
.alex-beacon-ring {
  position: absolute;
  width: 24px; height: 24px;
  margin: -12px 0 0 -12px;
  border-radius: 50%;
  border: 3px solid #fff;
  box-shadow:
    0 0 0 2px rgba(20,10,0,0.85),
    0 0 14px 4px rgba(255,255,255,0.85);
  animation: alexBeaconPulse 1.2s ease-out infinite;
  pointer-events: none;
}
.alex-beacon.bounded .alex-beacon-ring {
  animation: alexBeaconPulse 0.7s ease-out 4;
}
@keyframes alexBeaconPulse {
  0%   { transform: scale(0.45); opacity: 1; }
  70%  { transform: scale(2.7);  opacity: 0.28; }
  100% { transform: scale(3.0);  opacity: 0; }
}

/* Mobile: slim full-width mode strip under the topbar (v2 §8 option A). */
@media (max-width: 640px) {
  #mode-tabs {
    top: calc(env(safe-area-inset-top, 0px) + 82px);
    left: 10px; right: 10px;
    transform: none;
    justify-content: center;
    gap: 2px;
    padding: 2px;
    border-radius: 16px;
  }
  .mode-tab {
    flex: 1 1 0;
    justify-content: center;
    min-width: 0;
    height: 26px;
    font-size: var(--fs-9);
    letter-spacing: 0.35px;
    padding: 0 5px;
    overflow: hidden;
  }
  .mode-tab-glyph { display: none; }
  .mode-tab-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* ── TOPBAR RIGHT (era toggle + profile pill) ── */
#topbar-right {
  pointer-events: all;
  display: flex;
  align-items: center;
  gap: 10px;
}

#profile-pill {
  display: flex;
  align-items: center;
  gap: 7px;
  background: rgba(10,5,0,0.92);
  border: 1px solid var(--gold-dim);
  color: var(--gold);
  border-radius: 30px;
  padding: 7px 16px 7px 11px;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-11);
  letter-spacing: 2px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s;
}
#profile-pill:hover { color: var(--gold); border-color: var(--gold); background: rgba(212,168,83,0.12); }
#profile-pill.signed-in {
  background: linear-gradient(135deg, rgba(212,168,83,0.18), rgba(184,137,58,0.12));
  color: var(--gold);
  border-color: var(--gold-dim);
}
#profile-pill-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px; height: 24px;
  border-radius: 50%;
  background: rgba(212,168,83,0.18);
  font-size: var(--fs-12);
  color: var(--gold);
}
#profile-pill.signed-in #profile-pill-glyph {
  background: var(--gold);
  color: var(--ink);
  font-weight: 700;
}

/* ── AUTH MODAL ── */
#auth-modal {
  position: fixed;
  inset: 0;
  z-index: 2200;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(10,5,0,0.78);
  backdrop-filter: blur(4px);
}
#auth-modal.open { display: flex; }

#auth-modal-card {
  position: relative;
  width: min(380px, 92vw);
  background: var(--ink-panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 30px 26px 24px;
  box-shadow: 0 14px 50px rgba(0,0,0,0.6);
}

.auth-close {
  position: absolute;
  top: 10px; right: 10px;
  width: 32px; height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(212,168,83,0.1);
  border: 1px solid rgba(212,168,83,0.3);
  color: var(--gold);
  cursor: pointer;
  font-size: var(--fs-16);
  line-height: 1;
  border-radius: 50%;
}
.auth-close:hover { color: var(--ink); background: var(--gold); border-color: var(--gold); }

.auth-title {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-18);
  letter-spacing: 3px;
  color: var(--gold);
  margin-bottom: 8px;
}
.auth-sub {
  font-size: var(--fs-12);
  color: var(--text-body);
  line-height: 1.5;
  margin-bottom: 18px;
}

#auth-email-input {
  width: 100%;
  background: rgba(212,168,83,0.06);
  border: 1px solid var(--border);
  color: var(--parchment);
  padding: 11px 14px;
  font-family: 'Inter', sans-serif;
  font-size: var(--fs-14);
  border-radius: 4px;
  margin-bottom: 12px;
  outline: none;
}
#auth-email-input:focus { border-color: var(--gold-dim); background: rgba(212,168,83,0.1); }

#auth-error {
  font-size: var(--fs-12);
  color: var(--quest-location);
  margin-bottom: 10px;
  min-height: 16px;
  line-height: 1.3;
}

.auth-primary, .auth-secondary, .auth-tertiary {
  width: 100%;
  padding: 11px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-11);
  letter-spacing: 3px;
  font-weight: 600;
  transition: all 0.2s;
}
.auth-primary {
  background: linear-gradient(135deg, var(--gold), #b8893a);
  color: var(--ink);
}
.auth-primary:hover { box-shadow: 0 2px 14px rgba(212,168,83,0.4); }
.auth-primary:disabled { opacity: 0.6; cursor: not-allowed; }
.auth-secondary {
  background: transparent;
  color: var(--gold-dim);
  border: 1px solid var(--border);
}
.auth-secondary:hover { color: var(--gold); border-color: var(--gold-dim); }
.auth-tertiary {
  background: transparent;
  color: var(--text-body);
  font-size: var(--fs-12);
  letter-spacing: 2px;
  padding: 11px;
  margin-top: 4px;
  text-decoration: underline;
  text-decoration-color: rgba(212,168,83,0.4);
  text-underline-offset: 3px;
}
.auth-tertiary:hover { color: var(--gold); }

.auth-state                          { display: none; }
.auth-state + .auth-state            { margin-top: 0; }
button.auth-primary + button.auth-secondary,
button.auth-primary + button.auth-tertiary,
button.auth-secondary + button.auth-tertiary { margin-top: 8px; }

#auth-modal[data-state="signed-out"] #auth-signed-out { display: block; }
#auth-modal[data-state="link-sent"]  #auth-link-sent  { display: block; }
#auth-modal[data-state="signed-in"]  #auth-signed-in  { display: block; }
#auth-modal[data-state="guest"]      #auth-guest      { display: block; }
#auth-modal[data-state="import"]     #auth-import     { display: block; }

.auth-glyph-large {
  font-size: var(--fs-40);
  color: var(--gold);
  text-align: center;
  margin-bottom: 14px;
  text-shadow: 0 0 18px rgba(212,168,83,0.4);
}

/* ── CHECK-IN ROW (info panel) ── */
/* Quest progress meter — only rendered when signed in (.visible). */
#quest-progress {
  display: none;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
#quest-progress.visible { display: block; }
#qp-label {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-body);
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
}
#qp-count {
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}
#qp-track {
  height: 6px;
  border-radius: 3px;
  background: rgba(212,168,83,0.12);
  overflow: hidden;
}
#qp-fill {
  height: 100%;
  width: 0;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--gold), #b8893a);
  box-shadow: 0 0 8px rgba(212,168,83,0.5);
  transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

#checkin-row {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
#checkin-stats {
  font-size: var(--fs-11);
  color: var(--text-muted);
  letter-spacing: 1px;
}
#checkin-btn {
  width: 100%;
  padding: 10px;
  border: 1px solid var(--border);
  background: rgba(212,168,83,0.06);
  color: var(--gold);
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  letter-spacing: 2px;
  font-weight: 600;
  border-radius: 3px;
  cursor: pointer;
  transition: all 0.2s;
}
#checkin-btn:hover { background: rgba(212,168,83,0.14); border-color: var(--gold-dim); }
#checkin-btn.visited {
  background: rgba(123,196,123,0.1);
  border-color: rgba(123,196,123,0.4);
  color: #7bc47b;
}

/* ── BOTTOM CONTROLS ── */
#bottom-controls {
  position: fixed;
  bottom: 28px;
  left: 18px;
  z-index: 900;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.ctrl-btn {
  background: rgba(8,4,0,0.96);
  border: 1px solid rgba(212,168,83,0.4);
  color: rgba(240,230,211,0.92);
  padding: 9px 15px;
  border-radius: 7px;
  font-size: var(--fs-12);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  cursor: pointer;
  font-family: 'Cinzel', serif;
  transition: all 0.2s;
  display: flex;
  align-items: center;
  gap: 9px;
}

.ctrl-btn.active {
  border-color: var(--gold);
  color: var(--gold);
}

.ctrl-btn:hover { border-color: rgba(212,168,83,0.7); }

.ctrl-btn-names .ctrl-label {
  display: grid;
  gap: 2px;
  min-width: 112px;
  text-align: left;
  line-height: 1.15;
}

.ctrl-btn-names .ctrl-label-title {
  color: inherit;
  letter-spacing: 1.25px;
}

.ctrl-btn-names .ctrl-label-detail {
  color: rgba(240,230,211,0.62);
  font-family: 'Source Sans 3', sans-serif;
  font-size: var(--fs-9);
  font-weight: 400;
  letter-spacing: 0.45px;
  text-transform: none;
}

.ctrl-btn-names.active .ctrl-label-detail { color: rgba(224,181,98,0.82); }

.swatch-line {
  width: 18px; height: 3px;
  border-radius: 2px;
  background: #c9a45a;
  flex-shrink: 0;
}

.swatch-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--gold);
  flex-shrink: 0;
}

.swatch-campaign {
  width: 18px;
  height: 3px;
  border-radius: 2px;
  background: #8f7cc3;
  box-shadow: 0 0 0 1px rgba(240,230,211,0.12);
  flex-shrink: 0;
}

/* Mobile-only affordances — hidden on desktop, switched on in the ≤640px query.
   The icon glyphs replace the swatch+label on the compact chips; the FAB collapses
   the legend. */
.detail-control {
  background: rgba(8,4,0,0.96);
  border: 1px solid rgba(212,168,83,0.4);   /* match the control chips' gold outline */
  color: rgba(240,230,211,0.92);
  padding: 8px 11px 9px;
  border-radius: 7px;
  font-family: 'Cinzel', serif;
  width: 162px;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.detail-head {
  /* Stacked (title over readout) so the readout gets the box's full width. On one
     row the long "+ Documented · 24,455 places" string ran past the border — the
     title ate ~48px, leaving too little for the number. */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  font-size: var(--fs-9);
  letter-spacing: 1.5px;
  text-transform: uppercase;
}
.detail-title { color: var(--gold); }
#detail-readout {
  color: var(--text-body);
  font-family: 'Inter', sans-serif;
  font-size: var(--fs-10);
  letter-spacing: 0.2px;
  text-transform: none;
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}
#detail-slider {
  /* Inset by the thumb radius (+ its glow ring) so the thumb never overhangs the
     panel at the extremes — a full-width track lets the thumb center reach the
     very edge, pushing half the thumb past the container's right border. */
  width: calc(100% - 20px);
  margin: 0 10px;
  appearance: none;
  -webkit-appearance: none;
  height: 22px;
  background: transparent;
  cursor: pointer;
}
#detail-slider::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(90deg, rgba(212,168,83,0.28), rgba(212,168,83,0.9));
}
#detail-slider::-webkit-slider-thumb {
  appearance: none;
  width: 16px;
  height: 16px;
  margin-top: -6px;
  border-radius: 50%;
  background: var(--gold);
  border: 1px solid #1a0e00;
  box-shadow: 0 0 0 3px rgba(212,168,83,0.16);
}
#detail-slider::-moz-range-track {
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(90deg, rgba(212,168,83,0.28), rgba(212,168,83,0.9));
}
#detail-slider::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--gold);
  border: 1px solid #1a0e00;
  box-shadow: 0 0 0 3px rgba(212,168,83,0.16);
}
#detail-slider:focus-visible { outline: none; }
.ctrl-icon { display: none; }
#legend-fab { display: none; }
#mobile-guide { display: none; }
#build-badge { display: none; }

/* Mobile dock + its panels and the legend's folded-in master layer rows are
   mobile-only. Hidden on desktop, where the topbar search and #bottom-controls
   chips remain the controls. The ≤640px query switches these on. */
#dock,
#dock-scrim,
#dock-search-panel { display: none; }
/* #quest-legend-scoped so these beat the later `.legend-row { display:flex }`
   at equal class-specificity (source order was letting the rows leak onto
   desktop, duplicating the bottom-left Roads/Sites chips). */
#quest-legend .legend-layers-hint,
#quest-legend .legend-layer-row,
#quest-legend .legend-layers-sep { display: none; }

/* ── QUEST LEGEND ── */
#quest-legend {
  position: fixed;
  bottom: 28px;
  right: 18px;
  z-index: 900;
  background: rgba(8,4,0,0.96);
  border: 1px solid rgba(212,168,83,0.4);
  border-radius: 8px;
  padding: 11px 15px;
  display: none;
  flex-direction: column;
  gap: 7px;
}

/* The key is earned by an intentional entry point: Quests reveals the quest
   rows, while Roman Roads reveals the certainty rows. */
#quest-legend.context-open { display: flex; }
#quest-legend .legend-section { display: none; }
#quest-legend.show-quests #quest-site-filters,
#quest-legend.show-roads #road-certainty-filters { display: block; }

/* Contextual keys stay beside the control that introduced them. The quest key
   belongs to the era switch; the road key belongs to the Roman Roads chip. */
#quest-legend.show-quests {
  top: 160px;
  right: auto;
  bottom: auto;
  left: 18px;
}
#quest-legend.show-roads {
  right: auto;
  top: auto;
  bottom: auto;
  left: 18px;
  background: rgba(23,11,3,0.98);
  border-color: rgba(224,181,98,0.72);
  box-shadow: 0 10px 28px rgba(0,0,0,0.58);
}
#quest-legend.show-roads .legend-hint { color: rgba(235,189,105,0.98); }
#quest-legend.show-roads .legend-row { color: rgba(255,246,230,0.96); }

/* Small affordance so it's clear the legend rows are now controls, not a
   static key. */
.legend-hint {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-9);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: rgba(212,168,83,0.7);
  margin-bottom: 2px;
}

.legend-row {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: var(--fs-11);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: rgba(240,230,211,0.9);
  font-family: 'Cinzel', serif;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition: opacity 0.15s, color 0.15s;
  outline: none;
}

.legend-row:hover,
.legend-row:focus-visible,
.legend-row.active { color: var(--gold); }

/* Selected tier: ring the dot so the choice is unmistakable on touch (no
   hover state to lean on). */
.legend-row.active .legend-dot {
  box-shadow: 0 0 0 2px rgba(255,255,255,0.55);
}

/* When a filter is on, fade the tiers that are filtered out. The two filters
   (site tiers vs roads certainty) fade independently — each only dims its own
   rows so a site filter doesn't grey out the roads rows and vice-versa. */
#quest-legend.filtering .legend-row[data-tier]:not(.active) { opacity: 0.3; }
#quest-legend.roads-filtering #roman-legend .legend-row[data-cert]:not(.active) { opacity: 0.3; }

/* Per-tier count, right-aligned into a column. */
.legend-count {
  margin-left: auto;
  padding-left: 12px;
  font-size: var(--fs-10);
  color: rgba(212,168,83,0.85);
  font-variant-numeric: tabular-nums;
}

/* A tier with no sites (e.g. Text Quest today) isn't tappable. */
.legend-row.disabled { cursor: default; opacity: 0.3; }
.legend-row.disabled:hover { color: var(--text-muted); }

/* "?" explainer button on the legend header. */
#legend-info-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px; height: 15px;
  margin-left: 6px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(212,168,83,0.6);
  background: transparent;
  color: rgba(212,168,83,0.95);
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  line-height: 1;
  cursor: pointer;
  vertical-align: middle;
}
#legend-info-btn:hover { background: rgba(212,168,83,0.18); color: var(--gold); }

.legend-context-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  margin-left: 8px;
  padding: 0;
  border: 1px solid rgba(212,168,83,0.45);
  border-radius: 50%;
  background: rgba(212,168,83,0.06);
  color: rgba(212,168,83,0.95);
  cursor: pointer;
  font-family: sans-serif;
  font-size: 10px;
  line-height: 1;
  vertical-align: middle;
}
.legend-context-close:hover,
.legend-context-close:focus-visible { background: rgba(212,168,83,0.18); color: var(--gold); }

/* Legend term toast — slides up when a tier is selected, fades on its own. */
#legend-toast {
  position: fixed;
  left: 50%;
  bottom: 96px;
  transform: translateX(-50%) translateY(14px);
  z-index: 1500;
  width: min(340px, 88vw);
  background: rgba(8,4,0,0.97);
  border: 1px solid rgba(212,168,83,0.5);
  border-radius: 9px;
  padding: 13px 17px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s, transform 0.25s;
  box-shadow: 0 12px 34px rgba(0,0,0,0.55);
}
#legend-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
#legend-toast-title {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-12);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 5px;
}
#legend-toast-body {
  font-size: var(--fs-12);
  line-height: 1.45;
  color: rgba(240,230,211,0.92);
}
#legend-toast-close {
  position: absolute;
  top: 8px;
  right: 9px;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 1px solid rgba(212,168,83,0.35);
  border-radius: 50%;
  background: rgba(212,168,83,0.08);
  color: var(--gold);
  cursor: pointer;
  font-size: var(--fs-11);
}
#legend-toast-close:hover { background: rgba(212,168,83,0.18); }

/* The explanation is an anchored detail card, not a detached snackbar. */
#legend-toast {
  left: 18px;
  right: auto;
  bottom: auto;
  width: min(380px, calc(100vw - 36px));
  padding: 18px 42px 18px 19px;
  pointer-events: none;
  transform: translateY(14px);
}
#legend-toast.context-quests { top: 160px; }
#legend-toast.context-roads { top: auto; bottom: auto; }
#legend-toast.show {
  pointer-events: auto;
  transform: translateY(0);
}

/* Legend explainer modal — reuses the shared modal look. */
/* ── WELCOME MODAL (first-visit intro) ── */
#welcome-modal {
  position: fixed;
  inset: 0;
  z-index: 2100;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(10,5,0,0.82);
  backdrop-filter: blur(4px);
}
#welcome-modal.open { display: flex; }
#welcome-card {
  position: relative;
  width: min(440px, 92vw);
  background: var(--ink-panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 30px 28px 24px;
  box-shadow: 0 14px 50px rgba(0,0,0,0.6);
  max-height: 92vh;
  overflow-y: auto;
  text-align: center;
}
.welcome-glyph {
  font-size: var(--fs-38);
  color: var(--gold);
  margin-bottom: 12px;
  text-shadow: 0 0 18px rgba(212,168,83,0.4);
}
#welcome-card .auth-title { text-align: center; }
.welcome-tagline {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-11);
  letter-spacing: 3px;
  color: var(--gold-dim);
  text-transform: uppercase;
  margin-bottom: 18px;
}
#welcome-body {
  text-align: left;
  margin-bottom: 22px;
}
#welcome-body p {
  font-size: var(--fs-13);
  line-height: 1.6;
  color: var(--text-body);
  margin: 0 0 12px;
}
.welcome-quest-preview {
  margin: 16px 0 14px;
  padding: 12px 13px;
  border: 1px solid rgba(255,158,44,0.32);
  background: rgba(255,158,44,0.075);
  border-radius: 7px;
}
.welcome-quest-title {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  letter-spacing: 1.7px;
  text-transform: uppercase;
  color: var(--quest-photo);
  margin-bottom: 9px;
  text-align: center;
}
.welcome-quest-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 7px;
}
.welcome-quest-grid span {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 34px;
  padding: 6px;
  border: 1px solid rgba(212,168,83,0.18);
  border-radius: 5px;
  color: rgba(240,230,211,0.9);
  background: rgba(8,4,0,0.24);
  font-size: var(--fs-11);
  line-height: 1.25;
  text-align: center;
}
#welcome-body .welcome-kicker {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-13);
  letter-spacing: 1px;
  color: var(--gold);
  text-align: center;
  margin: 18px 0 0;
}
.welcome-sources {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid rgba(212,168,83,0.22);
}
.welcome-sources-title {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  letter-spacing: 1.7px;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 7px;
}
.welcome-sources-title:not(:first-child) { margin-top: 15px; }
.welcome-sources p { font-size: var(--fs-12); margin: 0; color: var(--text-body); }
.welcome-sources strong { color: rgba(240,230,211,0.98); }

/* "Two ways in" — the mode explainer at the top of the welcome modal. */
.welcome-modes {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 14px 0;
}
.welcome-mode {
  padding: 11px 13px;
  border: 1px solid rgba(212,168,83,0.22);
  border-radius: 8px;
  background: rgba(212,168,83,0.05);
}
.welcome-mode-name {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-13);
  font-weight: 600;
  color: var(--gold);
  margin-bottom: 5px;
}
.welcome-mode p { font-size: var(--fs-12); margin: 0; color: var(--text-body); }
.welcome-mode em { color: rgba(240,230,211,0.95); font-style: italic; }
.welcome-mode-glyph { font-size: var(--fs-15); line-height: 1; }
.welcome-mode-glyph.alex {
  font-family: 'Cinzel', serif;
  font-weight: 700;
  color: #c3b3e8;   /* campaign purple, matches the mode tab + cross-link chip */
}

/* The VIA block stacks: clickable title/subtitle, then the "Choose your world"
   switch pill directly beneath (bottom of the block). */
#app-brand {
  pointer-events: all;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}
/* Title + subtitle: the "About VIA" click target. */
#app-brand-title {
  cursor: pointer;
  border-radius: 6px;
  padding: 4px 8px;
  margin: -4px -8px;
  transition: background 0.15s ease;
}
#app-brand-title:hover { background: rgba(212,168,83,0.09); }
#app-brand-title:hover #app-subtitle { text-decoration: underline; text-underline-offset: 2px; }
#app-brand-title:hover #brand-info { opacity: 1; }
#app-brand-title:focus-visible { outline: 1px solid var(--gold-dim); outline-offset: 3px; }

/* "Choose your world" — the visible way back to the splash. The current world
   name pops in bright gold; the CTA line carries a back-arrow. A gold-outlined
   pill with a soft glow so it stands out against the map, filling solid on hover.
   Colour is never the only signal (border + arrow + label carry it too). */
#brand-switch {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  padding: 5px 12px;
  background: linear-gradient(135deg, rgba(212,168,83,0.20), rgba(184,137,58,0.12));
  border: 1px solid var(--gold);
  border-radius: 8px;
  cursor: pointer;
  text-align: left;
  box-shadow: 0 2px 14px rgba(212,168,83,0.22);
  transition: background 0.15s ease, box-shadow 0.15s ease;
}
#brand-switch-world {
  font-family: 'Cinzel', serif;
  font-weight: 700;
  font-size: var(--fs-14);
  letter-spacing: 1px;
  white-space: nowrap;
  color: var(--gold);
  text-shadow: 0 1px 10px rgba(10,5,0,0.85);
}
#brand-switch-cta {
  font-family: 'Inter', sans-serif;
  font-size: var(--fs-10);
  font-weight: 600;
  letter-spacing: 0.5px;
  color: rgba(240,230,211,0.92);
}
#brand-switch-arrow { font-weight: 700; color: var(--gold); }
#brand-switch:hover {
  background: linear-gradient(135deg, var(--gold), #b8893a);
  box-shadow: 0 3px 20px rgba(212,168,83,0.45);
}
#brand-switch:hover #brand-switch-world,
#brand-switch:hover #brand-switch-cta,
#brand-switch:hover #brand-switch-arrow { color: var(--ink); text-shadow: none; }
#brand-info {
  font-size: 0.5em;
  vertical-align: super;
  margin-left: 3px;
  opacity: 0.55;
  letter-spacing: 0;
  transition: opacity 0.15s ease;
}

#legend-info {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(10,5,0,0.78);
  backdrop-filter: blur(4px);
}
#legend-info.open { display: flex; }
#legend-info-card {
  position: relative;
  width: min(420px, 92vw);
  background: var(--ink-panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 28px 24px 22px;
  box-shadow: 0 14px 50px rgba(0,0,0,0.6);
  max-height: 92vh;
  overflow-y: auto;
}
#legend-info-list { margin: 18px 0 16px; }
.li-row {
  display: flex;
  gap: 13px;
  align-items: flex-start;
  padding: 13px 0;
  border-top: 1px solid rgba(212,168,83,0.12);
}
.li-row:first-child { border-top: none; }
.li-dot {
  width: 14px; height: 14px;
  margin-top: 3px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 7px currentColor;
}
.li-dot.diamond  { border-radius: 2px; transform: rotate(45deg); }
.li-dot.triangle { border-radius: 0; clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.li-title {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-13);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 4px;
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.li-count { font-size: var(--fs-10); color: rgba(212,168,83,0.7); font-variant-numeric: tabular-nums; }
.li-blurb { font-size: var(--fs-12); line-height: 1.5; color: var(--text-body); }
.li-section-title {
  padding: 15px 0 2px;
  border-top: 1px solid rgba(212,168,83,0.24);
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: rgba(212,168,83,0.82);
}

.legend-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
/* Shape-coded swatches mirror the map markers for red-green color vision. */
.legend-dot.diamond  { border-radius: 2px; transform: rotate(45deg); }
.legend-dot.triangle { border-radius: 0; clip-path: polygon(50% 0, 100% 100%, 0 100%); }

/* Thin divider between the site-quest tiers and the roads certainty rows. */
.legend-sep {
  height: 1px;
  margin: 3px 0 1px;
  background: rgba(212,168,83,0.22);
}

/* Roads certainty swatch — a short line whose DASH PATTERN mirrors the map
   (solid/dashed/dotted = certain/conjectured/hypothetical). The pattern is the
   colorblind-safe channel; colour only reinforces it. Width 16px so the dotted
   case shows several dots. */
.legend-line {
  width: 16px; height: 0;
  border-top: 2px solid #b89a6a;
  flex-shrink: 0;
}
.legend-line.solid  { border-top-style: solid;  border-top-color: #d2a657; }
.legend-line.dashed { border-top-style: dashed; border-top-color: #b89a6a; }
.legend-line.dotted { border-top-style: dotted; border-top-width: 2px; border-top-color: #9a86b8; }
.legend-line.alexander { border-top-style: solid; border-top-color: #8f7cc3; }
#campaign-legend .legend-line.alexander.dashed { border-top-style: dashed; }
#campaign-legend .legend-line.alexander.dotted { border-top-style: dotted; }
/* Selected certainty: brighten the line to gold (no dot to ring here). */
.legend-row.active .legend-line { border-top-color: var(--gold); }

/* Alexander's longer two-part key needs warmer light and firmer type contrast
   than the compact Roman filter key. Preserve the same footprint and hierarchy. */
body.mode-alexander #quest-legend {
  background: linear-gradient(155deg, rgba(54,32,15,0.96), rgba(27,15,8,0.96));
  border-color: rgba(224,181,98,0.72);
  box-shadow: 0 10px 32px rgba(0,0,0,0.48), 0 0 0 1px rgba(224,181,98,0.1) inset;
}

body.mode-alexander #campaign-legend .legend-hint { color: rgba(235,189,105,0.95); }
body.mode-alexander #campaign-legend .legend-sub { color: rgba(238,219,188,0.78); }
body.mode-alexander #campaign-legend .legend-row { color: rgba(255,246,230,0.96); }
body.mode-alexander #campaign-legend .legend-row.disabled { opacity: 0.78; }
body.mode-alexander #campaign-legend .phase-yrs { color: rgba(242,222,190,0.82); }
body.mode-alexander #campaign-legend .legend-sep { background: rgba(224,181,98,0.34); }
body.mode-alexander #campaign-legend .legend-line.alexander { border-top-color: #c9b7f1; }

/* ── INFO PANEL ── */
#info-panel {
  position: fixed;
  top: 0;
  right: calc(-1 * var(--panel-width) - 2px);
  width: var(--panel-width);
  height: 100%;
  z-index: 1000;
  background: var(--ink-panel);
  border-left: 1px solid var(--border);
  transition: right 0.38s cubic-bezier(0.4, 0, 0.2, 1);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

#info-panel.open { right: 0; }

#info-panel.alexander-panel #panel-hero {
  height: 128px;
}

#info-panel.alexander-panel #hero-icon {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-42);
  font-weight: 700;
  color: rgba(240,230,211,0.92);
}

/* Panel hero area */
#panel-hero {
  width: 100%;
  height: 180px;
  flex-shrink: 0;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: #1a0f00;
}

#hero-inner { text-align: center; }
#hero-icon  { font-size: var(--fs-34); margin-bottom: 8px; }

#hero-coords {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  letter-spacing: 2px;
  color: rgba(212,168,83,0.4);
}

#hero-modern {
  font-size: var(--fs-10);
  letter-spacing: 1px;
  color: rgba(240,230,211,0.2);
  margin-top: 5px;
  font-style: italic;
}

/* Credit/license caption shown over an elevation site's vici.org hero photo. */
#hero-credit {
  position: absolute;
  bottom: 6px;
  left: 10px;
  right: 18px;
  max-width: calc(100% - 28px);
  font-size: var(--fs-9);
  letter-spacing: 0.5px;
  color: rgba(240,230,211,0.7);
  text-align: left;
  text-shadow: 0 1px 3px rgba(0,0,0,0.9);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}

/* Honest label for stops whose hero depicts the river/feature, not the site. */
#hero-caption {
  position: absolute;
  bottom: 19px;
  left: 10px;
  right: 18px;
  max-width: calc(100% - 28px);
  font-size: var(--fs-10);
  font-style: italic;
  letter-spacing: 0.3px;
  color: rgba(240,230,211,0.92);
  text-align: left;
  text-shadow: 0 1px 3px rgba(0,0,0,0.95);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}

@media (max-width: 640px) {
  #hero-caption {
    left: 14px;
    right: 54px;
    bottom: 20px;
    font-size: var(--fs-9);
  }
}

/* Quest banner inside panel — louder treatment, the signature CTA */
#panel-quest-banner {
  display: none;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-11);
  line-height: 1.5;
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
}

/* Subtle pulse on the banner background so it doesn't fade into the panel. */
#panel-quest-banner.visible { display: flex; animation: questPulseBg 3.4s ease-in-out infinite; }

@keyframes questPulseBg {
  0%, 100% { box-shadow: inset 0 0 0 1px transparent; }
  50%      { box-shadow: inset 0 0 0 1px rgba(224,122,58,0.18); }
}

.quest-banner-icon {
  font-size: var(--fs-24);
  flex-shrink: 0;
  filter: drop-shadow(0 0 6px rgba(224,122,58,0.55));
  /* Icon pulse removed: it was redundant with the banner-background pulse
     (#panel-quest-banner.visible) — two ambient loops on one open panel. The
     drop-shadow keeps the icon prominent without the extra motion. */
}

.quest-banner-body { flex: 1; }

.quest-banner-title {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  letter-spacing: 2.5px;
  text-transform: uppercase;
  margin-bottom: 3px;
  font-weight: 700;
}

.quest-banner-text { font-size: var(--fs-12); color: var(--text-body); margin-bottom: 8px; }

.quest-banner-cta {
  background: transparent;
  border: 1px solid currentColor;
  color: inherit;
  padding: 6px 12px;
  border-radius: 3px;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  letter-spacing: 1.8px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.18s;
}
.quest-banner-cta:hover {
  background: rgba(255,255,255,0.08);
  transform: translateX(2px);
}
/* Color of the CTA is inherited from the banner title's color so it
   matches the quest tier (photo orange, location red, text purple). */
#panel-quest-banner .quest-banner-cta { color: var(--quest-photo); }
#panel-quest-banner.quest-location .quest-banner-cta { color: var(--quest-location); }
#panel-quest-banner.quest-text     .quest-banner-cta { color: var(--quest-text); }

/* ── QUEST MODAL ── */
#quest-modal {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(10,5,0,0.78);
  backdrop-filter: blur(4px);
}
#quest-modal.open { display: flex; }

#quest-modal-card {
  position: relative;
  width: min(440px, 92vw);
  background: var(--ink-panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 30px 26px 24px;
  box-shadow: 0 14px 50px rgba(0,0,0,0.6);
  max-height: 92vh;
  overflow-y: auto;
}

.quest-glyph-large {
  font-size: var(--fs-44);
  text-align: center;
  margin-bottom: 10px;
  filter: drop-shadow(0 0 12px rgba(224,122,58,0.5));
}

.quest-steps {
  list-style: none;
  padding: 0;
  margin: 18px 0 14px;
  counter-reset: quest-step;
}
.quest-steps li {
  counter-increment: quest-step;
  padding: 12px 0 12px 38px;
  position: relative;
  font-size: var(--fs-13);
  color: var(--text-body);
  border-top: 1px solid rgba(212,168,83,0.12);
  line-height: 1.5;
}
.quest-steps li:first-child { border-top: none; }
.quest-steps li::before {
  content: counter(quest-step);
  position: absolute;
  left: 0;
  top: 11px;
  width: 26px; height: 26px;
  background: rgba(212,168,83,0.12);
  color: var(--gold);
  font-family: 'Cinzel', serif;
  font-size: var(--fs-12);
  font-weight: 700;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.quest-steps li strong { color: var(--parchment); font-weight: 500; }
.quest-steps code {
  background: rgba(212,168,83,0.15);
  color: var(--gold);
  padding: 1px 6px;
  border-radius: 3px;
  font-family: 'Inter', monospace;
  font-size: var(--fs-12);
}

#panel-close {
  position: absolute;
  top: 11px; right: 11px;
  background: rgba(212,168,83,0.14);
  border: 1px solid rgba(212,168,83,0.4);
  color: var(--gold);
  width: 30px; height: 30px;
  border-radius: 50%;
  cursor: pointer;
  font-size: var(--fs-14);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
  z-index: 10;
}

#panel-close:hover {
  background: rgba(212,168,83,0.18);
  color: var(--gold);
}

/* Panel body */
#panel-body {
  padding: 20px 22px 40px;
  flex: 1;
}

.p-badge {
  display: inline-block;
  font-size: var(--fs-9);
  letter-spacing: 2px;
  text-transform: uppercase;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 3px;
  margin-bottom: 9px;
  font-family: 'Cinzel', serif;
}

#panel-name {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-26);
  font-weight: 700;
  color: var(--parchment);
  line-height: 1.15;
  margin-bottom: 5px;
}

#panel-modern-name {
  font-size: var(--fs-12);
  color: rgba(240,230,211,0.38);
  font-style: italic;
  margin-bottom: 16px;
}

.p-rule {
  height: 1px;
  background: linear-gradient(to right, rgba(212,168,83,0.25), transparent);
  margin: 15px 0;
}

#panel-period {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--fs-12);
  color: var(--text-muted);
  margin-bottom: 14px;
}

#panel-desc {
  font-size: var(--fs-13);
  line-height: 1.78;
  color: var(--text-body);
  margin-bottom: 18px;
}

/* "Places along this stretch" — roads↔sites bridge on road-segment panels. */
#segment-nearby { display: none; margin-bottom: 18px; }
.seg-evidence-row {
  display: grid;
  grid-template-columns: 108px minmax(0, 1fr);
  gap: 10px;
  padding: 7px 0;
  border-top: 1px solid rgba(212,168,83,0.1);
  font-size: var(--fs-11);
  line-height: 1.35;
}
.seg-evidence-row:first-child { border-top: none; padding-top: 0; }
.seg-evidence-row span {
  font-family: 'Cinzel', serif;
  color: rgba(212,168,83,0.68);
  letter-spacing: 1px;
  text-transform: uppercase;
  font-size: var(--fs-9);
}
.seg-evidence-row strong {
  color: var(--text-body);
  font-weight: 400;
}
.seg-near-label {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: rgba(212,168,83,0.75);
  margin-bottom: 8px;
}
.seg-near-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 6px 8px;
  margin: 0 0 4px;
  background: rgba(212,168,83,0.05);
  border: 1px solid rgba(212,168,83,0.15);
  border-radius: 7px;
  color: var(--text-body);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.seg-near-row:hover { background: rgba(212,168,83,0.12); border-color: rgba(212,168,83,0.4); }
.seg-near-thumb {
  width: 30px; height: 30px;
  flex-shrink: 0;
  border-radius: 5px;
  background-size: cover;
  background-position: center;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-14);
}
.seg-near-thumb.empty { background: rgba(212,168,83,0.1); }
.seg-near-name { flex: 1; font-size: var(--fs-12); color: var(--text-body); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.seg-near-km {
  font-size: var(--fs-11);
  color: rgba(212,168,83,0.85);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.seg-near-empty {
  font-size: var(--fs-12);
  color: var(--text-muted);
  font-style: italic;
  padding: 2px 0 2px;
}

/* Pleiades places on a road (Itiner-e association) */
#segment-pleiades { display: none; margin-top: 14px; }
.seg-pl-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 6px 8px;
  margin-bottom: 5px;
  background: rgba(212,168,83,0.05);
  border: 1px solid rgba(212,168,83,0.18);
  border-radius: 6px;
  cursor: pointer;
  text-align: left;
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
}
.seg-pl-row:hover { background: rgba(212,168,83,0.12); border-color: rgba(212,168,83,0.4); }
.seg-pl-name { flex: 1; font-size: var(--fs-12); color: var(--text-body); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.seg-pl-meta { font-size: var(--fs-10); color: rgba(212,168,83,0.85); flex-shrink: 0; letter-spacing: 0.3px; }
.seg-pl-more { font-size: var(--fs-11); color: var(--text-muted); font-style: italic; padding: 2px 0 0; }
.seg-pl-loading { font-size: var(--fs-12); color: var(--text-muted); font-style: italic; padding: 4px 0; }

/* ORBIS card */
#orbis-card {
  background: rgba(212,168,83,0.06);
  border: 1px solid rgba(212,168,83,0.2);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 18px;
  display: none;
}

#orbis-card.visible { display: block; }

#orbis-label {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-8);
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: rgba(212,168,83,0.5);
  margin-bottom: 8px;
}

#orbis-content {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

#orbis-days {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-28);
  font-weight: 700;
  color: var(--gold);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

#orbis-unit {
  font-size: var(--fs-12);
  color: var(--text-muted);
}

#orbis-detail {
  font-size: var(--fs-10);
  color: rgba(240,230,211,0.35);
  margin-top: 5px;
  letter-spacing: 0.5px;
}

/* Action buttons */
.p-actions { display: flex; flex-direction: column; gap: 8px; }

.p-btn {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 14px;
  border-radius: 8px;
  text-decoration: none;
  font-size: var(--fs-12);
  transition: all 0.2s;
  border: 1px solid;
  cursor: pointer;
}

.p-btn-maps  { background:rgba(60,120,230,0.07); border-color:rgba(60,120,230,0.22); color:#7aaaf5; }
.p-btn-maps:hover  { background:rgba(60,120,230,0.15); border-color:rgba(60,120,230,0.45); }
.p-btn-sat   { background:rgba(60,180,100,0.07); border-color:rgba(60,180,100,0.2);  color:#7acf9a; }
.p-btn-sat:hover   { background:rgba(60,180,100,0.15); border-color:rgba(60,180,100,0.4);  }
.p-btn-gold  { background:var(--gold-faint);     border-color:rgba(212,168,83,0.25); color:var(--gold); }
.p-btn-gold:hover  { background:rgba(212,168,83,0.17); }
.p-btn-vici  { background:rgba(150,110,200,0.07); border-color:rgba(150,110,200,0.22); color:#b394e0; }
.p-btn-vici:hover  { background:rgba(150,110,200,0.15); border-color:rgba(150,110,200,0.45); }
.p-btn-livius { background:rgba(200,130,70,0.07); border-color:rgba(200,130,70,0.22); color:#d99f6e; }
.p-btn-livius:hover { background:rgba(200,130,70,0.15); border-color:rgba(200,130,70,0.45); }
.p-btn-omnesviae { background:rgba(190,70,60,0.07); border-color:rgba(190,70,60,0.22); color:#e08578; }
.p-btn-omnesviae:hover { background:rgba(190,70,60,0.15); border-color:rgba(190,70,60,0.45); }
.p-btn-email { background:rgba(240,230,211,0.06); border-color:rgba(240,230,211,0.22); color:#e8dcc2; }
.p-btn-email:hover { background:rgba(240,230,211,0.13); border-color:rgba(240,230,211,0.45); }

/* Journey routing — an INTERNAL action (no ↗), indigo so it reads distinct
   from the external-link buttons and is colorblind-safe (not the map's
   red/green quest hues). Full-width button like the rest of the action stack. */
.p-btn-route { width:100%; text-align:left; font-family:inherit;
  background:rgba(99,102,241,0.1); border-color:rgba(99,102,241,0.3); color:#a5b4fc; }
.p-btn-route:hover { background:rgba(99,102,241,0.2); border-color:rgba(99,102,241,0.5); }

/* Cross-mode link — INTERNAL action (no ↗) that hops between the Roman and
   Alexander views of one place. Campaign purple so it reads distinct from the
   external-link buttons and the indigo route button; colorblind-safe. */
.p-btn-cross { width:100%; text-align:left; font-family:inherit;
  background:rgba(143,124,195,0.12); border-color:rgba(143,124,195,0.34); color:#c3b3e8; }
.p-btn-cross:hover { background:rgba(143,124,195,0.22); border-color:rgba(143,124,195,0.55); }
.p-btn-cross .p-btn-icon { font-family:'Cinzel', serif; font-weight:700; }

/* Public Research Lab bridge. Kept distinct from the world-to-world chip. */
.p-btn-research { width:100%; text-align:left; font-family:inherit;
  background:rgba(208,162,76,0.1); border-color:rgba(208,162,76,0.38); color:#e4bd73; }
.p-btn-research:hover { background:rgba(208,162,76,0.19); border-color:rgba(208,162,76,0.62); }
.p-btn-research .p-btn-icon { font-family:Georgia, serif; font-size:var(--fs-22); }

.p-btn-icon { font-size: var(--fs-19); flex-shrink: 0; }
.p-btn-main { font-weight: 500; }
.p-btn-sub  { font-size: var(--fs-10); opacity: 0.55; margin-top: 1px; }

/* ── JOURNEY ROUTING overlays ── */
/* Hint banner: shown while awaiting the destination tap. Top-centered pill. */
#route-hint {
  position: fixed; top: 68px; left: 50%; transform: translate(-50%, -12px);
  z-index: 1200; max-width: min(88vw, 460px);
  display: flex; align-items: center; gap: 10px;
  padding: 9px 15px; border-radius: 999px;
  background: rgba(30,27,60,0.94); border: 1px solid rgba(99,102,241,0.5);
  color: #e6e4f5; font-size: var(--fs-12); box-shadow: 0 6px 22px rgba(0,0,0,0.4);
  opacity: 0; pointer-events: none; transition: opacity 0.2s, transform 0.2s;
}
#route-hint.show { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
#route-hint::before { content: "🧭"; font-size: var(--fs-15); flex-shrink: 0; }
#route-hint-body { flex: 1; display: flex; flex-direction: column; gap: 2px; }
#route-hint-text { display: block; }
/* One-time primer: what ORBIS is, shown only on the first journey. Hidden until
   JS fills it in (empty = display:none via :empty). */
#route-hint-sub {
  font-size: var(--fs-10); line-height: 1.35; color: rgba(196,193,224,0.82);
}
#route-hint-sub:empty { display: none; }
#route-hint button {
  flex-shrink: 0; background: none; border: none; color: #a5b4fc;
  font-size: var(--fs-16); line-height: 1; cursor: pointer; padding: 2px 4px;
}

/* Result card: days/km/denarii readout. Bottom-centered, above the mobile
   controls; a close ✕ clears the route. */
#route-readout {
  position: fixed; left: 50%; bottom: 84px; transform: translate(-50%, 14px);
  z-index: 1200; width: min(90vw, 420px);
  padding: 13px 16px; border-radius: 12px;
  background: rgba(24,22,44,0.96); border: 1px solid rgba(99,102,241,0.45);
  color: #ece9fb; box-shadow: 0 8px 28px rgba(0,0,0,0.5);
  opacity: 0; pointer-events: none; transition: opacity 0.2s, transform 0.2s;
}
#route-readout.show { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
#route-readout-close {
  position: absolute; top: 8px; right: 10px;
  background: none; border: none; color: #a5b4fc;
  font-size: var(--fs-17); line-height: 1; cursor: pointer; padding: 3px 5px;
}
#route-readout-route  { font-size: var(--fs-12); font-weight: 600; color: #a5b4fc; padding-right: 22px; }
#route-readout-stats  { font-size: var(--fs-17); margin-top: 4px; letter-spacing: 0.2px; }
#route-readout-stats b { color: #c7d2fe; }
/* The figure the active basis optimizes gets a subtle underline + full-strength
   text (the rest dim slightly) so the toggle's effect is legible at a glance. */
#route-readout-stats .rstat { opacity: 0.5; transition: opacity 0.15s; }
#route-readout-stats .rstat.on { opacity: 1; text-decoration: underline; text-decoration-color: rgba(99,102,241,0.7); text-underline-offset: 3px; }
#route-readout-detail { font-size: var(--fs-10); opacity: 0.62; margin-top: 5px; line-height: 1.35; }

/* Fastest / Shortest / Cheapest segmented toggle. */
#route-readout-toggle { display: flex; gap: 0; margin-top: 9px; border-radius: 8px; overflow: hidden; border: 1px solid rgba(99,102,241,0.35); }
.rtoggle-btn {
  flex: 1; padding: 6px 4px; font-family: inherit; font-size: var(--fs-11); font-weight: 500;
  background: transparent; border: none; border-right: 1px solid rgba(99,102,241,0.25);
  color: #b9b7d6; cursor: pointer; transition: background 0.15s, color 0.15s;
}
.rtoggle-btn:last-child { border-right: none; }
.rtoggle-btn:hover { background: rgba(99,102,241,0.12); color: #e6e4f5; }
.rtoggle-btn.on { background: rgba(99,102,241,0.35); color: #fff; font-weight: 600; }

/* "Opens externally" cue — pinned top-right. Visible enough to read as a
   signpost ("this leaves VIA") without competing with the button label. */
.p-btn-ext  {
  margin-left: auto;
  flex-shrink: 0;
  align-self: flex-start;
  font-size: var(--fs-16);
  font-weight: 600;
  line-height: 1;
  opacity: 0.7;
  transition: opacity 0.2s, transform 0.2s;
}
.p-btn:hover .p-btn-ext { opacity: 1; transform: translate(1px, -1px); }

/* ── QUEST MARKER ANIMATION ── */
@keyframes questPulse {
  0%   { transform: scale(1);   opacity: 0.9; }
  50%  { transform: scale(1.5); opacity: 0;   }
  100% { transform: scale(1);   opacity: 0;   }
}

.quest-ring {
  position: absolute;
  top: -3px; left: -3px;
  width: calc(100% + 6px);
  height: calc(100% + 6px);
  border-radius: 50%;
  border: 2px solid currentColor;
  opacity: 0.65;
  box-shadow: 0 0 0 1px rgba(20,10,0,0.18), 0 0 6px currentColor;
  pointer-events: none;
}

@keyframes selectedMarkerPulse {
  0%   { transform: scale(0.9); opacity: 0.95; }
  55%  { transform: scale(2.6); opacity: 0; }
  100% { transform: scale(2.9); opacity: 0; }
}

.selected-marker-pulse {
  position: absolute;
  inset: -8px;
  border-radius: 50%;
  border: 2px solid #fff;
  /* dual-tone: dark backing + white ring so the pulse reads on pale terrain too,
     not only where currentColor happens to contrast (red-green-safe by luminance) */
  box-shadow:
    0 0 0 2px rgba(20,10,0,0.7),
    0 0 0 4px rgba(255,255,255,0.6),
    0 0 14px currentColor;
  animation: selectedMarkerPulse 0.7s ease-out 4;
  pointer-events: none;
}

/* ── MARKER CLUSTERS ── */
/* Per-tier cluster bubbles. 44px = mobile touch floor. Tier hue matches the
   marker it stands for. The user is red-green colorblind, so the most important
   distinction — quest cluster (actionable) vs documented (background) — is
   encoded by WEIGHT, not just color: quest bubbles get a bright white ring +
   colored halo, documented stays flat. The quest hues themselves (amber / blue /
   purple) are not a red-green pair. */
.via-cluster-wrap { background: transparent !important; }
.via-cluster {
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  font-family: 'Cinzel', serif;
  font-weight: 600;
  font-size: var(--fs-13);
  color: #1a0e00;
  border: 2px solid rgba(255,255,255,0.55);
  box-shadow: 0 2px 10px rgba(0,0,0,0.45);
}
.via-cluster--documented { background: #b89a6a; }
.via-cluster--photo {
  background: #ff9e2c;
  border-color: #fff;
  box-shadow: 0 0 0 3px rgba(255,158,44,0.32), 0 2px 10px rgba(0,0,0,0.45);
}
.via-cluster--location {
  background: #2b8cde; color: #fff;
  border-color: #fff;
  box-shadow: 0 0 0 3px rgba(43,140,222,0.32), 0 2px 10px rgba(0,0,0,0.45);
}
.via-cluster--text {
  background: #b15ad6; color: #fff;
  border-color: #fff;
  box-shadow: 0 0 0 3px rgba(177,90,214,0.32), 0 2px 10px rgba(0,0,0,0.45);
}

/* ── SCROLLBAR ── */
#info-panel::-webkit-scrollbar { width: 3px; }
#info-panel::-webkit-scrollbar-track { background: transparent; }
#info-panel::-webkit-scrollbar-thumb { background: rgba(212,168,83,0.18); border-radius: 2px; }

/* ── LEAFLET OVERRIDES ── */
.leaflet-control-zoom { display: none !important; }
.leaflet-control-attribution {
  background: rgba(10,5,0,0.65) !important;
  color: rgba(240,230,211,0.25) !important;
  font-size: var(--fs-9) !important;
}
.leaflet-control-attribution a { color: rgba(212,168,83,0.4) !important; }

/* Mobile attribution affordance. The on-map credit has no room on a phone, so
   the required attribution collapses behind a one-tap "ⓘ" sitting just left of
   the Key FAB. Hidden on desktop (the native bottom-right control shows there);
   the mobile media query flips #attrib-toggle to display:flex. */
#attrib-toggle {
  display: none;
  position: fixed;
  bottom: 18px;
  right: 100px;
  z-index: 901;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: rgba(8,4,0,0.96);
  border: 1px solid var(--gold);
  border-radius: 11px;
  color: var(--gold);
  font-family: 'Cinzel', serif;
  font-size: var(--fs-19);
  line-height: 1;
  cursor: pointer;
}
#attrib-popover {
  display: none;
  position: fixed;
  bottom: 70px;
  right: 12px;
  left: auto;
  max-width: min(300px, calc(100vw - 24px));
  max-height: 50vh;
  overflow-y: auto;
  z-index: 940;
  padding: 12px 14px;
  background: rgba(8,4,0,0.97);
  border: 1px solid rgba(212,168,83,0.4);
  border-radius: 12px;
  box-shadow: 0 18px 44px rgba(0,0,0,0.5);
  color: rgba(240,230,211,0.9);
  font-size: var(--fs-12);
  line-height: 1.55;
}
#attrib-popover.open { display: block; }
#attrib-popover a { color: var(--gold); }

.road-tip {
  background: rgba(10,5,0,0.93) !important;
  border: 1px solid rgba(212,168,83,0.3) !important;
  color: var(--parchment) !important;
  font-family: 'Inter', sans-serif !important;
  font-size: var(--fs-12) !important;
  padding: 8px 12px !important;
  border-radius: 6px !important;
  box-shadow: none !important;
}
.road-tip::before { display: none !important; }

/* Kill the browser's focus outline on clicked SVG paths — clicking a road's
   (invisible) hit-line drew a rectangle around its bounding box (the "perimeter"
   artifact). Roads/markers are mouse/touch targets, not keyboard-focus targets. */
.leaflet-interactive:focus { outline: none !important; }
path.leaflet-interactive { outline: none !important; }

/* ════════════════════════════════
   MOBILE  (≤ 640px)
   ════════════════════════════════ */
@media (max-width: 640px) {

  /* Tighter topbar so era toggle + profile pill fit on a 375px viewport
     (FINDING-001, FINDING-012). */
  #topbar         {
    z-index: 920;
    padding: calc(8px + env(safe-area-inset-top, 0px)) 10px 44px;
    align-items: flex-start;
  }
  #app-brand      {
    max-width: 176px;         /* room for the "Choose your world" pill */
    gap: 5px;
  }
  #app-brand-title {
    padding: 3px 4px;
    margin: -3px -4px;
  }
  /* Smaller pill on phones, but still the pop + arrow. */
  #brand-switch        { padding: 4px 9px; }
  #brand-switch-world  { font-size: var(--fs-11); letter-spacing: 0.4px; }
  #brand-switch-cta    { font-size: var(--fs-8); }
  #app-title      { font-size: var(--fs-18); letter-spacing: 3px; }
  #app-subtitle   {
    display: block;
    max-width: 128px;
    margin-top: 1px;
    font-size: var(--fs-8);
    letter-spacing: 0.7px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  #topbar-right   { gap: 6px; align-items: center; }
  /* Key moved back down into the bottom nav (Variant 3 pill dock: the Key tab).
     The topbar pill is retired on mobile; the profile pill is the only topbar-right
     control now. #topbar-key stays in the DOM (its aria-expanded is kept in lockstep
     by syncKeyExpanded) but is not shown. */
  #topbar-key { display: none; }
  /* Search moved off the top bar into the dock (see #dock-search-panel). The
     input + results are reparented into the search overlay at boot, so here we
     reset the topbar-search positioning to flow inside that panel. */
  #topbar-search  {
    position: static;
    top: auto;
    left: auto;
    right: auto;
    transform: none;
    width: 100%;
  }
  /* Era toggle sits directly under the VIA block (title + Choose-your-world pill),
     left-aligned so it never collides with the pill. Search lives in the dock, so
     the top-left column is just brand -> switch -> era. */
  #era-toggle-wrap {
    top: calc(env(safe-area-inset-top, 0px) + 92px);
    left: max(10px, env(safe-area-inset-left, 0px));
    right: auto;
    display: flex;
    justify-content: flex-start;
    z-index: 910;
  }
  #site-search-input {
    height: 46px;
    font-size: var(--fs-14);
  }
  #site-search-results {
    position: static;
    margin-top: 10px;
    max-height: min(46dvh, 360px);
    z-index: auto;
  }

  /* ── Mobile dock ───────────────────────────────────────── */
  #dock {
    display: flex;
    align-items: center;
    gap: 8px;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 960;
    padding: 8px 12px calc(8px + env(safe-area-inset-bottom, 0px));
    background: linear-gradient(to top, rgba(8,4,0,0.98) 55%, rgba(8,4,0,0.84));
    border-top: 1px solid rgba(212,168,83,0.28);
    box-shadow: 0 -8px 24px rgba(0,0,0,0.34);
  }
  .dock-btn {
    /* All three dock controls share ONE shape language: equal-rhythm pills.
       Search still leads (wider flex-grow below), but DETAIL/KEY now carry real
       width so the right side balances instead of trailing off as small tags. */
    flex: 1 1 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    height: 44px;
    padding: 0 14px;
    background: rgba(20,12,2,0.92);
    border: 1px solid rgba(212,168,83,0.34);
    border-radius: 999px;
    color: rgba(240,230,211,0.92);
    font-family: 'Cinzel', serif;
    font-size: var(--fs-11);
    letter-spacing: 1.4px;
    text-transform: uppercase;
    cursor: pointer;
  }
  .dock-btn[aria-expanded="true"],
  .dock-btn[aria-current="page"] {
    border-color: var(--gold);
    color: var(--gold);
    background: rgba(212,168,83,0.12);
  }
  .dock-btn svg { display: block; }

  /* ── Variant 3 pill dock: four equal Map · Sites · Quest · Key tabs ── */
  .dock-tab {
    gap: 5px;
    padding: 0 8px;
    letter-spacing: 0.8px;
    font-size: var(--fs-10);
  }
  .dock-tab svg { flex: 0 0 auto; }
  .dock-tab-label { line-height: 1; }
  /* Quest carries the Photo-Quest orange as a REDUNDANT accent when active — the
     camera glyph is the real signal, so this stays colorblind-safe. */
  .dock-btn.dock-quest[aria-current="page"] {
    border-color: #ff9e2c;
    color: #ff9e2c;
    background: rgba(255,158,44,0.14);
  }
  /* Search leads the row (≈1.6× a button) — its SIZE marks it primary, not a
     different shape. It stays an input affordance (Inter, sentence case) on
     purpose; a Cinzel-caps placeholder would read as a button, not a field.
     Slightly brighter text so the biggest element isn't also the faintest. */
  .dock-search-field {
    flex: 1.6 1 0;
    min-width: 0;
    justify-content: flex-start;
    text-transform: none;
    font-family: 'Inter', sans-serif;
    letter-spacing: 0;
    color: rgba(240,230,211,0.64);
  }
  .dock-search-field svg { color: rgba(212,168,83,0.7); flex: 0 0 auto; }
  .dock-search-placeholder {
    font-size: var(--fs-13);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .dock-btn-icon { font-size: var(--fs-15); line-height: 1; }
  .dock-btn-label { line-height: 1; }

  /* Scrim — only behind the search overlay. */
  #dock-scrim {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 955;
    background: rgba(4,2,0,0.5);
  }
  body.dock-search-open #dock-scrim { display: block; }

  /* Search overlay panel — rides above the dock, holds the reparented input. */
  #dock-search-panel {
    display: none;
    position: fixed;
    left: 12px; right: 12px;
    bottom: calc(var(--dock-h) + 10px);
    z-index: 965;
    flex-direction: column;
    padding: 12px;
    background: rgba(10,5,0,0.98);
    border: 1px solid rgba(212,168,83,0.3);
    border-radius: 16px;
    box-shadow: 0 18px 50px rgba(0,0,0,0.5);
    max-height: calc(100dvh - var(--dock-h) - 130px);
  }
  body.dock-search-open #dock-search-panel { display: flex; }
  #dock-search-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
  }
  #dock-search-title {
    font-family: 'Cinzel', serif;
    font-size: var(--fs-10);
    letter-spacing: 1.8px;
    text-transform: uppercase;
    color: rgba(212,168,83,0.7);
  }
  #dock-search-cancel {
    background: transparent;
    border: 0;
    color: var(--gold);
    font-family: 'Inter', sans-serif;
    font-size: var(--fs-13);
    cursor: pointer;
    padding: 4px 6px;
  }

  /* Era is a set-once preference, not primary navigation — so on mobile the
     toggle is deliberately small and subordinate: a compact pill sized to its
     content, quiet background, no glow. The active segment still reads by
     LUMINANCE (gold fill vs transparent), never hue, so it stays colorblind-safe.
     (Search + map are the primary chrome; this sits under them.) */
  #era-toggle {
    height: 26px;
    min-height: 26px;
    padding: 2px;
    min-width: 0;
    width: max-content;
    background: rgba(10,5,0,0.72);
    /* Shared chrome border (0.34) so the top controls belong to the same
       material system as the dock + map utilities, not the fainter 0.22. */
    border-color: rgba(212,168,83,0.34);
    box-shadow: 0 3px 10px rgba(0,0,0,0.14);
  }
  .era-btn {
    height: 22px;
    min-height: 22px;
    padding: 0 10px;
    font-size: var(--fs-8);
    letter-spacing: 1px;
  }
  /* Drop the bright glow — the fill alone marks the active era; no shouting. */
  .era-btn.active {
    box-shadow: none;
  }

  /* Collapse the profile pill to icon-only on mobile — keeps the affordance
     present without crowding the era toggle. */
  #profile-pill        {
    min-width: 34px;
    min-height: 34px;
    width: 34px;
    height: 34px;
    padding: 0;
    justify-content: center;
    gap: 0;
    /* Tie the signed-out "bullseye" into the shared 0.34 chrome border so it
       reads as part of the system, not a separate dark blob. (The signed-in
       gold-gradient state keeps its own border via higher specificity.) */
    border-color: rgba(212,168,83,0.34);
  }
  #profile-pill-glyph  { width: 19px; height: 19px; }
  #profile-pill-label  { display: none; }

  /* Layer toggles → a compact horizontal row of icon chips. The stacked,
     full-width labeled buttons ate the bottom-left; on a phone the glyph alone
     (🛣️/🏛️/⭐) carries the meaning and the gold border shows on/off state.
     Shape-distinct glyphs, NOT swatch color — the user is red-green colorblind. */
  /* The Roman Roads / Sites chips fold into the KEY panel's master layer rows;
     hide the chips themselves on mobile. (#bottom-controls stays in the DOM as
     the detail-control's parent — display:none on it would also hide the
     popover, so only the chips are hidden.) */
  #bottom-controls .ctrl-btn { display: none; }

  /* Curation popover — the Detail slider, opened from the dock's Detail button.
     Reuses #detail-control; fixed above the dock, hidden until curation is open. */
  .detail-control {
    position: fixed;
    left: 52px;
    right: 24px;
    bottom: calc(var(--dock-h) + 10px);
    width: auto;
    z-index: 958;
    display: none;
    padding: 13px 15px 15px;
    border-radius: 16px;
    box-shadow: 0 18px 50px rgba(0,0,0,0.5);
  }
  body.dock-curation-open .detail-control { display: flex; }
  .detail-head {
    font-size: var(--fs-9);
    letter-spacing: 1.3px;
  }
  #detail-readout {
    font-size: var(--fs-11);
    overflow: hidden;
    text-overflow: ellipsis;
  }
  #detail-slider { height: 30px; }

  /* The Key FAB is superseded by the dock's Key button — hide it. The legend
     panel it used to open is now opened from the dock. */
  #legend-fab { display: none; }

  /* Visible +/− zoom control so zoom never depends on double-tapping near a
     marker. Right edge, above the dock; pinch-to-zoom also works (Leaflet
     touchZoom). Leaflet renders it inside the top-right container (which is not
     hidden on mobile, unlike bottom-right), then we pin it fixed above the dock. */
  .leaflet-control-zoom {
    display: block !important;
    position: fixed !important;
    right: 12px;
    top: 50%;
    bottom: auto;
    transform: translateY(-50%);
    margin: 0 !important;
    z-index: 952;
  }
  /* Shared utility-chrome material (see #attrib-toggle, #build-badge): the same
     0.34 gold border + 0.92 glass the dock pills use, so the scattered map
     controls read as one quiet system instead of three different widgets. */
  .leaflet-control-zoom a {
    width: 40px !important;
    height: 34px !important;
    line-height: 34px !important;
    font-size: var(--fs-20) !important;
    background: rgba(8,4,0,0.92) !important;
    color: var(--gold) !important;
    border: 1px solid rgba(212,168,83,0.34) !important;
  }
  .leaflet-control-zoom a:first-child { border-radius: 11px 11px 0 0 !important; }
  .leaflet-control-zoom a:last-child  { border-radius: 0 0 11px 11px !important; border-top: none !important; }
  .leaflet-control-zoom a:hover { background: rgba(20,12,2,0.98) !important; }
  /* The bottom and top edges are both too crowded for a permanent credit (and
     the iPhone home indicator owns the bottom ~34px). Required attribution
     (Itiner-e CC BY 4.0 + OSM/CARTO/Leaflet) instead lives behind a one-tap
     "ⓘ" by the Key FAB — see #attrib-toggle / #attrib-popover. Hide the native
     on-map control on mobile; the ⓘ popover carries the exact same text. */
  .leaflet-bottom.leaflet-right { display: none; }
  /* ⓘ attribution affordance — bottom-left, riding above the dock (intentional
     pattern, commit 548de9c; satisfies CC BY without a persistent on-map line). */
  #attrib-toggle {
    display: flex;
    width: 34px;
    height: 34px;
    font-size: var(--fs-15);
    border-radius: 11px;
    /* Calm the once-loud full-gold border down to the shared utility material —
       attribution is the least-important control, it shouldn't shout. */
    border-color: rgba(212,168,83,0.34);
    background: rgba(8,4,0,0.92);
    bottom: calc(var(--dock-h) + 6px);
    left: 8px;
    right: auto;
  }
  #attrib-popover {
    bottom: calc(var(--dock-h) + 66px);
    left: 12px;
    right: auto;
  }
  #build-badge {
    display: block;
    position: fixed;
    top: auto;
    bottom: calc(var(--dock-h) + 6px);
    right: max(10px, env(safe-area-inset-right, 0px));
    z-index: 907;
    min-width: 0;
    padding: 3px 8px;
    border-radius: 999px;
    background: rgba(8,4,0,0.92);
    border: 1px solid rgba(212,168,83,0.34);
    color: rgba(240,230,211,0.7);
    font-family: 'Cinzel', serif;
    font-size: var(--fs-8);
    letter-spacing: 1px;
    text-align: center;
    box-shadow: 0 6px 16px rgba(0,0,0,0.2);
    pointer-events: none;
  }

  #mobile-guide {
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: calc(var(--dock-h) + 66px);
    z-index: 902;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 12px 12px 12px 14px;
    background: rgba(8,4,0,0.94);
    border: 1px solid rgba(212,168,83,0.5);
    border-radius: 9px;
    box-shadow: 0 12px 34px rgba(0,0,0,0.45);
    transition: opacity 0.22s, transform 0.22s;
  }
  #mobile-guide.hidden {
    opacity: 0;
    transform: translateY(8px);
    pointer-events: none;
  }
  /* Journey launcher rides just above the dock on a phone (fixed 26px would sit
     under the dock bar). */
  #journey-launch.journey-launch-show {
    bottom: calc(var(--dock-h) + 18px);
  }
  #mobile-guide-title {
    font-family: 'Cinzel', serif;
    color: var(--gold);
    font-size: var(--fs-11);
    letter-spacing: 1.6px;
    text-transform: uppercase;
    margin-bottom: 4px;
  }
  #mobile-guide-body {
    color: rgba(240,230,211,0.9);
    font-size: var(--fs-12);
    line-height: 1.42;
  }
  #mobile-guide-close {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    border: 1px solid rgba(212,168,83,0.22);
    border-radius: 50%;
    background: rgba(212,168,83,0.07);
    color: rgba(212,168,83,0.75);
    font-size: var(--fs-17);
    line-height: 1;
    cursor: pointer;
  }

  /* KEY panel — opened from the dock's Key button. Rides above the dock as a
     scrollable sheet. Contains the folded-in master layer rows (Roads / Sites)
     above the quest-tier and roads-certainty filter rows. */
  #quest-legend {
    display: none;
    left: 12px;
    right: 12px;
    bottom: calc(var(--dock-h) + 10px);
    z-index: 958;
    padding: 13px 15px;
    gap: 6px;
    border-radius: 16px;
    max-height: calc(100dvh - var(--dock-h) - 130px);
    overflow-y: auto;
  }
  #quest-legend.mobile-open,
  #quest-legend.context-open.mobile-open { display: flex; }
  #quest-legend.show-quests,
  #quest-legend.show-roads {
    top: auto;
    left: 12px;
    right: 12px;
    bottom: calc(var(--dock-h) + 10px);
  }
  .legend-hint { font-size: var(--fs-8); }
  .legend-row { font-size: var(--fs-11); letter-spacing: 0.5px; padding: 3px 0; }
  .legend-dot { width: 9px; height: 9px; }
  .legend-count { font-size: var(--fs-9); padding-left: 10px; }

  /* Folded-in master layer toggles (mobile only). active = layer on (gold via
     .legend-row.active); off = dimmed. */
  /* Match the #quest-legend-scoped desktop hide so these re-show on mobile. */
  #quest-legend .legend-layers-hint { display: block; }
  #quest-legend .legend-layers-sep  { display: block; }
  #quest-legend .legend-layer-row   { display: flex; }
  .legend-layer-row:not(.active) { opacity: 0.4; }
  .legend-layer-row .legend-line { width: 18px; }

  #legend-toast,
  #legend-toast.context-quests,
  #legend-toast.context-roads {
    top: auto;
    left: 50%;
    right: auto;
    bottom: calc(var(--dock-h) + 96px);
    width: min(340px, 88vw);
    padding: 18px 42px 18px 17px;
    transform: translateX(-50%) translateY(14px);
  }
  #legend-toast.show { transform: translateX(-50%) translateY(0); }

  /* Panel becomes a floating card on mobile */
  :root {
    --panel-width: 100vw;
    /* Full dock height = 8 (pad-top) + 44 (button) + 8 (pad-bottom) + the iPhone
       home-indicator inset. Everything that "rides above the dock" offsets by
       this, so panels never overlap the dock on notched phones. */
    --dock-h: calc(60px + env(safe-area-inset-bottom, 0px));
  }

  /* Slide the bottom sheet with transform, not an animated dvh-based `bottom`.
     iOS Safari mis-places fixed elements positioned with calc(dvh) + bottom (the
     panel opened offscreen — "tapping a city does nothing" on iPhone). A
     translateY transform is the reliable, GPU-accelerated bottom-sheet pattern. */
  /* Detail card: a dismissible panel anchored ABOVE the dock (the dock stays
     reachable beneath it). Scrolls internally; expands up to a tall max-height
     for rich road detail. Never a fixed-height card that truncates — see the
     removed line-clamps below. Slides up with a transform (the reliable iOS
     bottom-sheet pattern; an animated dvh `bottom` mis-places on iOS Safari). */
  #info-panel {
    top: auto;
    bottom: calc(var(--dock-h) + 8px);
    right: 8px;
    left: 8px;
    width: auto;
    height: auto;
    max-height: calc(100dvh - var(--dock-h) - 130px);
    border-left: none;
    border: 1px solid var(--border);
    border-radius: 16px;
    overflow-y: auto;
    transform: translateY(calc(100% + var(--dock-h) + 24px));  /* hidden below the dock */
    transition: transform 0.38s cubic-bezier(0.4, 0, 0.2, 1);
  }

  #info-panel.open { transform: translateY(0); }

  /* Panel focus mode: when a site/road panel is open on a phone, the panel IS
     the screen. Fade out the competing top chrome — brand + top search, era
     toggle, and the mode tabs/crosslink — so the ONLY things left are the panel
     and the map's flashing locator in the strip above it. This also uncovers the
     locator: panToWithPanelOffset (app.js) pushes the selected marker up into
     that top strip, where #mode-tabs / #mode-crosslink used to sit on top of it.
     The dock (bottom search) stays — it's the single, thumb-reachable search. */
  #topbar,
  #era-toggle-wrap,
  #mode-tabs,
  #mode-crosslink {
    transition: opacity 0.28s ease;
  }
  body:has(#info-panel.open) #topbar,
  body:has(#info-panel.open) #era-toggle-wrap,
  body:has(#info-panel.open) #mode-tabs,
  body:has(#info-panel.open) #mode-crosslink {
    opacity: 0;
    pointer-events: none;
  }

  #panel-hero { height: 82px; }
  #hero-inner { padding: 0 58px 0 22px; text-align: left; width: 100%; }
  #hero-icon  { display: none; }
  #hero-coords { font-size: var(--fs-9); letter-spacing: 1.6px; color: rgba(212,168,83,0.62); }
  #hero-modern { font-size: var(--fs-11); color: rgba(240,230,211,0.55); }
  #hero-credit {
    left: 14px;
    right: 54px;
    bottom: 7px;
    font-size: var(--fs-8);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  #panel-quest-banner {
    gap: 10px;
    padding: 10px 14px 12px;
    line-height: 1.35;
    align-items: flex-start;
  }
  .quest-banner-icon { font-size: var(--fs-20); }
  .quest-banner-title { font-size: var(--fs-9); letter-spacing: 1.9px; }
  .quest-banner-text {
    font-size: var(--fs-11);
    margin-bottom: 7px;
  }
  .quest-banner-cta {
    padding: 6px 10px;
    font-size: var(--fs-9);
    letter-spacing: 1.4px;
  }

  #panel-body { padding: 16px 20px 34px; }
  .p-badge { margin-bottom: 7px; }
  #panel-name { font-size: var(--fs-24); margin-bottom: 4px; }
  #panel-modern-name { margin-bottom: 12px; }
  .p-rule { margin: 12px 0; }
  #panel-period { margin-bottom: 11px; }
  #panel-desc {
    line-height: 1.55;
    margin-bottom: 14px;
  }
  #checkin-row {
    margin: 0 0 14px;
    padding: 12px;
    border: 1px solid rgba(212,168,83,0.18);
    border-radius: 8px;
    background: rgba(212,168,83,0.045);
  }
  #checkin-stats { line-height: 1.35; }
  #checkin-btn { padding: 11px; }

  #info-panel.segment-panel #panel-hero { height: 66px; }
  #info-panel.segment-panel #panel-name { font-size: var(--fs-23); }
  #info-panel.segment-panel #panel-modern-name { margin-bottom: 10px; }
  #info-panel.segment-panel #panel-period { margin-bottom: 9px; }
  #info-panel.segment-panel #panel-desc {
    margin-bottom: 12px;
  }
  #info-panel.segment-panel #segment-evidence {
    margin-bottom: 14px;
    padding: 10px 12px;
    border: 1px solid rgba(212,168,83,0.16);
    border-radius: 8px;
    background: rgba(212,168,83,0.04);
  }
  #info-panel.segment-panel .seg-evidence-row {
    grid-template-columns: 1fr;
    gap: 3px;
    padding: 7px 0;
  }

  /* Close / dismiss buttons need real tap targets + a clear glyph on a phone.
     The faint dim ✕ was hard to find at the bottom of a bright modal. */
  .auth-close {
    top: 12px; right: 12px;
    width: 40px; height: 40px;
    font-size: var(--fs-19);
  }
  #panel-close {
    top: 14px; right: 14px;
    width: 40px; height: 40px;
    font-size: var(--fs-18);
  }
  .auth-tertiary { font-size: var(--fs-13); padding: 13px; }

  /* Drag handle for bottom sheet */
  #info-panel::before {
    content: '';
    display: block;
    width: 36px; height: 4px;
    background: rgba(212,168,83,0.25);
    border-radius: 2px;
    margin: 10px auto 0;
  }

  /* On desktop the OS scrollbar itself signals there's more of the welcome
     card below the fold; mobile browsers overlay/auto-hide theirs, so nothing
     hints the card scrolls. A sticky fade pinned to the bottom of the visible
     area does the same job with no JS: as the last flow child, it's held at
     bottom:0 (overlapping the last ~32px of text) for every scroll position
     except the true end, where it settles into normal flow and stops
     overlaying anything — i.e. it disappears exactly when there's nothing
     left to scroll to. (The equivalent background-attachment:local trick was
     tried first and is a documented no-op in WebKit/Safari — verified dead
     on-device here — so this uses position:sticky instead, which Safari
     supports correctly.) */
  #welcome-card::after {
    content: '';
    display: block;
    position: sticky;
    bottom: 0;
    height: 32px;
    margin-top: -32px;
    background: linear-gradient(rgba(10,5,0,0), var(--ink-panel) 85%);
    pointer-events: none;
  }
}

/* ════════════════════════════════
   TABLET  (641px – 900px)
   ════════════════════════════════ */
@media (min-width: 641px) and (max-width: 900px) {
  :root { --panel-width: 340px; }
  #panel-name { font-size: var(--fs-22); }
}

/* ════════════════════════════════
   LINKED DATA SIDEBAR  (#linked-data-card)
   Pleiades inbound scholarly cross-references. Quiet by default — a stack of
   collapsible source rows below the action buttons. ★/☆ = reciprocity (shape,
   not color → colorblind-safe).
   ════════════════════════════════ */
#linked-data-card:empty { display: none; }
#linked-data-card {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.ld-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-13);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--gold);
}
.ld-head-icon { font-size: var(--fs-12); }
.ld-sub {
  margin-left: auto;
  font-family: 'Inter', sans-serif;
  font-size: var(--fs-11);
  font-weight: 400;
  color: var(--text-muted);
}
.ld-sources { margin-top: 8px; display: flex; flex-direction: column; gap: 2px; }
.ld-src { border-radius: 6px; }
.ld-src > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 8px;
  border-radius: 6px;
  font-size: var(--fs-13);
  color: var(--text-body);
  transition: background 0.12s ease;
}
.ld-src > summary::-webkit-details-marker { display: none; }
.ld-src > summary:hover { background: var(--gold-faint); }
.ld-star { width: 14px; text-align: center; color: var(--gold); font-size: var(--fs-12); }
.ld-label { flex: 1; }
.ld-n {
  font-size: var(--fs-11);
  color: var(--text-muted);
  background: rgba(240,230,211,0.06);
  border-radius: 10px;
  padding: 1px 8px;
  min-width: 22px;
  text-align: center;
}
.ld-src[open] > summary { color: var(--gold); }
.ld-links {
  list-style: none;
  margin: 2px 0 6px;
  padding: 0 8px 0 30px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ld-links a {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-12);
  color: var(--text-body);
  text-decoration: none;
  line-height: 1.35;
}
.ld-links a:hover { color: var(--gold); text-decoration: underline; }
.ld-links .p-btn-ext { font-size: var(--fs-10); opacity: 0.6; }
.ld-more { font-size: var(--fs-11); color: var(--text-muted); font-style: italic; }

/* ════════════════════════════════
   LIVE PLEIADES ENRICHMENT  (#pleiades-detail-card)
   Description/names fetched from the CORS-open Pleiades JSON API on panel open.
   Reuses the linked-data card vocabulary (.ld-*) so the two read as siblings;
   glyphs (✎ names, § notes) are shape, not color → colorblind-safe.
   ════════════════════════════════ */
#pleiades-detail-card:empty { display: none; }
#pleiades-detail-card {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.pl-src[open] > summary { color: var(--gold); }
.pl-list li { font-size: var(--fs-12); color: var(--text-body); line-height: 1.4; list-style: disc; margin-left: 4px; }
.pl-lang { color: var(--text-muted); font-size: var(--fs-11); }
.pl-notes {
  padding: 2px 8px 6px 30px;
  font-size: var(--fs-12);
  line-height: 1.5;
  color: var(--text-body);
}
.pl-tags { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 5px; }
.pl-tag {
  font-size: var(--fs-10);
  color: var(--text-muted);
  background: rgba(240,230,211,0.06);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 2px 8px;
}
.pl-credit { margin-top: 10px; font-size: var(--fs-10); color: var(--text-muted); font-style: italic; }
.pl-loading { display: flex; gap: 5px; padding: 12px 2px 4px; }
.pl-loading span {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--gold-faint);
  animation: pl-pulse 1s ease-in-out infinite;
}
.pl-loading span:nth-child(2) { animation-delay: 0.15s; }
.pl-loading span:nth-child(3) { animation-delay: 0.3s; }
@keyframes pl-pulse { 0%, 100% { opacity: 0.25; } 50% { opacity: 0.8; } }

/* ── DUAL-NAME LABELS ──────────────────────────────────────
   The "Names" chip swatch (a tiny serif Aa) and the on-map permanent tooltips
   that pair the ancient name with the modern one. Tooltips are non-interactive
   so they never steal a marker tap. */
.swatch-name {
  /* Boxed so it reads as a legend KEY (a type specimen), not as text that runs
     into the adjacent "Names" caps — "Aa NAMES" was misread as one word "AA". */
  font-family: 'Cinzel', serif;
  font-size: var(--fs-10);
  font-weight: 700;
  line-height: 1;
  color: var(--gold);
  text-align: center;
  padding: 2px 4px;
  border: 1px solid rgba(212,168,83,0.5);
  border-radius: 3px;
  background: rgba(212,168,83,0.08);
}
.leaflet-tooltip.via-name-label {
  background: rgba(10, 5, 0, 0.82);
  border: none;
  border-left: 2px solid var(--gold-dim);
  border-radius: 3px;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.5);
  padding: 2px 7px;
  white-space: nowrap;
  pointer-events: none;
}
.leaflet-tooltip.via-name-label::before { display: none; }   /* kill the arrow */
.via-name-label .vnl-ancient {
  display: block;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-12);
  font-weight: 600;
  letter-spacing: 0.3px;
  color: var(--gold);
  line-height: 1.15;
}
.via-name-label .vnl-modern {
  display: block;
  font-family: 'Inter', sans-serif;
  font-size: var(--fs-10);
  font-weight: 300;
  color: var(--parchment);
  opacity: 0.78;
  line-height: 1.1;
}

/* (Empire inset locator map removed — the DARE mini-map read as an unhelpful
   sepia smear at empire scale. World context now comes from the brand's
   "Choose your world" switch + the welcome splash.) */

/* ── REDUCED MOTION ──────────────────────────────────────────────────────
   Respect the OS "reduce motion" setting. Kill the ambient/infinite pulses
   (they loop forever on an idle map/panel), but keep layout intact and keep
   short bounded feedback usable. The quest-ring pulse is the eye-drawing cue
   for actionable quests — under reduced-motion we drop the MOTION channel but
   the marker's shape + color (colorblind-safe) still identify the tier, so no
   information is lost. Loading dots are slowed, not killed: they signal work. */
@media (prefers-reduced-motion: reduce) {
  .quest-ring,
  .alex-beacon-ring,
  .quest-banner-icon,
  #panel-quest-banner.visible { animation: none !important; }
  .pl-loading span { animation-duration: 2s !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   WELCOME REDESIGN — one shared prologue, two clear ways into VIA
   ═══════════════════════════════════════════════════════════════════════════ */
#welcome-modal {
  background: rgba(15,7,1,0.76);
  backdrop-filter: blur(5px) sepia(0.08);
}

#welcome-card {
  width: min(1100px, calc(100vw - 56px));
  height: min(690px, calc(100dvh - 40px));
  max-height: none;
  padding: 0;
  overflow: hidden;
  text-align: left;
  background: #1a0d04;
  border-color: rgba(224,181,98,0.62);
  border-radius: 8px;
  box-shadow: 0 22px 70px rgba(0,0,0,0.62), 0 0 0 1px rgba(90,43,8,0.5) inset;
  transform: translateX(48px);
  scrollbar-width: thin;
  scrollbar-color: rgba(224,181,98,0.62) rgba(23,11,3,0.92);
}

#welcome-card::-webkit-scrollbar,
#welcome-quest-card::-webkit-scrollbar { width: 8px; }

#welcome-card::-webkit-scrollbar-track,
#welcome-quest-card::-webkit-scrollbar-track { background: rgba(23,11,3,0.92); }

#welcome-card::-webkit-scrollbar-thumb,
#welcome-quest-card::-webkit-scrollbar-thumb {
  background: rgba(224,181,98,0.62);
  border: 2px solid rgba(23,11,3,0.92);
  border-radius: 999px;
}

#welcome-card > .auth-close {
  z-index: 3;
  top: 14px;
  right: 14px;
  background: rgba(26,13,4,0.78);
}

.welcome-layout {
  display: grid;
  grid-template-columns: minmax(320px, 34%) minmax(0, 1fr);
  height: 100%;
}

.welcome-overview {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 30px 28px 26px;
  background: linear-gradient(155deg, rgba(43,21,7,0.98), rgba(19,9,3,0.99));
  border-right: 1px solid rgba(224,181,98,0.48);
}

.welcome-heading {
  text-align: center;
  padding-bottom: 22px;
  border-bottom: 1px solid rgba(224,181,98,0.3);
}

.welcome-heading .welcome-glyph {
  margin: 0 0 7px;
  font-size: var(--fs-44);
  line-height: 1;
  color: #e0b562;
  text-shadow: 0 0 20px rgba(224,181,98,0.2);
}

.welcome-heading h2,
#welcome-quest-title {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-22);
  line-height: 1.2;
  letter-spacing: 2px;
  color: #e6b968;
}

.welcome-heading p {
  margin-top: 7px;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-13);
  font-style: italic;
  color: rgba(238,214,176,0.78);
}

.welcome-how {
  flex: 1 1 auto;
  padding: 19px 2px 17px;
}

.welcome-how h3,
.welcome-quest-name,
.welcome-path-overline,
.welcome-quest-eyebrow {
  font-family: 'Cinzel', serif;
  text-transform: uppercase;
  letter-spacing: 2px;
  color: #d8a653;
}

.welcome-how h3 {
  margin-bottom: 17px;
  text-align: center;
  font-size: var(--fs-11);
}

.welcome-how-item {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr);
  align-items: start;
  gap: 12px;
  margin-bottom: 17px;
}

.welcome-how-item:last-child { margin-bottom: 0; }

.welcome-how-icon {
  width: 42px;
  height: 42px;
  margin-top: 1px;
  object-fit: contain;
  filter: drop-shadow(0 3px 8px rgba(0,0,0,0.42));
}

.welcome-how-copy {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.welcome-how-item strong {
  font-size: var(--fs-13);
  line-height: 1.35;
  color: rgba(235,183,92,0.98);
}

.welcome-how-item span {
  font-size: var(--fs-12);
  line-height: 1.5;
  color: rgba(240,224,198,0.75);
}

.welcome-quest-link {
  width: 100%;
  display: grid;
  gap: 5px;
  padding: 17px 10px 0;
  border: 0;
  border-top: 1px solid rgba(224,181,98,0.3);
  background: transparent;
  color: rgba(240,224,198,0.76);
  text-align: center;
  font: inherit;
  cursor: pointer;
}

.welcome-quest-name { font-size: var(--fs-12); }
.welcome-quest-link > span:not(.welcome-quest-name):not(.welcome-quest-action) { font-size: var(--fs-12); }
.welcome-quest-action {
  justify-self: center;
  color: #e0b562;
  font-size: var(--fs-13);
  border-bottom: 1px solid rgba(224,181,98,0.48);
  transition: color 0.15s ease, border-color 0.15s ease;
}
.welcome-quest-link:hover .welcome-quest-action,
.welcome-quest-link:focus-visible .welcome-quest-action {
  color: #f1ca7c;
  border-bottom-color: #f1ca7c;
}

.welcome-paths {
  display: grid;
  grid-template-rows: repeat(2, minmax(0, 1fr));
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(224,181,98,0.62) rgba(23,11,3,0.92);
}

.welcome-path {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 0;
  overflow: hidden;
  background-size: cover;
  background-position: center right;
}

.welcome-path + .welcome-path { border-top: 1px solid rgba(180,94,91,0.7); }

.welcome-path-roman {
  background-image:
    linear-gradient(90deg, rgba(28,13,3,0.99) 4%, rgba(34,16,4,0.94) 54%, rgba(40,18,3,0.54) 100%),
    url('../assets/welcome-roman.jpg');
}

.welcome-path-alexander {
  background-image:
    linear-gradient(90deg, rgba(30,14,10,0.99) 4%, rgba(38,18,19,0.94) 54%, rgba(63,29,31,0.55) 100%),
    url('../assets/welcome-alexander.jpg');
}

.welcome-path-emblem {
  position: relative;
  z-index: 1;
  flex: 0 0 112px;
  width: 112px;
  height: 112px;
  margin-left: 18px;
  object-fit: contain;
  filter: drop-shadow(0 8px 18px rgba(0,0,0,0.52));
}

.welcome-path-copy {
  position: relative;
  z-index: 1;
  width: min(66%, 500px);
  padding: 35px 32px 35px 12px;
}

.welcome-path-overline {
  margin-bottom: 10px;
  font-size: var(--fs-10);
}

.welcome-path h3 {
  font-family: 'Cinzel', serif;
  font-size: var(--fs-28);
  line-height: 1.2;
  letter-spacing: 1px;
  color: #e9bd6e;
}

.welcome-path h3::after {
  content: '';
  display: block;
  width: 86px;
  margin-top: 15px;
  border-top: 1px solid rgba(224,181,98,0.55);
}

.welcome-path-alexander h3::after { border-color: rgba(190,105,113,0.72); }

.welcome-path p {
  margin-top: 17px;
  font-size: var(--fs-15);
  line-height: 1.6;
  color: rgba(244,231,209,0.9);
}

.welcome-path-cta {
  min-width: min(100%, 360px);
  margin-top: 22px;
  padding: 12px 18px;
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  border: 1px solid rgba(235,190,108,0.86);
  border-radius: 4px;
  background: linear-gradient(135deg, #e3b660, #bd8230);
  color: #1a0d04;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-11);
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(0,0,0,0.25);
  transition: filter 0.15s ease, transform 0.15s ease;
}

.welcome-path-alexander .welcome-path-cta {
  color: #f0c7a7;
  background: rgba(106,52,53,0.78);
  border-color: rgba(190,105,113,0.72);
}

.welcome-research-link {
  display: flex;
  align-items: center;
  gap: 13px;
  margin: 14px 20px 20px;
  padding: 13px 15px;
  border: 1px solid rgba(212,168,83,0.34);
  color: rgba(240,230,211,0.84);
  background: rgba(212,168,83,0.06);
  transition: border-color 160ms ease, background 160ms ease, transform 160ms ease;
}
.welcome-research-link:hover,
.welcome-research-link:focus-visible {
  border-color: var(--gold);
  background: rgba(212,168,83,0.12);
  transform: translateY(-1px);
}
.welcome-research-mark {
  color: var(--gold);
  font: 27px/1 'Instrument Serif', Georgia, serif;
}
.welcome-signin {
  justify-self: stretch;
  width: 100%;
  max-width: 100%;
  border: 0;
  background: none;
  color: rgba(244,231,209,0.62);
  padding: 10px 20px 0;
  font: 500 var(--fs-12)/1.4 Inter, sans-serif;
  text-align: right;
  white-space: normal;
  cursor: pointer;
}
.welcome-signin span { color: var(--gold); text-decoration: underline; text-underline-offset: 3px; }
.welcome-signin:hover span, .welcome-signin:focus-visible span { color: #f0c56d; }
.welcome-research-copy { display: grid; gap: 2px; min-width: 0; }
.welcome-research-copy .welcome-path-overline { margin: 0; color: var(--gold); }
.welcome-research-copy strong { color: rgba(244,231,209,0.96); font: 600 var(--fs-13)/1.2 Inter, sans-serif; }
.welcome-research-copy > span:last-child { color: rgba(244,231,209,0.62); font-size: var(--fs-11); line-height: 1.4; }
.welcome-research-arrow { margin-left: auto; color: var(--gold); font-size: 18px; }

.welcome-path-cta:hover { filter: brightness(1.1); transform: translateY(-1px); }

#welcome-quest-modal {
  position: fixed;
  inset: 0;
  z-index: 2110;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(15,7,1,0.82);
  backdrop-filter: blur(5px) sepia(0.08);
}
#welcome-quest-modal.open { display: flex; }

#welcome-quest-card {
  position: relative;
  width: min(520px, 94vw);
  max-height: calc(100dvh - 40px);
  overflow-y: auto;
  padding: 38px 34px 30px;
  background: linear-gradient(155deg, #2c1608, #170b03);
  border: 1px solid rgba(224,181,98,0.56);
  border-radius: 8px;
  box-shadow: 0 22px 70px rgba(0,0,0,0.62);
  scrollbar-width: thin;
  scrollbar-color: rgba(224,181,98,0.62) rgba(23,11,3,0.92);
}

.welcome-quest-eyebrow {
  margin-bottom: 8px;
  font-size: var(--fs-10);
}

#welcome-quest-title { margin: 0 36px 16px 0; }

#welcome-quest-card > p {
  font-size: var(--fs-14);
  line-height: 1.6;
  color: rgba(244,231,209,0.82);
}

.welcome-quest-steps {
  list-style: none;
  counter-reset: welcome-quest-step;
  display: grid;
  gap: 14px;
  margin: 24px 0;
}

.welcome-quest-steps li {
  counter-increment: welcome-quest-step;
  display: grid;
  grid-template-columns: 30px 1fr;
  column-gap: 10px;
  padding-top: 13px;
  border-top: 1px solid rgba(224,181,98,0.22);
}

.welcome-quest-steps li::before {
  content: counter(welcome-quest-step);
  grid-row: 1 / span 2;
  width: 25px;
  height: 25px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(224,181,98,0.5);
  border-radius: 50%;
  color: #e0b562;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-11);
}

.welcome-quest-steps strong { color: #e8b965; font-size: var(--fs-13); }
.welcome-quest-steps span { margin-top: 3px; color: rgba(244,231,209,0.72); font-size: var(--fs-12); line-height: 1.45; }
#welcome-quest-card .welcome-quest-note { margin-bottom: 22px; color: rgba(244,231,209,0.66); font-size: var(--fs-12); }

@media (max-width: 900px) and (min-width: 641px) {
  #welcome-card {
    width: calc(100vw - 32px);
    transform: none;
  }
  .welcome-layout { grid-template-columns: 300px minmax(0, 1fr); }
  .welcome-overview { padding: 26px 22px 22px; }
  .welcome-path-emblem { flex-basis: 82px; width: 82px; height: 82px; margin-left: 10px; }
  .welcome-path-copy { width: calc(100% - 92px); padding: 28px 24px 28px 8px; }
  .welcome-path h3 { font-size: var(--fs-22); }
  .welcome-path p { font-size: var(--fs-13); }
}

@media (max-width: 640px) {
  #app-brand {
    max-width: 154px;
    padding: 3px 4px;
    margin: -3px -4px;
  }
  #app-title { font-size: var(--fs-22); letter-spacing: 4px; }
  #app-subtitle {
    max-width: 150px;
    font-size: var(--fs-9);
    letter-spacing: 0.9px;
    color: rgba(240,230,211,0.94);
    overflow: visible;
    text-overflow: clip;
  }

  #mode-tabs,
  #mode-crosslink {
    top: calc(env(safe-area-inset-top, 0px) + 58px);
    left: 10px;
    right: 10px;
    transform: none;
    justify-content: center;
    gap: 0;
    padding: 2px;
    border-radius: 5px;
  }
  .mode-tab,
  .mode-cross {
    flex: 1 1 0;
    min-width: 0;
    height: 32px;
    padding: 0 7px;
    font-size: var(--fs-9);
    letter-spacing: 0.45px;
    border-radius: 3px;
  }
  #era-toggle-wrap {
    top: calc(env(safe-area-inset-top, 0px) + 99px);
    left: 10px;
    right: 10px;
  }

  #welcome-modal {
    align-items: flex-start;
    padding: max(10px, env(safe-area-inset-top, 0px)) 10px max(10px, env(safe-area-inset-bottom, 0px));
  }
  #welcome-card {
    width: 100%;
    height: auto;
    max-height: calc(100dvh - max(20px, env(safe-area-inset-top, 0px) + env(safe-area-inset-bottom, 0px)));
    overflow-y: auto;
    transform: none;
  }
  .welcome-layout {
    display: flex;
    flex-direction: column;
    height: auto;
  }
  .welcome-overview { display: contents; }
  .welcome-heading {
    order: 0;
    padding: 26px 46px 21px;
    background: linear-gradient(155deg, rgba(43,21,7,0.98), rgba(19,9,3,0.99));
  }
  .welcome-heading .welcome-glyph { font-size: var(--fs-38); }
  .welcome-heading h2 { font-size: var(--fs-20); }
  .welcome-paths {
    order: 1;
    display: grid;
    grid-template-rows: none;
  }
  .welcome-path {
    min-height: 320px;
    border-top: 1px solid rgba(224,181,98,0.34);
  }
  .welcome-path-emblem {
    position: absolute;
    top: 28px;
    left: 18px;
    width: 72px;
    height: 72px;
    margin: 0;
  }
  .welcome-path-copy {
    width: calc(100% - 82px);
    margin-left: 82px;
    padding: 32px 20px 32px 8px;
  }
  .welcome-path h3 { font-size: var(--fs-23); }
  .welcome-path p { font-size: var(--fs-14); line-height: 1.55; }
  .welcome-path-cta { min-width: 100%; font-size: var(--fs-10); letter-spacing: 1.25px; }
  .welcome-how {
    order: 2;
    padding: 24px 22px 7px;
    background: #1b0d04;
    border-top: 1px solid rgba(224,181,98,0.34);
  }
  .welcome-how h3 { margin-bottom: 19px; }
  .welcome-how-item { grid-template-columns: 46px minmax(0, 1fr); margin-bottom: 18px; }
  .welcome-how-icon { width: 46px; height: 46px; }
  .welcome-how-item strong { font-size: var(--fs-14); }
  .welcome-how-item span { font-size: var(--fs-13); }
  .welcome-quest-link {
    order: 3;
    width: auto;
    margin: 0 22px 26px;
    padding-top: 19px;
  }
  #welcome-quest-modal { align-items: flex-start; padding: 10px; }
  #welcome-quest-card { width: 100%; max-height: calc(100dvh - 20px); padding: 34px 22px 24px; }
}

/* ── QUEST FINDER (design options B + C, ?finder=1) ─────────────────────────
   C · Finder panel: a left-hand index of every site in the tapped category,
   grouped by region (Roman) or phase (Alexander). Desktop it sits opposite the
   right-hand info panel so both coexist; mobile it's a bottom sheet that closes
   on row-tap so the fly + pulse are visible. B · count-beacons are Leaflet
   divIcons styled below. */
#finder-panel {
  position: fixed;
  top: 96px;
  left: 12px;
  width: 320px;
  max-height: calc(100vh - 120px);
  display: none;
  flex-direction: column;
  background: var(--ink-panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 14px 42px rgba(0,0,0,0.55);
  z-index: 938;                 /* below the info panel (940) so tapped sites win */
  overflow: hidden;
  font-family: 'Inter', system-ui, sans-serif;
}
#finder-panel.open { display: flex; }

#finder-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 14px 8px;
}
#finder-title {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-16);
  color: var(--gold);
  line-height: 1.2;
}
.finder-swatch {
  width: 12px; height: 12px;
  flex: 0 0 auto;
  border-radius: 3px;
  background: var(--fc, var(--gold));
  box-shadow: 0 0 0 1px rgba(0,0,0,0.4);
}
#finder-close {
  flex: 0 0 auto;
  width: 30px; height: 30px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: transparent;
  color: var(--parchment);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
#finder-close:hover { color: var(--gold); border-color: var(--gold-dim); }

#finder-sub {
  margin: 0;
  padding: 0 14px 10px;
  font-size: var(--fs-12);
  color: rgba(240,230,211,0.62);
  line-height: 1.35;
}

#finder-body {
  overflow-y: auto;
  padding: 0 6px 12px;
}

.finder-group { margin-bottom: 6px; }
.finder-group-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 8px 8px 6px;
  font-family: 'Cinzel', serif;
  font-size: var(--fs-12);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: rgba(240,230,211,0.82);
  cursor: pointer;
  border-radius: 8px;
}
.finder-group-head:hover { background: var(--gold-faint); color: var(--gold); }
.finder-group-label { flex: 1; }
.finder-group-count {
  flex: 0 0 auto;
  min-width: 22px;
  padding: 1px 7px;
  text-align: center;
  border-radius: 999px;
  font-family: 'Inter', sans-serif;
  font-size: var(--fs-11);
  font-weight: 700;
  color: var(--ink);
  background: var(--fc, var(--gold));
}

.finder-list { list-style: none; margin: 0; padding: 0; }
.finder-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 10px;
  border-radius: 8px;
  cursor: pointer;
}
.finder-row:hover { background: var(--gold-faint); }
.finder-row-name {
  flex: 0 1 auto;
  font-size: var(--fs-14);
  font-weight: 600;
  color: var(--parchment);
  /* Read as a tappable link — an underline is the universal "this goes somewhere"
     affordance, which the old plain text lacked (the "tap a name" hint was doing
     all the work). Dimmed until hover so the list still scans calmly. */
  text-decoration: underline;
  text-decoration-color: var(--gold-dim);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.finder-row:hover .finder-row-name,
.finder-row:focus-visible .finder-row-name {
  color: var(--gold);
  text-decoration-color: var(--gold);
}
.finder-row-modern {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--fs-12);
  color: rgba(240,230,211,0.5);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.finder-row-visited {
  flex: 0 0 auto;
  color: #4caf6a;
  font-size: var(--fs-13);
  font-weight: 700;
}

/* B · count-beacons — an always-visible pill on the map. The NUMBER is the
   primary channel (colour-blind safe); the tint is secondary. */
.finder-beacon { background: none; border: none; }
.finder-beacon-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transform: translate(-50%, -50%);
  padding: 3px 10px 3px 3px;
  border: 1.5px solid var(--fc, var(--gold));
  border-radius: 999px;
  background: var(--ink-panel);
  color: var(--parchment);
  font-family: 'Inter', sans-serif;
  cursor: pointer;
  white-space: nowrap;
  box-shadow: 0 3px 10px rgba(0,0,0,0.45);
}
.finder-beacon-btn:hover { border-color: var(--gold); color: var(--gold); }
.finder-beacon-btn .fb-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px; height: 22px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--fc, var(--gold));
  color: var(--ink);
  font-size: var(--fs-13);
  font-weight: 700;
}
.finder-beacon-btn .fb-label {
  font-size: var(--fs-12);
  letter-spacing: 0.02em;
}

@media (max-width: 640px) {
  /* Bottom sheet, mirroring the info panel. It closes on row-tap (quest-finder.js)
     so it never fights the info panel for the screen. */
  #finder-panel {
    top: auto;
    bottom: calc(var(--dock-h) + 8px);
    left: 8px;
    right: 8px;
    width: auto;
    max-height: calc(100dvh - var(--dock-h) - 120px);
    border-radius: 16px;
  }
  .finder-row { padding: 10px; }            /* fatter tap targets */
  .finder-group-head { padding: 10px 10px 7px; }
  /* When the finder is the active sheet, fade the top chrome like the info panel
     does, so the beacons + map read cleanly behind it — including the mode tabs
     (Roman World / Alexander's Empire), which otherwise sit above the sheet. */
  body:has(#finder-panel.open) #topbar,
  body:has(#finder-panel.open) #era-toggle-wrap,
  body:has(#finder-panel.open) #mode-tabs,
  body:has(#finder-panel.open) #mode-crosslink {
    opacity: 0;
    pointer-events: none;
  }
}
