/* =========================================================================
   STACKED — COLORS & TYPE
   Your Bitcoin — Stacked.
   ========================================================================= */

/* ---------- Fonts ---------- */
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-Thin.ttf") format("truetype");         font-weight: 100; font-style: normal; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-ThinItalic.ttf") format("truetype");   font-weight: 100; font-style: italic; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-XLight.ttf") format("truetype");       font-weight: 200; font-style: normal; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-XLightItalic.ttf") format("truetype"); font-weight: 200; font-style: italic; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-Light.ttf") format("truetype");        font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-LightItalic.ttf") format("truetype");  font-weight: 300; font-style: italic; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-Book.ttf") format("truetype");         font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-BookItalic.ttf") format("truetype");   font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-Medium.ttf") format("truetype");       font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-MediumItalic.ttf") format("truetype"); font-weight: 500; font-style: italic; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-Bold.ttf") format("truetype");         font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-BoldItalic.ttf") format("truetype");   font-weight: 700; font-style: italic; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-Black.ttf") format("truetype");        font-weight: 800; font-style: normal; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-BlackItalic.ttf") format("truetype");  font-weight: 800; font-style: italic; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-Ultra.ttf") format("truetype");        font-weight: 900; font-style: normal; font-display: swap; }
@font-face { font-family: "Gotham"; src: url("/fonts/Gotham-UltraItalic.ttf") format("truetype");  font-weight: 900; font-style: italic; font-display: swap; }

/* ---------- Theme system fonts (woff2, self-hosted, OFL) ---------- */
@font-face { font-family: "Fraunces";        src: url("/fonts/Fraunces-Regular.woff2")     format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Fraunces";        src: url("/fonts/Fraunces-SemiBold.woff2")    format("woff2"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Fraunces";        src: url("/fonts/Fraunces-ExtraBold.woff2")   format("woff2"); font-weight: 800; font-style: normal; font-display: swap; }

@font-face { font-family: "Inter";           src: url("/fonts/Inter-Regular.woff2")        format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Inter";           src: url("/fonts/Inter-Medium.woff2")         format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Inter";           src: url("/fonts/Inter-Bold.woff2")           format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }

@font-face { font-family: "IBM Plex Sans";   src: url("/fonts/IBMPlexSans-Regular.woff2")  format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "IBM Plex Sans";   src: url("/fonts/IBMPlexSans-Medium.woff2")   format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "IBM Plex Sans";   src: url("/fonts/IBMPlexSans-Bold.woff2")     format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }

@font-face { font-family: "IBM Plex Mono";   src: url("/fonts/IBMPlexMono-Medium.woff2")   format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }

/* =========================================================================
   THEME SYSTEM — three data-theme blocks. Sunfire is the default.
   Tokens shared across themes (spacing, radii, type scale, motion) live in :root.
   Per-theme tokens (colour, fonts, weight/letter-spacing baselines) live in
   :root[data-theme="<name>"] blocks below.
   ========================================================================= */

:root {
  /* ============ TYPE SCALE (theme-invariant) ============ */
  --fs-display-xl: clamp(56px, 8vw, 112px);
  --fs-display-lg: clamp(44px, 6vw, 80px);
  --fs-display:    clamp(36px, 4.5vw, 60px);
  --fs-h1:         44px;
  --fs-h2:         32px;
  --fs-h3:         24px;
  --fs-h4:         20px;
  --fs-body-lg:    18px;
  --fs-body:       16px;
  --fs-body-sm:    14px;
  --fs-caption:    12px;
  --fs-micro:      11px;

  --lh-tight: 1.02;
  --lh-display: 1.05;
  --lh-heading: 1.15;
  --lh-body: 1.55;
  --lh-ui: 1.3;

  --ls-tight: -0.02em;
  --ls-display: -0.015em;
  --ls-normal: 0;
  --ls-caps: 0.12em;

  /* ============ ACCENT (theme-invariant) ============ */
  /* Bitcoin-orange accent used by .mode-btn-active border/text and the
     rgba(247,147,26,…) background on the same element. Single source of
     truth so the active mode toggle renders correctly. */
  --amber-500: #f7931a;
  /* Stale-feed (degraded) alarm ring on globe pillars + the legend swatch.
     Amber reads as "caution" against both dark themes; inherits to both
     since it lives in the base :root. */
  --quality-warning: var(--amber-500);

  /* ============ SPACING ============ */
  --space-0: 0;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;
  --space-20: 80px;
  --space-24: 96px;
  --space-32: 128px;

  /* ============ RADII ============ */
  --r-none: 0;
  --r-sm: 4px;
  --r-md: 8px;
  --r-lg: 12px;
  --r-xl: 20px;
  --r-pill: 999px;

  /* ============ SHADOWS ============ */
  --shadow-xs: 0 1px 2px rgba(11, 12, 13, 0.04);
  --shadow-sm: 0 2px 6px rgba(11, 12, 13, 0.06);
  --shadow-md: 0 8px 20px rgba(11, 12, 13, 0.08);
  --shadow-lg: 0 20px 40px rgba(11, 12, 13, 0.10);
  --shadow-brand: 0 10px 30px rgba(var(--brand-rgb), 0.25);
  --shadow-focus: 0 0 0 3px rgba(var(--brand-rgb), 0.35);

  /* ============ MOTION ============ */
  --dur-fast: 120ms;
  --dur-base: 200ms;
  --dur-slow: 320ms;
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);

  /* ============ LAYOUT ============ */
  --container-max: 1200px;
  --container-wide: 1400px;

  /* ============ FONT WEIGHTS (semantic, mapped per theme) ============ */
  --fw-thin: 100;
  --fw-xlight: 200;
  --fw-light: 300;
  --fw-book: 400;
  --fw-medium: 500;
  --fw-bold: 700;
  --fw-black: 800;
  --fw-ultra: 900;
}

