/*
 * globe.css — chrome for the Global Reach showpiece globe.
 *
 * Layout + dark-surface treatment only. Colors, fonts, radii resolve to hub
 * tokens from ../map/design-tokens.css so the page matches the map / hub /
 * lineage surfaces. Mirrors the lineage page's full-bleed-canvas + floating
 * glass-panel pattern. The deck.gl GlobeView owns the #globe canvas; the
 * atmosphere glow and vignette are pure CSS layered behind / over it.
 */

:root {
  --glb-panel-bg: rgba(9, 30, 58, 0.82);        /* brand-blue-deep, mostly opaque */
  --glb-border: rgba(181, 212, 244, 0.16);      /* brand-blue-light @ 16% */
  --glb-text: #e7ecf5;
  --glb-muted: var(--color-brand-blue-light);   /* #B5D4F4 */
  --glb-faint: #9fadc6;
  --glb-shadow: 0 8px 28px rgba(4, 9, 18, 0.45);

  /* Arc + hub accents — kept in CSS so the legend swatches and the deck.gl
     layer colors (mirrored as RGB arrays in app.js) stay visually in sync. */
  --glb-oceanic: #54d6e8;   /* luminous cyan — the hero ocean crossings */
  --glb-warm:    #f4c560;   /* warm gold the oceanic arcs fade toward */
  --glb-domestic:#5b7fb0;   /* muted steel — domestic / regional */
  --glb-hub:     #ffd27a;   /* warm hub glow */
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
[hidden] { display: none !important; }

body {
  background:
    radial-gradient(140% 110% at 50% 42%, #0a2547 0%, #061a33 38%, #03101f 72%, #020a16 100%);
  color: var(--glb-text);
  font-family: var(--font-family);
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

/* Stacking (back → front): starfield(0) · atmosphere(1) · globe canvas(2) ·
   vignette(3) · panels(5). The deck canvas clears transparent (app.js), so the
   atmosphere ring and the starfield show through around the globe; the opaque
   earth sphere occludes whatever is behind it. */
#starfield {
  position: fixed;
  inset: -24px;            /* oversized so the parallax sway never bares an edge */
  z-index: 0;
  pointer-events: none;
  will-change: transform;
}

/* ?bare=1 — globe + arcs + rim only, on flat hub-card navy (no UI, no starfield,
   no vignette). Used to render the static hero image for the hub showpiece card;
   the flat bg matches the card so the captured frame has no rectangle seam. */
body.bare { background: var(--color-brand-blue-deep); }
body.bare #head,
body.bare #stats,
body.bare #legend,
body.bare #legendToggle,
body.bare #timeline,
body.bare #hub-pills,
body.bare #starfield,
body.bare #vignette,
body.bare #loading { display: none !important; }

/* Rim light — behind the deck canvas (z:1), so the opaque globe covers its
   inner half and only the faint outer ramp shows just beyond the silhouette.
   The radial-gradient (radius in px) is set by app.js from the globe's screen
   radius, centered on the viewport center where GlobeView centers the globe. */
#rim {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

#globe { position: fixed; inset: 0; z-index: 2; }
#globe canvas { outline: none; background: transparent; }
/* Gesture control: deck handles all touch gestures (drag-spin + pinch-zoom) on the
   canvas. Page-scroll-through over the embed is NOT handled here anymore — it's
   governed by the host-page "click/tap to activate" SHIELD overlay (sp-globe.js):
   while inactive the shield passes wheel/touch to the page; once activated it lets
   the canvas take full gestures. (Superseded the old touch-action:pan-y guard.) */
#globe, #globe canvas { touch-action: none; }

/* Atmosphere glow DISABLED in Stage 2.6. It was a fixed-size CSS halo, so on
   zoom-out (when the globe shrinks) it stayed huge and floated detached from
   the limb — broken at low zoom. The starfield now gives limb separation, so
   the glow is pure liability. Kept here, commented, as a tunable in case a
   zoom-responsive (canvas/shader) atmosphere is wanted later; to re-enable,
   restore the <div id="atmosphere"> element AND make it track globe scale.
#atmosphere {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(circle at 50% 50%,
      rgba(84, 170, 232, 0.00) 36%,
      rgba(84, 170, 232, 0.03) 43%,
      rgba(70, 140, 220, 0.009) 48%,
      rgba(0, 0, 0, 0) 55%);
}
*/

/* Vignette seats the globe in the frame (over the canvas, under the panels). */
#vignette {
  position: fixed;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: radial-gradient(120% 92% at 50% 47%, transparent 52%, rgba(2, 6, 14, 0.68) 100%);
}

/* ───── Shared glass panel ───── */
.glb-panel {
  position: fixed;
  z-index: 5;
  background: var(--glb-panel-bg);
  border: 1px solid var(--glb-border);
  border-radius: var(--radius-card);
  box-shadow: var(--glb-shadow);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

/* ───── Header (top-left) ───── */
#head {
  top: var(--space-5);
  left: var(--space-5);
  padding: var(--space-4) var(--space-5);
  max-width: 360px;
}

/* Back link — identical component to the map / lineage hub pages (pill). */
.home-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  align-self: flex-start;
  margin-bottom: 10px;
  padding: 6px 12px 6px 8px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.04);
  color: var(--color-text-on-dark);
  text-decoration: none;
  font-size: var(--type-button-size);
  font-weight: var(--type-button-weight);
  line-height: 1;
  transition: background 150ms ease, border-color 150ms ease;
}
@media (hover: hover) {
  .home-link:hover {
    background: rgba(255, 255, 255, 0.10);
    border-color: rgba(255, 255, 255, 0.28);
  }
}
.home-link:focus-visible {
  outline: 2px solid var(--color-brand-green-light);
  outline-offset: 2px;
}
.home-link-icon { width: 16px; height: 16px; display: block; }

