/* F1 Jet Tracker — the public website.
 *
 * Three faces, each with one job: Archivo at its widest for headings and the
 * jets' names (the stretched grotesque of motorsport liveries), Inter for
 * reading, and JetBrains Mono for what a flight strip carries — registrations,
 * ICAO codes, flight levels, times.
 *
 * Light and dark are the same page read the other way up: every colour is a
 * token on :root, redefined for [data-theme="dark"] (theme.js sets it before
 * first paint). --accent and --track are replaced at runtime by the posting
 * bot's own colours.
 */

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url("assets/archivo-var.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/inter-var.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("assets/jetbrains-mono-var.woff2") format("woff2");
}

/* ── Tokens ─────────────────────────────────────────────────────── */

:root {
  --bg: #f4f6f9;
  --bg-deep: #e9edf2;
  --surface: #ffffff;
  --surface-2: #f1f4f7;
  --surface-3: #e6ebf0;
  --line: rgba(12, 20, 32, 0.09);
  --line-strong: rgba(12, 20, 32, 0.16);
  --ink: #0a0f17;
  --ink-2: #465163;
  --ink-3: #7a8494;
  --accent: #da1519;
  --track: #da1519;
  --on-accent: #ffffff;
  --air: #0b9f6e;
  --air-soft: rgba(11, 159, 110, 0.12);
  --ground: #5b61d6;
  --ground-soft: rgba(91, 97, 214, 0.1);
  --glass: rgba(244, 246, 249, 0.72);
  --shadow-card: 0 1px 2px rgba(12, 20, 32, 0.05), 0 12px 32px -18px rgba(12, 20, 32, 0.22);
  --shadow-float: 0 2px 6px rgba(12, 20, 32, 0.08), 0 24px 48px -20px rgba(12, 20, 32, 0.32);
  --band: #eaeef3;
  --globe-dot: #5a6577;
  --edge-hi: rgba(255, 255, 255, 0.95);
  --edge-lo: rgba(12, 20, 32, 0.06);
  --glare: rgba(255, 255, 255, 0.7);
  --tilt-near: rgba(12, 20, 32, 0.12);
  --rim: color-mix(in srgb, var(--accent) 55%, transparent);
  --tilt-far: rgba(12, 20, 32, 0.32);
  --shadow-3d: 0 1px 1px rgba(12, 20, 32, 0.05), 0 6px 12px -4px rgba(12, 20, 32, 0.08), 0 22px 40px -20px rgba(12, 20, 32, 0.3);
  --shadow-3d-hover: 0 1px 1px rgba(12, 20, 32, 0.05), 0 10px 18px -6px rgba(12, 20, 32, 0.1), 0 34px 60px -26px rgba(12, 20, 32, 0.38);

  /* The map's markers, on Liberty-pale ground. */
  --map-ink-strong: rgba(255, 255, 255, 0.95);
  --map-halo: rgba(255, 255, 255, 0.7);
  --map-halo-hot: rgba(255, 255, 255, 0.95);
  --map-halo-ring: var(--accent);
  --map-pill: rgba(255, 255, 255, 0.94);
  --map-pill-edge: rgba(12, 20, 32, 0.14);
  --map-pill-text: #0a0f17;
  --map-outline: #ffffff;
  --map-shade: rgba(12, 20, 32, 0.3);
  --map-airborne: #0b9f6e;
  --map-landed: #5b61d6;
  --map-stem: rgba(70, 81, 99, 0.55);
  --map-ping-ground: rgba(91, 97, 214, 0.14);

  --font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --font: "Inter", "Helvetica Neue", Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --radius-sm: 10px;
  --radius: 16px;
  --radius-lg: 24px;
  --pill: 999px;
  --gutter: clamp(16px, 4vw, 40px);
  --max: 1240px;
  --nav-h: 64px;

  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-1: 120ms;
  --dur-2: 180ms;
  --dur-3: 280ms;

  color-scheme: light;
}

:root[data-theme="dark"] {
  --bg: #07090d;
  --bg-deep: #040508;
  --surface: #0e1219;
  --surface-2: #141a23;
  --surface-3: #1b222d;
  --line: rgba(255, 255, 255, 0.075);
  --line-strong: rgba(255, 255, 255, 0.14);
  --ink: #eef2f7;
  --ink-2: #a3adbd;
  --ink-3: #6c7688;
  --air: #34d399;
  --air-soft: rgba(52, 211, 153, 0.12);
  --ground: #a5b4fc;
  --ground-soft: rgba(165, 180, 252, 0.1);
  --glass: rgba(7, 9, 13, 0.7);
  --shadow-card: 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 20px 40px -24px rgba(0, 0, 0, 0.8);
  --shadow-float: 0 1px 0 rgba(255, 255, 255, 0.06) inset, 0 28px 56px -20px rgba(0, 0, 0, 0.85);
  --band: #0b0e14;
  --globe-dot: #8f9bb0;
  --edge-hi: rgba(255, 255, 255, 0.13);
  --edge-lo: rgba(0, 0, 0, 0.55);
  --glare: rgba(255, 255, 255, 0.09);
  --tilt-near: rgba(0, 0, 0, 0.45);
  --rim: rgba(255, 255, 255, 0.55);
  --tilt-far: rgba(0, 0, 0, 0.85);
  --shadow-3d: 0 1px 1px rgba(0, 0, 0, 0.5), 0 8px 16px -6px rgba(0, 0, 0, 0.55), 0 30px 60px -28px rgba(0, 0, 0, 0.95);
  --shadow-3d-hover: 0 1px 1px rgba(0, 0, 0, 0.5), 0 12px 22px -8px rgba(0, 0, 0, 0.6), 0 42px 80px -30px rgba(0, 0, 0, 1);

  --map-ink-strong: rgba(222, 234, 250, 0.85);
  --map-halo: rgba(6, 10, 16, 0.62);
  --map-halo-hot: rgba(6, 10, 16, 0.86);
  --map-pill: rgba(16, 21, 30, 0.9);
  --map-pill-edge: rgba(168, 191, 219, 0.35);
  --map-pill-text: #eaf2fb;
  --map-outline: #dce8f6;
  --map-shade: rgba(0, 0, 0, 0.55);
  --map-airborne: #34d399;
  --map-landed: #a5b4fc;
  --map-stem: rgba(201, 206, 214, 0.5);
  --map-ping-ground: rgba(165, 180, 252, 0.16);

  color-scheme: dark;
}

/* ── Base ───────────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: var(--nav-h); -webkit-text-size-adjust: 100%; }
html, body { margin: 0; }
body {
  background: var(--bg);
  color: var(--ink);
  font: 400 15px/1.55 var(--font);
  letter-spacing: -0.008em;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}
img, svg { display: block; }
a { color: inherit; }
button { font: inherit; color: inherit; letter-spacing: inherit; }
h1, h2, h3, p { margin: 0; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 6px; }

.skip {
  position: absolute; left: -999px; top: 8px; z-index: 100;
  background: var(--accent); color: var(--on-accent); padding: 10px 14px; border-radius: var(--pill);
  text-decoration: none; font-weight: 600;
}
.skip:focus { left: 12px; }

.wrap { width: 100%; max-width: calc(var(--max) + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter); }
.mono { font-family: var(--font-mono); font-feature-settings: "zero" 0; letter-spacing: 0; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

::view-transition-old(root), ::view-transition-new(root) { animation-duration: 320ms; }
/* The header is left out of the cross-fade: it cuts to the new theme in the
   same frame as the browser's bar above it, which cannot fade. */
@media (hover: hover) and (pointer: fine) { .nav { view-transition-name: site-nav; } }
::view-transition-group(site-nav), ::view-transition-new(site-nav) { animation: none; }
::view-transition-old(site-nav) { display: none; }

/* ── Nav ────────────────────────────────────────────────────────── */