:root[data-theme="sunfire"] {
  /* brand identity */
  --brand:               #ffd05a;
  --brand-strong:        #e6a020;
  --brand-subtle:        rgba(255, 208, 90, 0.10);
  --brand-rgb:           255, 208, 90;
  --brand-on:            #150e08;

  /* surfaces */
  --surface-bg-1:        #2d1f0e;
  --surface-bg-2:        #1a1207;
  --surface-bg-3:        #0a0703;
  --surface-raised:      #1f160a;
  --hairline:            rgba(255, 248, 224, 0.08);
  --hairline-strong:     rgba(255, 248, 224, 0.16);

  /* foreground */
  --ink:                 #fff8e0;
  --ink-muted:           rgba(255, 248, 224, 0.65);
  --ink-soft:            rgba(255, 248, 224, 0.40);

  /* data semantics */
  --data-renewable:      #67e8f9;
  --data-renewable-tip:  #cffafe;
  --data-flare:          #d83923;
  --data-flare-tip:      #ff7048;

  /* fuel breakouts */
  --fuel-solar:          #ffd05a;
  --fuel-wind:           #67e8f9;
  --fuel-hydro:          #b8cdff;

  /* globe */
  --globe-dot-day:       #fff8e0;
  --globe-dot-night:     #c9a662;
  --globe-border:        rgba(255, 208, 90, 0.35);
  --day-gradient-1:      rgba(255, 208, 90, 0.55);
  --day-gradient-2:      rgba(230, 160, 32, 0.25);
  --day-gradient-3:      rgba(0, 0, 0, 0);
  --night-overlay:       rgba(20, 14, 5, 0.42);
  --pillar-base-alpha:   99;   /* hex pair appended to fuel hex; 0x99 ≈ 60% */

  /* state */
  --success:             #5eead4;
  --warning:             #ffb84d;
  --danger:              #f87171;
  --info:                var(--data-renewable);

  /* type */
  --font-display:        "Fraunces", Georgia, "Times New Roman", serif;
  --font-body:           "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-mono:           "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --font-sans:           var(--font-body);   /* alias: legacy rules read --font-sans */
  --display-weight-strong: 800;
  --display-weight-base:   600;
}

:root[data-theme="deepcurrent"] {
  --brand:               #64d8ff;
  --brand-strong:        #38b0d8;
  --brand-subtle:        rgba(100, 216, 255, 0.10);
  --brand-rgb:           100, 216, 255;
  --brand-on:            #061018;

  --surface-bg-1:        #0a1828;
  --surface-bg-2:        #060f1a;
  --surface-bg-3:        #030810;
  --surface-raised:      #0d1e30;
  --hairline:            rgba(180, 220, 255, 0.08);
  --hairline-strong:     rgba(180, 220, 255, 0.16);

  --ink:                 #e0f0ff;
  --ink-muted:           rgba(224, 240, 255, 0.65);
  --ink-soft:            rgba(224, 240, 255, 0.40);

  --data-renewable:      #64d8ff;
  --data-renewable-tip:  #b0ecff;
  --data-flare:          #d83923;
  --data-flare-tip:      #ff7048;

  --fuel-solar:          #ffb845;
  --fuel-wind:           #64d8ff;
  --fuel-hydro:          #b4a0f0;

  --globe-dot-day:       #e0f0ff;
  --globe-dot-night:     #4080a0;
  --globe-border:        rgba(100, 216, 255, 0.35);
  --day-gradient-1:      rgba(100, 216, 255, 0.45);
  --day-gradient-2:      rgba(56, 176, 216, 0.20);
  --day-gradient-3:      rgba(0, 0, 0, 0);
  --night-overlay:       rgba(3, 8, 16, 0.45);
  --pillar-base-alpha:   99;

  --success:             #5eead4;
  --warning:             #ffb84d;
  --danger:              #f87171;
  --info:                var(--data-renewable);

  --font-display:        "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-body:           "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-mono:           "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --font-sans:           var(--font-body);
  --display-weight-strong: 700;
  --display-weight-base:   500;
}

/* Fallback: if no boot script runs (SSR-rendered intermediate, e.g. Observable's
   initial document before our inline <head> script), default to Sunfire so the
   page is never unstyled. */
:root:not([data-theme]) {
  color-scheme: dark;
}
:root:not([data-theme]),
html:not([data-theme]) body {
  /* paint at least the page chrome with hardcoded Sunfire values */
  background: radial-gradient(ellipse at 50% 40%, #2d1f0e 0%, #1a1207 60%, #0a0703 100%);
  color: #fff8e0;
}

/* Backwards-compatibility aliases for legacy palette tokens still referenced
   by non-chrome rules (data panels, globe, chart elements). Aliases route to
   the active theme's brand/ink so they compile correctly in both themes. */
:root {
  --slate-800: var(--surface-bg-1);
  --white:     var(--ink);
  --btc-orange: var(--data-flare);
  /* `--surface` / `--border` were used in light-on-light contexts that no
     longer exist; map them to dark equivalents so any straggler rule
     doesn't render white-on-white. */
  --surface:           var(--surface-raised);
  --surface-raised-bg: var(--surface-raised);
  --surface-sunken:    var(--surface-bg-2);
  --border:            var(--hairline);
  --border-strong:     var(--hairline-strong);
  --fg-on-dark:        var(--ink);
  --fg-on-dark-muted:  var(--ink-muted);
}

/* ============ SEMANTIC ELEMENT STYLES ============ */
html, body {
  font-family: var(--font-sans);
  color: var(--ink);
  background: radial-gradient(ellipse at 50% 40%, var(--surface-bg-1) 0%, var(--surface-bg-2) 60%, var(--surface-bg-3) 100%);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-book);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

.display-xl, .display-lg, .display,
h1, h2, h3, h4 {
  font-family: var(--font-sans);
  color: var(--ink);
  letter-spacing: var(--ls-display);
  line-height: var(--lh-heading);
  font-weight: var(--fw-bold);
  text-wrap: balance;
  margin: 0;
}

.display-xl { font-size: var(--fs-display-xl); font-weight: var(--fw-black); line-height: var(--lh-display); letter-spacing: var(--ls-tight); }
.display-lg { font-size: var(--fs-display-lg); font-weight: var(--fw-black); line-height: var(--lh-display); letter-spacing: var(--ls-tight); }
.display    { font-size: var(--fs-display);    font-weight: var(--fw-bold);  line-height: var(--lh-display); letter-spacing: var(--ls-tight); }

h1 { font-size: var(--fs-h1); font-weight: var(--fw-bold); }
h2 { font-size: var(--fs-h2); font-weight: var(--fw-bold); }
h3 { font-size: var(--fs-h3); font-weight: var(--fw-medium); }
h4 { font-size: var(--fs-h4); font-weight: var(--fw-medium); }

p { margin: 0; text-wrap: pretty; }
p.lead  { font-size: var(--fs-body-lg); color: var(--ink-muted); line-height: 1.5; }
/* On the dark app shell the slate-500 token is nearly invisible — use a
   lighter tint that reads clearly against the dark background. */
.app-shell p.lead { color: rgba(255,255,255,0.72); }
p.small { font-size: var(--fs-body-sm); }

.eyebrow {
  font-size: var(--fs-caption);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--brand);
}