.head-lockup { display: flex; align-items: flex-start; gap: var(--space-3); }
.head-logo { width: 38px; height: 38px; object-fit: contain; margin-top: 2px; }
.head-eyebrow { margin: 0 0 4px; }
.head-title {
  margin: 0;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.4px;
  line-height: 1.15;
  color: var(--glb-text);
}
.head-sub {
  margin-top: 4px;
  font-size: 13px;
  color: var(--glb-faint);
  line-height: 1.45;
}
/* Honesty line — quiet, but the "uploaded" framing is load-bearing: the data is
   every JLB clients chose to upload to the portal, a verifiable floor (not a
   claim of total usage). Understated, not apologetic. */
.head-note {
  margin-top: 7px;
  padding-top: 7px;
  border-top: 1px solid var(--glb-border);
  font-size: 11.5px;
  font-style: italic;
  color: var(--glb-faint);
  line-height: 1.4;
  max-width: 300px;
}

/* ───── Hub hover tooltip (deck.gl getTooltip; container styled inline) ───── */
.globe-tip-city { font-weight: 700; }
.globe-tip-name { color: var(--glb-muted); font-size: 12px; margin-top: 1px; }
.globe-tip-flights { color: var(--glb-oceanic); font-weight: 600; margin-top: 4px; }

/* ───── Animated stat counters ─────
   A single horizontal row, centered above the globe near the top (the globe is
   viewport-centered, so CSS centering keeps the row over it). Sits above the
   globe's top edge, clear of the arc bloom; clears the title card at ≥1366. */
#stats {
  top: var(--space-4);
  left: 50%;
  transform: translateX(-50%);
  padding: var(--space-3) var(--space-5);
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-5);
}
.stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1.05;
}
.stat + .stat {
  padding-left: var(--space-5);
  border-left: 1px solid var(--glb-border);
}
.stat-num {
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -0.5px;
  color: var(--color-brand-green-light); /* bright Scott IPC green — pops on dark */
  font-variant-numeric: tabular-nums; /* digits hold width while counting */
}

/* ───── Hub label pills (HTML/DOM overlay, positioned by app.js) ───── */
#hub-pills {
  position: fixed;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}
.hub-pill {
  position: absolute;
  top: 0;
  left: 0;
  font-family: ui-monospace, 'Cascadia Mono', Menlo, Consolas, monospace;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: #dde9f8;
  background: rgba(8, 20, 38, 0.82);
  border: 1px solid rgba(181, 212, 244, 0.18);
  border-radius: 5px;
  padding: 2px 6px;
  white-space: nowrap;
  line-height: 1.1;
  box-shadow: 0 1px 4px rgba(2, 6, 14, 0.45);
  will-change: transform;
}
.stat-label {
  margin-top: 3px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--glb-faint);
}