.nav {
  position: sticky; top: 0; z-index: 40;
  /* Solid, in the page's own ground: the same colour theme.js gives the
     browser's bar above it, so the two read as one in either theme. */
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  padding-top: env(safe-area-inset-top);
}
.nav-inner {
  display: flex; align-items: center; gap: 20px;
  height: var(--nav-h);
  max-width: calc(var(--max) + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter);
}
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; min-width: 0; }
.brand img { width: 34px; height: 34px; object-fit: contain; flex: none; padding: 3px; border-radius: 10px; background: #0d0d0e; }
.brand-name {
  font-family: var(--font-display); font-stretch: 125%; font-weight: 800;
  font-size: 15px; letter-spacing: -0.01em; text-transform: uppercase; white-space: nowrap;
}
.nav-links { display: flex; gap: 4px; margin-left: 12px; }
.nav-links a {
  text-decoration: none; font-size: 14px; font-weight: 500; color: var(--ink-2);
  padding: 7px 12px; border-radius: var(--pill);
  transition: color var(--dur-2) var(--ease), background-color var(--dur-2) var(--ease);
}
.nav-links a:hover { color: var(--ink); background: var(--surface-2); }
.nav-end { margin-left: auto; display: flex; align-items: center; gap: 8px; }

.status {
  display: inline-flex; align-items: center; gap: 8px; height: 34px; padding: 0 12px;
  border: 1px solid var(--line); border-radius: var(--pill); background: var(--surface);
  font-size: 12.5px; font-weight: 600; white-space: nowrap;
}
.status-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ink-3); flex: none; position: relative; }
.status[data-state="live"] .status-dot { background: var(--air); }
.status[data-state="live"] .status-dot::after {
  content: ""; position: absolute; inset: -4px; border-radius: 50%; border: 1.5px solid var(--air);
  animation: pulse 2s var(--ease-out) infinite;
}
.status[data-state="stale"] .status-dot { background: #e0a100; }
.status[data-state="down"] .status-dot { background: var(--accent); }
.status-clock { font-family: var(--font-mono); font-weight: 500; color: var(--ink-3); padding-left: 8px; border-left: 1px solid var(--line); }
@keyframes pulse { from { transform: scale(0.6); opacity: 0.9; } to { transform: scale(1.6); opacity: 0; } }

.icon-btn {
  width: 38px; height: 38px; flex: none; display: grid; place-items: center; cursor: pointer;
  border: 1px solid var(--line); border-radius: 50%; background: var(--surface);
  transition: background-color var(--dur-2) var(--ease), transform var(--dur-1) var(--ease);
}
.icon-btn:hover { background: var(--surface-2); }
.icon-btn:active { transform: scale(0.94); }
.icon-btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.i-moon { fill: currentColor !important; stroke: none !important; }
:root[data-theme="dark"] .i-moon, :root:not([data-theme="dark"]) .i-sun { display: none; }
.menu-btn { display: none; }
/* Two bars that cross into an ×: plain boxes, so every browser turns them
   about the same point (SVG paths turned about different ones in Safari). */
.menu-icon { position: relative; display: block; width: 18px; height: 12px; }
.menu-icon span {
  position: absolute; left: 0; width: 100%; height: 2px; border-radius: 2px; background: currentColor;
  transition: translate var(--dur-3) var(--ease-out), rotate var(--dur-3) var(--ease-out);
}
.menu-icon span:first-child { top: 1px; }
.menu-icon span:last-child { bottom: 1px; }
.menu-btn[aria-expanded="true"] .menu-icon span:first-child { translate: 0 4px; rotate: 45deg; }
.menu-btn[aria-expanded="true"] .menu-icon span:last-child { translate: 0 -4px; rotate: -45deg; }
/* With the menu open, the page under it blurs and dims, and stays still. */
body::after {
  /* Past every edge, so no strip of the page is left sharp where a phone's
     bars and safe areas move the viewport about. */
  content: ""; position: fixed; top: -120px; bottom: -120px; left: -20px; right: -20px; z-index: 39; pointer-events: none;
  background: color-mix(in srgb, var(--bg) 35%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  opacity: 0; visibility: hidden; transition: opacity var(--dur-3) var(--ease), visibility 0s linear var(--dur-3);
}
body.menu-open::after { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity var(--dur-3) var(--ease), visibility 0s; }
body.menu-open { overflow: hidden; }

/* The phone menu: a sheet that unrolls from under the header, its pages
   by name, each rising into place one after another; under
   them the accounts and the small print. It rolls back up on close. */
.menu { display: none; }
@media (max-width: 899px) {
  .nav-links { display: none; }
  .menu-btn { display: grid; }
  .menu {
    display: block; position: absolute; top: 100%; left: 0; right: 0;
    max-height: calc(100dvh - var(--nav-h) - env(safe-area-inset-top)); overflow-y: auto; overscroll-behavior: contain;
    padding: 6px var(--gutter) calc(18px + env(safe-area-inset-bottom));
    background: var(--bg); border-bottom: 1px solid var(--line);
    box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.35);
    clip-path: inset(0 0 100% 0); visibility: hidden;
    transition: clip-path 380ms cubic-bezier(0.4, 0, 0.2, 1), visibility 0s linear 380ms;
  }
  .menu[data-open="true"] {
    clip-path: inset(0 0 -60px 0); visibility: visible;
    transition: clip-path 520ms cubic-bezier(0.22, 1, 0.36, 1), visibility 0s;
  }
}
.menu-list { list-style: none; margin: 0; padding: 0; }
.menu-list li, .menu-foot {
  opacity: 0; translate: 0 14px;
  transition: opacity 200ms var(--ease), translate 200ms var(--ease);
}
.menu[data-open="true"] .menu-list li, .menu[data-open="true"] .menu-foot {
  opacity: 1; translate: none;
  transition: opacity 420ms var(--ease-out) calc(90ms + var(--i) * 45ms), translate 560ms cubic-bezier(0.22, 1, 0.36, 1) calc(90ms + var(--i) * 45ms);
}
.menu-list a {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 12px;
  padding: 15px 4px; border-bottom: 1px solid var(--line); text-decoration: none; color: var(--ink);
  -webkit-tap-highlight-color: transparent;
}
.menu-t { display: grid; gap: 3px; min-width: 0; }
.menu-t b { font-family: var(--font-display); font-stretch: 125%; font-weight: 800; font-size: 22px; letter-spacing: -0.02em; line-height: 1.1; }
.menu-go { font-size: 18px; color: var(--ink-3); transition: translate var(--dur-3) var(--ease-out), color var(--dur-2) var(--ease); }
.menu-list a:hover .menu-go, .menu-list a:active .menu-go { translate: 5px 0; color: var(--accent); }
.menu-list a:active { background: var(--surface-2); }
/* Where you are: a red bar at the edge and the arrow in red. */
.menu-list a[aria-current="page"]::before { content: ""; position: absolute; left: -8px; top: 16px; bottom: 16px; width: 3px; border-radius: 3px; background: var(--accent); }
.menu-list a[aria-current="page"] .menu-go { color: var(--accent); }
.menu-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px; padding: 18px 4px 4px; }
.menu-socials { list-style: none; margin: 0; padding: 0; display: flex; gap: 6px; }
.menu-socials a { display: grid; place-items: center; width: 38px; height: 38px; border-radius: 50%; border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); }
.menu-socials a:active { color: var(--accent); }
.menu-socials svg { width: 16px; height: 16px; fill: currentColor; }
.menu-small { display: flex; gap: 14px; font-size: 13px; }
.menu-small a { padding: 6px 0; color: var(--ink-3); text-decoration: none; }
@media (prefers-reduced-motion: reduce) {
  .menu, .menu[data-open="true"], .menu-list li, .menu-foot, .menu[data-open="true"] .menu-list li, .menu[data-open="true"] .menu-foot { transition: none !important; }
}
@media (max-width: 520px) {
  .status-clock { display: none; }
  .brand-name { font-size: 13px; }
}
@media (max-width: 380px) {
  .brand-name { display: none; }
}
@keyframes menuIn { from { opacity: 0; transform: translateY(-6px); } }

/* ── The backdrop ───────────────────────────────────────────────
   One background under the whole site — a dot grid, drifting glows and a
   vignette — drawn by backdrop.js into this canvas, fixed to the window.
   It starts hidden and backdrop.js fades it in. Sections and the footer are
   see-through over it, so it runs unbroken from the top to the bottom; only
   the cards stand on it. */
.backdrop { position: fixed; inset: 0; z-index: -1; width: 100%; height: 100%; pointer-events: none; opacity: 0; }

/* ── Buttons & chips ────────────────────────────────────────────── */

.btn {
  position: relative; isolation: isolate; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 48px; padding: 0 22px; border-radius: var(--pill);
  font-weight: 600; font-size: 15px; text-decoration: none; cursor: pointer;
  /* --tx/--ty are the magnetic pull app.js sets while the cursor is near;
     --mx/--my place the spotlight under it. Leaving springs back. */
  translate: var(--tx, 0px) var(--ty, 0px);
  transition: translate 520ms cubic-bezier(0.3, 1.25, 0.6, 1), scale var(--dur-1) var(--ease),
    background-color var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), box-shadow var(--dur-3) var(--ease);
}
.btn.is-near { transition-duration: 160ms, var(--dur-1), var(--dur-2), var(--dur-2), var(--dur-3); transition-timing-function: var(--ease-out); }
.btn:active { scale: 0.96; }
/* The spotlight: a soft glow that follows the cursor across the face. */
.btn::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  background: radial-gradient(120px circle at var(--mx, 50%) var(--my, 50%), var(--btn-glow), transparent 70%);
  opacity: 0; transition: opacity var(--dur-3) var(--ease);
}
.btn:hover::before { opacity: 1; }
/* The label drifts a little further than the button, so it reads as depth. */
.btn-label {
  display: inline-flex; height: 1.3em; line-height: 1.3; overflow: hidden;
  translate: calc(var(--tx, 0px) * 0.15) calc(var(--ty, 0px) * 0.15);
  transition: inherit; transition-property: translate;
}
/* Each letter carries its own copy one line down (the text-shadow) and rolls
   up into it on hover, one after another. */
.btn-char {
  display: inline-block; white-space: pre; text-shadow: 0 1.3em currentColor;
  transition: translate 460ms var(--ease-out) calc(var(--i) * 14ms);
}
.btn:hover .btn-char, .btn:focus-visible .btn-char { translate: 0 -1.3em; }
.btn-primary { --btn-glow: color-mix(in srgb, var(--accent) 55%, transparent); background: var(--ink); color: var(--bg); box-shadow: var(--shadow-card); }
.btn-primary:hover {
  box-shadow: var(--shadow-float), 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent),
    0 10px 36px -8px color-mix(in srgb, var(--accent) 55%, transparent);
}
.btn-ghost { --btn-glow: color-mix(in srgb, var(--ink) 12%, transparent); border: 1px solid var(--line-strong); background: var(--surface); }
.btn-ghost:hover { background: var(--surface-2); border-color: color-mix(in srgb, var(--ink) 45%, transparent); box-shadow: var(--shadow-card); }
@media (prefers-reduced-motion: reduce) {
  .btn, .btn-char { transition-duration: 0s !important; }
  .btn:hover .btn-char, .btn:focus-visible .btn-char { translate: none; }
}
.btn-sm { height: 38px; padding: 0 16px; font-size: 14px; }

.chips { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding: 2px 2px 14px; margin: 0 -2px; }
.chips::-webkit-scrollbar { display: none; }
.chip {
  flex: none; height: 36px; padding: 0 16px; cursor: pointer; white-space: nowrap;
  border: 1px solid var(--line); border-radius: var(--pill); background: var(--surface);
  font-size: 13.5px; font-weight: 500; color: var(--ink-2);
  transition: background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), transform var(--dur-1) var(--ease);
}
.chip:hover { color: var(--ink); border-color: var(--line-strong); }
.chip:active { transform: scale(0.96); }
.chip[aria-pressed="true"] { background: var(--ink); color: var(--bg); border-color: var(--ink); }

/* ── Hero ───────────────────────────────────────────────────────── */

.hero {
  position: relative; overflow: hidden;
  padding: clamp(28px, 5vw, 64px) 0 clamp(8px, 2vw, 16px);
}
.hero-grid { display: grid; gap: clamp(36px, 5vw, 64px); align-items: center; }
@media (min-width: 1040px) { .hero-grid { grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr); } }

.eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 6px 14px 6px 10px; border: 1px solid var(--line); border-radius: var(--pill); background: var(--surface);
  font-size: 13px; font-weight: 500; color: var(--ink-2);
}
.eyebrow-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--air); box-shadow: 0 0 0 4px var(--air-soft); }

.hero h1 {
  margin-top: 22px;
  font-family: var(--font-display); font-stretch: 125%; font-weight: 800;
  font-size: clamp(40px, 6vw, 80px); line-height: 0.95; letter-spacing: -0.035em;
  text-wrap: balance;
}
/* The headline: each word rises out of its own line box on load, and a jet
   crosses behind it on a curve, drawing a contrail in the accent. */
.headline { position: relative; margin-top: 22px; }
.headline h1 { position: relative; z-index: 1; margin-top: 0; }
.headline .flightpath { z-index: 2; }
.hero h1 .w { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: 0.08em; margin-bottom: -0.08em; }
.hero h1 .w > span { display: inline-block; animation: wordUp 900ms var(--ease-out) backwards; animation-delay: calc(120ms + var(--i) * 75ms); }
@keyframes wordUp { from { transform: translateY(105%); } }
/* "flies..." is typed, deleted and typed again by app.js, forever, the way
   a person types it. The ghost holds the finished word's width so nothing
   around it moves while it is being typed; the live copy sits over it. */