.caption { font-size: var(--fs-caption); color: var(--ink-muted); }
.micro   { font-size: var(--fs-micro);   color: var(--ink-soft);  letter-spacing: 0.04em; }

code, .mono {
  font-family: var(--font-mono);
  font-size: 0.92em;
  font-feature-settings: "tnum", "zero";
}

/* Tabular figures for money/BTC amounts */
.num-tabular { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }

/* Utility: ink on dark backgrounds */
.on-dark        { color: var(--fg-on-dark); }
.on-dark.muted  { color: var(--fg-on-dark-muted); }

/* =========================================================
   PAGE LOADER — visible immediately from raw HTML, before
   any JS executes. Dismissed via JS after globe mounts.
   ========================================================= */
#page-loader {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: radial-gradient(ellipse at 50% 40%, var(--surface-bg-1) 0%, var(--surface-bg-2) 60%, var(--surface-bg-3) 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  /* Ensure it covers the Observable Framework chrome while JS boots */
  pointer-events: none;
}

#page-loader.is-fading {
  animation: loader-fade-out 0.38s ease-out forwards;
}

@keyframes loader-fade-out {
  to { opacity: 0; }
}

/* Thin shimmer bar at the very top */
.loader-topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: rgba(255,255,255,0.04);
  overflow: hidden;
}

.loader-topbar-fill {
  position: absolute;
  top: 0; left: 0;
  height: 100%;
  width: 45%;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--brand) 40%,
    rgba(255, 255, 255, 0) 60%,
    transparent 100%
  );
  animation: loader-sweep 1.6s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

@keyframes loader-sweep {
  0%   { transform: translateX(-120%); }
  100% { transform: translateX(320%); }
}

/* Centred mark + label */
.loader-center-mark {
  font-size: 22px;
  color: var(--brand);
  animation: loader-pulse 1.6s ease-in-out infinite;
  line-height: 1;
}

@keyframes loader-pulse {
  0%, 100% { opacity: 0.3; transform: scale(0.92); }
  50%       { opacity: 1;   transform: scale(1.04); }
}

.loader-center-text {
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.3);
  font-family: var(--font-mono, monospace);
  margin-bottom: 20px;
}

/* ── Terminal feed ─────────────────────────────────────────── */
.loader-terminal {
  width: 280px;
  background: rgba(0, 0, 0, 0.38);
  border: 1px solid rgba(255, 248, 224, 0.09);
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 14px;
}

.loader-terminal-bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 10px;
  background: rgba(255, 255, 255, 0.025);
  border-bottom: 1px solid rgba(255, 248, 224, 0.07);
}

.loader-terminal-dots {
  display: flex;
  gap: 5px;
  flex-shrink: 0;
}

.loader-terminal-dots span {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(255, 248, 224, 0.10);
}

.loader-terminal-dots span:nth-child(1) { background: rgba(255, 248, 224, 0.13); }
.loader-terminal-dots span:nth-child(2) { background: rgba(255, 248, 224, 0.08); }
.loader-terminal-dots span:nth-child(3) { background: rgba(255, 248, 224, 0.05); }

.loader-terminal-title {
  font-size: 9px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(255, 248, 224, 0.20);
  font-family: var(--font-mono, monospace);
}

/* Fixed-height viewport — shows exactly 5 rows */
.loader-terminal-viewport {
  height: 115px;
  overflow: hidden;
  position: relative;
}

/* Fade masks top & bottom for depth */
.loader-terminal-viewport::before,
.loader-terminal-viewport::after {
  content: '';
  position: absolute;
  left: 0; right: 0;
  height: 26px;
  z-index: 2;
  pointer-events: none;
}
.loader-terminal-viewport::before {
  top: 0;
  background: linear-gradient(to bottom, rgba(0,0,0,0.5), transparent);
}
.loader-terminal-viewport::after {
  bottom: 0;
  background: linear-gradient(to top, rgba(0,0,0,0.5), transparent);
}

/* Scrolling column — translateY'd by JS */
.loader-terminal-scroll {
  display: flex;
  flex-direction: column;
}

/* Individual region row — 23px tall (115 / 5) */
.loader-t-row {
  display: grid;
  grid-template-columns: 18px 1fr;
  align-items: center;
  height: 23px;
  padding: 0 11px;
  font-size: 10px;
  letter-spacing: 0.04em;
  font-family: var(--font-mono, monospace);
  flex-shrink: 0;
  color: rgba(255, 248, 224, 0.38);
  text-transform: uppercase;
}

.loader-t-row.done {
  color: rgba(255, 248, 224, 0.45);
}

.loader-t-row.active {
  color: rgba(255, 208, 90, 0.92);
  background: rgba(255, 208, 90, 0.04);
}

.loader-t-icon {
  font-size: 9px;
  text-align: center;
  flex-shrink: 0;
}

.loader-t-row.done .loader-t-icon {
  color: #5eead4;
}

.loader-t-row.active .loader-t-icon {
  animation: loader-blink 0.75s ease-in-out infinite;
}

@keyframes loader-blink {
  0%, 100% { opacity: 0.25; }
  50%       { opacity: 1; }
}

.loader-t-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Region counter below the terminal */
.loader-counter {
  font-size: 10px;
  letter-spacing: 0.08em;
  color: rgba(255, 248, 224, 0.32);
  font-family: var(--font-mono, monospace);
}

.loader-counter #loader-n {
  color: rgba(255, 248, 224, 0.72);
  font-weight: 600;
}

.loader-counter #loader-total {
  color: rgba(255, 248, 224, 0.48);
}

/* Dashboard body - always dark.
   Target html as well as body so mobile overscroll shows dark chrome, not the
   white fallback that the Stacked base sheet applies to html.
   Gradient stops are intentionally darker than --slate-800 (#161718) for depth;
   the start (#0f1517) is brand-shifted for cool chrome feel. */
html,
body {
  background: radial-gradient(ellipse at 50% 40%, var(--surface-bg-1) 0%, var(--surface-bg-2) 60%, var(--surface-bg-3) 100%);
  color: var(--ink);
  min-height: 100vh;
}