/* ───── Legend (bottom-left) ───── */
#legend {
  left: var(--space-5);
  bottom: var(--space-5);
  padding: var(--space-3) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.legend-row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  color: var(--glb-muted);
}
.legend-swatch {
  width: 22px;
  height: 3px;
  border-radius: 2px;
  flex: none;
}
.swatch-oceanic {
  background: linear-gradient(90deg, var(--glb-oceanic), var(--glb-warm));
  box-shadow: 0 0 8px rgba(84, 214, 232, 0.65);
  height: 4px;
}
.swatch-domestic { background: var(--glb-domestic); opacity: 0.8; }
.swatch-hub {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--glb-hub);
  box-shadow: 0 0 10px rgba(255, 210, 122, 0.8);
}

/* ───── Loading overlay ───── */
#loading {
  position: fixed;
  inset: 0;
  z-index: 8;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  background: radial-gradient(120% 100% at 50% 45%, rgba(6, 26, 51, 0.4), rgba(2, 8, 18, 0.85));
  transition: opacity 600ms ease;
}
#loading.hide { opacity: 0; pointer-events: none; }
.load-orb {
  width: 54px;
  height: 54px;
  border-radius: 50%;
  border: 2px solid rgba(84, 170, 232, 0.18);
  border-top-color: var(--glb-oceanic);
  animation: glb-spin 1s linear infinite;
}
.load-text {
  font-size: 13px;
  letter-spacing: 0.04em;
  color: var(--glb-faint);
}
@keyframes glb-spin { to { transform: rotate(360deg); } }

/* ───── Load-error fallback ───── */
#loadError {
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  max-width: 440px;
  padding: var(--space-5);
  text-align: center;
  color: var(--glb-text);
  font-size: 14px;
  line-height: 1.5;
}

@media (prefers-reduced-motion: reduce) {
  .load-orb { animation: none; }
}

/* ───── Timeline scrubber (bottom-center) ───── */
#timeline {
  left: 50%;
  bottom: var(--space-5);
  transform: translateX(-50%);
  width: min(620px, calc(100vw - 2 * var(--space-5)));
  padding: var(--space-2) var(--space-4) var(--space-3);
  display: flex;
  align-items: flex-end;
  gap: var(--space-4);
}

.tl-play {
  flex: none;
  width: 40px;
  height: 40px;
  margin-bottom: 2px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(255, 255, 255, 0.05);
  color: var(--glb-text);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 150ms ease, border-color 150ms ease;
}
.tl-play:hover { background: rgba(255, 255, 255, 0.12); border-color: rgba(255, 255, 255, 0.3); }
.tl-play:focus-visible { outline: 2px solid var(--color-brand-green-light); outline-offset: 2px; }
.tl-play svg { width: 20px; height: 20px; fill: currentColor; }
/* Show play OR pause depending on state. */
.tl-play .tl-icon-pause { display: none; }
.tl-play.is-playing .tl-icon-play { display: none; }
.tl-play.is-playing .tl-icon-pause { display: block; }

.tl-main { flex: 1 1 auto; min-width: 0; }

/* Readout — its own line (controls moved to .tl-controls above), so the date
   range never collides with the toggles. */
.tl-readout {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 5px;
  white-space: nowrap;
}
.tl-readout-label {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--glb-faint);
}
#tlDate {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.2px;
  color: var(--glb-text);
}

/* Controls row — mode toggle + the contextual secondary control on their own
   line. Wraps gracefully on narrow widths. */