.hero h1 em { font-style: normal; color: var(--accent); white-space: nowrap; display: inline-grid; }
.type-ghost, .type-live { grid-area: 1 / 1; }
.type-ghost { visibility: hidden; }
.type-live { display: inline-flex; align-items: baseline; }
.typed > span { display: inline-block; }
.typed > .key { animation: keyIn 130ms cubic-bezier(0.2, 1.6, 0.4, 1); }
@keyframes keyIn { from { transform: translateY(0.06em) scale(0.82); opacity: 0.4; } }
.typed > .dot.wave { animation: dotWave 1.5s ease-in-out infinite; animation-delay: calc(var(--k) * 160ms); }
@keyframes dotWave { 0%, 55%, 100% { transform: none; } 25% { transform: translateY(-0.2em); } }
.caret {
  align-self: stretch; width: 0.06em; margin: 0.12em 0 0.1em 0.04em; border-radius: 2px;
  background: currentColor; animation: caretBlink 1.05s steps(1) infinite;
}
.type-live.is-typing .caret { animation: none; }
@keyframes caretBlink { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }
.flightpath { position: absolute; z-index: 0; left: 0; top: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.flightpath path { fill: none; }
.contrail { stroke: var(--accent); stroke-width: 2.4; stroke-linecap: round; opacity: 0.6; filter: drop-shadow(0 0 6px color-mix(in srgb, var(--accent) 50%, transparent)); }
.jet path { fill: var(--ink); stroke: var(--bg); stroke-width: 1.2; paint-order: stroke; filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.25)); }
.lede { margin-top: 22px; max-width: 34em; font-size: clamp(16px, 1.5vw, 18.5px); line-height: 1.55; color: var(--ink-2); text-wrap: pretty; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; }

.hero-facts {
  display: grid; grid-template-columns: repeat(3, auto); justify-content: start; gap: 0;
  margin: 32px 0 0; padding: 0;
}
.hero-facts > div { padding: 0 clamp(16px, 3vw, 32px); border-left: 1px solid var(--line-strong); }
.hero-facts > div:first-child { padding-left: 0; border-left: 0; }
.hero-facts dt { font-size: 12.5px; color: var(--ink-3); font-weight: 500; }
.hero-facts dd {
  margin: 4px 0 0; font-family: var(--font-display); font-stretch: 112%; font-weight: 700;
  font-size: clamp(22px, 2.6vw, 30px); letter-spacing: -0.02em; line-height: 1.1;
}
.hero-facts dd small { font-size: 0.55em; font-weight: 600; color: var(--ink-3); margin-left: 3px; letter-spacing: 0; }
@media (max-width: 460px) {
  .hero-facts { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .hero-facts > div { padding: 0 10px; }
  .hero-facts dt { font-size: 11.5px; }
}

/* ── The board: every jet as a flight strip ─────────────────────── */

.board {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-float); padding: 8px; position: relative;
}
.board-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 14px 14px 12px; }
.board-head h2 { font-family: var(--font-display); font-stretch: 125%; font-weight: 700; font-size: 15px; text-transform: uppercase; letter-spacing: 0.02em; }
#tower-summary { font-size: 13px; color: var(--ink-3); text-align: right; }
#tower-summary em { font-style: normal; color: var(--air); font-weight: 600; }
.board-foot { padding: 12px 14px 8px; font-size: 12px; color: var(--ink-3); }

.strips { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.strip {
  position: relative; width: 100%; text-align: left; cursor: pointer;
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(64px, auto); align-items: center; gap: 14px;
  padding: 12px 14px 12px 18px; border: 1px solid transparent; border-radius: var(--radius);
  background: var(--surface-2);
  transition: background-color var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), transform var(--dur-1) var(--ease);
}
/* The strip's coloured edge: green aloft, indigo on the ground, as on the map. */
.strip::before {
  content: ""; position: absolute; left: 7px; top: 12px; bottom: 12px; width: 3px; border-radius: 3px;
  background: var(--ground); opacity: 0.55;
}
.strip.is-airborne::before { background: var(--air); opacity: 1; }
.strip:hover { background: var(--surface-3); }
.strip:active { transform: scale(0.99); }
.strip[aria-pressed="true"] { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 6%, var(--surface-2)); }
.strip-who { min-width: 0; }
.strip-name {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--font-display); font-stretch: 118%; font-weight: 700; font-size: 16px; letter-spacing: -0.01em;
}
.strip-meta { display: block; margin-top: 2px; font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.strip-route { display: flex; align-items: center; gap: 8px; font-family: var(--font-mono); font-size: 13px; font-weight: 600; }
.strip-route .to { color: var(--ink-2); }
.strip-leg { position: relative; width: 44px; height: 2px; border-radius: 2px; background: var(--line-strong); overflow: hidden; }
.strip.is-airborne .strip-leg { background: color-mix(in srgb, var(--air) 45%, transparent); }
.strip.is-airborne .strip-leg::after {
  content: ""; position: absolute; inset: 0; width: 40%;
  background: linear-gradient(90deg, transparent, var(--air), transparent);
  animation: legSheen 1.8s var(--ease) infinite;
}
.strip-place { font-family: var(--font-mono); font-size: 13px; font-weight: 600; color: var(--ink-2); }
.strip-read { text-align: right; }
.strip-read b { display: block; font-family: var(--font-mono); font-size: 14px; font-weight: 600; white-space: nowrap; }
.strip.is-airborne .strip-read b { color: var(--air); }
.strip-read > span { display: block; margin-top: 2px; font-size: 11.5px; color: var(--ink-3); white-space: nowrap; }
@keyframes legSheen { from { transform: translateX(-100%); } to { transform: translateX(260%); } }

.strips.is-loading .strip { pointer-events: none; }
.strip-skeleton { height: 62px; border-radius: var(--radius); background: var(--surface-2); animation: shimmer 1.4s var(--ease) infinite alternate; }
@keyframes shimmer { from { opacity: 0.55; } to { opacity: 1; } }

/* The board arrives one strip after another on first load. */
.strips.is-first > li { animation: stripIn 520ms var(--ease-out) backwards; }
.strips.is-first > li:nth-child(2) { animation-delay: 50ms; }
.strips.is-first > li:nth-child(3) { animation-delay: 100ms; }
.strips.is-first > li:nth-child(4) { animation-delay: 150ms; }
.strips.is-first > li:nth-child(5) { animation-delay: 200ms; }
.strips.is-first > li:nth-child(6) { animation-delay: 250ms; }
.strips.is-first > li:nth-child(n+7) { animation-delay: 300ms; }
@keyframes stripIn { from { opacity: 0; transform: translateY(8px); } }

@media (max-width: 520px) {
  .strip { grid-template-columns: minmax(0, 1fr) auto; gap: 10px; }
  .strip-route, .strip-place { grid-column: 1; grid-row: 2; }
  .strip-read { grid-row: 1 / span 2; grid-column: 2; }
  .strip-name { font-size: 15px; }
}

/* ── Sections ───────────────────────────────────────────────────── */

/* Sections alternate between the page's ground and a band of their own, so
   each reads as one block; two plain ones in a row share their gap. */
.section { padding-block: clamp(40px, 5.5vw, 72px); }
.section.band { background: color-mix(in srgb, var(--band) 35%, transparent); border-block: 1px solid var(--line); }
.section:not(.band) + .section:not(.band) { padding-top: 0; }

/* A section opens on a ruled label, then its title and a note beside it. */
.section-head {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 30em); align-items: end; gap: 12px 48px; margin-bottom: 24px;
}
.section-head > .kicker { grid-column: 1 / -1; }
.section-head > div h1, .section-head > div h2 { margin-top: 0; }
@media (max-width: 760px) { .section-head { grid-template-columns: minmax(0, 1fr); } }
.kicker {
  display: flex; align-items: center; gap: 14px;
  font-family: var(--font-mono); font-size: 12px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--accent);
}
.section-head > .kicker::after { content: ""; flex: 1; height: 1px; background: var(--line-strong); }
.section-head h1, .section-head h2, .follow h2 {
  margin-top: 10px;
  font-family: var(--font-display); font-stretch: 125%; font-weight: 800;
  font-size: clamp(28px, 4vw, 48px); line-height: 1; letter-spacing: -0.03em; text-wrap: balance;
}

/* ── Map ────────────────────────────────────────────────────────── */

/* The map is the page's globe: no frame, no border, no ground of its own —
   the space around the planet is the page itself (app.js paints the sky in
   the page's colour), so the globe floats in the page. Arriving at the
   section, the heading and the map fill the screen under the bar. */
.map-stage { --stage-pad: clamp(28px, 4vw, 48px); padding-top: var(--stage-pad); }
.map-wrap {
  display: flex; flex-direction: column;
  min-height: calc(100vh - var(--nav-h) - var(--stage-pad));
  min-height: calc(100svh - var(--nav-h) - var(--stage-pad) - env(safe-area-inset-top));
}
.maplibregl-ctrl-bottom-right { margin: 0 var(--gutter) 16px 0; }
/* A phone pinches to zoom, and the buttons would sit under the panel. */
@media (max-width: 640px) { .maplibregl-ctrl-bottom-right { display: none; } }
.map-wrap > .section-head { margin-bottom: 0; }
/* Edge to edge, past the page's margins, so the planet is never cut off by
   them; its controls stay in line with the rest of the page. */
.map-frame { position: relative; flex: 1; min-height: 440px; isolation: isolate; margin-inline: calc(-1 * var(--gutter)); }
.map-frame:fullscreen { background: var(--bg); opacity: 1 !important; }
.map-full { position: absolute; z-index: 4; top: 12px; right: var(--gutter); }
.map-full[hidden] { display: none; }
.map-full .i-close { display: none; }
.map-frame:fullscreen .map-full { right: 16px; top: 16px; }
.map-frame:fullscreen .map-full .i-open { display: none; }
.map-frame:fullscreen .map-full .i-close { display: block; }
/* The map's edges fade into the page, so a coastline or a label running off
   the side never stops on a hard line. */
.map canvas {
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 9%, #000 91%, transparent), linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(to bottom, transparent, #000 9%, #000 91%, transparent), linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
  mask-composite: intersect;
}
.map-frame:fullscreen .map canvas { -webkit-mask-image: none; mask-image: none; }
.map { position: absolute; inset: 0; }