/* =========================================================================
   RESPONSIVENESS & ACCESSIBILITY
   ========================================================================= */

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

body {
  margin: 0;
  overflow-x: hidden;
  font-size: clamp(15px, 0.95rem + 0.15vw, var(--fs-body));
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

@media (max-width: 640px) {
  main > div[style*="display: flex"][style*="gap: 2rem"] {
    flex-wrap: wrap;
    gap: 1rem !important;
  }

  body {
    padding-inline: 4vw;
  }

  .display-xl {
    line-height: 1;
  }
}

main table {
  display: block;
  overflow-x: auto;
  max-width: 100%;
}

/* ============ APP SHELL LAYOUT ============ */
.app-shell {
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
  max-width: 1600px;
  margin: 0 auto;
  padding: 24px 32px;
  gap: 16px;
  color: var(--ink);
}

.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  row-gap: 12px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--hairline);
  position: relative;   /* needed for z-index to apply */
  z-index: 10;          /* layers above the fixed globe canvas (z-index: 0) */
}

.app-header-right {
  display: inline-flex;
  align-items: center;
  gap: 14px;
}

.app-title {
  display: flex;
  align-items: center;
  gap: 14px;
}

.app-mark {
  color: var(--brand);
  font-size: 20px;
}

.app-wordmark {
  font-weight: 800;
  font-size: 16px;
  letter-spacing: 0.04em;
  color: var(--ink);
}

/* Editorial italic accent on the wordmark — carried over from the Ledger
   redesign because Simon liked it. Uses Fraunces (already loaded for both
   Sunfire and Deepcurrent themes) and picks up --brand so it tints yellow
   on Sunfire and blue on Deepcurrent. */
.app-wordmark-accent {
  font-family: "Fraunces", Georgia, "Times New Roman", serif;
  font-style: italic;
  font-weight: 600;
  color: var(--brand);
  letter-spacing: -0.005em;
  margin-left: 1px;
}

.app-tag {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
  padding-left: 14px;
  border-left: 1px solid var(--hairline-strong);
  margin-left: 2px;
}

/* Observable Framework's theme sets `a[href]{color:var(--theme-foreground-focus)}`
 * (specificity 0,1,1). Scoping with `.app-tag` lifts our rule to (0,2,0)
 * so the link inherits the muted tag colour instead of the framework blue. */
.app-tag .app-tag-version {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted var(--hairline-strong);
  transition: color 120ms ease, border-color 120ms ease;
}

.app-tag .app-tag-version:hover,
.app-tag .app-tag-version:focus-visible {
  color: var(--brand);
  border-bottom-color: var(--brand);
}

.app-methodology {
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  text-decoration: none;
  padding: 8px 14px;
  border: 1px solid var(--hairline-strong);
  border-radius: 999px;
}

.app-methodology:hover {
  background: var(--brand-subtle);
  color: var(--ink);
  border-color: var(--brand);
}

/* Primary nav (right-aligned in header) */
.app-nav {
  display: inline-flex;
  gap: 4px;
  align-items: center;
}
.app-nav a {
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  text-decoration: none;
  padding: 7px 14px;
  border-radius: 999px;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
  border: 1px solid transparent;
}
.app-nav a:hover,
.app-nav a[aria-current="page"] {
  background: var(--brand-subtle);
  color: var(--ink);
  border-color: var(--brand);
}

.app-body {
  display: grid;
  grid-template-columns: minmax(300px, 1fr) minmax(400px, 2fr) minmax(280px, 1fr);
  gap: 32px;
  align-items: center;
  align-self: start;   /* don't stretch to fill app-shell's 1fr row — prevents
                          the globe being pushed down to the vertical midpoint */
  padding: 8px 0;
  position: relative;
}

.panel {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.panel-left {
  justify-content: center;
  position: relative;
  z-index: 1;
  padding: 80px 0 80px 24px;
  /* Opaque at outer edge, fades to transparent toward globe */
  background: linear-gradient(
    to right,
    var(--surface-bg-3) 0%,
    rgba(10, 7, 3, 0.92) 50%,
    rgba(26, 18, 7, 0.40) 80%,
    transparent 100%
  );
  /* Soften the top and bottom edges of the dark background */
  mask-image: linear-gradient(to bottom, transparent, black 80px, black calc(100% - 80px), transparent);
  -webkit-mask-image: linear-gradient(to bottom, transparent, black 80px, black calc(100% - 80px), transparent);
}

/* Globe panel sits in the center column of the 3-column grid.
   No position: relative here — the canvas-area uses position: absolute
   and must escape to .app-body as its containing block. */
.panel-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: visible;
}

/* Globe canvas-area sits absolute within .app-body (position: relative) so it
   spans from the header's bottom border to the timeline's top border, across
   the full content width, and scrolls naturally with the page.
   top and height are set directly by syncGlobeRect() in globe.js. */
.globe-canvas-area {
  display: grid;
  align-items: center;
  justify-items: center;
  position: absolute;
  left: 0;
  right: 0;
  z-index: 0;
  pointer-events: none;  /* panel content layers above and receives events */
}

.globe-canvas-area > * {
  grid-area: 1 / 1;
}

.panel-right {
  justify-content: flex-start;
  position: relative;
  z-index: 1;
  padding: 80px 16px 80px 0;
  /* Mirror of panel-left — transparent toward globe, opaque at outer edge */
  background: linear-gradient(
    to left,
    var(--surface-bg-3) 0%,
    rgba(10, 7, 3, 0.92) 50%,
    rgba(26, 18, 7, 0.40) 80%,
    transparent 100%
  );
  /* Soften the top and bottom edges of the dark background */
  mask-image: linear-gradient(to bottom, transparent, black 80px, black calc(100% - 80px), transparent);
  -webkit-mask-image: linear-gradient(to bottom, transparent, black 80px, black calc(100% - 80px), transparent);
}

#globe-canvas {
  display: block;
  width: 100%;
  height: 100%;   /* fills the fixed canvas-area top→bottom */
  pointer-events: all;  /* canvas itself is interactive even though parent is not */
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

#globe-canvas.is-dragging {
  cursor: grabbing;
}

#globe-canvas[hidden] {
  visibility: hidden;
}

.globe-placeholder {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  background:
    radial-gradient(circle at 50% 40%, rgba(var(--brand-rgb),0.12), rgba(var(--brand-rgb),0.04) 35%, rgba(255,255,255,0.02) 60%, transparent 75%),
    radial-gradient(circle at 50% 50%, rgba(255,255,255,0.03), rgba(0,0,0,0) 72%);
}