.tl-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-bottom: 7px;
  /* The play button (40px) + gap (16px) sit to the LEFT of .tl-main, so centering
     within .tl-main lands ~28px right of the box center. Shift left to compensate
     so the mode toggle reads centered in the whole timeline box. */
  transform: translateX(-28px);
}
.tl-modes,
.tl-windows {
  display: inline-flex;
  flex: none;
  border: 1px solid var(--glb-border);
  border-radius: var(--radius-pill);
  padding: 2px;
  gap: 2px;
}
.tl-mode-btn,
.tl-win-btn {
  border: none;
  background: transparent;
  color: var(--glb-muted);
  font-family: var(--font-family);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 4px 11px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.tl-win-btn { padding: 4px 9px; }
.tl-mode-btn:hover,
.tl-win-btn:hover { color: var(--glb-text); }
.tl-mode-btn.is-active,
.tl-win-btn.is-active {
  /* Bright Scott IPC green so the selected state clearly stands out (matches the
     stat-counter green). Green tint + a defining ring read as a lit pill. */
  background: rgba(93, 202, 165, 0.22);
  color: var(--color-brand-green-light);
  box-shadow: inset 0 0 0 1px rgba(93, 202, 165, 0.5);
}
.tl-mode-btn:focus-visible,
.tl-win-btn:focus-visible,
.tl-date-input:focus-visible { outline: 2px solid var(--color-brand-green-light); outline-offset: 2px; }

/* Range mode: start/end date inputs. */
.tl-range { display: inline-flex; align-items: center; gap: 6px; }
.tl-range-sep { color: var(--glb-faint); }
.tl-date-input {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--glb-border);
  border-radius: 6px;
  color: var(--glb-text);
  font-family: var(--font-family);
  font-size: 11px;
  padding: 3px 6px;
  color-scheme: dark; /* dark native date picker */
}

/* Contextual visibility: secondary control by mode; no playhead/play in Range. */
.tl-windows, .tl-range { display: none; }
#timeline[data-mode="rolling"] .tl-windows { display: inline-flex; }
#timeline[data-mode="range"] .tl-range { display: inline-flex; }
#timeline[data-mode="range"] #tlPlay,
#timeline[data-mode="range"] #tlHead { display: none; }

.tl-track {
  position: relative;
  height: 18px;        /* tall hit area; the visible rail is centered within */
  cursor: pointer;
  touch-action: none;  /* let pointer drags scrub instead of scrolling */
}
/* The visible rail. */
.tl-track::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 4px;
  border-radius: 2px;
  background: rgba(181, 212, 244, 0.18);
}
.tl-fill {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 4px;
  width: 0;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--glb-oceanic), var(--glb-warm));
  box-shadow: 0 0 8px rgba(84, 214, 232, 0.5);
  pointer-events: none;
}
.tl-head {
  position: absolute;
  top: 50%;
  left: 0;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: #fff6e0;
  box-shadow: 0 0 10px rgba(255, 210, 122, 0.9), 0 0 0 1px rgba(255, 210, 122, 0.6);
  transform: translate(-50%, -50%);
  pointer-events: none;
}

/* Range mode: draggable start/end handles on the track. Hidden in other modes;
   shown (and given a hit area) only when #timeline[data-mode="range"]. */
.tl-range-handle { display: none; }
#timeline[data-mode="range"] .tl-range-handle {
  display: block;
  position: absolute;
  top: 50%;
  left: 0;
  width: 12px;
  height: 18px;
  border-radius: 4px;
  background: #fff6e0;
  box-shadow: 0 0 8px rgba(84, 214, 232, 0.65), 0 0 0 1px rgba(84, 214, 232, 0.5);
  transform: translate(-50%, -50%);
  cursor: ew-resize;
  touch-action: none;
  pointer-events: auto;
  transition: box-shadow 0.12s ease, transform 0.06s ease;
}
#timeline[data-mode="range"] .tl-range-handle::before {
  /* grip ticks so it reads as draggable */
  content: "";
  position: absolute;
  inset: 4px 4px;
  background: repeating-linear-gradient(90deg,
    rgba(11, 22, 38, 0.55) 0 1px, transparent 1px 3px);
}
#timeline[data-mode="range"] .tl-range-handle:hover,
#timeline[data-mode="range"] .tl-range-handle:focus-visible {
  box-shadow: 0 0 12px rgba(84, 214, 232, 0.95), 0 0 0 2px rgba(84, 214, 232, 0.75);
  outline: none;
}