.detail {
  position: absolute; z-index: 5; left: var(--gutter); bottom: 16px; width: min(380px, calc(100% - 2 * var(--gutter)));
  max-height: calc(100% - 32px); overflow: auto;
  padding: 18px; border-radius: var(--radius);
  background: color-mix(in srgb, var(--surface) 86%, transparent);
  backdrop-filter: blur(20px) saturate(1.6); -webkit-backdrop-filter: blur(20px) saturate(1.6);
  border: 1px solid var(--line-strong); box-shadow: var(--shadow-float);
}
.detail[hidden] { display: none; }
.detail.is-opening { animation: detailIn var(--dur-3) var(--ease-out); }
@keyframes detailIn { from { opacity: 0; transform: translateY(10px) scale(0.98); } }
.detail-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.detail h3 { font-family: var(--font-display); font-stretch: 118%; font-weight: 800; font-size: 20px; letter-spacing: -0.02em; line-height: 1.15; }
.detail-meta { margin-top: 4px; font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); }
.detail .close {
  flex: none; width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--line); background: var(--surface);
  cursor: pointer; display: grid; place-items: center; font-size: 18px; line-height: 1; color: var(--ink-2);
}
.detail .close:hover { color: var(--ink); background: var(--surface-2); }

.route { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 10px; margin-top: 16px; padding: 14px; border-radius: var(--radius-sm); background: var(--surface-2); }
.stop.to { text-align: right; }
.stop .cap { font-size: 11.5px; color: var(--ink-3); }
.stop .code { font-family: var(--font-mono); font-weight: 700; font-size: 20px; letter-spacing: 0; margin-top: 2px; }
.stop .airport { font-size: 12px; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.route .line { position: relative; width: 48px; height: 2px; border-radius: 2px; background: var(--line-strong); overflow: hidden; }
.route.is-air .line { background: var(--air); }
.route.is-air .line::after {
  content: ""; position: absolute; inset: 0; width: 40%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.85), transparent);
  animation: legSheen 1.8s var(--ease) infinite;
}

.cells { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; margin: 12px 0 0; border-radius: var(--radius-sm); overflow: hidden; background: var(--line); }
.cell { background: var(--surface); padding: 10px 12px; }
.cell dt { font-size: 11.5px; color: var(--ink-3); }
.cell dd { margin: 2px 0 0; font-family: var(--font-mono); font-weight: 600; font-size: 15px; white-space: nowrap; }
.cell dd small { font-size: 11px; font-weight: 500; color: var(--ink-3); margin-left: 3px; }

/* One flight open: a wider panel, the times under the airports, an
   altitude and speed profile, and the jet's other flights. */
.detail.is-flight { width: min(420px, calc(100% - 2 * var(--gutter))); }
/* On a wide frame the panel, a jet or an open flight, stands at the top
   left under the heading, and the map makes room for it beside it. */
@media (min-width: 641px) { .detail { top: 12px; bottom: auto; width: min(420px, calc(100% - 2 * var(--gutter))); max-height: calc(100% - 28px); } }
.detail-kicker { font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--accent); margin-bottom: 4px; }
.stop .when { margin-top: 2px; font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-3); }
.profile-box { --alt: #38bdf8; margin-top: 12px; padding: 12px 12px 6px; border-radius: var(--radius-sm); background: var(--surface-2); }
.profile-key { display: flex; align-items: center; gap: 14px; font-size: 11.5px; color: var(--ink-3); }
.profile-key .k-alt::before, .profile-key .k-spd::before { content: ""; display: inline-block; width: 10px; height: 3px; border-radius: 2px; margin-right: 6px; vertical-align: middle; }
.profile-key .k-alt::before { background: var(--alt); }
.profile-key .k-spd::before { background: var(--ink-2); }
.profile-read { margin-left: auto; font-family: var(--font-mono); color: var(--ink); white-space: nowrap; }
.profile { display: block; width: 100%; height: auto; margin-top: 6px; touch-action: none; cursor: crosshair; overflow: visible; }
.profile .alt { fill: none; stroke: var(--alt); stroke-width: 1.8; stroke-linejoin: round; }
.profile .spd { fill: none; stroke: var(--ink-2); stroke-width: 1.2; stroke-dasharray: 3 2; opacity: 0.8; }
.profile .grid { stroke: var(--line); stroke-width: 1; }
.profile text { font-family: var(--font-mono); font-size: 9.5px; fill: var(--ink-3); }
.profile .cursor { stroke: var(--ink); stroke-width: 1; opacity: 0.6; }
.profile .dot { fill: #fff; stroke: var(--accent); stroke-width: 2; }
.profile-empty { margin-top: 12px; padding: 16px; border-radius: var(--radius-sm); background: var(--surface-2); color: var(--ink-3); font-size: 13px; text-align: center; }
.trips { margin-top: 14px; }
.trips-title { font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 6px; }
.trips ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.trips button {
  width: 100%; display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 14px; align-items: center;
  padding: 8px 10px; border: 0; border-radius: 8px; background: transparent; cursor: pointer; text-align: left;
  transition: background-color var(--dur-2) var(--ease);
}
.trips button:hover { background: var(--surface-2); }
.trip-route { font-family: var(--font-mono); font-weight: 700; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trip-when { font-size: 12px; color: var(--ink-3); white-space: nowrap; }
.trip-time { min-width: 7.5em; font-family: var(--font-mono); font-size: 12px; color: var(--ink-2); text-align: right; white-space: nowrap; }
/* One flight, as a ticket: codes large on either end of a dashed path with
   the jet on it, the flight time over the path, full airport names under. */
.fx-route { margin-top: 18px; }
.fx-codes { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 14px; }
.fx-code { font-family: var(--font-display); font-stretch: 118%; font-weight: 800; font-size: 30px; letter-spacing: -0.01em; line-height: 1; }
.fx-path { display: grid; gap: 6px; justify-items: center; min-width: 0; }
.fx-dur { font-family: var(--font-mono); font-size: 11.5px; font-weight: 600; color: var(--ink-2); white-space: nowrap; }
.fx-track {
  position: relative; width: 100%; height: 2px;
  background: repeating-linear-gradient(90deg, var(--line-strong) 0 6px, transparent 6px 11px);
}
.fx-track::before, .fx-track::after { content: ""; position: absolute; top: 50%; width: 7px; height: 7px; margin-top: -3.5px; border-radius: 50%; border: 2px solid var(--ink); background: var(--surface); }
.fx-track::before { left: -4px; }
.fx-track::after { right: -4px; }
.fx-plane { position: absolute; left: 50%; top: 50%; width: 22px; height: 22px; translate: -50% -50%; display: grid; place-items: center; border-radius: 50%; background: var(--surface); }
.fx-plane svg { width: 16px; height: 16px; rotate: 90deg; fill: var(--ink); }
.fx-route.is-air .fx-track { background: repeating-linear-gradient(90deg, var(--air) 0 6px, transparent 6px 11px); background-size: 22px 2px; animation: fxDash 1.2s linear infinite; }
.fx-route.is-air .fx-plane svg { fill: var(--air); }
@keyframes fxDash { to { background-position: 22px 0; } }
.fx-stops { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; margin-top: 10px; }
.fx-stop.to { text-align: right; }
.fx-name { font-size: 12.5px; line-height: 1.35; color: var(--ink-2); text-wrap: balance; }
.fx-when { margin-top: 3px; font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-3); }
.fx-figs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 18px 0 0; padding: 14px 0; border-block: 1px solid var(--line); }
.fx-figs > div { padding: 0 14px; border-left: 1px solid var(--line); }
.fx-figs > div:first-child { padding-left: 0; border-left: 0; }
.fx-figs dt { font-size: 11.5px; color: var(--ink-3); }
.fx-figs dd { margin: 3px 0 0; font-family: var(--font-mono); font-weight: 700; font-size: 17px; white-space: nowrap; }
.fx-figs dd small { margin-left: 3px; font-size: 11px; font-weight: 500; color: var(--ink-3); }
.fx-burn {
  margin-top: 14px; padding: 10px 12px; border-radius: var(--radius-sm); font-size: 13px; color: var(--ink-2);
  background: color-mix(in srgb, var(--accent) 7%, transparent); border-left: 3px solid var(--accent);
}
.fx-burn b { font-family: var(--font-mono); font-weight: 700; color: var(--ink); }
.detail.is-flight .profile-box { margin-top: 14px; padding: 10px 0 0; background: none; border-radius: 0; }
.detail.is-flight .trips { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
@media (max-width: 640px) { .fx-code { font-size: 24px; } .fx-figs dd { font-size: 15px; } }

/* Sharing a flight: a pill beside the close button, and a menu over the
   panel's own content (the panel scrolls, so it is placed against it). */
.detail-actions { flex: none; display: flex; align-items: center; gap: 8px; }
.share-btn {
  display: inline-flex; align-items: center; gap: 7px; height: 32px; padding: 0 13px 0 11px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--pill); background: var(--surface); color: var(--ink);
  font-size: 13px; font-weight: 600; transition: background-color var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}
.share-btn .share-glyph svg { width: 14px; height: 14px; }
.share-btn:hover, .share.is-open .share-btn { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); }
.share-glyph { display: grid; place-items: center; }
.share-glyph svg { width: 20px; height: 20px; fill: currentColor; }
.share-menu {
  display: none; position: absolute; z-index: 6; top: 64px; left: 12px; right: 12px;
  padding: 14px; border-radius: var(--radius); background: var(--surface); border: 1px solid var(--line-strong); box-shadow: var(--shadow-float);
}
.share.is-open .share-menu { display: grid; gap: 12px; animation: menuIn var(--dur-3) var(--ease-out); }
.share-line { padding-bottom: 12px; border-bottom: 1px solid var(--line); font-size: 13px; line-height: 1.45; color: var(--ink-2); }
.share-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 4px; }
.share-item {
  display: grid; justify-items: center; gap: 6px; padding: 10px 4px; border: 0; border-radius: 10px; cursor: pointer;
  background: transparent; color: var(--ink); text-decoration: none; font-size: 12px; font-weight: 500;
  transition: background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}
.share-item:hover { background: var(--surface-2); color: var(--accent); }
.share-status { min-height: 1em; font-size: 12px; font-weight: 600; color: var(--air); text-align: center; overflow-wrap: anywhere; }
.share-status:empty { display: none; }
@media (max-width: 640px) { .share-btn > span:last-child { display: none; } .share-btn { width: 32px; padding: 0; justify-content: center; } }

/* The rest of the fleet steps back while one flight is open. */
.map.is-focus .marker:not(.is-selected) { opacity: 0.25; transition: opacity var(--dur-3) var(--ease); }