.globe-placeholder-label {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.58);
}

/* Zoom control row — pinned to the bottom-right corner of the canvas-area.
   position: absolute escapes the stacked grid and gives precise placement.
   pointer-events: auto restores interactivity since parent canvas-area has none. */
.globe-zoom-controls {
  position: absolute;
  bottom: 12px;
  right: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
  z-index: 1;
  pointer-events: auto;
}

.globe-zoom-label {
  font-size: 10px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.40);
  user-select: none;
  flex-shrink: 0;
}

.globe-zoom-slider {
  width: 110px;
  cursor: pointer;
  accent-color: rgba(255,255,255,0.65);
  opacity: 0.65;
  transition: opacity 0.15s;
}

.globe-zoom-slider:hover,
.globe-zoom-slider:focus {
  opacity: 1;
  outline: none;
}

.globe-zoom-slider:focus-visible {
  outline: 2px solid rgba(255, 255, 255, 0.6);
  outline-offset: 2px;
}

@media (hover: none) {
  .globe-zoom-slider {
    width: 140px;
  }
}

/* Flare toggle — sits inline to the right of the flare footnote paragraph. */
.flare-footnote-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--hairline);
}

.flare-toggle-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  flex-shrink: 0;
  padding-top: 1px;
}

.flare-toggle-btn {
  width: 36px;
  height: 20px;
  border-radius: 10px;
  background: rgba(255,255,255,0.10);
  border: 1px solid rgba(255,255,255,0.20);
  cursor: pointer;
  position: relative;
  transition: background 0.2s, border-color 0.2s;
  padding: 0;
  flex-shrink: 0;
}

.flare-toggle-thumb {
  position: absolute;
  left: 3px;
  top: 3px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: rgba(255,255,255,0.45);
  transition: transform 0.2s ease, background 0.2s;
}

.flare-toggle-btn:hover {
  background: rgba(255,255,255,0.16);
}

.flare-toggle-btn.is-active {
  background: rgba(216,57,35,0.28);
  border-color: rgba(216,57,35,0.60);
}

.flare-toggle-btn.is-active .flare-toggle-thumb {
  transform: translateX(16px);
  background: var(--data-flare);
}

.flare-toggle-label {
  font-size: 9px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.40);
  user-select: none;
  white-space: nowrap;
}

#pct-readout .pct-sign,
#pct-readout {
  line-height: 0.9;
  letter-spacing: -0.04em;
  color: var(--white);
}

#pct-readout {
  display: inline-block;
}

.stats-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 18px;
  margin-top: 8px;
}

.flare-footnote {
  font-size: 12px;
  line-height: 1.45;
  color: rgba(255,255,255,0.55);
  margin: 0;
}

.flare-footnote #flare-readout {
  color: var(--btc-orange);
  font-weight: 600;
}

/* =========================================================================
   REGION TOOLTIP — floating card shown on globe hotspot click
   ========================================================================= */

.region-tooltip {
  position: fixed;
  z-index: 100;
  width: 260px;
  padding: 12px 14px 10px;
  background: rgba(16, 22, 26, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(var(--brand-rgb), 0.12) inset;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: rgba(255, 255, 255, 0.88);
  font-size: 12px;
  line-height: 1.4;
  pointer-events: auto;
  animation: region-tooltip-in 140ms var(--ease-out, cubic-bezier(0.2, 0.8, 0.2, 1));
}

@keyframes region-tooltip-in {
  from { opacity: 0; transform: translateY(4px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.region-tooltip[hidden] { display: none; }

.region-tooltip-close {
  position: absolute;
  top: 6px;
  right: 8px;
  background: transparent;
  border: none;
  color: rgba(255, 255, 255, 0.45);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 4px;
  transition: background 120ms, color 120ms;
}
.region-tooltip-close:hover {
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.9);
}

.region-tooltip-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-right: 22px;
  margin-bottom: 8px;
}
.region-tooltip-titles {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.region-tooltip-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--white);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.region-tooltip-country {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.5);
  margin-top: 1px;
}

.region-tooltip-stats {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 8px;
}
.region-tooltip-stat {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 12px;
}
.region-tooltip-stat > span:first-child {
  color: rgba(255, 255, 255, 0.55);
}
.region-tooltip-stat > span:last-child {
  color: var(--white);
  font-weight: 500;
}

.region-tooltip-sparkline {
  display: block;
  width: 100%;
  height: 48px;
  margin: 4px 0 8px;
  border-radius: 4px;
}

.region-tooltip-source {
  font-size: 11px;
  padding-top: 6px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.region-tooltip-source a {
  color: var(--brand);
  text-decoration: none;
}
.region-tooltip-source a:hover {
  text-decoration: underline;
}

.region-tooltip-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding-top: 6px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 11px;
}
.region-tooltip-footer a {
  color: var(--brand);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 60%;
}
.region-tooltip-footer a:hover { text-decoration: underline; }

.region-tooltip-freshness-live {
  color: #3fc1be;
  font-size: 10.5px;
  white-space: nowrap;
}
.region-tooltip-freshness-cached {
  color: #f5c542;
  font-size: 10.5px;
  white-space: nowrap;
}
.region-tooltip-freshness-degraded {
  color: #ff7a59;
  font-size: 10.5px;
  white-space: nowrap;
}
.region-tooltip-freshness-modeled,
.region-tooltip-freshness-anchored {
  color: rgba(255, 255, 255, 0.55);
  font-size: 10.5px;
  white-space: nowrap;
}

.region-tooltip-note {
  margin-top: 4px;
  font-size: 10px;
  line-height: 1.35;
  color: rgba(255, 255, 255, 0.4);
}

.region-tooltip-fuel-swatch {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  vertical-align: middle;
  margin-right: 2px;
}

.stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.stat-value {
  font-size: 22px;
  font-weight: 700;
  color: var(--white);
}

.stat-unit {
  font-size: 13px;
  color: rgba(255,255,255,0.55);
  font-weight: 400;
}

.stat-secondary {
  font-size: 13px;
  color: rgba(255,255,255,0.45);
  font-weight: 400;
}

.hotspot-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 16px;
  margin-top: 10px;
}

.hotspot-columns-three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-auto-rows: min-content;
  gap: 10px;
}