.tl-ticks { position: absolute; inset: 0; pointer-events: none; }
.tl-tick {
  position: absolute;
  top: 50%;
  width: 1px;
  height: 9px;
  transform: translate(-50%, -50%);
  background: rgba(181, 212, 244, 0.28);
}
.tl-tick-label {
  position: absolute;
  top: 11px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--glb-faint);
}

/* ───── Responsive: tablets & narrow windows (iPad portrait/landscape) ─────
   The four corner panels are tuned for wide desktops: the viewport-centered
   counter strip only clears the top-left header at ≥1366px, and the centered
   timeline overruns the bottom-left legend. Below that, stack the top —
   counters become the banner, identity + legend sit beneath it (left / right)
   — and the timeline runs full-width along the bottom on its own. The counter
   strip has a stable single-row height, so anchoring the header/legend beneath
   it is robust regardless of how the header text wraps. */
@media (max-width: 1366px) {
  #stats {
    left: 50%;
    transform: translateX(-50%);
    max-width: calc(100vw - 2 * var(--space-4));
  }
  /* Drop the identity + legend below the counter banner (≈62px tall + gap). */
  #head {
    top: calc(var(--space-4) + 76px);
    left: var(--space-5);
  }
  #legend {
    top: calc(var(--space-4) + 76px);
    right: var(--space-5);
    left: auto;
    bottom: auto;
  }
  /* Legend removed (2026-06-24), so the timeline no longer needs to dodge the
     bottom-left panel — keep it centered + capped (don't stretch full-width). */
  #timeline {
    width: min(620px, calc(100vw - 2 * var(--space-4)));
  }
}

/* Legend toggle — a compact info button. Hidden on desktop (≥1367, where the
   full legend panel is always visible); shown on tablets (≤1366, both
   orientations), where it toggles #legend as a popover. */
.legend-toggle {
  display: none;
  position: fixed;
  z-index: 6;
  width: 40px;
  height: 40px;
  align-items: center;
  justify-content: center;
  padding: 0;
  color: var(--color-text-on-dark);
  cursor: pointer;
}
.legend-toggle svg { width: 20px; height: 20px; }
@media (hover: hover) {
  .legend-toggle:hover { border-color: rgba(255, 255, 255, 0.28); }
}

/* ───── Tablets (iPad mini → 12.9" Pro, BOTH orientations) ─────
   The identity becomes a slim, WIDE bar (horizontal lockup, redundant totals
   line dropped, honesty note kept), the counter cards drop beneath it, and the
   legend collapses to an info button parked at the BOTTOM (just above the
   timeline) so the whole top stays open. Applied to both portrait and landscape
   (up to the 12.9" Pro's 1366px landscape width) — desktop ≥1367 keeps the
   floating-corner layout. The cards anchor to the title bar's MEASURED height
   (--glb-head-h) and the legend to the timeline's (--glb-timeline-h) — both set
   by app.js measureChrome on load (+ fonts.ready), resize, and mode change — so
   wrapping never causes overlap. */