@media (max-width: 640px) {
  .detail { left: 10px; right: 10px; bottom: 10px; width: auto; padding: 14px; max-height: 58%; }
  .detail h3 { font-size: 17px; }
  .route { margin-top: 12px; padding: 10px 12px; }
}

/* Map controls, as a floating capsule. */
.maplibregl-ctrl-attrib { display: none !important; }
.maplibregl-ctrl-group {
  background: color-mix(in srgb, var(--surface) 85%, transparent) !important;
  border: 1px solid var(--line-strong); border-radius: var(--pill) !important; overflow: hidden;
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); box-shadow: var(--shadow-card) !important;
}
.maplibregl-ctrl-group button { width: 36px !important; height: 36px !important; background: transparent !important; }
.maplibregl-ctrl-group button:hover { background: var(--surface-2) !important; }
.maplibregl-ctrl-group button + button { border-top-color: var(--line) !important; }
:root[data-theme="dark"] .maplibregl-ctrl-icon { filter: invert(0.9); }
.maplibregl-ctrl-bottom-right .maplibregl-ctrl { margin: 0; }

/* ── Map markers: the dashboard's live map, as drawn there ───────── */

/* Absolute, as MapLibre's own .maplibregl-marker rule has it: this file loads
   after that one, and a relative marker drops into the canvas container's flow
   and draws 14px below the point it was placed at, off the end of its track. */
.marker { position: absolute; top: 0; left: 0; width: 0; height: 0; cursor: pointer; border: 0; padding: 0; background: transparent; }
.marker .halo {
  position: absolute; left: -13px; top: -13px; width: 26px; height: 26px; border-radius: 50%;
  background: var(--map-halo); box-shadow: 0 0 0 1.6px transparent;
  transition: background 0.15s ease, box-shadow 0.15s ease;
}
.marker:hover .halo, .marker.is-selected .halo { background: var(--map-halo-hot); }
.marker.is-selected .halo { left: -15px; top: -15px; width: 30px; height: 30px; box-shadow: 0 0 0 2px var(--map-halo-ring); }
.marker svg { position: absolute; overflow: visible; filter: drop-shadow(0 0 1px var(--map-shade)) drop-shadow(0 2px 5px var(--map-shade)); }
.marker .dot {
  position: absolute; left: -5.4px; top: -5.4px; width: 10.8px; height: 10.8px; border-radius: 50%;
  background: var(--map-landed); box-shadow: 0 0 0 1.8px var(--map-outline), 0 1px 3px var(--map-shade);
}
.marker .dot::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 3.8px; height: 3.8px; margin: -1.9px 0 0 -1.9px;
  border-radius: 50%; background: var(--map-pill);
}
/* A jet in the air sends out a slow ping in its own green, and a parked one
   sits in a faint ring, so neither is lost at globe zoom. */
.marker::before {
  content: ""; position: absolute; left: -11px; top: -11px; width: 22px; height: 22px; border-radius: 50%;
  box-shadow: 0 0 0 5px var(--map-ping-ground); pointer-events: none;
}
.marker.is-airborne::before {
  left: -20px; top: -20px; width: 40px; height: 40px; box-shadow: none;
  border: 2px solid var(--map-airborne); opacity: 0;
  animation: ping 2.2s ease-out infinite;
}
@keyframes ping {
  0% { transform: scale(0.45); opacity: 0.75; }
  100% { transform: scale(1.5); opacity: 0; }
}
.plane-body { fill: var(--map-airborne); stroke: var(--map-ink-strong); stroke-width: 1.8; stroke-linejoin: round; }
.plane-accent { fill: none; stroke: var(--map-ink-strong); stroke-linecap: round; opacity: 0.5; }
.marker:not(.is-airborne) svg { filter: drop-shadow(0 0 1px var(--map-shade)) drop-shadow(0 0.5px 1.5px var(--map-shade)); }
/* The jet on the track where the profile is being read. */
.scrub-plane { position: absolute; top: 0; left: 0; width: 0; height: 0; pointer-events: none; z-index: 3; }
.scrub-plane svg { position: absolute; overflow: visible; filter: drop-shadow(0 0 1px var(--map-shade)) drop-shadow(0 3px 6px var(--map-shade)); }
.scrub-plane .plane-body { fill: var(--accent); stroke: #fff; stroke-width: 1.6; }
.scrub-plane .plane-accent { stroke: #fff; opacity: 0.7; }
.marker:not(.is-airborne) .plane-body { fill: var(--map-landed); stroke-width: 1.5; }

.marker-label {
  position: absolute; left: 50%; top: 17px; transform: translateX(-50%);
  padding: 0 8px; height: 20px; line-height: 18px; border-radius: 10px;
  background: var(--map-pill); border: 1px solid var(--map-pill-edge); color: var(--map-pill-text);
  font-family: var(--font); font-size: 11px; font-weight: 600; letter-spacing: 0.2px; white-space: nowrap; pointer-events: none;
  box-shadow: 0 2px 6px -2px var(--map-shade);
}
.marker.is-glyph .marker-label { top: 21px; }
.marker.is-airborne .marker-label { top: 24px; }
.marker.is-selected .marker-label { background: var(--accent); border-color: transparent; color: var(--on-accent); }
.marker.is-selected, .marker:hover { z-index: 5 !important; }
.map.is-far .marker:not(.is-airborne):not(.is-selected):not(.is-stand):not(.is-fanned):not(:hover) .marker-label { display: none; }

/* A stand: jets parked close enough together to be one pile on screen. */
.marker.is-stand .halo { left: -16px; top: -16px; width: 32px; height: 32px; }
.marker.is-stand::before { left: -15px; top: -15px; width: 30px; height: 30px; }
.marker.is-stand .stand-dot {
  position: absolute; left: -11px; top: -11px; width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--map-landed); box-shadow: 0 0 0 1.8px var(--map-outline), 0 1px 3px var(--map-shade);
}
.marker.is-stand .count { font-size: 11px; font-weight: 700; line-height: 1; letter-spacing: 0; color: #0d0d0e; }
:root:not([data-theme="dark"]) .marker.is-stand .count { color: #fff; }
.marker.is-stand .marker-label { top: 19px; }
.marker.is-stand.is-open .halo { left: -11px; top: -11px; width: 22px; height: 22px; }
.marker.is-stand.is-open::before { box-shadow: none; }
.marker.is-stand.is-open .stand-dot { left: -5px; top: -5px; width: 10px; height: 10px; background: transparent; box-shadow: 0 0 0 1.5px var(--map-pill-edge); }
.marker.is-stand.is-open .marker-label { display: none; }
.marker .stem {
  position: absolute; left: 0; top: 0; width: 0; height: 1px; display: none;
  transform-origin: 0 50%; pointer-events: none;
  background: linear-gradient(90deg, var(--map-stem), transparent);
}
.marker.is-fanned .stem { display: block; }

/* ── Flight log ─────────────────────────────────────────────────── */

/* One panel, one line a flight: who, where from and to, how long, what it
   burned and where it stands now. Days are slim dividers inside it. */
.log {
  list-style: none; margin: 0; padding: 4px 0; display: grid;
  border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface); overflow: hidden;
}
.log-day {
  display: flex; align-items: center; gap: 12px; padding: 14px 18px 6px;
  font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-3);
}
.log-day::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.log-day:first-child { padding-top: 10px; }
.flight {
  display: grid; align-items: center; gap: 16px;
  grid-template-columns: 8px minmax(150px, 1fr) minmax(240px, 380px) 96px 90px 82px;
  min-height: 48px; padding: 6px 18px;
  transition: background-color var(--dur-2) var(--ease);
}
.flight + .flight { box-shadow: inset 0 1px 0 color-mix(in srgb, var(--line) 60%, transparent); }
.flight:hover { background: var(--surface-2); }
.flight-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ink-3); }
.flight.is-landed .flight-dot { background: var(--ground); }
.flight.is-air .flight-dot { background: var(--air); box-shadow: 0 0 0 4px var(--air-soft); }

.flight-jet { display: flex; align-items: baseline; gap: 10px; min-width: 0; text-align: left; background: none; border: 0; padding: 0; cursor: pointer; text-decoration: none; color: inherit; }
.flight { position: relative; cursor: pointer; }
.flight-jet::after { content: ""; position: absolute; inset: 0; }
.flight:hover .flight-jet .name { color: var(--accent); }
.flight-route .stop { position: relative; z-index: 1; }
.flight-jet .name { font-weight: 600; font-size: 14.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: none; max-width: 60%; }
.flight-jet:hover .name { color: var(--accent); }
.flight-jet .reg { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }

.flight-route { display: grid; grid-template-columns: auto minmax(24px, 1fr) auto; align-items: center; gap: 10px; min-width: 0; }
.flight-route .stop { display: inline-flex; align-items: baseline; gap: 7px; white-space: nowrap; cursor: default; }
.flight-route .code { font-family: var(--font-mono); font-weight: 700; font-size: 13.5px; }
.flight-route .time { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-3); }
.flight-route .leg { position: relative; height: 12px; display: flex; align-items: center; }
.flight-route .leg::before { content: ""; flex: 1; height: 1px; background: var(--line-strong); }
.flight-route .leg svg { position: absolute; left: 50%; top: 50%; width: 12px; height: 12px; margin: -6px 0 0 -6px; fill: var(--ink-3); background: var(--surface); padding: 0 3px; box-sizing: content-box; }
.flight:hover .flight-route .leg svg { background: var(--surface-2); }
.flight.is-landed .flight-route .leg svg { fill: var(--ground); }
.flight.is-air .flight-route .leg::before { background: linear-gradient(90deg, var(--air) 50%, var(--line-strong) 50%); }
.flight.is-air .flight-route .leg svg { fill: var(--air); }

.flight-num { font-family: var(--font-mono); font-size: 12.5px; text-align: right; white-space: nowrap; color: var(--ink-2); }
.flight-num.co2 { display: grid; gap: 1px; }
.flight-num.co2 small { font-size: 11px; color: var(--ink-3); }
.flight-state { font-size: 12px; font-weight: 600; text-align: right; white-space: nowrap; color: var(--ink-3); }
.flight.is-air .flight-state { color: var(--air); }
.flight.is-landed .flight-state { color: var(--ground); }

.more {
  display: block; width: 100%; height: 42px; cursor: pointer;
  border: 0; border-top: 1px solid var(--line); background: transparent;
  font-size: 13px; font-weight: 600; color: var(--ink-2);
  transition: background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}