@media (max-width: 1100px) {
  .hotspot-columns-three {
    grid-template-columns: 1fr 1fr;
  }
}
@media (max-width: 700px) {
  .hotspot-columns-three {
    grid-template-columns: 1fr;
  }
}

.hotspot-column {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.hotspot-column-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(255,255,255,0.6);
  padding-bottom: 4px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}

.hotspot-column-subtitle {
  font-size: 9.5px;
  line-height: 1.25;
  color: rgba(255,255,255,0.38);
  margin: 3px 0 4px;
  letter-spacing: 0.02em;
  font-style: italic;
}

.hotspot-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  max-height: 240px;
  overflow-y: auto;
  min-height: 36px;
  /* Thin scrollbar — Firefox */
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,0.18) transparent;
}

/* Thin scrollbar — WebKit (Chrome, Safari, Edge) */
.hotspot-list::-webkit-scrollbar {
  width: 4px;
}
.hotspot-list::-webkit-scrollbar-track {
  background: transparent;
}
.hotspot-list::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,0.18);
  border-radius: 2px;
}
.hotspot-list::-webkit-scrollbar-thumb:hover {
  background: rgba(255,255,255,0.32);
}

.hotspot-list:empty::after {
  content: "—";
  color: rgba(255,255,255,0.25);
  font-size: 12px;
  padding: 4px 0;
}

/* On desktop, scale each hotspot list to the viewport height so taller monitors
   show more items without wasted white space, but cap it so short screens still
   scroll rather than overflow. The list itself has overflow-y: auto, so anything
   beyond this cap becomes scrollable. */
@media (min-width: 1100px) {
  .hotspot-list {
    max-height: min(calc(100vh - 420px), 720px);
    min-height: 180px;
  }
}

/* On mobile (stacked single-column), keep each list to ~6 items so you can
   actually see all three fuel buckets without one swallowing the viewport.
   Still scrollable via base rule's overflow-y: auto, but with a tighter cap
   so the touch-gesture ambiguity of nested scrolls is less severe. */
@media (max-width: 700px) {
  .hotspot-list {
    max-height: 260px;
  }
}

.hotspot-item {
  display: grid;
  grid-template-columns: 8px minmax(0, 1fr);
  grid-template-rows: auto auto;
  column-gap: 6px;
  row-gap: 1px;
  align-items: start;
  font-size: 11.5px;
  color: rgba(255,255,255,0.82);
  padding: 5px 0;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}

.hotspot-gap-row {
  list-style: none;
  padding: 8px 0 4px;
  border-top: 1px dashed rgba(255, 255, 255, 0.12);
  margin-top: 6px;
}

.hotspot-gap-label {
  display: block;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.4;
}

.hotspot-gap-gw {
  font-size: 12px;
  opacity: 0.5;
}

.hotspot-item .dot {
  width: 8px;
  height: 8px;
  margin-top: 4px;
  grid-row: 1 / span 2;
}

.hotspot-name {
  grid-column: 2;
  grid-row: 1;
  white-space: normal;
  overflow-wrap: anywhere;
  line-height: 1.2;
  color: var(--white);
  font-weight: 500;
}

.hotspot-gw {
  grid-column: 2;
  grid-row: 2;
  color: rgba(255,255,255,0.62);
  font-size: 10.5px;
  font-weight: 400;
  letter-spacing: 0.02em;
}

.hotspot-country { display: none; }

@media (max-width: 900px) {
  .hotspot-columns {
    grid-template-columns: 1fr;
    gap: 14px;
  }
}

.hotspot-country {
  color: rgba(255,255,255,0.45);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.hotspot-gw {
  color: var(--white);
  font-weight: 500;
}

.dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  display: inline-block;
  flex-shrink: 0;
}

.dot-brand {
  background: var(--brand);
  box-shadow: 0 0 10px rgba(var(--brand-rgb),0.5);
}

.dot-orange {
  background: var(--btc-orange);
  box-shadow: 0 0 10px rgba(216,57,35,0.5);
}

/* Fuel-themed dots — resolved at paint time from CSS custom properties so
   they always match the canvas bars regardless of which theme is active.
   Avoids the bake-at-eval bug that occurred when inline style="background:
   getFuelColor()" was called before non-Sunfire theme CSS had resolved. */
.dot--solar {
  background: var(--fuel-solar);
  box-shadow: 0 0 9px var(--fuel-solar);
}
.dot--wind {
  background: var(--fuel-wind);
  box-shadow: 0 0 9px var(--fuel-wind);
}
.dot--hydro {
  background: var(--fuel-hydro);
  box-shadow: 0 0 9px var(--fuel-hydro);
}

.legend {
  display: flex;
  gap: 14px;
  padding-top: 14px;
  border-top: 1px solid rgba(255,255,255,0.06);
  font-size: 11px;
  color: rgba(255,255,255,0.6);
}

.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.app-footer {
  padding-top: 16px;
  border-top: 1px solid rgba(255,255,255,0.06);
  position: relative;
  z-index: 10;
  background: var(--surface-bg-3);
}

.app-footer .caption {
  color: rgba(255,255,255,0.55);
  font-size: 11.5px;
  line-height: 1.6;
  max-width: 1100px;
}

.app-footer .caption strong {
  color: rgba(255,255,255,0.75);
  font-weight: 500;
  letter-spacing: 0.03em;
}

.app-footer .caption a {
  color: var(--brand);
  text-decoration: none;
}
.app-footer .caption a:hover { text-decoration: underline; }

.footer-refresh {
  display: inline-block;
  margin-left: 6px;
  opacity: 0.7;
}

@media (max-width: 900px) {
  .app-body {
    grid-template-columns: 1fr;
  }

  .panel-center {
    min-height: 400px;
    order: -1;
  }

  .panel-left,
  .panel-right {
    z-index: auto;
    background: none;
    mask-image: none;
    -webkit-mask-image: none;
    padding: 0 0 0 16px;
  }

  .globe-canvas-area {
    /* Reset absolute positioning back to normal flow on mobile/tablet */
    position: relative;
    top: auto;
    left: auto;
    right: auto;
    height: auto;
    z-index: auto;
    pointer-events: auto;
    width: 100%;
    grid-template-columns: 1fr;
  }

  #globe-canvas {
    pointer-events: auto;
    height: 500px;
    width: 100%;
  }

  /* Tighter padding on tablets and phones — desktop wastes less
     horizontal space than these screens can afford to lose. */
  .app-shell {
    padding: 18px 18px;
    gap: 12px;
  }

  /* Responsive lead copy — 17px desktop body text dominates small
     viewports and pushes the globe below the fold. */
  .app-shell p.lead {
    font-size: 14.5px;
    line-height: 1.5;
  }
}