@media (max-width: 1366px) {
  /* Back link → icon-only circle (text kept for screen readers): vertically
     centered in the bar (overrides the base align-self: flex-start) and the
     chevron centered within it (the base has asymmetric text padding + gap). */
  .home-link {
    margin-bottom: 0;
    flex: none;
    align-self: center;
    justify-content: center;
    gap: 0;
    padding: 7px;
  }
  .home-link span {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    clip: rect(0 0 0 0); clip-path: inset(50%);
    overflow: hidden; white-space: nowrap;
  }
  /* Identity → a slim bar spanning the FULL width ("all the way across"), the
     honesty note pushed to the right so the bar reads balanced (identity left,
     framing right) instead of left-heavy. */
  #head {
    top: var(--space-5);
    left: var(--space-5);
    right: var(--space-5);
    max-width: none;
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-5);
  }
  /* Divider separates the back control from the brand lockup (cleaner than two
     adjacent circles). */
  .head-lockup {
    align-items: center;
    padding-left: var(--space-4);
    border-left: 1px solid var(--glb-border);
  }
  .head-sub { display: none; }            /* drop "10,692 plots · …" — redundant with the cards */
  /* Honesty note pulled out of flow to the bar's right edge (vertically
     centered) so the full-width bar reads balanced: identity left, framing
     right. Absolute within #head (a positioned/fixed ancestor); the lockup
     (now just eyebrow + title) sets the bar height, so the note can't push it. */
  .head-note {
    position: absolute;
    top: 50%;
    right: var(--space-5);
    transform: translateY(-50%);
    margin: 0;
    padding: 0;
    border-top: 0;
    max-width: 260px;     /* clears the title block down to iPad mini (744) */
    text-align: right;
  }
  /* Counter cards drop below the measured title bar, spread within a centered
     band. Capped width so the row stays tidy on the wide 12.9" landscape instead
     of stretching the five counters to the far edges; on portrait the cap is
     above the viewport so it still spans edge-to-edge as before. */
  #stats {
    /* Balanced with the timeline's bottom gap (var(--space-5)=24px) so the globe
       sits centered between them. Was offset ~40px for the now-removed header card. */
    top: var(--space-5);
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    width: min(calc(100vw - 2 * var(--space-5)), 800px);
    justify-content: space-between;
  }
  /* Legend → info button at the bottom-left, just above the timeline; the
     popover opens upward from there. */
  .legend-toggle {
    display: flex;
    top: auto;
    right: auto;
    left: var(--space-5);
    bottom: calc(var(--space-5) + var(--glb-timeline-h, 120px) + var(--space-3));
  }
  #legend {
    display: none;
    top: auto;
    right: auto;
    left: var(--space-5);
    bottom: calc(var(--space-5) + var(--glb-timeline-h, 120px) + var(--space-3) + 40px + var(--space-3));
  }
  #legend.is-open { display: flex; }
}

/* Narrow viewports (≤700px, either orientation): too tight for the honesty note
   beside the title, so return it to flow under the title (the bar grows taller;
   the cards re-anchor via the measured --glb-head-h). iPad mini portrait (744)
   stays above this, so the note keeps its balanced right-edge placement there. */
@media (max-width: 700px) {
  .head-note {
    position: static;
    transform: none;
    margin-top: 3px;
    max-width: none;
    text-align: left;
  }
}

/* Phones / very narrow: show only the THREE headline footprint KPIs. */
@media (max-width: 560px) {
  /* 5 KPIs don't fit one phone-width row — the earlier fix wrapped them to a cramped
     3 + 2 grid that crowded the globe. Better: show the three headline footprint
     metrics — Plots · Countries · Airports — in one clean single row, and hide the
     other two: Oceanic (2nd; nearly equal to Plots here, so it read redundant beside
     it) and Continents (4th; a small number that reads weak on its own). The hidden
     counters keep animating (app.js updates them by id) — this is display-only, so
     re-widening the viewport restores all five. Dividers are restored because three
     items sit in a single row where the vertical rules read correctly again. */
  #stats {
    flex-wrap: nowrap;
    justify-content: center;
    gap: 0;
    padding: var(--space-2) var(--space-4);
    width: min(calc(100vw - 2 * var(--space-4)), 340px);
    top: var(--space-3);   /* sit near the top edge (was ~40px) — frees globe room */
  }
  #stats .stat:nth-child(2),   /* Oceanic   — hidden on phones */
  #stats .stat:nth-child(4) {  /* Continents — hidden on phones */
    display: none;
  }
  /* Mirror the stat banner's top gap so the globe is vertically centered between
     the two panels (timeline sits the same 12px from the bottom as stats from top). */
  #timeline { bottom: var(--space-3); }
  #stats .stat { flex: 0 0 auto; padding: 0 14px; border-left: none; }
  /* Dividers before the 2nd and 3rd VISIBLE stats (Countries=child 3, Airports=child 5). */
  #stats .stat:nth-child(3),
  #stats .stat:nth-child(5) { border-left: 1px solid var(--glb-border); }
  .stat-num { font-size: 20px; }
  /* Timeline: the rolling-mode date RANGE ("March 2022 – October 2022") + the
     "ACTIVITY IN" label overflow the phone-width readout and clip. Drop the label
     (the mode toggle right above already gives context) so the date range fits. */
  .tl-readout-label { display: none; }
  #tlDate { font-size: 15px; }
}