.log > li:has(> .more) { margin-bottom: -4px; }
.more:hover { background: var(--surface-2); color: var(--ink); }
.log-wait { padding: 32px; text-align: center; color: var(--ink-3); }
.log-empty {
  display: grid; justify-items: center; gap: 6px; padding: 56px 20px; text-align: center;
  border: 1px dashed var(--line-strong); border-radius: var(--radius); color: var(--ink-2);
}
.log-empty[hidden] { display: none; }
.log-empty b { font-family: var(--font-display); font-stretch: 118%; font-size: 17px; color: var(--ink); }
.is-new { animation: stripIn var(--dur-3) var(--ease-out) backwards; }

/* Narrower: the figures drop under the route; on a phone, two lines. */
@media (max-width: 980px) {
  .flight { grid-template-columns: 8px minmax(0, 1fr) minmax(0, 1.2fr) 72px; }
  .flight-num.co2 { display: none; }
  .flight-state { display: none; }
}
@media (max-width: 640px) {
  .flight { grid-template-columns: 8px minmax(0, 1fr) auto; gap: 4px 12px; padding: 10px 16px; }
  .flight-dot { grid-row: 1; }
  .flight-jet { grid-column: 2; grid-row: 1; }
  .flight-num.dur { grid-column: 3; grid-row: 1; }
  .flight-route { grid-column: 2 / -1; grid-row: 2; justify-self: start; width: min(100%, 300px); }
  .flight-jet .name { max-width: 70%; }
}


/* ── Footprint ──────────────────────────────────────────────────── */

.footprint { display: grid; gap: 16px; }
@media (min-width: 960px) { .footprint { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); } }
.co2-card, .rank-card {
  border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface);
  box-shadow: var(--shadow-card); padding: clamp(20px, 3vw, 32px);
}
.co2-card { display: flex; flex-direction: column; justify-content: space-between; gap: 32px; position: relative; overflow: hidden; }
.co2-card::after {
  content: ""; position: absolute; right: -80px; top: -80px; width: 280px; height: 280px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--accent) 12%, transparent), transparent);
}
.co2-hero .cap { display: block; font-size: 14px; color: var(--ink-2); font-weight: 500; }
.hero-value {
  display: flex; align-items: baseline; gap: 8px; margin-top: 8px;
  font-family: var(--font-display); font-stretch: 125%; font-weight: 800;
  font-size: clamp(56px, 9vw, 112px); line-height: 0.95; letter-spacing: -0.04em;
}
.hero-value small { font-size: 0.32em; letter-spacing: -0.01em; color: var(--ink-3); font-weight: 700; }
.totals { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1px; margin: 0; border-radius: var(--radius); overflow: hidden; background: var(--line); border: 1px solid var(--line); }
.stat { background: var(--surface); padding: 16px 18px; }
.stat dt { font-size: 12.5px; color: var(--ink-3); }
.stat dd { margin: 4px 0 0; font-family: var(--font-display); font-stretch: 110%; font-weight: 700; font-size: clamp(20px, 2.2vw, 26px); letter-spacing: -0.02em; white-space: nowrap; }
.stat dd small { font-size: 0.55em; color: var(--ink-3); margin-left: 3px; font-weight: 600; }

.card-title { font-family: var(--font-display); font-stretch: 118%; font-weight: 700; font-size: 17px; letter-spacing: -0.01em; margin-bottom: 18px; }
.bars { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; }
.bars li { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; grid-template-rows: auto auto; column-gap: 12px; row-gap: 7px; align-items: baseline; }
.bars .rank { grid-row: 1 / span 2; font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); align-self: start; padding-top: 2px; }
.bars .name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bars .value { font-family: var(--font-mono); font-weight: 600; font-size: 14px; text-align: right; }
.bars .meta { font-size: 12px; color: var(--ink-3); margin-left: 8px; font-weight: 400; }
.bars .track { grid-column: 2 / -1; height: 8px; border-radius: 8px; background: var(--surface-2); overflow: hidden; }
.bars .fill { display: block; height: 100%; border-radius: 8px; background: var(--accent); transform-origin: left; transition: width 600ms var(--ease-out); }
.bars li:not(:first-child) .fill { background: color-mix(in srgb, var(--accent) 55%, var(--ink-3)); }
.bars li.is-idle .name, .bars li.is-idle .value { color: var(--ink-3); }
@keyframes growRight { from { transform: scaleX(0); } }
.bars.is-first .fill { animation: growRight 700ms var(--ease-out) backwards; }
.bars.is-first li:nth-child(2) .fill { animation-delay: 60ms; }
.bars.is-first li:nth-child(3) .fill { animation-delay: 120ms; }
.bars.is-first li:nth-child(n+4) .fill { animation-delay: 180ms; }
/* With scroll reveals on, the bars fill when their card comes into view instead. */
.js-reveal .bars.is-first .fill { animation: none; }

/* ── How it works ───────────────────────────────────────────────── */

.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; counter-reset: step; }
@media (min-width: 820px) { .steps { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 640px) { .steps-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .steps-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 640px) and (max-width: 1099px) { .steps-4 li:nth-child(2n)::after { display: none; } }
.steps li {
  position: relative; padding: 26px; border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface); box-shadow: var(--shadow-card);
}
.step-n {
  display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%;
  background: var(--ink); color: var(--bg); font-family: var(--font-mono); font-weight: 700; font-size: 14px;
}
.steps h3 { margin-top: 22px; font-family: var(--font-display); font-stretch: 125%; font-weight: 800; font-size: 22px; letter-spacing: -0.02em; }
.steps p { margin-top: 8px; color: var(--ink-2); font-size: 14.5px; text-wrap: pretty; }
/* The steps run into each other on a wide screen: a short connector. */
@media (min-width: 820px) {
  .steps li:not(:last-child)::after {
    content: ""; position: absolute; top: 43px; right: -17px; width: 18px; height: 2px; background: var(--line-strong);
  }
}

/* ── Follow ─────────────────────────────────────────────────────── */

.follow {
  display: grid; gap: 28px; align-items: center;
  padding: clamp(24px, 4vw, 48px); border-radius: var(--radius-lg);
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-card);
  position: relative; overflow: hidden;
}
@media (min-width: 960px) { .follow { grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); } }
.follow-copy { position: relative; }
.follow h2 { max-width: 12em; }
.follow-copy p:last-child { margin-top: 12px; color: var(--ink-2); max-width: 30em; }
.socials { position: relative; list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 8px; }
.social {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: var(--radius);
  text-decoration: none; background: var(--surface-2); border: 1px solid var(--line);
  transition: background-color var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), transform var(--dur-1) var(--ease);
}
.social:hover { background: var(--surface-3); border-color: var(--line-strong); }
.social:active { transform: scale(0.98); }
.social svg { width: 20px; height: 20px; fill: currentColor; flex: none; }
.social .s-name { display: block; font-weight: 600; font-size: 14px; }
.social .s-handle { display: block; font-size: 12px; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.social > span { min-width: 0; }

/* ── Footer ─────────────────────────────────────────────────────── */

/* The brand and its accounts on the left, two short link groups on the
   right; under a hairline, the data credits as one quiet line and the year.
   On a phone the brand comes first and the groups sit side by side. */
.foot { border-top: 1px solid var(--line); background: color-mix(in srgb, var(--band) 55%, transparent); padding: clamp(36px, 5vw, 56px) 0 calc(24px + env(safe-area-inset-bottom)); }
.foot-top { display: grid; gap: 32px 24px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.foot-brand { grid-column: 1 / -1; }
@media (min-width: 900px) {
  .foot-top { grid-template-columns: minmax(0, 2fr) repeat(2, minmax(0, 0.8fr)); gap: 40px 56px; }
  .foot-brand { grid-column: auto; }
}
.foot-mark { display: inline-flex; align-items: center; gap: 12px; text-decoration: none; color: inherit; }
.foot-mark img { width: 44px; height: 44px; object-fit: contain; flex: none; padding: 4px; border-radius: 12px; background: #0d0d0e; }
.foot-name { display: block; font-family: var(--font-display); font-stretch: 125%; font-weight: 800; text-transform: uppercase; font-size: 15px; }
.foot-sub { margin-top: 14px; max-width: 34em; font-size: 14px; line-height: 1.55; color: var(--ink-2); text-wrap: pretty; }
.foot-socials { list-style: none; margin: 18px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.foot-socials a {
  display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-2);
  transition: color var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), translate var(--dur-2) var(--ease-out);
}
.foot-socials a:hover { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); translate: 0 -2px; }
.foot-socials svg { width: 17px; height: 17px; fill: currentColor; }
.foot-col { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.foot-col h2 { font-family: var(--font-mono); font-size: 11.5px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--accent); margin-bottom: 8px; }
.foot-col a { padding: 5px 0; text-decoration: none; font-size: 15px; font-weight: 500; color: var(--ink-2); transition: color var(--dur-2) var(--ease); }
.foot-col a:hover { color: var(--ink); }
.foot-bottom {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 10px 32px;
  margin-top: clamp(32px, 5vw, 48px); padding-top: 20px; border-top: 1px solid var(--line);
  font-size: 12.5px; color: var(--ink-3);
}
.foot-credits { flex: 1 1 28em; text-wrap: pretty; line-height: 1.6; }
.foot-cap { margin-right: 6px; font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-2); }
.foot-copy { white-space: nowrap; font-family: var(--font-mono); font-size: 11.5px; }

/* ── Rolling digits ─────────────────────────────────────────────── */