@media (max-width: 540px) {
  .app-shell {
    padding: 14px 14px;
  }

  .app-tag {
    display: none;
  }

  .stats-row {
    grid-template-columns: 1fr 1fr;
  }

  .app-shell p.lead {
    font-size: 14px;
  }
}

/* Touch-target minimums — iOS guideline is 44×44, Material is 48×48.
   On non-hover pointers (touch), bump the play button and speed/mode
   chips so they're reliably tappable. */
@media (hover: none) {
  .ctl-play {
    width: 44px;
    height: 44px;
    font-size: 18px;
  }
  .ctl-speed-chip,
  .mode-btn {
    min-height: 34px;
    padding: 7px 12px;
    font-size: 12px;
  }
  .region-tooltip-close {
    font-size: 24px;
    padding: 6px 10px;
    min-width: 36px;
    min-height: 36px;
  }
}

/* Tooltip width shouldn't overflow narrow viewports. */
@media (max-width: 400px) {
  .region-tooltip {
    width: min(260px, calc(100vw - 20px));
  }
}

main > h1:first-child {
  display: none;
}

/* ============ TIMELINE + CONTROLS ============ */
.app-timeline {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px 0 0;
  border-top: 1px solid rgba(255,255,255,0.06);
  margin-top: 8px;
  position: relative;  /* needed for z-index to apply */
  z-index: 10;         /* layers above the fixed globe canvas (z-index: 0) */
  background: var(--surface-bg-3);  /* opaque so globe doesn't bleed through */
}
.timeline-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.timeline-header .caption {
  font-size: 11px;
  color: rgba(255,255,255,0.45);
  letter-spacing: 0.04em;
}
#timeline-canvas {
  width: 100%;
  height: 88px;
  display: block;
  cursor: ew-resize;
}
.timeline-controls {
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}
#timeline-controls {
  display: flex;
  gap: 12px;
  align-items: center;
}
.ctl-play {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--brand);
  border: 1px solid rgba(255,255,255,0.1);
  color: var(--slate-800);
  cursor: pointer;
  font-weight: 700;
  font-size: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  line-height: 1;
  transition: background 140ms ease, transform 140ms ease;
}
.ctl-play:hover { transform: scale(1.04); }
.ctl-play[aria-pressed="true"] {
  background: rgba(255,255,255,0.08);
  color: var(--white);
}
.ctl-play-icon {
  display: inline-block;
  line-height: 1;
  /* ⏵ triangle's visual centre-of-mass sits ~1px left of its geometric
     centre; this nudge makes play/pause feel truly centred in the circle. */
  transform: translate(0.5px, 0);
}
.ctl-play[aria-pressed="true"] .ctl-play-icon {
  /* Pause glyph is symmetric — undo the play-triangle nudge when paused. */
  transform: none;
}
.ctl-speed {
  display: inline-flex;
  gap: 4px;
}
.ctl-speed-chip {
  padding: 5px 10px;
  font-size: 11px;
  font-weight: 600;
  background: transparent;
  border: 1px solid rgba(255,255,255,0.12);
  color: rgba(255,255,255,0.6);
  border-radius: 6px;
  cursor: pointer;
  font-family: inherit;
}
.ctl-speed-chip.is-active {
  background: rgba(var(--brand-rgb),0.2);
  border-color: var(--brand);
  color: var(--brand);
}
.mode-toggle {
  display: inline-flex;
  gap: 4px;
}
.mode-btn {
  padding: 5px 10px;
  min-height: 28px;
  font-size: 11px;
  font-weight: 600;
  background: transparent;
  border: 1px solid rgba(255,255,255,0.12);
  color: rgba(255,255,255,0.6);
  cursor: pointer;
  font-family: inherit;
}
.mode-btn:first-child {
  border-radius: 6px 2px 2px 6px;
}
.mode-btn:last-child {
  border-radius: 2px 6px 6px 2px;
}
.mode-btn-active {
  background: rgba(247,147,26,0.18);
  border-color: var(--amber-500);
  color: var(--amber-500);
}

/* Headline row — flex container for pct readout */
.stat-headline-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-left: -24px;
}

.ctl-utc {
  font-size: 12px;
  color: rgba(255,255,255,0.55);
  letter-spacing: 0.04em;
}

/* Mobile */
@media (max-width: 640px) {
  #timeline-canvas { height: 72px; }
  .ctl-play { width: 32px; height: 32px; }
}

/* =========================================================================
   METHODOLOGY PAGE — academic typography pass
   ========================================================================= */

/* Back-nav that appears at the top of Methodology and About pages when the
   Framework sidebar is disabled (sidebar: false in observablehq.config.ts). */
.page-back-nav {
  max-width: 780px;
  margin: 0 auto;
  padding: 20px 32px 0;
}
.page-back-nav a {
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(var(--brand-rgb),0.85);
  text-decoration: none;
  transition: color 0.15s;
}
.page-back-nav a:hover {
  color: rgba(var(--brand-rgb),1);
}

.methodology-doc {
  max-width: 780px;
  margin: 0 auto;
  padding: 24px 32px 96px;
  color: rgba(255,255,255,0.85);
  font-size: 15px;
  line-height: 1.68;
}

.methodology-doc .methodology-header {
  padding-bottom: 28px;
  margin-bottom: 44px;
  border-bottom: 1px solid rgba(255,255,255,0.1);
}

.methodology-doc .methodology-eyebrow {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brand, #ffd05a);
  margin-bottom: 14px;
}

.methodology-doc h1 {
  font-size: 44px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.12;
  margin: 0 0 18px;
  color: var(--white);
  border-bottom: none;
  padding-bottom: 0;
}

.methodology-doc .methodology-deck {
  font-size: 18px;
  line-height: 1.55;
  color: rgba(255,255,255,0.75);
  max-width: 680px;
  margin: 0 0 20px;
}

.methodology-doc .methodology-toc {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  margin-top: 14px;
}
.methodology-doc .methodology-toc a {
  font-size: 12px;
  color: rgba(255,255,255,0.58);
  text-decoration: none;
  padding: 5px 11px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,0.08);
  transition: background 140ms, color 140ms, border-color 140ms;
}
.methodology-doc .methodology-toc a:hover {
  background: rgba(var(--brand-rgb),0.08);
  color: var(--white);
  border-color: rgba(var(--brand-rgb),0.35);
}