.roll { display: inline-flex; white-space: pre; }
.wheel {
  display: inline-block; height: 1lh; overflow: hidden; vertical-align: top;
  mask-image: linear-gradient(transparent, #000 22%, #000 78%, transparent);
  -webkit-mask-image: linear-gradient(transparent, #000 22%, #000 78%, transparent);
}
.wheel > span { display: flex; flex-direction: column; }
.wheel > span.is-rolling { transition: transform 600ms var(--ease-out); }
.wheel > span > span { height: 1lh; }

/* ── Disclaimer page ────────────────────────────────────────────── */

.doc { max-width: 720px; padding-top: clamp(28px, 5vw, 56px); padding-bottom: clamp(40px, 5.5vw, 72px); }
.doc h1 { font-family: var(--font-display); font-stretch: 125%; font-weight: 800; font-size: clamp(36px, 6vw, 64px); letter-spacing: -0.035em; line-height: 1; margin: 18px 0 28px; }
.doc h2 { font-family: var(--font-display); font-stretch: 118%; font-weight: 700; font-size: 20px; margin: 36px 0 10px; }
.doc p { color: var(--ink-2); font-size: 16.5px; line-height: 1.65; margin-top: 14px; }
.doc a { color: var(--ink); text-underline-offset: 3px; }
.doc-kicker { margin-top: 28px; }
.doc h1 + .doc-lede { margin-top: 0; }
.doc-lede { font-size: 19px !important; color: var(--ink) !important; line-height: 1.55 !important; text-wrap: pretty; }
.doc ul { margin: 14px 0 0; padding-left: 20px; color: var(--ink-2); font-size: 16.5px; line-height: 1.65; }
.doc li + li { margin-top: 10px; }
.doc li b { color: var(--ink); }
.doc h2 { padding-top: 24px; border-top: 1px solid var(--line); }
.back { display: inline-block; padding: 8px 0; font-size: 14px; font-weight: 500; text-decoration: none; color: var(--ink-3) !important; }
.back:hover { color: var(--ink) !important; }

/* ── Motion ─────────────────────────────────────────────────────── */

/* The hero arrives in order on load: status, headline, text, actions, figures. */
.hero-copy > * { animation: rise 760ms var(--ease-out) backwards; }
.hero-copy > .headline { animation: none; }
.hero-copy > :nth-child(2) { animation-delay: 70ms; }
.hero-copy > :nth-child(3) { animation-delay: 140ms; }
.hero-copy > :nth-child(4) { animation-delay: 210ms; }
.hero-copy > :nth-child(5) { animation-delay: 280ms; }
.board { animation: rise 900ms 180ms var(--ease-out) backwards; }
@keyframes rise { from { opacity: 0; transform: translateY(18px); } }

/* Everything below the hero comes up as it is scrolled to. Hidden only once
   theme.js has said it will reveal them (html.js-reveal), so a page without
   script, or without IntersectionObserver, simply shows everything. */
.js-reveal .reveal {
  opacity: 0; translate: 0 40px;
  transition: opacity 700ms var(--ease-out), translate 900ms var(--ease-out), scale 900ms var(--ease-out), transform 500ms var(--ease-out), box-shadow 300ms var(--ease);
  transition-delay: calc(var(--d, 0) * 90ms), calc(var(--d, 0) * 90ms), calc(var(--d, 0) * 90ms), 0ms, 0ms;
}
.js-reveal .reveal-zoom { scale: 0.95; }
.js-reveal .reveal.is-visible { opacity: 1; translate: none; scale: none; }

/* The CO₂ bars fill once their card is in view. */
.js-reveal .rank-card:not(.is-visible) .fill { transform: scaleX(0); }
.js-reveal .rank-card .fill { transition: width 600ms var(--ease-out), transform 1000ms var(--ease-out); }
.js-reveal .rank-card li:nth-child(2) .fill { transition-delay: 0ms, 80ms; }
.js-reveal .rank-card li:nth-child(3) .fill { transition-delay: 0ms, 160ms; }
.js-reveal .rank-card li:nth-child(4) .fill { transition-delay: 0ms, 240ms; }
.js-reveal .rank-card li:nth-child(n+5) .fill { transition-delay: 0ms, 320ms; }

/* How far down the page, as a hairline of accent under the bar. */
.progress { display: none; }
@supports (animation-timeline: scroll()) {
  .progress {
    display: block; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
    background: var(--accent); transform-origin: left; transform: scaleX(0);
    animation: progress linear both; animation-timeline: scroll(root);
  }
  @keyframes progress { to { transform: scaleX(1); } }
}

/* The section you are in, marked in the bar. */
.nav-links a[aria-current="true"], .nav-links a[aria-current="page"] { color: var(--ink); background: var(--surface-2); }
.menu a[aria-current="page"] { color: var(--ink); font-weight: 600; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; }
  .js-reveal .reveal { opacity: 1; translate: none; scale: none; transition: none; }
  .js-reveal .rank-card:not(.is-visible) .fill { transform: none; }
  .progress { display: none; }
  .flightpath, .caret { display: none; }
  .wheel > span.is-rolling, .bars .fill { transition: none; }
  .marker.is-airborne::before { opacity: 0.5; transform: none; }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}

/* On a phone the header keeps only the menu and the theme: the status pill
   goes, and the menu button stands before the theme toggle. */
@media (max-width: 640px) {
  .nav-end .status { display: none; }
}
@media (max-width: 899px) {
  .nav-end .menu-btn { order: 1; }
  .nav-end [data-theme-toggle] { order: 2; }
}

/* ── Privacy ────────────────────────────────────────────────────── */

.legal-hero { position: relative; overflow: hidden; padding: clamp(28px, 5vw, 56px) 0 clamp(32px, 4vw, 48px); border-bottom: 1px solid var(--line); background: color-mix(in srgb, var(--band) 35%, transparent); }
.legal-hero .kicker { margin-top: 24px; }
.legal-hero h1 {
  margin-top: 12px; max-width: 14em;
  font-family: var(--font-display); font-stretch: 125%; font-weight: 800;
  font-size: clamp(36px, 5.6vw, 72px); line-height: 0.98; letter-spacing: -0.035em; text-wrap: balance;
}
.legal-lede { margin-top: 18px; max-width: 36em; font-size: clamp(16px, 1.5vw, 18.5px); color: var(--ink-2); text-wrap: pretty; }
.glance { list-style: none; margin: 32px 0 0; padding: 0; display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.glance li {
  display: grid; grid-template-columns: auto 1fr; column-gap: 12px; row-gap: 3px; align-items: start;
  padding: 16px 18px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-card);
}
.glance svg { grid-row: 1 / span 2; width: 26px; height: 26px; padding: 5px; border-radius: 50%; background: var(--air-soft); fill: none; stroke: var(--air); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.glance b { font-weight: 600; font-size: 15px; }
.glance span { font-size: 13px; color: var(--ink-3); }

.legal-body { display: grid; gap: 24px; padding-top: clamp(28px, 4vw, 48px); padding-bottom: clamp(40px, 5.5vw, 72px); }
@media (min-width: 900px) { .legal-body { grid-template-columns: 240px minmax(0, 720px); gap: 64px; } }
.toc { display: flex; flex-direction: column; gap: 2px; align-self: start; }
@media (min-width: 900px) { .toc { position: sticky; top: calc(var(--nav-h) + 24px); } }
@media (max-width: 899px) { .toc { display: none; } }
.toc p { font-family: var(--font-mono); font-size: 11.5px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 8px; }
.toc a { text-decoration: none; font-size: 14px; color: var(--ink-2); padding: 7px 12px; margin-left: -12px; border-radius: var(--radius-sm); border-left: 2px solid transparent; }
.toc a:hover { color: var(--ink); background: var(--surface-2); }
.legal-text section + section { margin-top: 36px; padding-top: 32px; border-top: 1px solid var(--line); }
.legal-text h2 { font-family: var(--font-display); font-stretch: 118%; font-weight: 700; font-size: clamp(20px, 2vw, 24px); letter-spacing: -0.015em; }
.legal-text p { margin-top: 12px; color: var(--ink-2); font-size: 16px; line-height: 1.7; }
.legal-text a:not(.btn) { color: var(--ink); text-underline-offset: 3px; }
.parties { display: grid; gap: 10px; margin: 16px 0 0; }
.parties > div { padding: 16px 18px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.parties dt { font-weight: 700; font-size: 15px; }
.parties dd { margin: 6px 0 0; color: var(--ink-2); font-size: 15px; line-height: 1.65; }
.parties dd a { display: inline-block; margin-top: 4px; }
.legal-text .mail { margin-top: 14px; }
.legal-text ul { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 10px; }
.legal-text li { position: relative; padding-left: 22px; color: var(--ink-2); font-size: 16px; line-height: 1.6; text-wrap: pretty; }
.legal-text li::before { content: ""; position: absolute; left: 3px; top: 0.62em; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
.legal-text li b { color: var(--ink); }

/* ── Depth ──────────────────────────────────────────────────────
   Every panel stands a little off the page: a lit top edge, a darker lower
   one, and a shadow in three layers — contact, near and far. With a mouse,
   theme.js tips the one under the pointer towards it, lifts it off the page,
   puts a soft light where the pointer is and throws the shadow away from it,
   as if the pointer were the lamp. */
.board, .log, .co2-card, .rank-card, .steps li, .follow, .glance li, .parties > div, .detail, .door, .fleet-card, .glossary, .stat-fig, .stat-airports, .stat-longest, .jet-card {
  box-shadow: inset 0 1px 0 var(--edge-hi), inset 0 -1px 0 var(--edge-lo), var(--shadow-3d);
}
.tilt {
  transform: perspective(750px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateZ(var(--lift, 0px));
  transition: transform 600ms var(--ease-out), box-shadow 400ms var(--ease);
}
.tilt.is-tilting {
  --lift: 8px;
  transition: transform 120ms linear, box-shadow 160ms linear;
  box-shadow: inset 0 1px 0 var(--edge-hi), inset 0 -1px 0 var(--edge-lo),
    calc(var(--sx, 0px) * 0.4) calc(var(--sy, 0px) * 0.4 + 6px) 14px -6px var(--tilt-near),
    var(--sx, 0px) calc(var(--sy, 0px) + 34px) 70px -24px var(--tilt-far);
  background-image: radial-gradient(420px circle at var(--gx, 50%) var(--gy, 50%), var(--glare), transparent 60%);
}
/* A rim of light along the edge nearest the pointer, drawn on the border
   alone: the panel's edge catches the lamp. */
.tilt { position: relative; }
.tilt::before {
  content: ""; position: absolute; inset: -1px; z-index: 3; pointer-events: none;
  border-radius: inherit; padding: 1px;
  background: radial-gradient(240px circle at var(--gx, 50%) var(--gy, 50%), var(--rim), transparent 70%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  opacity: 0; transition: opacity 300ms var(--ease);
}
.tilt.is-tilting::before { opacity: 1; }
/* What is on the panel floats a little above it while it tips, so the
   panel reads as a tray with things on it, not a picture of one. */
.tilt.is-tilting { transform-style: preserve-3d; }
.tilt > * { transition: transform 600ms var(--ease-out); }
.tilt.is-tilting > * { transform: translateZ(9px); transition-duration: 200ms; }
@media (prefers-reduced-motion: reduce) {
  .tilt, .tilt.is-tilting { transform: none; transition: none; }
  .tilt.is-tilting > * { transform: none; }
}

/* ── The pages' own content ─────────────────────────────────────── */

.card-note { margin-top: 4px; font-size: 13px; color: var(--ink-3); }

/* Home: three doors into the site, and the latest flights. */
.doors { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.door {
  display: grid; gap: 8px; padding: 24px; text-decoration: none; color: inherit;
  border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface);
}
.door-kicker { font-family: var(--font-mono); font-size: 11.5px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--accent); }
.door-value { font-family: var(--font-display); font-stretch: 118%; font-weight: 800; font-size: 28px; letter-spacing: -0.02em; line-height: 1.1; }
.door-text { color: var(--ink-2); font-size: 14px; }
.door-go { margin-top: 6px; font-size: 20px; color: var(--ink-3); transition: transform var(--dur-2) var(--ease), color var(--dur-2) var(--ease); }
.door:hover .door-go { transform: translateX(6px); color: var(--accent); }
.latest { margin-top: 28px; }
.latest-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 12px; }
.latest-all { display: inline-block; padding: 8px 0; font-size: 14px; font-weight: 600; color: var(--ink-2); text-decoration: none; }
.latest-all:hover { color: var(--accent); }

/* Map: the fleet under the globe. */
.fleet { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.fleet-card { display: grid; border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface); overflow: hidden; }
.fleet-card > button {
  display: grid; gap: 4px; padding: 20px 20px 16px; text-align: left; background: none; border: 0; cursor: pointer; color: inherit;
}
.fleet-state { font-size: 12px; font-weight: 600; color: var(--ground); display: inline-flex; align-items: center; gap: 6px; }
.fleet-state::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.fleet-card.is-air .fleet-state { color: var(--air); }
.fleet-name { margin-top: 6px; font-family: var(--font-display); font-stretch: 118%; font-weight: 800; font-size: 19px; letter-spacing: -0.015em; }
.fleet-card > button:hover .fleet-name { color: var(--accent); }
.fleet-meta { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-3); }
.fleet-where { margin-top: 8px; font-family: var(--font-mono); font-weight: 700; font-size: 15px; }
.fleet-figs { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 12.5px; color: var(--ink-3); }
.fleet-figs b { font-family: var(--font-mono); color: var(--ink); font-weight: 600; }
.fleet-last { padding: 12px 20px; border-top: 1px solid var(--line); font-family: var(--font-mono); font-size: 12px; color: var(--ink-2); text-decoration: none; }
.fleet-last:hover { background: var(--surface-2); color: var(--ink); }

/* Jets: every jet on a card of its own, its silhouette on a lit stage. */
.hangar-sum { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 22px; }
.hangar-sum > span {
  display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 14px;
  border: 1px solid var(--line); border-radius: var(--pill); background: var(--surface); font-size: 13.5px; color: var(--ink-2);
}
.hangar-sum b { font-family: var(--font-mono); font-weight: 700; color: var(--ink); }
.hangar-sum .is-air b { color: var(--air); }
.hangar { list-style: none; margin: 0; padding: 0; display: grid; gap: 18px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 330px), 1fr)); }
.jet-card { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface); overflow: hidden; }
.hangar.is-first .jet-card { animation: stripIn 700ms var(--ease-out) both; animation-delay: calc(var(--i) * 70ms); }
.jet-stage {
  position: relative; height: 200px; display: grid; place-items: center; overflow: hidden;
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(circle at 50% 55%, color-mix(in srgb, var(--accent) 10%, transparent), transparent 62%),
    radial-gradient(color-mix(in srgb, var(--ink) 14%, transparent) 1px, transparent 1.4px) 0 0 / 16px 16px,
    var(--surface-2);
}
.jet-card.is-air .jet-stage { background:
    radial-gradient(circle at 50% 55%, var(--air-soft), transparent 62%),
    radial-gradient(color-mix(in srgb, var(--ink) 14%, transparent) 1px, transparent 1.4px) 0 0 / 16px 16px,
    var(--surface-2); }
.jet-art { width: 170px; height: 170px; display: grid; place-items: center; transition: translate 700ms var(--ease-out), scale 700ms var(--ease-out); }
.jet-art svg { position: static; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(14px 22px 10px color-mix(in srgb, var(--ink) 16%, transparent)); }
.jet-art .plane-turn { transform: rotate(45deg); transform-origin: center; transform-box: fill-box; }
.jet-art .plane-body { fill: var(--surface); stroke: var(--ink); stroke-width: 1.4; }
.jet-art .plane-accent { stroke: var(--ink); opacity: 0.35; }
.jet-card.is-air .jet-art .plane-body { fill: var(--accent); stroke: color-mix(in srgb, var(--accent) 60%, var(--ink)); }
.jet-card.is-air .jet-art .plane-accent { stroke: var(--on-accent); opacity: 0.6; }
.jet-card:hover .jet-art { translate: 8px -8px; scale: 1.04; }
.jet-state {
  position: absolute; top: 14px; left: 14px; display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px;
  border-radius: var(--pill); background: var(--surface); border: 1px solid var(--line); font-size: 12px; font-weight: 600; color: var(--ground);
}
.jet-state::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.jet-card.is-air .jet-state { color: var(--air); }
.jet-type { margin-top: 6px; font-family: var(--font-mono); font-size: 11.5px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-3); }
.jet-body { display: grid; gap: 16px; padding: 20px 22px 22px; flex: 1; }
.jet-name { font-family: var(--font-display); font-stretch: 125%; font-weight: 800; font-size: 26px; line-height: 1.05; letter-spacing: -0.025em; text-wrap: balance; }
.jet-now { display: grid; gap: 2px; }
.jet-now-cap { font-size: 12px; color: var(--ink-3); }
.jet-now b { font-family: var(--font-mono); font-weight: 700; font-size: 18px; }
.jet-now > span:last-child { font-size: 13px; color: var(--ink-2); min-height: 1.3em; }
.jet-figs { margin: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; padding-top: 14px; border-top: 1px dashed var(--line-strong); }
.jet-figs dt { font-size: 11.5px; color: var(--ink-3); }
.jet-figs dd { margin: 2px 0 0; font-family: var(--font-mono); font-weight: 700; font-size: 15px; white-space: nowrap; }
@media (max-width: 420px) { .jet-figs { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.jet-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0 16px; padding: 6px 22px; border-top: 1px solid var(--line); }
.jet-go { display: inline-flex; gap: 8px; padding: 8px 0; font-weight: 600; font-size: 14px; color: var(--ink); text-decoration: none; }
.jet-go span { transition: translate var(--dur-3) var(--ease-out); }
.jet-go:hover { color: var(--accent); }
.jet-go:hover span { translate: 5px 0; }
.jet-last { padding: 8px 0; font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); text-decoration: none; }
.jet-last:hover { color: var(--ink); }
@media (prefers-reduced-motion: reduce) { .jet-art, .jet-go span { transition: none; } }

/* Flights: the week in figures over the log. */
.log-stats { display: grid; gap: 12px; margin-bottom: 20px; }
.stat-row { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.stat-fig, .stat-airports, .stat-longest {
  display: grid; gap: 4px; padding: 16px 18px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
}
.stat-fig b { font-family: var(--font-display); font-stretch: 118%; font-weight: 800; font-size: 26px; letter-spacing: -0.02em; }
.stat-fig span, .stat-longest span { font-size: 13px; color: var(--ink-3); }
/* On a phone the three figures share one row instead of a screen each. */
@media (max-width: 640px) {
  .stat-row:first-child { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .stat-row:first-child .stat-fig { padding: 12px; }
  .stat-row:first-child .stat-fig b { font-size: 19px; }
  .stat-row:first-child .stat-fig span { font-size: 11.5px; line-height: 1.3; }
}
.stat-cap { font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-3); }
.stat-airports > div { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.apt { padding: 4px 10px; border-radius: var(--pill); background: var(--surface-2); font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); }
.apt b { color: var(--ink); }
.stat-longest { text-decoration: none; color: inherit; }
.stat-longest b { font-family: var(--font-mono); font-size: 18px; }
.stat-longest:hover b { color: var(--accent); }

/* Footprint: day by day, and in perspective. */
/* The second row runs the page's full width, the day chart filling its
   card's height, the equivalents side by side beside it. */
.footprint-more { display: grid; gap: 16px; grid-column: 1 / -1; }
@media (min-width: 960px) { .footprint-more { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); } }
.footprint-more > .rank-card { display: flex; flex-direction: column; }
.days { flex: 1; display: grid; grid-template-columns: repeat(14, minmax(0, 1fr)); gap: clamp(6px, 1vw, 12px); align-items: end; height: auto; min-height: 220px; margin-top: 18px; }
.day { display: grid; grid-template-rows: 1fr auto; gap: 6px; height: 100%; }
.day-bar { align-self: end; height: max(3px, var(--h)); border-radius: 6px 6px 2px 2px; background: linear-gradient(var(--accent), color-mix(in srgb, var(--accent) 45%, transparent)); }
.day.is-empty .day-bar { background: var(--surface-2); }
.day-label { text-align: center; font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); }
.equiv { list-style: none; margin: 18px 0 0; padding: 0; display: grid; gap: 14px; }
.equiv li { display: grid; gap: 2px; padding-bottom: 14px; border-bottom: 1px solid var(--line); }
.equiv li:last-child { border-bottom: 0; padding-bottom: 0; }
.equiv b { font-family: var(--font-display); font-stretch: 118%; font-weight: 800; font-size: 28px; letter-spacing: -0.02em; }
.equiv span { font-size: 13.5px; color: var(--ink-2); }
@media (min-width: 640px) {
  .equiv { flex: 1; grid-template-columns: repeat(3, minmax(min-content, 1fr)); gap: 0; align-content: center; }
  .equiv li, .equiv li:last-child { align-content: start; padding: 4px 18px; border-bottom: 0; border-left: 1px solid var(--line); }
  .equiv li:first-child { padding-left: 0; border-left: 0; }
  .equiv b { font-size: clamp(22px, 2.1vw, 32px); white-space: nowrap; }
}

/* How it works: questions and a glossary. */
.faq-wrap { display: grid; gap: 20px; }
@media (min-width: 960px) { .faq-wrap { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); } .faq-wrap > .section-head { grid-column: 1 / -1; } }
.faq { display: grid; gap: 8px; }
.faq details { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.faq summary { list-style: none; cursor: pointer; padding: 16px 20px; font-weight: 600; font-size: 15.5px; display: flex; justify-content: space-between; gap: 16px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-size: 20px; line-height: 1; color: var(--ink-3); transition: transform var(--dur-2) var(--ease); }
.faq details[open] summary::after { transform: rotate(45deg); color: var(--accent); }
.faq details p { padding: 0 20px 18px; color: var(--ink-2); font-size: 14.5px; line-height: 1.6; text-wrap: pretty; }
.faq details p a { color: var(--ink); font-weight: 600; text-underline-offset: 3px; }
.faq details p a:hover { color: var(--accent); }
.glossary { align-self: start; padding: 22px; border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface); }
.glossary dl { margin: 12px 0 0; display: grid; gap: 12px; }
.glossary dt { font-family: var(--font-mono); font-weight: 700; font-size: 14px; }
.glossary dd { margin: 2px 0 0; color: var(--ink-2); font-size: 13.5px; }
.card-title + .card-note { margin-top: -12px; }