.methodology-doc h2 {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.005em;
  margin: 56px 0 16px;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  color: var(--white);
}

.methodology-doc h3 {
  font-size: 16px;
  font-weight: 600;
  margin: 32px 0 8px;
  color: rgba(255,255,255,0.9);
}

.methodology-doc p {
  margin: 0 0 16px;
  color: rgba(255,255,255,0.82);
}

.methodology-doc strong {
  color: var(--white);
  font-weight: 600;
}

.methodology-doc a {
  color: var(--brand, #ffd05a);
  text-decoration: none;
  border-bottom: 1px solid rgba(63,193,190,0.35);
  transition: border-color 140ms, color 140ms;
}
.methodology-doc a:hover {
  color: var(--white);
  border-bottom-color: var(--brand, #ffd05a);
}

.methodology-doc ul,
.methodology-doc ol {
  padding-left: 24px;
  margin: 0 0 18px;
}
.methodology-doc li {
  margin-bottom: 8px;
  color: rgba(255,255,255,0.82);
}
.methodology-doc li::marker {
  color: rgba(255,255,255,0.4);
}

.methodology-doc code {
  font-family: var(--font-mono);
  font-size: 13px;
  padding: 2px 6px;
  border-radius: 4px;
  background: rgba(255,255,255,0.06);
  color: rgba(255,255,255,0.9);
}

.methodology-doc pre {
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 6px;
  padding: 14px 16px;
  overflow-x: auto;
  font-size: 13px;
  line-height: 1.5;
  margin: 16px 0 24px;
}
.methodology-doc pre code {
  background: none;
  padding: 0;
}

/* Tables */
.methodology-doc table {
  width: 100%;
  border-collapse: collapse;
  margin: 20px 0 28px;
  font-size: 13px;
}
.methodology-doc th,
.methodology-doc td {
  text-align: left;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  vertical-align: top;
}
.methodology-doc th {
  font-weight: 600;
  text-transform: uppercase;
  font-size: 10.5px;
  letter-spacing: 0.08em;
  color: rgba(255,255,255,0.55);
  border-bottom: 1px solid rgba(255,255,255,0.18);
}
.methodology-doc td {
  color: rgba(255,255,255,0.78);
}
.methodology-doc tr:hover td {
  background: rgba(255,255,255,0.02);
}

/* Callout boxes */
.methodology-doc .methodology-callout {
  padding: 20px 24px;
  margin: 20px 0 28px;
  border-left: 3px solid var(--brand);
  background: rgba(var(--brand-rgb),0.04);
  border-radius: 0 6px 6px 0;
}
.methodology-doc .methodology-callout p:last-child {
  margin-bottom: 0;
}
.methodology-doc .methodology-callout-abstract {
  font-size: 15.5px;
  line-height: 1.65;
}
.methodology-doc .methodology-callout-abstract p {
  color: rgba(255,255,255,0.88);
}

/* Horizontal rules */
.methodology-doc hr {
  border: none;
  border-top: 1px solid rgba(255,255,255,0.08);
  margin: 40px 0;
}

/* References (§7) — compact list style */
.methodology-doc h2[id="references"] + ul {
  font-size: 13px;
  line-height: 1.55;
  padding-left: 0;
  list-style: none;
}
.methodology-doc h2[id="references"] + ul li {
  padding: 7px 0;
  border-bottom: 1px dotted rgba(255,255,255,0.06);
  color: rgba(255,255,255,0.72);
}
.methodology-doc h2[id="references"] + ul li strong {
  color: rgba(255,255,255,0.92);
  font-weight: 500;
}

/* Trailing italic author note */
.methodology-doc p em:only-child {
  display: inline-block;
  font-size: 13px;
  color: rgba(255,255,255,0.52);
  font-style: italic;
  line-height: 1.5;
}

@media (max-width: 700px) {
  .methodology-doc {
    padding: 16px 18px 64px;
    font-size: 14.5px;
  }
  .methodology-doc h1 { font-size: 32px; }
  .methodology-doc .methodology-deck { font-size: 16px; }
  .methodology-doc h2 { font-size: 20px; margin-top: 40px; }
}

/* ============ THEME TOGGLE ============ */
.theme-toggle {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--surface-raised);
}
.theme-toggle button {
  font: 500 11px / 1 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 6px 12px;
  border-radius: 999px;
  border: 0;
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.theme-toggle button:hover { color: var(--ink); }
.theme-toggle button[aria-checked="true"] {
  background: var(--brand-subtle);
  color: var(--brand);
}
.theme-toggle button:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

@media (max-width: 640px) {
  .theme-toggle button { padding: 5px 9px; }
}

/* ============ GLOBE QUALITY LEGEND ============ */
.globe-legend {
  position: absolute;
  left: 12px;
  bottom: 12px;
  z-index: 3;
  font-size: 12px;
  color: var(--ink);
  background: color-mix(in srgb, var(--surface-bg-2) 82%, transparent);
  border: 1px solid var(--globe-border);
  border-radius: 8px;
  padding: 6px 10px;
  max-width: 220px;
  backdrop-filter: blur(3px);
}
.globe-legend-summary {
  cursor: pointer;
  list-style: none;
  font-weight: 600;
  color: var(--ink-muted);
}
.globe-legend-summary::-webkit-details-marker { display: none; }
.globe-legend-body { margin-top: 6px; display: grid; gap: 4px; }
.globe-legend-row { display: flex; align-items: center; gap: 7px; }
.globe-legend-caption { margin-top: 4px; color: var(--ink-soft); font-size: 11px; }
.ql-dot {
  display: inline-block; width: 12px; height: 12px; border-radius: 50%;
  flex: 0 0 auto; box-sizing: border-box;
}
.ql-measured { background: var(--ink); }
.ql-anchored { background: var(--ink); box-shadow: 0 0 0 2px var(--surface-bg-2), 0 0 0 3px var(--ink); }
.ql-estimated { background: transparent; border: 1.5px solid var(--ink); }
.ql-degraded { background: transparent; border: 1.5px dashed var(--quality-warning); }

@media (max-width: 900px) {
  .globe-legend { left: 8px; bottom: 8px; font-size: 11px; max-width: 60vw; }
}
