/* ═════════════════════════════════════════════════════════════════════════
 * style.css — the live site's single stylesheet.
 *
 * Generated 2026-05-02 by merging the prior `_legacy-base.css` (v1
 * structural primitives + legacy design-language) with `style-v2.css`
 * (Snow Leopard / Aqua design overrides, scoped under
 * `html[data-design="v2"]`). The two files used to load separately;
 * consolidating them removes any chance of v1 design-language sneaking
 * back as a separately-shipped file.
 *
 * Snapshots of the pre-merge files live in _archive/v1-design-language/.
 *
 * Architecture inside this file:
 *  ▸ The first ~5800 lines are v1 base — flex/grid layouts, positioning,
 *    animations, mobile @media breakpoints, focus rings, base reset.
 *    Plus some legacy decorative rules that v2 overrides below; pruning
 *    those is a future cleanup pass.
 *  ▸ The remainder is v2 design-language overrides (Lucida Grande body,
 *    Inter heads, Aqua-blue accents, soft drop shadows, hover tilts).
 *    Every rule prefixed `html[data-design="v2"]`. The attribute is
 *    hard-coded on <html> in index.html — load-bearing for specificity.
 * ═════════════════════════════════════════════════════════════════════════ */

/* ═════════════════════════════════════════════════════════════════════════════
 * _legacy-base.css — DO NOT EDIT
 *
 * This file was `public/style.css` until 2026-05-03. It carries the v1
 * design language PLUS the structural layout primitives (flex grids,
 * positions, animations, mobile breakpoints) that style-v2.css does NOT
 * redefine. style-v2.css is overrides on top of this file — without this
 * file the site renders as nearly-unstyled HTML with v2 colors floating
 * in space.
 *
 * The rename + this banner are intentional. This file is no longer the
 * design source of truth. Treat it as legacy structure pending fold-in
 * to style-v2.css.
 *
 * If you are tempted to add new styles here: STOP. Add to style-v2.css.
 *
 * If you are tempted to remove rules here: ALSO STOP. Many rules are
 * silently load-bearing — verify the rule has an equivalent in
 * style-v2.css across every page before removing.
 *
 * Retirement plan (separate session): audit which rules in this file
 * have NO override in style-v2.css → those are the structural primitives
 * v2 silently relies on → fold them into style-v2.css unprefixed → strip
 * the html[data-design="v2"] prefix from style-v2.css → drop this file.
 * ═════════════════════════════════════════════════════════════════════════════
 */

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

/* ── ORIGINAL PALETTE (revert by swapping blocks) ──────────────────────────
:root {
  --bg: #f5f5f7;
  --surface: #fff;
  --text: #1d1d1f;
  --text-2: #6e6e73;
  --text-3: #aeaeb2;
  --border: rgba(0,0,0,0.06);
  --green: #30d158;
  --red: #ff453a;
  --amber: #ff9f0a;
  --hero-bg: #13111a;
  --hero-accent: #e85d2a;
  --radius: 14px;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}
───────────────────────────────────────────────────────────────────────────── */

:root {
  /* warm palette — cream/terracotta/navy */
  --bg: #f4f1eb;
  --surface: #fdfcf9;
  --text: #2c2926;
  --text-2: #7a7368;
  --text-3: #b0a89a;
  --border: rgba(44, 41, 38, 0.08);
  --green: #3a9a5c;
  --red: #c4453a;
  --amber: #d4890a;
  /* CURRENT HERO BG (swap blocks to revert) ─────────────────────────────── */
  /* --hero-bg: #1a1e2e;   ← original: cool navy night sky */
  /* --hero-accent: #e85d2a; */
  /* ──────────────────────────────────────────────────────────────────────── */
  --hero-bg: #0e0f1e;       /* sunrise: deep indigo night sky */
  --hero-accent: #e85d2a;
  --hero-glow: #e8e5df;
  --nav-shell-pad: 3px;
  --mono: 'Monaco', 'Menlo', 'Andale Mono', 'Courier New', monospace;
  --radius: 14px;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  /* Mobile/touch design tokens. iOS HIG min tap target = 44px.
     env() insets fall back to 0px on non-notched devices, so these are
     safe to use as additive padding everywhere. */
  --tap: 44px;
  --safe-top:    env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left:   env(safe-area-inset-left, 0px);
  --safe-right:  env(safe-area-inset-right, 0px);
}

:root[data-hero-theme="day"] {
  --hero-bg: #87c7ee;
  --hero-accent: #b97c12;
  --hero-glow: #f7f1df;
}

html {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  -webkit-font-smoothing: antialiased;
  color: var(--text);
  background: var(--bg);
}

body { min-height: 100vh; overflow-x: hidden; display: flex; flex-direction: column; }
#app { flex: 1; }

/* ═══════════════════════════════════════════════════════════════════════════ */
/* NAV                                                                        */
/* ═══════════════════════════════════════════════════════════════════════════ */

/* Cream cross-fade scrim used during page transitions. Lives at the
 * highest z-index so it blankets nav + map + everything else, then
 * lifts to reveal the new view underneath. Cream (not white) so the
 * fade reads as part of the app's palette, not a flash to nothing. */
.page-cream-overlay {
  position: fixed;
  inset: 0;
  background: var(--bg);
  pointer-events: none;
  opacity: 0;
  z-index: 200;
  transition: opacity 250ms cubic-bezier(0.4, 0, 0.2, 1);
}
.page-cream-overlay.is-fade-in {
  opacity: 1;
  pointer-events: all;
}
.page-cream-overlay.is-fade-out {
  /* slightly slower fade-out so the destination view has a beat to
   * settle (basemap tiles, layer creation) before the scrim lifts */
  transition: opacity 350ms cubic-bezier(0.4, 0, 0.2, 1);
  opacity: 0;
}
@media (prefers-reduced-motion: reduce) {
  .page-cream-overlay { transition-duration: 0ms; }
}

/* Brand stack — fixed top-left wrapper holding the logo + the
   "a project by funnest.world" tagline beneath it. The wrapper owns the
   positioning so the two elements stay aligned across themes. */
.brand-stack {
  position: fixed;
  top: 2px;
  left: 24px;
  z-index: 101;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.brand-logo {
  display: inline-block;
  text-decoration: none;
  padding: 4px 6px;
  border-radius: 8px;
  transition: opacity 200ms ease, transform 200ms ease;
}
.brand-logo-img {
  display: block;
  /* Asset is 400×79 cropped to its visible bbox; serve at half-size for
     a crisp 2× retina render. The image is its own visual extent, so
     brand-stack's align-items: center lines the tagline up directly
     beneath it without any layout-vs-visual compensation. */
  width: 200px;
  height: auto;
  /* Theme-aware tint — solid black art inverts on dark hero. */
  transition: filter 200ms ease;
}
.brand-tagline {
  margin: -2px 0 0;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.2;
  color: var(--text-3);
  text-align: center;
  /* Nudge the tagline left to read centered against the visible
     wordmark rather than the pixel-center of the logo bbox. The plane
     icon at the right of the asset adds ~16px of visual weight that
     pulls perceived "center" rightward; this counter-nudges. */
  transform: translateX(-16px);
}
.brand-tagline-link {
  color: var(--hero-accent);
  text-decoration: none;
  font-weight: 600;
  transition: opacity 200ms ease;
}
.brand-tagline-link:hover { text-decoration: underline; }
body.is-home .brand-tagline {
  color: rgba(255, 246, 238, 0.7);
  text-shadow: 0 1px 12px rgba(10, 14, 28, 0.26);
}
body.is-home .brand-tagline-link {
  color: rgba(255, 246, 238, 0.95);
}
:root[data-hero-theme="day"] body.is-home .brand-tagline {
  color: rgba(44, 41, 38, 0.7);
  text-shadow: none;
}
:root[data-hero-theme="day"] body.is-home .brand-tagline-link {
  color: rgba(44, 41, 38, 0.95);
}
.brand-logo:hover {
  opacity: 0.7;
  transform: translateY(-1px);
}
/* On the homepage the nav is dark, so the logo inverts to a light tint
   to stay legible. Day-mode hero gets a softened black instead. */
body.is-home .brand-logo-img {
  filter: invert(1) opacity(0.94);
}
:root[data-hero-theme="day"] body.is-home .brand-logo-img {
  filter: opacity(0.92);
}

nav {
  position: fixed;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  display: flex;
  gap: 2px;
  padding: var(--nav-shell-pad);
  border-radius: 12px;
  transition: all 0.6s ease;
  /* WARM: muted warm glass */
  background: rgba(244, 241, 235, 0.7);
  backdrop-filter: blur(20px) saturate(150%);
  /* WARM: warm border */
  border: 1px solid rgba(44, 41, 38, 0.08);
  box-shadow: 0 1px 4px rgba(0,0,0,0.05);
}

.nav-indicator {
  position: absolute;
  top: var(--nav-shell-pad);
  left: var(--nav-shell-pad);
  width: 0;
  height: calc(100% - (var(--nav-shell-pad) * 2));
  border-radius: 9px;
  background: var(--surface);
  box-shadow: 0 1px 3px rgba(0,0,0,0.05);
  transform: translateX(0);
  opacity: 0;
  z-index: 0;
  transition:
    transform 0.42s cubic-bezier(0.22, 1, 0.36, 1),
    width 0.42s cubic-bezier(0.22, 1, 0.36, 1),
    background 0.35s ease,
    box-shadow 0.35s ease,
    opacity 0.18s ease;
}

nav.dark {
  background: rgba(255,255,255,0.08);
  border-color: rgba(255,255,255,0.1);
  box-shadow: 0 1px 4px rgba(0,0,0,0.2);
}

nav.dark .nav-indicator {
  background: rgba(255,255,255,0.12);
  box-shadow: none;
}

:root[data-hero-theme="day"] nav.dark {
  background: rgba(54, 66, 79, 0.2);
  border-color: rgba(54, 66, 79, 0.26);
  box-shadow: 0 10px 28px rgba(65, 93, 121, 0.16);
}

:root[data-hero-theme="day"] nav.dark .nav-indicator {
  background: rgba(255, 255, 255, 0.54);
  box-shadow: 0 1px 3px rgba(44, 74, 98, 0.1);
}

.nav-link {
  position: relative;
  z-index: 1;
  padding: 7px 18px; font-size: 13px; font-weight: 500;
  text-decoration: none; border-radius: 9px;
  transition: color 0.3s ease; user-select: none; color: var(--text-2);
}
.nav-link:hover { color: var(--text); }
/* WARM: cream active tab */
.nav-link.active { color: var(--text); }
nav.dark .nav-link { color: rgba(255,255,255,0.5); }
nav.dark .nav-link:hover { color: rgba(255,255,255,0.85); }
nav.dark .nav-link.active { color: #fff; }

:root[data-hero-theme="day"] nav.dark .nav-link {
  color: rgba(36, 54, 71, 0.68);
}

:root[data-hero-theme="day"] nav.dark .nav-link:hover {
  color: rgba(29, 46, 62, 0.95);
}

:root[data-hero-theme="day"] nav.dark .nav-link.active {
  color: #1f3447;
}

/* The v1/v2 design-language toggle lived here from 2026-04-30 to
   2026-05-02. Removed when v2 became the default; see
   _archive/v1-design-language/ for the v1 snapshot + revert path. */

/* ═══════════════════════════════════════════════════════════════════════════ */
/* ROUTES PAGE — two separate layers, no layout animation                     */
/* ═══════════════════════════════════════════════════════════════════════════ */

.routes-page {
  position: relative;
  min-height: 100vh;
}

/* ── Layer 1: Dark hero (fixed, full screen, fades out) ──────────────────── */

.hero-layer {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 32px;

  /* ORIGINAL HERO GRADIENTS (revert by swapping blocks) ──────────────────
  background:
    radial-gradient(ellipse 110% 80% at 50% 30%, rgba(232, 93, 42, 0.15) 0%, transparent 60%),
    radial-gradient(ellipse 70% 50% at 20% 70%, rgba(60, 80, 140, 0.25) 0%, transparent 55%),
    radial-gradient(ellipse 60% 40% at 80% 50%, rgba(40, 60, 120, 0.15) 0%, transparent 50%),
    var(--hero-bg);
  ──────────────────────────────────────────────────────────────────────── */

  /* sunrise: warm light from lower-right, indigo upper-left */
  background:
    radial-gradient(ellipse 110% 70% at 90% 95%, rgba(255, 90, 30, 0.42) 0%, transparent 60%),
    radial-gradient(ellipse 95% 60% at 75% 80%, rgba(255, 55, 40, 0.28) 0%, transparent 55%),
    radial-gradient(ellipse 120% 50% at 80% 100%, rgba(255, 150, 50, 0.32) 0%, transparent 55%),
    radial-gradient(ellipse 80% 45% at 55% 72%, rgba(180, 50, 80, 0.16) 0%, transparent 55%),
    radial-gradient(ellipse 80% 70% at 20% 25%, rgba(50, 40, 120, 0.25) 0%, transparent 55%),
    radial-gradient(ellipse 60% 50% at 10% 15%, rgba(40, 35, 100, 0.2) 0%, transparent 50%),
    var(--hero-bg);

  /* will be animated by JS — starts visible */
  opacity: 1;
  transition: opacity 0.55s ease; /* JS controls fades, theme controls crossfade */
}

.hero-layer::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 120% 80% at 88% 92%, rgba(255, 202, 84, 0.55) 0%, transparent 58%),
    radial-gradient(ellipse 95% 65% at 74% 78%, rgba(255, 178, 67, 0.34) 0%, transparent 55%),
    radial-gradient(ellipse 130% 60% at 82% 100%, rgba(255, 229, 154, 0.3) 0%, transparent 54%),
    radial-gradient(ellipse 95% 60% at 24% 16%, rgba(255, 255, 255, 0.28) 0%, transparent 52%),
    radial-gradient(ellipse 80% 55% at 18% 36%, rgba(163, 214, 247, 0.24) 0%, transparent 56%),
    radial-gradient(ellipse 90% 70% at 55% 20%, rgba(126, 193, 237, 0.18) 0%, transparent 54%),
    #87c7ee;
  opacity: 0;
  transition: opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
}

:root[data-hero-theme="day"] .hero-layer::before {
  opacity: 1;
}

/* grain */
.hero-layer::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--grain-url);
  background-size: 200px 200px;
  opacity: 0.4;
  pointer-events: none;
  transition: opacity 0.55s ease;
}

.hero-layer.hidden {
  pointer-events: none;
}

/* ── Glow box — bright screen on dark background ─────────────────────────── */

.glow-box {
  position: relative;
  z-index: 1;
  padding: 52px 72px 28px;
  border-radius: 12px;
  max-width: 900px;
  width: 100%;
  text-align: center;

  /* Warm muted screen — not pure white, slightly warm/grey */
  background: var(--hero-glow);
  border: 4px solid #2a2a30;
  border-radius: 14px;

  /* Screen glow cast onto dark surroundings */
  box-shadow:
    0 0 160px 50px rgba(232, 229, 223, 0.1),
    0 0 60px 20px rgba(232, 229, 223, 0.07),
    0 0 15px 3px rgba(255, 255, 255, 0.08);
  transition:
    background 0.45s ease,
    border-color 0.45s ease,
    box-shadow 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

:root[data-hero-theme="day"] .glow-box {
  border-color: rgba(87, 104, 123, 0.8);
  box-shadow:
    0 0 180px 52px rgba(255, 223, 147, 0.14),
    0 0 70px 24px rgba(255, 248, 214, 0.12),
    0 0 18px 4px rgba(255, 255, 255, 0.1);
}

/* Grain on the screen surface */
.glow-box::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 0;
  background: var(--grain-url);
  background-size: 200px 200px;
  opacity: 0.12;
}

/* ── Sentence (hero state) ───────────────────────────────────────────────── */

.sentence-main {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
  font-size: clamp(26px, 4.5vw, 44px);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.5;
  color: var(--text);
}

.sentence-sub {
  display: block;
  margin-top: 28px;
  font-size: clamp(16px, 2.2vw, 22px);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--hero-accent);
  min-height: 1.4em;
  transition: color 0.4s ease;
}

/* The hero <form> wraps the sentence + subtitle + CTA so Enter triggers
   native form submission (single code path with the Fly button click).
   display: contents removes the form from layout entirely — children
   behave as if they were direct children of .glow-box, preserving the
   existing flow exactly. */
.hero-form {
  display: contents;
}

/* CTA row — Fly button on its own line, centered below the subtitle.
   Always rendered; .go-btn:disabled handles the greyed pre-fill state so
   no slot ever appears empty. */
.hero-cta-row {
  display: flex;
  justify-content: center;
  margin-top: 24px;
}
.hero-cta-row .go-btn {
  opacity: 1;
  transform: none;
  pointer-events: all;
  transition: opacity 0.2s ease, background 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
.hero-cta-row .go-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
  box-shadow: none;
  transform: none;
}

/* ── Hero center column: glow-box + followup link ────────────────────────── */
.hero-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 900px;
  gap: 26px;
}

.hero-theme-toggle {
  position: fixed;
  left: 18px;
  bottom: 18px;
  z-index: 120;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.14);
  backdrop-filter: blur(18px) saturate(145%);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.14);
  transition:
    background 0.35s ease,
    border-color 0.35s ease,
    box-shadow 0.35s ease;
}

.hero-toggle-btn {
  font: inherit;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.72);
  background: transparent;
  border: none;
  border-radius: 999px;
  padding: 7px 11px;
  cursor: pointer;
  transition: color 0.2s ease, background 0.2s ease;
}

.hero-toggle-btn:hover {
  color: rgba(255, 255, 255, 0.95);
}

.hero-toggle-btn.active {
  color: #fff;
  background: rgba(255, 255, 255, 0.16);
}

:root[data-hero-theme="day"] .hero-theme-toggle {
  background: rgba(248, 252, 255, 0.3);
  border-color: rgba(255, 255, 255, 0.34);
  box-shadow: 0 10px 28px rgba(92, 136, 170, 0.16);
}

:root[data-hero-theme="day"] .hero-toggle-btn {
  color: rgba(41, 69, 95, 0.72);
}

:root[data-hero-theme="day"] .hero-toggle-btn:hover {
  color: rgba(41, 69, 95, 0.98);
}

:root[data-hero-theme="day"] .hero-toggle-btn.active {
  color: #23405d;
  background: rgba(255, 255, 255, 0.52);
}

/* Typewriter cursor */
.typewriter-cursor {
  display: inline-block;
  width: 2px;
  height: 0.85em;
  background: var(--hero-accent);
  vertical-align: text-bottom;
  margin-left: 1px;
  animation: blink 0.6s step-end infinite;
  transition: background 0.4s ease;
}

@keyframes blink {
  50% { opacity: 0; }
}

/* ── Glow box inner flash (child element, lives inside the box) ──────────── */

.glow-box-flash {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: white;
  opacity: 0;
  pointer-events: none;
  z-index: 10;
}

/* ── Airport inputs (bright screen) ──────────────────────────────────────── */

.airport-input-wrapper { position: relative; display: inline-flex; }

.airport-input {
  font-family: var(--mono); font-size: inherit; font-weight: 400;
  color: var(--text);
  background: rgba(0, 0, 0, 0.04);
  border: 1.5px solid rgba(0, 0, 0, 0.12);
  border-radius: 8px;
  padding: 6px 14px; width: 130px;
  text-align: center; text-transform: uppercase;
  letter-spacing: 0.06em; outline: none;
  transition: all 0.25s ease;
}

.airport-input::placeholder { color: var(--text-3); font-weight: 400; text-transform: uppercase; }

.airport-input:focus {
  border-color: rgba(0, 0, 0, 0.25);
  background: rgba(0, 0, 0, 0.02);
  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.05);
}

.go-btn {
  font-family: inherit; font-size: 15px; font-weight: 600;
  color: #fff; background: var(--text);
  border: none; border-radius: 8px;
  padding: 8px 20px; cursor: pointer;
  transition: all 0.3s ease;
  opacity: 0; transform: translateY(6px); pointer-events: none;
  letter-spacing: -0.01em;
}
.go-btn.visible { opacity: 1; transform: translateY(0); pointer-events: all; }
.go-btn:hover { box-shadow: 0 4px 16px rgba(0,0,0,0.12); transform: translateY(-1px); }
.go-btn:active { transform: translateY(1px); }
.go-arrow { display: inline-block; margin-left: 2px; transition: transform 0.2s ease; }
.go-btn:hover .go-arrow { transform: translateX(3px); }

/* ── Dropdown (hero state — high z-index) ────────────────────────────────── */

.dropdown {
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%) translateY(-6px);
  background: #fff; border: 1px solid rgba(0,0,0,0.08);
  border-radius: 12px; box-shadow: 0 12px 40px rgba(0,0,0,0.2);
  min-width: 220px; max-height: 260px; overflow-y: auto;
  z-index: 500; /* above everything */
  opacity: 0; pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
  overscroll-behavior: contain; color: var(--text);
}

.dropdown.open { opacity: 1; pointer-events: all; transform: translateX(-50%) translateY(0); }

.dropdown-item {
  padding: 10px 14px; cursor: pointer; font-size: 14px;
  display: flex; justify-content: space-between; align-items: center;
  transition: background 0.1s;
}
.dropdown-item:first-child { border-radius: 11px 11px 0 0; }
.dropdown-item:last-child { border-radius: 0 0 11px 11px; }
/* WARM: warm hover */
.dropdown-item:hover, .dropdown-item.highlighted { background: #f4f1eb; }
.dropdown-item .code { font-family: var(--mono); font-weight: 400; font-size: 14px; letter-spacing: 0.04em; }
.dropdown-item .name { color: var(--text-3); font-size: 13px; margin-left: 14px; }

/* ── Split-flap departure board overlay ─────────────────────────────────── */

.flap-display {
  display: inline-flex;
  gap: 4px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
}

.flap-display.visible { opacity: 1; }

/* Hide input text whenever the flap overlay is visible — keying off the
   overlay's own state (not focus) so the input text never bleeds through
   the flap cells when the animation fires while the input is still focused
   (e.g. selecting a destination without a follow-up focus shift). */
.airport-input-wrapper.has-flap:has(.flap-display.visible) .airport-input {
  color: transparent !important;
  caret-color: transparent;
}

.flap-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0.7em;
  height: 1.3em;
  padding: 0 2px;
  background: rgb(10, 14, 28);
  border-radius: 3px;
  font-family: var(--mono);
  font-size: inherit;
  line-height: 1;
  color: rgba(255, 255, 255, 0.7);
  position: relative;
  box-shadow:
    0 1px 3px rgba(0, 0, 0, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

/* The horizontal split — the signature departure-board detail */
.flap-cell::after {
  content: '';
  position: absolute;
  left: 0; right: 0;
  top: calc(50% - 0.5px);
  height: 1px;
  background: rgba(0, 0, 0, 0.25);
  z-index: 1;
}

/* Character "lands" — brightens */
.flap-cell.landed {
  color: rgba(255, 255, 255, 0.95);
}

/* ── Layer 2: Results page (normal flow, always rendered) ────────────────── */

.results-page {
  position: relative;
  z-index: 5;
  min-height: 100vh;
  padding: 96px 24px 80px;
  background: var(--bg);
  /* starts hidden, JS fades it in */
  opacity: 0;
  pointer-events: none;
}

.results-page.visible {
  opacity: 1;
  pointer-events: all;
}

/* ── Compact input bar (sits at top of results page) ─────────────────────── */

.compact-bar {
  max-width: 600px;
  margin: 0 auto 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 500;
  color: var(--text-2);
}

.compact-bar-sentence {
  gap: 6px;
}

.compact-bar-sentence > span:first-child,
.compact-bar-sentence > span:nth-of-type(2) {
  white-space: nowrap;
}

/* WARM: warm compact inputs */
.compact-bar .airport-input {
  color: var(--text);
  background: var(--surface);
  border: 1.5px solid rgba(44, 41, 38, 0.1);
  width: 60px; padding: 4px 8px;
  font-size: 14px; border-radius: 7px;
}

.compact-bar .airport-input::placeholder { color: var(--text-3); }

.compact-bar .airport-input:focus {
  border-color: rgba(0,0,0,0.25);
  box-shadow: 0 0 0 3px rgba(0,0,0,0.04);
  background: var(--surface);
}

.compact-bar .go-btn {
  padding: 4px 14px; font-size: 12px; border-radius: 6px;
  color: #fff; background: var(--text);
  margin-left: 2px; opacity: 1; transform: none; pointer-events: all;
}
.compact-bar .go-btn:hover { background: #333; box-shadow: 0 2px 8px rgba(0,0,0,0.1); transform: none; }

.results-inner { max-width: 600px; margin: 0 auto; }

.results-header {
  display: flex; align-items: baseline;
  justify-content: space-between; margin-bottom: 20px;
}

.results-route { font-size: 22px; font-weight: 700; letter-spacing: -0.025em; }
.results-route .code { font-family: var(--mono); font-weight: 400; letter-spacing: 0.02em; }
.results-route .arrow { color: var(--text-3); margin: 0 2px; font-weight: 400; }
.results-count { font-size: 13px; color: var(--text-3); font-weight: 500; }

.no-results { text-align: center; padding: 80px 24px; }
.no-results .big { font-size: 18px; font-weight: 600; color: var(--text-2); margin-bottom: 6px; }
.no-results .sub { font-size: 14px; color: var(--text-3); line-height: 1.5; }

/* ═══════════════════════════════════════════════════════════════════════════ */
/* WINNER CARD — breakout card for #1 result on route search                  */
/* ═══════════════════════════════════════════════════════════════════════════ */

.winner-card {
  position: relative;
  background: linear-gradient(180deg, #fffefa 0%, #f9f6ee 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px 28px 22px;
  margin-bottom: 20px;
}

.winner-card { cursor: pointer; transition: box-shadow 0.2s ease, transform 0.2s ease; }
.winner-card:hover { box-shadow: 0 4px 20px rgba(0,0,0,0.08); transform: translateY(-1px); }
.winner-card:active { transform: translateY(0); }
.winner-card::after {
  content: "›";
  position: absolute; right: 16px; top: 50%; transform: translateY(-50%);
  font-size: 24px; font-weight: 300; color: var(--text-3);
  opacity: 0.4; transition: opacity 0.2s ease, transform 0.2s ease;
  z-index: 2;
}
.winner-card:hover::after { opacity: 0.8; transform: translateY(-50%) translateX(2px); }

/* Grain overlay — on top of content, pointer-events none */
.winner-card::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 2;
  background: var(--grain-url);
  background-size: 200px 200px;
  opacity: 0.12;
}

.winner-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-2);
  margin-bottom: 14px;
}

.winner-name {
  font-size: 26px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.03em;
}

.winner-code {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-3);
  letter-spacing: 0.03em;
  margin-left: 8px;
}

.winner-metrics {
  display: flex;
  gap: 32px;
  margin-top: 20px;
  flex-wrap: wrap;
}

.winner-metric {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.winner-metric-value {
  font-size: 34px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.winner-metric-label {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-3);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Entrance animation */
.winner-card.will-enter {
  opacity: 0;
  transform: translateY(16px);
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* SHARED: AIRLINE / AIRPORT LIST ROWS                                        */
/* ═══════════════════════════════════════════════════════════════════════════ */

/* WARM: warm surface with grain overlay */
.airline-list {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--surface);
  border-radius: var(--radius);
  overflow: hidden;
  border: 1.5px solid rgba(44, 41, 38, 0.1);
  box-shadow: 0 1px 3px rgba(0,0,0,0.03), 0 4px 16px rgba(0,0,0,0.03);
}

/* WARM: subtle grain on the list surface */
.airline-list::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 0;
  background: var(--grain-url);
  background-size: 200px 200px;
  opacity: 0.06;
}

.airline-row {
  display: grid;
  grid-template-columns: 40px 1fr auto;
  align-items: center;
  gap: 0 14px;
  padding: 18px 24px;
  background: var(--surface);
  transition: background 0.15s;
  /* entrance animation handled by JS, start visible by default for non-animated contexts */
}
/* Connection-panel rows hide the rank cell (it's meaningless once we've
 * pinned a non-default winner and grouped the rest by alliance). Collapse
 * the column so the name doesn't sit in front of empty space. */
.airline-row.no-rank {
  grid-template-columns: 1fr auto;
}

.airline-row:not(:last-child) { border-bottom: 1px solid var(--border); }
/* WARM: warm hover */
.airline-row:hover { background: #f6f3ed; }

/* animate-in class: JS adds this then removes it */
.airline-row.will-enter { opacity: 0; transform: translateY(16px); }

.row-rank {
  font-family: var(--mono); font-size: 15px; font-weight: 400; color: var(--text-3);
  text-align: center;
}

.airline-row.top-1 .row-rank { color: #b8860b; }
.airline-row.top-2 .row-rank { color: #8e8e93; }
.airline-row.top-3 .row-rank { color: #a0522d; }

.row-center { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.row-name {
  font-size: 15px; font-weight: 600; color: var(--text); letter-spacing: -0.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.row-code {
  font-family: var(--mono); font-weight: 400; color: var(--text-3); font-size: 12px;
  letter-spacing: 0.04em; margin-left: 6px;
}

.row-sub { font-size: 13px; color: var(--text-3); display: flex; gap: 14px; }
.row-sub span { white-space: nowrap; }
.row-sub .c-green { color: var(--green); font-weight: 500; }
.row-sub .c-amber { color: var(--amber); font-weight: 500; }
.row-sub .c-red { color: var(--red); font-weight: 500; }

.row-primary { text-align: right; padding-left: 20px; flex-shrink: 0; }

.row-primary-value {
  font-family: var(--mono); font-size: 22px; font-weight: 400; letter-spacing: 0;
  line-height: 1;
}

.row-primary-label {
  font-size: 10px; font-weight: 600; color: var(--text-3);
  text-transform: uppercase; letter-spacing: 0.05em; margin-top: 3px;
}

.row-metrics { display: flex; gap: 16px; padding-left: 20px; flex-shrink: 0; }
.row-metric { text-align: center; min-width: 60px; }
.row-metric-value {
  font-family: var(--mono); font-size: 20px; font-weight: 400; letter-spacing: 0;
  line-height: 1;
}
.row-metric-label {
  font-size: 9px; font-weight: 600; color: var(--text-3);
  text-transform: uppercase; letter-spacing: 0.05em; margin-top: 3px;
}

.c-green { color: var(--green); }
.c-amber { color: var(--amber); }
.c-red { color: var(--red); }
.c-muted { color: var(--text-3); }

.row-nodata { font-size: 13px; color: var(--text-3); font-style: italic; }

/* Low-sample caveat — small amber "!" icon next to the airline name.
 * Lighter visual weight than the old "limited sample" text. Tooltip
 * on hover surfaces the full caveat. */
.row-caveat {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  margin-left: 8px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--amber) 22%, transparent);
  color: color-mix(in srgb, var(--amber) 90%, var(--text));
  font-family: var(--mono);
  font-weight: 700;
  font-size: 11px;
  line-height: 1;
  cursor: help;
  flex: 0 0 auto;
  vertical-align: 1px;
}
.row-caveat::before { content: none; }

.click-hint { font-size: 12px; color: var(--text-3); margin-bottom: 8px; padding: 0 4px; }

.airline-row.clickable { cursor: pointer; position: relative; padding-right: 28px; }
.airline-row.clickable::after {
  content: "›";
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  font-size: 20px; font-weight: 300; color: var(--text-3);
  opacity: 0.5; transition: opacity 0.2s ease, transform 0.2s ease;
}
.airline-row.clickable:hover::after { opacity: 1; transform: translateY(-50%) translateX(2px); }
/* WARM: warm clickable hover */
.airline-row.clickable:hover { background: #f6f3ed; }

/* ═══════════════════════════════════════════════════════════════════════════ */
/* RANKINGS + AIRPORTS PAGES                                                  */
/* ═══════════════════════════════════════════════════════════════════════════ */

.rankings-page, .airports-page { max-width: 600px; margin: 0 auto; padding: 96px 24px 80px; }

.controls { display: flex; align-items: center; gap: 6px; margin-bottom: 20px; flex-wrap: wrap; }
.controls-airports {
  width: fit-content;
  margin-left: auto;
  margin-right: auto;
  justify-content: center;
}
.controls-label { font-size: 13px; color: var(--text-3); font-weight: 500; margin-right: 4px; }
.controls-sep { width: 1px; height: 20px; background: var(--border); margin: 0 4px; }

/* WARM: warm pill buttons */
.sort-btn {
  font-family: inherit; font-size: 13px; font-weight: 500;
  color: var(--text-2); background: var(--surface);
  border: 1.5px solid rgba(44, 41, 38, 0.1); border-radius: 20px;
  padding: 6px 15px; cursor: pointer; transition: all 0.15s; user-select: none;
}
.sort-btn:hover { border-color: var(--text-3); color: var(--text); }
.sort-btn.active { color: var(--surface); background: var(--text); border-color: var(--text); }

/* ── Sort group pushes to the right edge of the controls bar ───────────── */
.controls .sort-group { margin-left: auto; }

/* ── Segmented control (iOS-style) ──────────────────────────────────────── */
.segmented {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  padding: 3px;
  background: rgba(44, 41, 38, 0.06);
  border-radius: 20px;
  isolation: isolate;
}
.segmented-btn {
  position: relative;
  z-index: 1;
  grid-row: 1;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-2);
  background: transparent;
  border: none;
  border-radius: 16px;
  padding: 5px 18px;
  min-width: 64px;
  cursor: pointer;
  transition: color 0.2s ease;
  user-select: none;
}
.segmented-btn:nth-child(1) { grid-column: 1; }
.segmented-btn:nth-child(2) { grid-column: 2; }
.segmented-btn:hover { color: var(--text); }
.segmented-btn.active { color: var(--text); font-weight: 600; }
.segmented-thumb {
  position: absolute;
  top: 3px;
  bottom: 3px;
  left: 3px;
  width: calc(50% - 3px);
  background: var(--surface);
  border-radius: 16px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08), 0 0 0 0.5px rgba(44, 41, 38, 0.06);
  transition: transform 0.32s cubic-bezier(0.32, 0.72, 0, 1);
  z-index: 0;
}
.segmented-thumb[data-pos="1"] { transform: translateX(100%); }

/* ── Sort group: dropdown + direction pill ──────────────────────────────── */
.sort-group { display: inline-flex; align-items: center; gap: 6px; }
.sort-dir-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 13px;
}
.sort-dir-label { line-height: 1; }
.sort-dir-arrow {
  display: inline-block;
  font-size: 9px;
  line-height: 1;
  color: var(--text-3);
  transition: transform 0.28s cubic-bezier(0.32, 0.72, 0, 1), color 0.15s ease;
}
.sort-dir-btn:hover .sort-dir-arrow { color: var(--text-2); }
.sort-dir-btn.desc .sort-dir-arrow { transform: rotate(180deg); }

.ui-atmosphere .segmented { background: rgba(72, 57, 36, 0.08); }
.ui-atmosphere .segmented-thumb {
  background: #fcfaf5;
  box-shadow: 0 1px 3px rgba(94, 68, 27, 0.1), 0 0 0 0.5px rgba(72, 57, 36, 0.06);
}

.list-header { display: flex; justify-content: space-between; margin-bottom: 8px; padding: 0 4px; }
.list-header-label { font-size: 11px; font-weight: 600; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.08em; }

/* ═══════════════════════════════════════════════════════════════════════════ */
/* MODAL                                                                      */
/* ═══════════════════════════════════════════════════════════════════════════ */

.modal-overlay {
  position: fixed; inset: 0; z-index: 300;
  display: flex; align-items: center; justify-content: center;
  padding: 24px; opacity: 0; pointer-events: none; transition: opacity 0.35s ease;
}
.modal-overlay.open { opacity: 1; pointer-events: all; }

.modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* WARM: warm modal panel with border.
   Scoped font override: inside a modal, `var(--mono)` resolves to Inter so
   stat values and codes feel modern instead of the retro Share Tech Mono
   used elsewhere on the site. Same move as .flap-board-page. */
.modal-panel {
  --mono: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  position: relative; width: 100%; max-width: 560px; max-height: 80vh;
  overflow: hidden; border-radius: 16px;
  background: var(--surface); border: 1.5px solid rgba(44, 41, 38, 0.1);
  box-shadow: 0 24px 80px rgba(0,0,0,0.12), 0 8px 24px rgba(0,0,0,0.06);
  transform: scale(0.95) translateY(12px);
  transition: transform 0.4s var(--ease-out);
  display: flex; flex-direction: column;
  font-feature-settings: 'tnum', 'ss01';
}
.modal-overlay.open .modal-panel { transform: scale(1) translateY(0); }

/* Header — flat cream surface with a dashed rule, Board-style. */
.modal-header {
  padding: 22px 28px 18px;
  background: transparent;
  border-bottom: 1px dashed rgba(44, 41, 38, 0.18);
  flex-shrink: 0;
}
.modal-kicker {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 10px;
}
.modal-title {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 22px; font-weight: 700; letter-spacing: -0.025em;
  line-height: 1.15;
  margin-bottom: 4px;
}
.modal-title-text { min-width: 0; }
.modal-code { /* legacy inline code span — kept so any other caller still works */
  font-size: 14px; font-weight: 500; color: var(--text-3); margin-left: 8px; letter-spacing: 0.02em;
}
.modal-subtitle { font-size: 14px; color: var(--text-2); }

/* Paper-tile IATA — visual callback to the Board's flap cells.
   Static (no flap animation) since it's a detail view, not a leaderboard. */
.modal-code-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 42px;
  height: 34px;
  padding: 0 8px;
  font-family: var(--mono);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text);
  background: #f7efdd;
  border: 1px solid rgba(44, 41, 38, 0.14);
  border-radius: 3px;
  box-shadow:
    0 1px 0 rgba(44, 41, 38, 0.06),
    inset 0 -1px 0 rgba(44, 41, 38, 0.08);
  position: relative;
  flex-shrink: 0;
}
/* Signature horizontal split line */
.modal-code-tile::after {
  content: '';
  position: absolute;
  left: 0; right: 0;
  top: calc(50% - 0.5px);
  height: 0.5px;
  background: rgba(44, 41, 38, 0.18);
  pointer-events: none;
}

.route-codes { font-family: var(--mono); letter-spacing: 0.03em; }

/* Route section labels — quiet mono kicker with a dot prefix, instead of a
   loud colored header. Color lives in the dot; label stays muted. */
.route-section-label {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text-3);
  padding: 20px 0 10px;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 10px;
}
.route-section-label::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--green);
  box-shadow: 0 0 0 1px rgba(44, 41, 38, 0.04);
}
.route-section-label.worst::before { background: var(--red); }
.route-section-label.worst { padding-top: 22px; }

.modal-close {
  position: absolute; top: 16px; right: 16px;
  width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  border: none; background: rgba(0,0,0,0.04); border-radius: 50%;
  font-size: 16px; color: var(--text-2); cursor: pointer; transition: all 0.15s; line-height: 1;
}
.modal-close:hover { background: rgba(0,0,0,0.08); color: var(--text); }

/* Low-sample caveat — subtle amber strip between header and stats.
   Only rendered when measured_flights < LOW_SAMPLE_THRESHOLD. */
.modal-caveat {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 28px;
  background: rgba(212, 137, 10, 0.06);
  border-bottom: 1px solid rgba(212, 137, 10, 0.2);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--amber);
  flex-shrink: 0;
}
.modal-caveat-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--amber);
  flex-shrink: 0;
}

/* Stat strip — flat, divided cells instead of floating rounded cards.
   Reads like a single data line at the top of the modal. */
.modal-stats {
  display: flex;
  padding: 16px 28px;
  gap: 0;
  flex-shrink: 0;
  border-bottom: 1px solid rgba(44, 41, 38, 0.08);
}
.modal-stat {
  flex: 1;
  min-width: 0;
  padding: 4px 18px;
  background: transparent;
  border: 0;
  border-left: 1px solid rgba(44, 41, 38, 0.08);
  border-radius: 0;
  box-shadow: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.modal-stat:first-child { border-left: 0; padding-left: 0; }
.modal-stat:last-child { padding-right: 0; }
.modal-stat-value {
  font-family: var(--mono);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.005em;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  white-space: nowrap;
}
.modal-stat-label {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  color: var(--text-3);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 5-cell variant (airport modal) — tighter padding + slightly smaller
   labels so 5 cells fit inside a 560px modal without clipping. */
.modal-stats-5 .modal-stat { padding: 4px 10px; }
.modal-stats-5 .modal-stat:first-child { padding-left: 0; }
.modal-stats-5 .modal-stat:last-child { padding-right: 0; }
.modal-stats-5 .modal-stat-label { letter-spacing: 0.1em; }
.modal-stats-5 .modal-stat-value { font-size: 18px; }

/* Day-of-week strip inside the flight-detail modal, below the 3 stats. */
.modal-dow {
  padding: 8px 24px 12px;
  flex-shrink: 0;
}
.modal-dow .airline-row-dow {
  margin: 0;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  gap: 12px;
}

.modal-body {
  overflow-y: auto; padding: 4px 16px 24px; flex: 1; overscroll-behavior: contain;
}
.modal-body .airline-list { border: none; box-shadow: none; border-radius: 10px; }
.modal-body .airline-row { padding: 14px 16px; gap: 0 10px; grid-template-columns: 32px 1fr auto; }
.modal-body .row-primary-value { font-size: 18px; }
/* Fix alignment across route rows — lock each metric to a stable width so
   "7m late" and "18m late" sit in the same column regardless of char count.
   Smaller value size than the default 20px so "14m early" stays on one line. */
.modal-body .row-metric { width: 92px; min-width: 92px; flex-shrink: 0; }
.modal-body .row-metric-value { font-size: 16px; white-space: nowrap; }
.modal-body .row-metric-label { white-space: nowrap; }

/* ── Disclaimers ────────────────────────────────────────────────────────── */
.disclaimer {
  display: block;
  text-align: center;
  padding: 20px 16px 8px;
  font-size: 11px;
  font-weight: 400;
  color: #b0a89a;
  letter-spacing: 0.01em;
  line-height: 1.4;
  opacity: 0.8;
}
.disclaimer + .disclaimer { padding-top: 2px; }
.dot-note {
  font-size: 11px;
  color: #b0a89a;
  line-height: 1.4;
  padding: 4px 0 0;
  letter-spacing: 0.01em;
}

/* ── Flight Detail Modal ─────────────────────────────────────────────────── */
.flight-modal .modal-panel { max-width: 620px; }

.flight-list { display: flex; flex-direction: column; gap: 0; }

.flight-date-label {
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-3); padding: 14px 8px 6px; border-bottom: 1px solid var(--border);
}
.flight-date-group:first-child .flight-date-label { padding-top: 4px; }

.flight-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 8px; border-bottom: 1px solid rgba(0,0,0,0.03);
  transition: background 0.15s;
}
.flight-row:last-child { border-bottom: none; }
.flight-row:hover { background: rgba(0,0,0,0.02); }

.flight-num {
  font-family: var(--mono); font-size: 13px; font-weight: 600;
  color: var(--text); min-width: 72px; letter-spacing: -0.01em;
}

.flight-times {
  display: flex; align-items: center; gap: 8px; flex: 1;
}
.flight-time-pair { display: flex; flex-direction: column; align-items: center; gap: 1px; }
.flight-time-label {
  font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-3);
}
.flight-time-value { font-family: var(--mono); font-size: 14px; color: var(--text-2); }
.flight-arrow { color: var(--text-3); font-size: 12px; margin: 6px 2px 0; }

.flight-delay {
  font-family: var(--mono); font-size: 13px; font-weight: 600;
  padding: 3px 10px; border-radius: 20px; white-space: nowrap;
  min-width: 72px; text-align: center;
}
.flight-delay.c-green { background: rgba(58, 154, 92, 0.1); color: var(--green); }
.flight-delay.c-amber { background: rgba(212, 137, 10, 0.1); color: var(--amber); }
.flight-delay.c-red { background: rgba(196, 69, 58, 0.1); color: var(--red); }
.flight-delay.c-muted { background: rgba(0,0,0,0.03); color: var(--text-3); }

/* ── Region Dropdown ────────────────────────────────────────────────────── */

.region-dropdown {
  position: relative;
  display: inline-flex;
}

.region-trigger {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.region-caret {
  font-size: 10px;
  color: var(--text-3);
  transition: transform 0.25s var(--ease-out);
  display: inline-block;
}

.region-menu.open + .region-trigger .region-caret,
.region-dropdown:has(.region-menu.open) .region-caret {
  transform: rotate(180deg);
}

.region-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 180px;
  background: var(--surface);
  border: 1.5px solid rgba(44, 41, 38, 0.1);
  border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.04);
  z-index: 200;
  overflow: hidden;
  /* animation */
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition:
    opacity 0.2s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.region-menu.open {
  opacity: 1;
  transform: translateY(0);
  pointer-events: all;
}

.region-option {
  padding: 9px 16px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-2);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
  user-select: none;
  white-space: nowrap;
}

.region-option:first-child {
  padding-top: 10px;
}

.region-option:last-child {
  padding-bottom: 10px;
}

.region-option:hover {
  background: rgba(44, 41, 38, 0.04);
  color: var(--text);
}

.region-option.active {
  color: var(--text);
  font-weight: 600;
  background: rgba(44, 41, 38, 0.06);
}

.ui-editorial .region-menu {
  background: #fcfaf5;
  border-color: rgba(72, 57, 36, 0.1);
  box-shadow: 0 12px 40px rgba(94, 68, 27, 0.1), 0 2px 8px rgba(0,0,0,0.04);
}

.ui-editorial .region-option:hover {
  background: #f8f2e8;
}

.ui-editorial .region-option.active {
  background: #f3ead6;
}

/* ── Pagination ─────────────────────────────────────────────────────────── */

.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 24px 0 8px;
}

.pagination-pages {
  display: flex;
  align-items: center;
  gap: 2px;
}

.pagination-btn {
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-2);
  background: var(--surface);
  border: 1.5px solid rgba(44, 41, 38, 0.1);
  border-radius: 8px;
  padding: 7px 14px;
  text-decoration: none;
  cursor: pointer;
  transition: all 0.15s ease;
  user-select: none;
}

.pagination-btn:hover:not(.disabled) {
  border-color: var(--text-3);
  color: var(--text);
}

.pagination-btn.disabled {
  opacity: 0.35;
  cursor: default;
}

.pagination-page {
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 400;
  color: var(--text-3);
  background: none;
  border: none;
  border-radius: 8px;
  padding: 7px 11px;
  text-decoration: none;
  cursor: pointer;
  transition: all 0.15s ease;
  min-width: 36px;
  text-align: center;
}

.pagination-page:hover:not(.active) {
  background: rgba(44, 41, 38, 0.04);
  color: var(--text);
}

.pagination-page.active {
  color: var(--surface);
  background: var(--text);
  border-radius: 8px;
  font-weight: 400;
}

.pagination-ellipsis {
  font-size: 13px;
  color: var(--text-3);
  padding: 0 4px;
  user-select: none;
}

/* ── Loading ─────────────────────────────────────────────────────────────── */
.loading {
  display: flex; align-items: center; justify-content: center;
  padding: 80px; color: var(--text-3); font-size: 14px; font-weight: 500;
}
.spinner {
  width: 16px; height: 16px; border: 2px solid var(--border);
  border-top-color: var(--text-3); border-radius: 50%;
  animation: spin 0.6s linear infinite; margin-right: 10px;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ═══════════════════════════════════════════════════════════════════════════ */
/* "WHY?" LINK — fixed top-right, handwritten                                 */
/* ═══════════════════════════════════════════════════════════════════════════ */

.why-link {
  position: fixed;
  top: 20px;
  right: 24px;
  z-index: 100;
  font-family: 'Kalam', cursive;
  font-size: 17px;
  font-weight: 700;
  color: var(--text-2);
  text-decoration: none;
  transition: color 0.25s ease;
}

.why-link:hover {
  color: var(--text);
}

/* Light version when hero is visible */
nav.dark ~ .why-link {
  color: rgba(255, 255, 255, 0.4);
  transition: color 0.6s ease;
}

nav.dark ~ .why-link:hover {
  color: rgba(255, 255, 255, 0.8);
}

:root[data-hero-theme="day"] nav.dark ~ .why-link {
  color: rgba(36, 54, 71, 0.45);
}

:root[data-hero-theme="day"] nav.dark ~ .why-link:hover {
  color: rgba(29, 46, 62, 0.85);
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* WHY PAGE                                                                   */
/* ═══════════════════════════════════════════════════════════════════════════ */

.why-page {
  max-width: 480px;
  margin: 0 auto;
  padding: 120px 24px 80px;
}

.why-title {
  font-size: 38px;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--text);
  margin-bottom: 28px;
}

.why-content p {
  font-size: 16px;
  line-height: 1.7;
  color: var(--text);
  margin-bottom: 18px;
}

.why-content em {
  font-style: italic;
  color: var(--text);
}

.why-content ul {
  list-style: none;
  padding: 0;
  margin: 0 0 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.why-content li {
  font-size: 15px;
  line-height: 1.55;
  color: var(--text);
  padding-left: 18px;
  position: relative;
}

.why-content li::before {
  content: '·';
  position: absolute;
  left: 4px;
  font-weight: 700;
  color: var(--text-3);
}

.why-content strong {
  font-weight: 600;
  color: var(--text);
}

.why-sign-off {
  margin-top: 28px;
  margin-bottom: 0 !important;
  color: var(--text);
}


.ui-atmosphere .compact-bar,
.ui-atmosphere .controls {
  position: relative;
  background: none;
  border: none;
  box-shadow: none;
  backdrop-filter: none;
}

.ui-atmosphere .compact-bar {
  margin-bottom: 28px;
}

.ui-atmosphere .controls.controls-airports {
  width: fit-content;
  max-width: none;
}

.ui-atmosphere .winner-card {
  background:
    radial-gradient(ellipse 120% 90% at 0% 0%, rgba(255, 241, 209, 0.62) 0%, transparent 58%),
    linear-gradient(180deg, #f7efdc 0%, #f3ead6 100%);
  box-shadow:
    0 10px 30px rgba(127, 92, 24, 0.08),
    0 2px 10px rgba(0,0,0,0.04);
}

.ui-atmosphere .airline-list {
  border-color: rgba(44, 41, 38, 0.08);
  box-shadow:
    0 1px 4px rgba(0,0,0,0.03),
    0 12px 32px rgba(103, 78, 38, 0.05);
}

.ui-atmosphere .list-header {
  padding: 0 6px 6px;
}

.ui-atmosphere .list-header-label {
  color: #9e927f;
}

.ui-atmosphere .modal-panel {
  box-shadow:
    0 24px 80px rgba(0,0,0,0.12),
    0 10px 34px rgba(102, 73, 29, 0.08);
}

.ui-atmosphere .modal-header {
  background:
    radial-gradient(ellipse 120% 100% at 12% 0%, rgba(255, 244, 220, 0.8) 0%, transparent 56%),
    linear-gradient(135deg, rgba(232, 229, 223, 0.56) 0%, rgba(244, 241, 235, 0.34) 100%);
}


.ui-atmosphere .disclaimer,
.ui-atmosphere .dot-note {
  color: #a09079;
}

.ui-editorial .compact-bar,
.ui-editorial .controls {
  background: none;
  border: none;
  box-shadow: none;
  backdrop-filter: none;
}

.ui-editorial .compact-bar {
  color: #6d6254;
}

.ui-editorial .winner-card {
  background:
    radial-gradient(ellipse 140% 100% at 0% 0%, rgba(255, 238, 195, 0.52) 0%, transparent 56%),
    linear-gradient(180deg, #f4e9d2 0%, #efdfc0 100%);
  border-color: #373129;
  box-shadow:
    0 2px 0 rgba(255,255,255,0.35) inset,
    0 12px 30px rgba(94, 68, 27, 0.06);
}

.ui-editorial .airline-list {
  background: #fcfaf5;
  border-color: rgba(72, 57, 36, 0.1);
  box-shadow:
    0 2px 0 rgba(255,255,255,0.5) inset,
    0 12px 30px rgba(94, 68, 27, 0.04);
}

.ui-editorial .airline-list::after {
  opacity: 0.04;
}

.ui-editorial .airline-row:hover,
.ui-editorial .airline-row.clickable:hover {
  background: #f8f2e8;
}

.ui-editorial .modal-panel {
  background: #fcfaf5;
  border-color: rgba(72, 57, 36, 0.12);
  box-shadow:
    0 24px 80px rgba(0,0,0,0.12),
    0 14px 34px rgba(90, 64, 24, 0.06);
}

.ui-editorial .modal-header {
  background:
    radial-gradient(ellipse 120% 100% at 10% 0%, rgba(255, 237, 198, 0.7) 0%, transparent 56%),
    linear-gradient(180deg, #f4ebdc 0%, #efe4d3 100%);
}

.ui-editorial .modal-stat {
  background: #fffdf8;
  border-color: rgba(72, 57, 36, 0.1);
}



/* ── Responsive ──────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  nav { top: 8px; }
  .hero-theme-toggle { left: 14px; bottom: 14px; }
  .hero-toggle-btn { padding: 6px 10px; }
  .glow-box { padding: 40px 28px; border-radius: 24px; }
  .airport-input { width: 100px; }
  .airline-row { grid-template-columns: 32px 1fr auto; padding: 14px 16px; gap: 0 10px; }
  .row-primary-value { font-size: 18px; }
  .row-metrics { gap: 10px; padding-left: 12px; }
  .row-metric-value { font-size: 16px; }
  .row-metric { min-width: 48px; }
  .compact-bar { gap: 6px; font-size: 14px; }
  .why-content p { font-size: 15px; }
  .why-content li { font-size: 14px; }
  .ui-atmosphere .compact-bar,
  .ui-atmosphere .controls { border-radius: 16px; }
  .region-menu { min-width: 160px; }
  .region-option { padding: 8px 14px; font-size: 12px; }
  .pagination { gap: 4px; }
  .pagination-btn { font-size: 12px; padding: 6px 10px; }
  .pagination-page { font-size: 12px; padding: 6px 8px; min-width: 30px; }
}



/* ═════════════════════════════════════════════════════════════════════════
 * REPORT CARD — per-flight 30-day stats + Oracle-derived letter grade.
 * Layout follows Rankings: .board-intro (title + subtitle, no kicker) →
 * inputs → always-rendered card with row stats and a flap-animated value
 * column. Picking a flight populates rows via renderFlap(), same helper
 * the rankings board uses.  See DESIGN.md for the canonical patterns.
 * ═════════════════════════════════════════════════════════════════════════ */

.reportcard-page {
  max-width: 620px;
  margin: 0 auto;
  padding: 96px 24px 80px;
}

.rc-form {
  display: flex;
  flex-direction: column;
  gap: 22px;
  margin-top: 8px;
}

.rc-route-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-size: 20px;
}
.rc-route-row .airport-input {
  font-size: 20px;
  width: 108px;
  padding: 8px 12px;
}
.rc-arrow {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text-3);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.rc-field { display: flex; flex-direction: column; gap: 8px; align-items: center; }
.rc-field-label {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-3);
}
.rc-flight-row { display: flex; justify-content: center; }

.rc-card {
  margin-top: 32px;
  background: var(--surface, #fdfaf2);
  border: 1px solid rgba(44, 41, 38, 0.08);
  border-radius: 14px;
  padding: 28px 28px 24px;
  box-shadow:
    0 14px 34px rgba(90, 64, 24, 0.06),
    0 1px 3px rgba(37, 24, 27, 0.04);
}
/* Head: flight identity on the left, large grade glyph on the right. */
.rc-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-bottom: 18px;
  margin-bottom: 18px;
  border-bottom: 1px solid rgba(44, 41, 38, 0.06);
}
.rc-card-flight { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.rc-card-code {
  display: inline-flex;
  align-items: baseline;
  font-family: var(--mono);
  font-size: 26px;
  font-weight: 400;
  letter-spacing: 0.04em;
  color: var(--text);
  min-height: 1em;
}
.rc-card-route {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.005em;
}
.rc-card-meta {
  font-size: 13px;
  color: var(--text-3);
}

.rc-grade {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
}
.rc-grade-letter {
  display: inline-flex;
  align-items: baseline;
  font-family: var(--mono);
  font-size: 64px;
  line-height: 0.92;
  font-weight: 400;
  letter-spacing: -0.02em;
  color: var(--rc-grade-color, var(--text));
  text-shadow: 0 0 0.6px currentColor;
  min-height: 0.9em;
}
.rc-grade-caption {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--text-3);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.rc-caveat {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-3);
  letter-spacing: 0.06em;
  text-align: center;
  padding: 0 0 14px;
}

/* Single-column row list — looks like a real report card.
   Label sits left, value flap-cells right, dotted leader fills the gap. */
.rc-rows {
  display: flex;
  flex-direction: column;
  margin-bottom: 22px;
  --mono: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-feature-settings: 'tnum', 'ss01';
}
.rc-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 13px 0;
  border-bottom: 1px dashed rgba(44, 41, 38, 0.10);
}
.rc-row:last-child { border-bottom: none; }
.rc-row-label {
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  letter-spacing: -0.005em;
  flex: 0 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rc-row-leader {
  flex: 1 1 auto;
  border-bottom: 1px dotted rgba(44, 41, 38, 0.18);
  align-self: flex-end;
  margin-bottom: 5px;
  min-width: 12px;
}
.rc-row-value {
  display: inline-flex;
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--text);
  font-feature-settings: 'tnum', 'ss01';
}
/* Flap cells inside .rc-row-value inherit color from cc()/rcOnTimeClass()
   classes set on the container. */
.rc-row-value.c-green { color: var(--green); }
.rc-row-value.c-amber { color: var(--amber); }
.rc-row-value.c-red   { color: var(--red); }
.rc-row-value.c-muted { color: var(--text-3); }
/* Strip the paper-tile chrome from all report-card flap cells — we want
   clean text, not the rankings board's flap-tile look. Selectors include
   `.landed` to beat .board-flap-cell.landed's specificity, so colour set
   on the container (c-green/c-amber/c-red, --rc-grade-color) wins. */
.rc-row-value .flap-cell,
.rc-row-value .flap-cell.landed,
.rc-card-code .flap-cell,
.rc-card-code .flap-cell.landed,
.rc-grade-letter .flap-cell,
.rc-grade-letter .flap-cell.landed {
  /* Override base .flap-cell flex centering — for plain text we want each
     cell to sit on the same text baseline, not center its content as a
     flex container (which makes letters and digits render at different
     vertical positions because their box metrics differ). */
  display: inline-block;
  text-align: center;
  vertical-align: baseline;
  width: auto;
  min-width: 0.62em;
  height: auto;
  padding: 0 1px;
  background: transparent;
  border: none;
  box-shadow: none;
  border-radius: 0;
  font-size: inherit;
  font-weight: inherit;
  line-height: 1.2;
  color: inherit;
}
/* Hide the rankings-board hairline split — looks wrong on flat text. */
.rc-row-value .flap-cell::after,
.rc-card-code .flap-cell::after,
.rc-grade-letter .flap-cell::after {
  display: none;
}

.rc-expand-btn {
  display: block;
  margin: 0 auto;
  padding: 9px 20px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text);
  background: transparent;
  border: 1px solid rgba(44, 41, 38, 0.15);
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;
}
.rc-expand-btn:hover:not(:disabled) {
  background: rgba(44, 41, 38, 0.04);
  border-color: rgba(44, 41, 38, 0.25);
}
.rc-expand-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.rc-source {
  margin-top: 28px;
  font-size: 12px;
  color: var(--text-3);
  text-align: center;
  line-height: 1.55;
}
.rc-source em { font-style: italic; }

@media (max-width: 640px) {
  .reportcard-page { padding: 72px 16px 64px; }
  .rc-route-row { font-size: 18px; }
  .rc-route-row .airport-input { font-size: 18px; width: 92px; }
  .rc-card { padding: 22px 18px 18px; border-radius: 12px; }
  .rc-card-head { gap: 14px; }
  .rc-card-code { font-size: 22px; }
  .rc-grade-letter { font-size: 52px; }
  .rc-row { padding: 11px 0; }
  .rc-row-label { font-size: 13px; }
  .rc-row-value { font-size: 15px; }
}

/* ═════════════════════════════════════════════════════════════════════════
 * THE ORACLE — flight delay oracle in the form of a Magic 8-Ball.
 * Layout is intentionally minimal: a single headline, the inputs woven into
 * one prose sentence (with inline tokens that open popovers), the 8-ball
 * itself as the focus (clickable when ready — it IS the consult button),
 * a red→green sliding scale beneath, and a single sentence that fades in
 * once the verdict has landed.
 * ═════════════════════════════════════════════════════════════════════════ */

.oracle-page {
  max-width: 720px;
  margin: 0 auto;
  padding: 80px 24px 80px;
}

.oracle-headline {
  font-size: 38px;
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.15;
  text-align: center;
  margin: 0 0 24px;
  color: var(--text);
  text-wrap: balance;
}

/* Subhead under the oracle headline. .board-subtitle is left-aligned by
   default (since the rankings/reportcard pages use left-aligned headers);
   the oracle page is centered, so re-center it here. */
.oracle-page .board-subtitle { text-align: center; }

/* The whole form lives inside one sentence. Three editable tokens —
   airport, airline, time — use a single .oracle-token treatment so they
   render at identical height/baseline. Only the background color and a
   couple of details (input width, button hover) differ between them. */
.oracle-prompt {
  font-family: inherit;
  font-size: 22px;
  font-weight: 400;
  line-height: 1.85;
  color: var(--text);
  text-align: center;
  margin: 0 auto;
  max-width: 640px;
  text-wrap: balance;
}

.oracle-pop-wrap {
  position: relative;
  display: inline-block;
  vertical-align: baseline;
}

/* The single source of truth for token styling. Applied to <input>s
   (airport) and <button>s (airline, time) alike — same display, same
   line-height, same padding, same baseline. */
.oracle-token {
  display: inline-block;
  vertical-align: baseline;
  font-family: inherit;
  font-size: inherit;
  font-weight: 500;
  font-style: normal;
  line-height: 1.3;
  letter-spacing: 0;
  color: var(--text);
  background: var(--token-bg, rgba(0, 0, 0, 0.06));
  border: none;
  outline: none;
  padding: 1px 10px 2px;
  margin: 0 2px;
  border-radius: 6px;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  text-transform: none;
  -webkit-appearance: none;
  appearance: none;
  transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.oracle-token:hover {
  background: var(--token-hover-bg, var(--token-bg));
  transform: translateY(-1px);
  box-shadow: 0 3px 8px rgba(44, 41, 38, 0.08);
}
.oracle-token:focus-visible {
  outline: 2px solid var(--hero-accent, #e85d2a);
  outline-offset: 3px;
  box-shadow: none;
}
/* Default ("an airline" / "at any time") rendered like a placeholder. */
.oracle-token.is-empty {
  color: rgba(44, 41, 38, 0.5);
}

/* Airport — soft cyan; sized for 3-char codes; behaves as a text field. */
.oracle-token.is-airport {
  --token-bg: rgba(118, 180, 225, 0.36);
  --token-hover-bg: rgba(118, 180, 225, 0.5);
  width: 3.4em;
  text-transform: uppercase;
  cursor: text;
}
.oracle-token.is-airport::placeholder {
  color: rgba(44, 41, 38, 0.5);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: uppercase;
}
.oracle-token.is-airport:focus {
  --token-bg: rgba(118, 180, 225, 0.55);
  box-shadow: 0 0 0 2px rgba(118, 180, 225, 0.6);
}
/* Invalid code: red wash + red text. Cleared on focus / typing. */
.oracle-token.is-airport.is-error {
  --token-bg: rgba(196, 69, 58, 0.18);
  color: var(--red, #c4453a);
  box-shadow: 0 0 0 1.5px rgba(196, 69, 58, 0.4);
}

/* Airline — warm amber. */
.oracle-token.is-airline {
  --token-bg: rgba(255, 188, 110, 0.45);
  --token-hover-bg: rgba(255, 188, 110, 0.65);
}
.oracle-token.is-airline[aria-expanded="true"] {
  background: rgba(255, 188, 110, 0.65);
}

/* Time-of-day — soft rose / lavender. */
.oracle-token.is-tod {
  --token-bg: rgba(196, 156, 210, 0.45);
  --token-hover-bg: rgba(196, 156, 210, 0.65);
}
.oracle-token.is-tod[aria-expanded="true"] {
  background: rgba(196, 156, 210, 0.65);
}

/* Flight number — pale teal. */
.oracle-token.is-flight {
  --token-bg: rgba(132, 205, 196, 0.45);
  --token-hover-bg: rgba(132, 205, 196, 0.65);
  font-family: var(--mono);
  letter-spacing: 0.04em;
}
.oracle-token.is-flight[aria-expanded="true"] {
  background: rgba(132, 205, 196, 0.65);
}
.oracle-token.is-flight.is-empty {
  font-family: inherit;
  letter-spacing: normal;
}

/* Tails are wrappers; their children participate directly in the
   prompt's flow (prose on desktop, flex column on mobile). */
.oracle-prompt-tail { display: contents; }

/* Show only the active prompt tail. Defaults to flight mode. */
.oracle-prompt[data-mode="flight"] .oracle-prompt-tail[data-tail="manual"],
.oracle-prompt[data-mode="manual"] .oracle-prompt-tail[data-tail="flight"] {
  display: none;
}

/* "Don't know your flight number?" toggle — small text-button under prompt. */
.oracle-mode-toggle {
  display: block;
  margin: 14px auto 0;
  background: transparent;
  border: none;
  padding: 4px 8px;
  font: inherit;
  font-size: 13px;
  color: var(--text-2);
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 3px;
  cursor: pointer;
}
.oracle-mode-toggle:hover {
  color: var(--text);
  text-decoration-style: solid;
}
.oracle-mode-toggle:focus-visible {
  outline: 2px solid var(--accent, #e85d2a);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Error message under the prompt. */
.oracle-error {
  margin: 14px auto 0;
  max-width: 480px;
  font-size: 14px;
  color: var(--red, #c4453a);
  text-align: center;
  font-family: var(--mono);
  letter-spacing: 0.04em;
}
.oracle-error[hidden] { display: none !important; }

/* Popover */
.oracle-pop-wrap {
  position: relative;
  display: inline-block;
}
.oracle-popover {
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  min-width: 220px;
  max-width: 280px;
  max-height: 320px;
  overflow-y: auto;
  background: var(--surface);
  border: 1.5px solid rgba(44, 41, 38, 0.12);
  border-radius: 14px;
  box-shadow:
    0 14px 40px rgba(44, 41, 38, 0.16),
    0 2px 6px rgba(44, 41, 38, 0.06);
  padding: 6px;
  z-index: 50;
  text-align: left;
  font-size: 14px;
  line-height: 1.4;
  /* Override the parent .oracle-prompt font-size cascade. */
}
.oracle-popover[hidden] { display: none !important; }
.oracle-popover-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  padding: 8px 10px;
  font: inherit;
  color: var(--text);
  background: transparent;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  text-align: left;
  text-decoration: none;
  transition: background 0.12s ease;
}
.oracle-popover-item:hover,
.oracle-popover-item.kbd-highlighted { background: rgba(44, 41, 38, 0.1); }
.oracle-popover-item.active { background: var(--text); color: var(--surface); }
.oracle-popover-item.active .oracle-popover-name { color: rgba(255,255,255,0.7); }
.oracle-popover-item.active.kbd-highlighted { background: var(--text); box-shadow: 0 0 0 2px rgba(232, 93, 42, 0.5) inset; }

/* Airline color coding — left swatch + tinted flight code. Stable per
   airline IATA via airlineColor() in app.js. */
.oracle-popover-item.has-airline-color {
  position: relative;
  padding-left: 16px;
}
.oracle-popover-item.has-airline-color::before {
  content: "";
  position: absolute;
  left: 6px;
  top: 8px;
  bottom: 8px;
  width: 4px;
  border-radius: 2px;
  background: var(--airline-color, var(--text-3));
}
.oracle-popover-item.has-airline-color .oracle-popover-code {
  color: var(--airline-color, var(--text));
}
.oracle-popover-item.has-airline-color:hover,
.oracle-popover-item.has-airline-color.kbd-highlighted {
  background: var(--airline-color-soft, rgba(44, 41, 38, 0.1));
}
.oracle-popover-item.has-airline-color.active {
  background: var(--airline-color, var(--text));
  color: var(--surface);
}
.oracle-popover-item.has-airline-color.active .oracle-popover-code {
  color: var(--surface);
}
.oracle-popover-item.has-airline-color.active::before {
  background: var(--surface);
}
.oracle-popover-code {
  font-family: var(--mono);
  font-weight: 600;
  letter-spacing: 0.04em;
  font-size: 13px;
}
.oracle-popover-name {
  font-size: 13px;
  color: var(--text-2);
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.oracle-popover-hint {
  padding: 10px 12px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--text-3);
  text-align: center;
}

/* The hint that lives just under the orb, doubling as the call-to-action. */
.oracle-hint {
  margin: 14px auto 0;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
  text-align: center;
  transition: color 0.18s ease;
}
.oracle-hint[hidden] { display: none !important; }
.oracle-hint.is-ready {
  color: var(--text);
  font-size: 16px;
  letter-spacing: 0.18em;
  font-weight: 600;
  margin-top: 18px;
  animation: hint-breathe 2.4s ease-in-out infinite;
}
@keyframes hint-breathe {
  0%, 100% { opacity: 1; transform: translateY(0); }
  50%      { opacity: 0.6; transform: translateY(-1px); }
}

/* ── The 8-ball ────────────────────────────────────────────────────────── */

.oracle-eightball {
  position: relative;
  width: 320px;
  height: 320px;
  margin: 28px auto 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Click target: only when ready. */
  cursor: default;
  outline: none;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.25s var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.oracle-eightball[data-ready="true"] {
  cursor: pointer;
  /* Gentle bob — invitation to tap. */
  animation: eightball-bob 3.4s ease-in-out infinite;
}
.oracle-eightball[data-ready="true"]:hover {
  transform: translateY(-3px) scale(1.02);
  animation-play-state: paused;
}
.oracle-eightball[data-state="shaking"],
.oracle-eightball[data-state="verdict"] {
  animation: none;
}
.oracle-eightball:focus-visible { outline: none; }
.oracle-eightball:focus-visible .oracle-eightball-sphere {
  outline: 2px solid rgba(44, 41, 38, 0.4);
  outline-offset: 3px;
}

@keyframes eightball-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-4px); }
}

.oracle-eightball-sphere {
  position: relative;
  width: 280px;
  height: 280px;
  border-radius: 50%;
  /* Classic glossy black billiard sphere: highlight up-top-left, deep core,
     subtle equatorial darkening at the bottom. */
  background:
    radial-gradient(circle at 32% 26%, #6a6a6a 0%, #1a1a1a 28%, #050505 70%, #000 100%);
  box-shadow:
    inset 0 -28px 48px rgba(0, 0, 0, 0.85),
    inset 0 18px 28px rgba(255, 255, 255, 0.06),
    inset 0 0 0 1px rgba(255, 255, 255, 0.02),
    0 24px 40px rgba(0, 0, 0, 0.35),
    0 6px 14px rgba(0, 0, 0, 0.18);
}

/* Cast shadow under the ball — a sibling of the sphere (not a child) so
   the shake animation doesn't drag the shadow with it. The shadow stays
   put while the sphere bounces around above it. */
.oracle-eightball-shadow {
  position: absolute;
  bottom: 8px;
  left: 50%;
  transform: translateX(-50%);
  width: 62%;
  height: 22px;
  border-radius: 50%;
  background: radial-gradient(ellipse 100% 100% at 50% 50%, rgba(0, 0, 0, 0.32), transparent 70%);
  filter: blur(3px);
  pointer-events: none;
  z-index: 0;
}

/* Bright glossy highlight on the sphere's top-left. */
.oracle-eightball-highlight {
  position: absolute;
  top: 11%;
  left: 17%;
  width: 36%;
  height: 22%;
  border-radius: 50%;
  background:
    radial-gradient(ellipse 60% 80% at 50% 40%, rgba(255, 255, 255, 0.65) 0%, rgba(255, 255, 255, 0.18) 45%, rgba(255, 255, 255, 0) 75%);
  filter: blur(0.5px);
  pointer-events: none;
}

/* The classic white inner circle holding the icon (idle) or verdict (after).
   Background morphs from white → grainy cream once the verdict lands. */
.oracle-eightball-circle {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 38%;
  height: 38%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: #fbfaf4;
  box-shadow:
    inset 0 1px 2px rgba(0, 0, 0, 0.18),
    inset 0 -1px 2px rgba(0, 0, 0, 0.06),
    0 0 0 0.5px rgba(0, 0, 0, 0.18);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  transition: background 0.45s ease;
}

/* Cream + grain texture once the oracle has spoken — matches the rest of
   the site's body bg, so the verdict feels written on the page itself. */
.oracle-eightball[data-state="verdict"] .oracle-eightball-circle,
.oracle-eightball[data-state="error"]   .oracle-eightball-circle {
  background:
    var(--grain-url) 0 0 / 220px 220px,
    linear-gradient(180deg, #f4ead4 0%, #ecdfc1 100%);
}

/* The airplane glyph in the center — the only thing that visibly changes
   from a stock 8-ball. Dark indigo for that crisp ink-on-ivory feel.
   Dimmed when the form isn't filled out yet (the oracle is "asleep"); it
   wakes to full opacity once a route + airline are picked. */
.oracle-eightball-icon {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #0e0f1e;
  opacity: 0.5;
  transition: opacity 0.5s ease;
  pointer-events: none;
}
.oracle-eightball-icon svg {
  width: 56%;
  height: 56%;
  transform: rotate(-12deg);
}
/* Wake up to full strength once the form is ready to consult. */
.oracle-eightball[data-ready="true"][data-state="idle"] .oracle-eightball-icon {
  opacity: 1;
}
/* Idle wing wiggle — every ~7s the airplane gives a small ±4° rock so the
   sphere reads as alive, not pasted. Only when ready and idle. */
.oracle-eightball[data-ready="true"][data-state="idle"] .oracle-eightball-icon {
  animation: plane-wiggle 7s ease-in-out infinite;
}
@keyframes plane-wiggle {
  0%, 92%, 100% { transform: rotate(0deg); }
  94%           { transform: rotate(-4deg); }
  97%           { transform: rotate(4deg); }
}
.oracle-eightball[data-state="verdict"] .oracle-eightball-icon,
.oracle-eightball[data-state="error"]   .oracle-eightball-icon {
  opacity: 0;
}

/* The verdict text — replaces the icon when the oracle has spoken. */
.oracle-eightball-verdict {
  position: relative;
  z-index: 2;
  padding: 0 8px;
  font-family: 'Kalam', cursive;
  font-weight: 700;
  font-size: 15px;
  line-height: 1.18;
  color: #2c2926;
  text-align: center;
  text-wrap: balance;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.45s ease 0.1s, transform 0.45s ease 0.1s;
}
.oracle-eightball[data-state="verdict"] .oracle-eightball-verdict {
  opacity: 1;
  transform: none;
}
.oracle-eightball[data-state="error"] .oracle-eightball-verdict {
  opacity: 1;
  transform: none;
  font-family: var(--mono);
  font-weight: 400;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: #b85c5c;
}

/* Consult: the airplane glyph spins in place — ease-in-out so it ramps up
   to dizzying mid-rotation speed and settles cleanly. 5 full turns over
   1.5s ≈ 3.3 rps average, ~6 rps at peak. Fast enough to blur slightly,
   slow enough at start/end to read as a single rotation. The sphere
   itself stays still — no shake. */
.oracle-eightball[data-state="shaking"] .oracle-eightball-icon {
  animation: plane-spin 1.5s ease-in-out forwards;
}

@keyframes plane-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(1800deg); }
}

/* ── The risk scale (sliding gradient + arrow marker) ──────────────────── */

.oracle-scale {
  position: relative;
  margin: 36px auto 0;
  max-width: 460px;
  padding: 14px 0 0;
}
.oracle-scale-track {
  height: 8px;
  border-radius: 999px;
  background:
    linear-gradient(to right,
      hsl(140, 65%, 40%) 0%,
      hsl(70,  73%, 38%) 50%,
      hsl(0,   81%, 38%) 100%);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.16);
}
/* Downward-pointing triangle marker that sits just above the track. */
.oracle-scale-marker {
  position: absolute;
  top: 0;
  left: 50%;
  width: 0;
  height: 0;
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  border-top: 12px solid var(--text);
  transform: translateX(-50%);
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.22));
  opacity: 0;
  transition: opacity 0.2s ease;
  pointer-events: none;
}
.oracle-scale[data-state="jittering"] .oracle-scale-marker {
  opacity: 1;
  /* Slightly under the JS tick (400ms) so the marker eases into each
     target and rests for a beat — reads as a searching needle. */
  transition: left 380ms cubic-bezier(0.45, 0, 0.55, 1), opacity 0.2s ease;
}
.oracle-scale[data-state="landed"] .oracle-scale-marker {
  opacity: 1;
  border-top-color: var(--marker-color, var(--text));
  transition: left 0.55s cubic-bezier(0.2, 0.7, 0.25, 1),
              border-top-color 0.4s ease;
}
.oracle-scale-axis {
  display: flex;
  justify-content: space-between;
  margin: 10px 4px 0;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
}

/* ── Source / methodology line ─────────────────────────────────────────── */

.oracle-source {
  margin: 18px auto 0;
  max-width: 460px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-2);
  text-align: center;
  text-wrap: balance;
}
.oracle-source em {
  font-style: italic;
  color: var(--text);
}

/* ── The single fade-in sentence ───────────────────────────────────────── */

.oracle-sentence {
  margin: 22px auto 0;
  max-width: 460px;
  font-size: 17px;
  line-height: 1.5;
  color: var(--text);
  text-align: center;
  text-wrap: balance;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.oracle-sentence[hidden] { display: none !important; }
.oracle-sentence.visible { opacity: 1; transform: none; }
.oracle-sentence strong {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 640px) {
  .oracle-page { padding: 56px 16px 64px; }
  .oracle-headline { margin-bottom: 18px; }
  .oracle-prompt { font-size: 18px; line-height: 1.5; }
  .oracle-token.is-airport { width: 3.2em; }
  .oracle-eightball { width: 264px; height: 264px; margin-top: 24px; }
  .oracle-eightball-sphere { width: 230px; height: 230px; }
  .oracle-eightball-verdict { font-size: 13px; padding: 0 6px; }
  .oracle-sentence { font-size: 15px; }
  .oracle-popover { min-width: 200px; max-width: 240px; }
}

/* ═════════════════════════════════════════════════════════════════════════
 * EXPLORE (map-first route browser)
 * Layout: full-bleed map on the left with a floating ticker input + legend,
 * airline-rankings panel on the right. Reuses .winner-card and .airline-row
 * from the Routes page — panel-scoped overrides below keep them tight.
 * ═════════════════════════════════════════════════════════════════════════ */

.explore-root {
  display: block;
  position: relative;
  height: calc(100vh - 72px);
  min-height: 560px;
  margin-top: 72px;
  border-top: 1px solid var(--border);
}

.explore-map-wrap {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #e8ecf2;
}

/* Panel overlays the map and slides in from the right when origin or
 * route is selected. Default state shows the hub overlay on the map. */
.explore-panel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: clamp(340px, 32vw, 440px);
  transform: translateX(100%);
  transition: transform 320ms cubic-bezier(0.16, 1, 0.3, 1);
  z-index: 15;
  box-shadow: -10px 0 32px rgba(12, 12, 24, 0.10);
}
.explore-panel.is-open { transform: translateX(0); }
.explore-panel-close {
  position: absolute;
  top: 24px;
  right: 14px;
  z-index: 2;
  width: 28px;
  height: 28px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-2);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 160ms ease, color 160ms ease, transform 160ms ease;
}
.explore-panel-close:hover {
  background: var(--bg);
  color: var(--text);
  transform: scale(1.05);
}

/* MapLibre's own stylesheet loads AFTER ours and forces
 * `.maplibregl-map { position: relative }` onto this element, which nukes
 * position: absolute + inset. Use width/height directly so the sizing
 * survives MapLibre's CSS override. */
.map-canvas {
  width: 100%;
  height: 100%;
}
.map-canvas .maplibregl-canvas { outline: none !important; }
/* Attribution is required by OSM/Carto — keep it present but subtle. */
.map-canvas .maplibregl-ctrl-bottom-right {
  bottom: 6px;
  right: 6px;
}
.map-canvas .maplibregl-ctrl-attrib {
  background: rgba(253, 252, 249, 0.72);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-size: 10px;
  line-height: 1.4;
  padding: 2px 7px;
  border-radius: 8px;
  color: var(--text-2);
}
.map-canvas .maplibregl-ctrl-attrib a { color: var(--text-2); }
.map-canvas .maplibregl-ctrl-attrib.maplibregl-compact-show {
  background: rgba(253, 252, 249, 0.95);
}
.map-canvas .maplibregl-ctrl-logo { display: none !important; }

/* Hub overlay — small card on the map when no origin is picked, with
 * tabbed top-5 lists (Busiest / Most on time / Most delayed). */
.explore-hub-overlay {
  position: absolute;
  top: 96px;
  left: 20px;
  z-index: 9;
  width: 280px;
  background: rgba(253, 252, 249, 0.92);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 4px 24px rgba(12, 12, 24, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
  padding: 12px 12px 10px;
  opacity: 1;
  transform: translateX(0);
  transition: opacity 250ms ease, transform 250ms var(--ease-out);
}
.explore-hub-overlay.is-hidden {
  opacity: 0;
  transform: translateX(-12px);
  pointer-events: none;
}
.hub-overlay-title {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
  margin: 0 2px 8px;
}
.hub-tabs {
  display: flex;
  gap: 2px;
  padding: 3px;
  background: rgba(44, 41, 38, 0.06);
  border-radius: 8px;
  margin-bottom: 8px;
}
.hub-tab {
  flex: 1;
  font-size: 11px;
  font-weight: 500;
  padding: 5px 4px;
  text-align: center;
  border-radius: 6px;
  cursor: pointer;
  color: var(--text-2);
  background: transparent;
  border: 0;
  font-family: inherit;
  transition: background 160ms ease, color 160ms ease;
}
.hub-tab:hover { color: var(--text); }
.hub-tab.is-active {
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.hub-overlay-loading {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 16px 0 10px;
}
.hub-overlay-empty {
  font-size: 12px;
  color: var(--text-2);
  padding: 10px 2px 6px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.hub-retry {
  align-self: flex-start;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  cursor: pointer;
  font-family: inherit;
}
.hub-retry:hover { background: var(--bg); }
.hub-overlay-list { display: flex; flex-direction: column; gap: 1px; }
.hub-overlay-list .hub-row { padding: 6px 8px; border-radius: 8px; grid-template-columns: 42px 1fr auto; gap: 8px; }
.hub-overlay-list .hub-row-code { font-size: 12px; }
.hub-overlay-list .hub-row-name { font-size: 12.5px; }
.hub-overlay-list .hub-row-sub { font-size: 10.5px; }
.hub-overlay-list .hub-row-right { font-size: 11px; }

/* Frosted-glass tooltip for airport/destination hover. Positioned via
 * transform (JS sets x/y) so it doesn't interfere with MapLibre events. */
.explore-tooltip {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 12;
  opacity: 0;
  transition: opacity 120ms ease;
  min-width: 140px;
  max-width: 240px;
  padding: 10px 12px 10px;
  border-radius: 12px;
  background: rgba(253, 252, 249, 0.92);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  border: 1px solid var(--border);
  box-shadow: 0 8px 28px rgba(12, 12, 24, 0.10), 0 1px 2px rgba(0, 0, 0, 0.04);
  color: var(--text);
  will-change: transform, opacity;
}
.explore-tooltip-code {
  font-family: var(--mono);
  font-size: 14px;
  letter-spacing: 0.08em;
  line-height: 1;
  color: var(--text);
}
.explore-tooltip-city {
  font-size: 13px;
  line-height: 1.25;
  color: var(--text);
  margin-top: 3px;
  font-weight: 500;
}
.explore-tooltip-meta {
  font-size: 11px;
  color: var(--text-2);
  margin-top: 2px;
  letter-spacing: 0.01em;
}
.explore-tooltip-stats {
  margin-top: 6px;
  font-size: 11.5px;
  color: var(--text-2);
  letter-spacing: 0.005em;
}
.explore-tooltip-stats .c-green { color: var(--green); font-weight: 500; }
.explore-tooltip-stats .c-amber { color: var(--amber); font-weight: 500; }
.explore-tooltip-stats .c-red   { color: var(--red);   font-weight: 500; }

/* Floating dual-input picker above the map, sentence-style to match the
 * homepage glow-box — frosted pill that stays legible over any basemap. */
.explore-ticker {
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  background: rgba(253, 252, 249, 0.86);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 12px 22px;
  box-shadow: 0 4px 24px rgba(12, 12, 24, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  max-width: calc(100% - 40px);
  transition: opacity 200ms ease;
}
.explore-ticker.is-dim { opacity: 0.5; }
.explore-ticker.is-dim:hover,
.explore-ticker:focus-within { opacity: 1; }

.explore-ticker-sentence {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--text);
}

.explore-ticker-label {
  color: var(--text-2);
  font-weight: 400;
}

.explore-ticker .airport-input {
  font-family: var(--mono);
  font-size: 18px;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-align: center;
  padding: 4px 6px;
  width: 70px;
  border: none;
  border-bottom: 1.5px solid var(--text-3);
  background: transparent;
  color: var(--text);
  border-radius: 0;
  outline: none;
  transition: border-color 0.15s ease;
}
.explore-ticker .airport-input::placeholder { color: var(--text-3); letter-spacing: 0.08em; }
.explore-ticker .airport-input:focus { border-bottom-color: var(--hero-accent, #e85d2a); }


/* Legend anchored bottom-left of the map, explaining the arc colors. */
.explore-legend {
  position: absolute;
  left: 20px;
  bottom: 20px;
  z-index: 9;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  background: rgba(253, 252, 249, 0.86);
  backdrop-filter: blur(12px) saturate(150%);
  -webkit-backdrop-filter: blur(12px) saturate(150%);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 12px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--text-2);
  max-width: calc(100% - 40px);
}
.explore-legend .legend-title {
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 10px;
  color: var(--text-3);
  margin-right: 2px;
}
.explore-legend .legend-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}
.explore-legend .legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  display: inline-block;
}
.explore-legend .legend-green .legend-dot { background: var(--green); }
.explore-legend .legend-amber .legend-dot { background: var(--amber); }
.explore-legend .legend-red .legend-dot { background: var(--red); }
.explore-legend .legend-none .legend-dot { background: rgba(60,63,107,0.55); }

/* Right panel — airline rankings. Uses shared .winner-card / .airline-row but
 * with tightened proportions so it reads well in a ~400px column.
 * Scoped font override: --mono resolves to Inter inside the panel so codes
 * + kickers feel cohesive with the Board and the modals. The Explore input
 * (.explore-ticker) is outside this scope, so its flap animation keeps the
 * site-wide Share Tech Mono. */
.explore-panel {
  --mono: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--surface);
  border-left: 1px solid var(--border);
  overflow-y: auto;
  padding: 24px 20px 40px;
  font-feature-settings: 'tnum', 'ss01';
}

.explore-panel-header {
  margin-bottom: 14px;
}

.results-meta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.explore-panel-kicker {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 4px;
}

.explore-panel-title {
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 10px;
}
.explore-panel-title .code {
  font-family: var(--mono);
  font-size: 26px;
  letter-spacing: 0.04em;
}
.explore-arrow { color: var(--text-3); font-weight: 300; }

.explore-panel-sub {
  font-size: 13px;
  color: var(--text-2);
  margin-top: 4px;
}
.explore-panel-sub-city {
  font-size: 12px;
  color: var(--text-3);
  letter-spacing: 0.02em;
}

.explore-back {
  display: inline-block;
  font-size: 12px;
  color: var(--text-2);
  text-decoration: none;
  margin-bottom: 8px;
  padding: 4px 0;
  letter-spacing: 0.02em;
  cursor: pointer;
}
.explore-back:hover { color: var(--text); }

.explore-back[data-back-conn] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  font-size: 18px;
  line-height: 1;
  margin: 0;
  padding: 0;
  letter-spacing: 0;
  border-radius: 999px;
  flex-shrink: 0;
}
.explore-back[data-back-conn]:hover {
  background: var(--bg-2, rgba(0,0,0,0.04));
}

.hub-row {
  display: grid;
  grid-template-columns: 44px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 8px 8px;
  border-radius: 10px;
  cursor: pointer;
  transition: background 160ms ease, transform 160ms var(--ease-out);
}
.hub-row:hover {
  background: rgba(44, 41, 38, 0.04);
  transform: translateX(2px);
}
.hub-row-code {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.08em;
  color: var(--text);
}
.hub-row-name { font-size: 13px; font-weight: 500; color: var(--text); line-height: 1.2; }
.hub-row-sub { font-size: 11px; color: var(--text-3); margin-top: 1px; }
.hub-row-right { font-size: 12px; color: var(--text-2); text-align: right; }

/* Segmented sort toggle above the destinations list. Frosted track, soft
 * surface pill that slides underneath the active button (JS positions
 * the pill via transform so it animates cleanly on change). */
/* Sort + random row: keeps the sort toggle aligned with the random
 * button, so the right column shows "Random" right of "Most on time". */
.sort-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 10px 0 14px;
}
.sort-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 3px;
  background: rgba(44, 41, 38, 0.06);
  border-radius: 999px;
  isolation: isolate;
}
.random-dest-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid color-mix(in srgb, #f3b91f 60%, var(--text) 40%);
  border-radius: 999px;
  background: linear-gradient(180deg, #f7cf4d 0%, #f3b91f 100%);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--text);
  cursor: pointer;
  box-shadow: 0 1px 0 rgba(255,255,255,0.45) inset, 0 1px 2px rgba(180, 120, 0, 0.18);
  transition: background 160ms ease, border-color 160ms ease, transform 120ms ease, box-shadow 160ms ease;
  white-space: nowrap;
}
.random-dest-btn:hover {
  background: linear-gradient(180deg, #ffd95a 0%, #f5bf26 100%);
  box-shadow: 0 1px 0 rgba(255,255,255,0.55) inset, 0 2px 6px rgba(180, 120, 0, 0.28);
}
.random-dest-btn:active { transform: translateY(1px); }
.random-dest-btn:focus-visible {
  outline: 2px solid color-mix(in srgb, #f3b91f 70%, var(--text) 30%);
  outline-offset: 2px;
}
.random-dest-icon {
  font-size: 14px;
  line-height: 1;
  display: inline-block;
  transform-origin: 50% 55%;
}
.random-dest-btn.is-rolling .random-dest-icon {
  animation: random-roll 420ms cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes random-roll {
  0%   { transform: rotate(0deg) scale(1); }
  50%  { transform: rotate(220deg) scale(1.25); }
  100% { transform: rotate(360deg) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .random-dest-btn.is-rolling .random-dest-icon { animation: none; }
}
.sort-toggle-btn {
  position: relative;
  z-index: 1;
  border: 0;
  background: transparent;
  padding: 6px 14px;
  font: inherit;
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--text-2);
  cursor: pointer;
  border-radius: 999px;
  transition: color 200ms ease;
  white-space: nowrap;
}
.sort-toggle-btn:hover { color: var(--text); }
.sort-toggle-btn.is-active {
  color: var(--text);
  font-weight: 600;
}
.sort-toggle-btn:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--text) 25%, transparent);
  outline-offset: 2px;
}
.sort-toggle-pill {
  position: absolute;
  top: 3px;
  bottom: 3px;
  left: 0;
  width: 0;
  background: var(--surface);
  border-radius: 999px;
  box-shadow:
    0 1px 2px rgba(12, 12, 24, 0.06),
    0 0 0 1px rgba(44, 41, 38, 0.04);
  transform: translateX(0);
  transition:
    transform 300ms cubic-bezier(0.16, 1, 0.3, 1),
    width 300ms cubic-bezier(0.16, 1, 0.3, 1);
  z-index: 0;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .sort-toggle-pill { transition-duration: 0ms; }
}

.explore-dest-list { display: flex; flex-direction: column; gap: 2px; }

.dest-row {
  display: grid;
  grid-template-columns: 48px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 10px 10px;
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.15s var(--ease-out);
}
.dest-row:hover { background: rgba(0, 0, 0, 0.025); }
.dest-row-code {
  font-family: var(--mono); font-size: 14px; letter-spacing: 0.05em; color: var(--text);
}
.dest-row-city { font-size: 14px; font-weight: 500; color: var(--text); }
.dest-row-sub {
  font-size: 11px; color: var(--text-3); margin-top: 2px; letter-spacing: 0.01em;
}
.dest-row-metric {
  font-family: var(--mono); font-size: 13px; letter-spacing: 0.04em;
}

.explore-route-body { margin-top: 4px; }

/* Panel-scoped overrides for the shared ranking cards */
.explore-panel .results-header {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 12px; padding: 0 4px;
}
.explore-panel .results-route {
  font-size: 20px; font-weight: 600; letter-spacing: -0.01em;
}
.explore-panel .results-route .code {
  font-family: var(--mono); font-size: 20px; letter-spacing: 0.04em;
}
.explore-panel .results-route .arrow { color: var(--text-3); font-weight: 300; }
.explore-panel .results-count {
  font-size: 11px; color: var(--text-3); letter-spacing: 0.06em; text-transform: uppercase;
}

/* Cleaner winner card inside the explore panel — drops the loud 3px
 * border + grain overlay from the main site's editorial card, lands
 * closer to the rest of flight-check's neutral/Flighty aesthetic. */
.explore-panel .winner-card {
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--green) 5%, var(--surface)) 0%,
      var(--surface) 100%);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 16px 18px 14px;
  margin: 0 0 14px;
  box-shadow: 0 1px 2px rgba(12, 12, 24, 0.04);
}
.explore-panel .winner-card::before { display: none; }
.explore-panel .winner-card::after { display: none; }
.explore-panel .winner-card:hover { box-shadow: 0 4px 14px rgba(12, 12, 24, 0.07); transform: translateY(-1px); }
.explore-panel .winner-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--text-2);
  margin-bottom: 10px;
}
.explore-panel .winner-name { font-size: 19px; letter-spacing: -0.015em; }
.explore-panel .winner-code { font-size: 11.5px; color: var(--text-3); margin-left: 6px; }
.explore-panel .winner-metrics {
  gap: 0;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  display: grid;
  grid-template-columns: repeat(2, 1fr);
}
.explore-panel .winner-metric {
  gap: 4px;
  padding-right: 12px;
}
.explore-panel .winner-metric + .winner-metric {
  border-left: 1px solid var(--border);
  padding-left: 14px;
}
.explore-panel .winner-metric-value {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
}
.explore-panel .winner-metric-label {
  font-size: 10px;
  font-weight: 500;
  color: var(--text-3);
  letter-spacing: 0.08em;
}
.explore-panel .winner-card.has-dow .airline-row-dow {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.explore-panel .airline-list {
  border: 1px solid var(--border); border-radius: 12px; overflow: hidden;
  background: var(--surface);
}
.explore-panel .airline-row {
  padding: 12px 16px;
  grid-template-columns: 28px 1fr auto;
  gap: 0 10px;
}
/* In the connection panel the rank cell is dropped (pinActive mode);
 * collapse the rank column so .row-center can take the freed-up space
 * instead of getting squeezed into the 28px slot and truncating to "B…". */
.explore-panel .airline-row.no-rank {
  grid-template-columns: 1fr auto;
}
.explore-panel .airline-row.clickable { padding-right: 24px; }
.explore-panel .row-name { font-size: 14px; }
.explore-panel .row-primary-value { font-size: 18px; }
.explore-panel .row-sub { font-size: 11px; gap: 10px; }
.explore-panel .click-hint { font-size: 11px; margin-bottom: 6px; padding: 0 4px; }
.explore-panel .disclaimer { font-size: 11px; }

/* Day-of-week strip: lives inside .airline-row as a full-width 2nd grid row
 * when .has-dow is set. Also appended to .winner-card when DOW is present. */
.airline-row.has-dow {
  grid-template-rows: auto auto;
}
.airline-row.has-dow .row-rank,
.airline-row.has-dow .row-center,
.airline-row.has-dow .row-primary { align-self: start; }
.airline-row.has-dow.clickable::after { top: 22px; transform: none; }
.airline-row.has-dow.clickable:hover::after { transform: translateX(2px); }

.airline-row-dow {
  grid-column: 1 / -1;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.winner-card.has-dow .airline-row-dow {
  margin-top: 14px;
  padding-top: 14px;
}
.dow-label {
  font-size: 11px;
  color: var(--text-3);
  letter-spacing: 0.02em;
}
.dow-grid {
  display: grid;
  grid-template-columns: repeat(7, 18px);
  gap: 6px;
  flex-shrink: 0;
}
.dow-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  cursor: default;
}
/* Each day is a single circle. Filled = flies, hollow = doesn't. Fill
 * color conveys delay performance; inner dot size encodes frequency. */
.dow-dot {
  --dot-color: rgba(60, 63, 107, 0.32);
  --dot-fill: transparent;
  --dot-ring: transparent;
  position: relative;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1.5px solid var(--dot-color);
  background: var(--dot-fill);
  box-shadow: 0 0 0 2px var(--dot-ring);
  transition: background 200ms ease, border-color 200ms ease, box-shadow 200ms ease;
}
/* Performance-tinted colors (used only when the day operates) */
.dow-dot-green { --dot-color: var(--green); }
.dow-dot-amber { --dot-color: var(--amber); }
.dow-dot-red   { --dot-color: var(--red); }
.dow-dot-none  { --dot-color: rgba(44, 41, 38, 0.45); }
/* Day doesn't operate: hollow muted circle, low emphasis */
.dow-dot-off {
  --dot-color: rgba(44, 41, 38, 0.18);
  --dot-fill: transparent;
}
/* Frequency tiers: 1 = sparse, 2 = moderate, 3 = busy (0 is handled by -off above) */
.dow-dot-freq-1 { --dot-fill: color-mix(in srgb, var(--dot-color) 22%, transparent); }
.dow-dot-freq-2 { --dot-fill: color-mix(in srgb, var(--dot-color) 55%, transparent); }
.dow-dot-freq-3 { --dot-fill: var(--dot-color); }
/* Best-performing day gets a soft ring */
.dow-dot.is-best {
  --dot-ring: color-mix(in srgb, var(--dot-color) 30%, transparent);
}
.dow-letter {
  font-family: var(--mono);
  font-size: 9px;
  color: var(--text-3);
  letter-spacing: 0.05em;
  line-height: 1;
}

/* Mobile: panel becomes a bottom sheet that slides up, map stays full-bleed. */
@media (max-width: 820px) {
  .explore-root {
    height: calc(100vh - 64px);
    margin-top: 64px;
  }
  .explore-panel {
    top: auto;
    left: 0;
    right: 0;
    width: 100%;
    height: 72%;
    transform: translateY(100%);
    border-left: none;
    border-top: 1px solid var(--border);
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -10px 32px rgba(12, 12, 24, 0.10);
    padding: 22px 16px 40px;
  }
  .explore-panel.is-open { transform: translateY(0); }
  .explore-hub-overlay {
    top: 80px;
    left: 12px;
    right: 12px;
    width: auto;
    max-width: 360px;
  }
  .explore-ticker {
    top: 12px;
    padding: 10px 14px;
    max-width: calc(100% - 24px);
  }
  .explore-ticker-sentence { font-size: 15px; gap: 6px; }
  .explore-ticker .airport-input { font-size: 16px; width: 60px; }
  .explore-legend {
    left: 12px; bottom: 12px;
    padding: 6px 10px; gap: 4px 8px;
    font-size: 10px;
  }
  .explore-panel-title, .explore-panel-title .code { font-size: 22px; }
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* BOARD (preview) — /board/airports and /board/rankings                      */
/* Light-mode split-flap treatment. Paper-tile flap cells on the site's cream */
/* surface so it reads as a printed schedule board, not a glowing monitor.    */
/* Preview-only; does not alter the live /airports and /rankings pages.       */
/* ═══════════════════════════════════════════════════════════════════════════ */

:root {
  --board-paper:      #fbf6ea;            /* cells + inner panel — warmer cream */
  --board-panel-bg:   #fdfcf9;            /* matches --surface */
  --board-ink:        #2c2926;            /* full charcoal — landed state */
  --board-ink-soft:   rgba(44, 41, 38, 0.35);  /* rotating chars */
  --board-ink-dim:    rgba(44, 41, 38, 0.6);
  --board-ink-faint:  rgba(44, 41, 38, 0.4);
  --board-rule:       rgba(44, 41, 38, 0.08);
  --board-hover:      #f6f3ed;
  --board-gold:       #b8860b;
  --board-silver:     #8e8e93;
  --board-bronze:     #a0522d;
}

.flap-board-page {
  /* Scoped font override: the board uses Inter everywhere (including where
     --mono is referenced) so the mechanical texture comes from the flap
     cells, not the font. Cleaner, more modern, much more readable than the
     retro Share Tech Mono used elsewhere on the site. */
  --mono: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  max-width: 780px;
  margin: 0 auto;
  padding: 96px 24px 80px;
  font-feature-settings: 'tnum', 'ss01';
}

/* Canonical page header — the pattern every utility-style page (Rankings,
   Report Card, etc.) uses: a left-aligned bold title + subtitle, no kicker.
   See DESIGN.md ("Page header") for usage rules. */
.board-intro { margin-bottom: 22px; }
.board-kicker {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 10px;
}
.board-title {
  font-size: 38px;
  font-weight: 700;
  letter-spacing: -0.035em;
  margin-bottom: 6px;
  color: var(--text);
}
.board-subtitle { font-size: 15px; color: var(--text-2); margin-bottom: 0; }

.board-controls {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin: 26px 0 20px;
}
.board-controls-primary {
  display: flex;
  align-items: center;
}
.board-controls-filters {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* ── Best/Worst pill tabs ──────────────────────────────────────────────── */
.board-tabs {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--surface);
  border: 1.5px solid rgba(44, 41, 38, 0.12);
  border-radius: 999px;
  padding: 4px;
  width: 164px;
  min-height: 38px;
}
.board-tab {
  position: relative;
  z-index: 2;
  background: transparent;
  border: 0;
  padding: 0 14px;
  height: 30px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
  cursor: pointer;
  border-radius: 999px;
  transition: color 0.2s ease;
}
.board-tab.active { color: var(--text); }
.board-tabs-thumb {
  position: absolute;
  z-index: 1;
  top: 4px; bottom: 4px;
  left: 4px;
  width: calc(50% - 4px);
  background: #ebe4d4;
  border-radius: 999px;
  transition: transform 0.28s var(--ease-out);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
}
.board-tabs-thumb[data-pos="1"] { transform: translateX(100%); }

/* ── Outer board frame — matches .airline-list chrome ──────────────────── */
.board-panel {
  position: relative;
  background: var(--board-panel-bg);
  border: 1.5px solid rgba(44, 41, 38, 0.1);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow:
    0 1px 3px rgba(0, 0, 0, 0.03),
    0 10px 28px -12px rgba(44, 41, 38, 0.12);
}
/* Grain overlay — reuses the site's shared grain token */
.board-panel::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: var(--grain-url);
  background-size: 200px 200px;
  opacity: 0.05;
  z-index: 0;
}

.board-panel-inner {
  position: relative;
  z-index: 1;
  padding: 20px 22px 14px;
}

/* ── Header strip — prints the board's title + freshness ──────────────── */
.board-header-strip {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 4px 16px;
  margin-bottom: 14px;
  border-bottom: 1px dashed rgba(44, 41, 38, 0.18);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--board-ink-dim);
}
.board-header-label { display: inline-flex; align-items: center; gap: 8px; }
.board-header-glyph {
  color: var(--green);
  font-size: 13px;
  display: inline-block;
  animation: board-plane-hover 6s ease-in-out infinite;
}
@keyframes board-plane-hover {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(4px); }
}
.board-header-meta { color: var(--board-ink-faint); }

/* ── Column scaffold ──────────────────────────────────────────────────── */
.board-columns {
  display: grid;
  gap: 18px;
  padding: 2px 10px 12px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--board-ink-faint);
}
.board-columns-airport,
.board-columns-airline {
  grid-template-columns: 52px 106px 1fr 128px 22px;
  align-items: center;
}
.board-columns .ta-r { text-align: right; }
.board-columns .ta-c { text-align: center; }

/* ── Rows ─────────────────────────────────────────────────────────────── */
.board-rows { position: relative; }

.board-row {
  display: grid;
  grid-template-columns: 52px 106px 1fr 128px 22px;
  align-items: center;
  gap: 18px;
  padding: 18px 10px;
  color: var(--board-ink);
  cursor: pointer;
  border-top: 1px solid var(--board-rule);
  transition: background 0.15s ease;
  outline: none;
}
.board-row:first-child { border-top: 0; }
.board-row:hover,
.board-row:focus-visible { background: var(--board-hover); }
.board-row:focus-visible { box-shadow: inset 0 0 0 1px rgba(184, 134, 11, 0.45); }

/* Top-3 row emphasis — thin tinted left rule */
.board-row.board-top-1 { box-shadow: inset 3px 0 0 var(--board-gold); }
.board-row.board-top-2 { box-shadow: inset 3px 0 0 var(--board-silver); }
.board-row.board-top-3 { box-shadow: inset 3px 0 0 var(--board-bronze); }

/* Rank flap group (2 cells — "01", "02" etc) */
.board-rank {
  display: inline-flex;
  gap: 2px;
  justify-content: flex-start;
}
.board-row.board-top-1 .board-rank .board-flap-cell.landed { color: var(--board-gold); }
.board-row.board-top-2 .board-rank .board-flap-cell.landed { color: var(--board-silver); }
.board-row.board-top-3 .board-rank .board-flap-cell.landed { color: var(--board-bronze); }

/* Flap groups — code and on-time are inline-flex cell rows; name is a plain
   text line so it reads like body text once the flap animation lands. */
.board-code, .board-ontime {
  display: inline-flex;
  gap: 4px;
  flex-wrap: nowrap;
  overflow: hidden;
  min-width: 0;
}
.board-code { justify-content: flex-start; }
.board-ontime { justify-content: flex-end; }

.board-name {
  display: block;
  min-width: 0;
  font-size: 19px;
  font-weight: 500;
  line-height: 1.2;
  color: var(--board-ink);
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Flap cell in light mode — paper tiles on cream ───────────────────── */
/* Overrides the Explore base .flap-cell (which is dark-mode) for the board. */
.board-flap-cell {
  min-width: 24px;
  height: 32px;
  padding: 0 4px;
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--board-ink-soft);
  background: var(--board-paper);
  border: 1px solid rgba(44, 41, 38, 0.09);
  border-radius: 3px;
  box-shadow:
    0 1px 0 rgba(44, 41, 38, 0.04),
    inset 0 -1px 0 rgba(44, 41, 38, 0.05);
  transition: color 0.18s ease;
}
/* The signature horizontal split, visible as a fine dark hairline */
.board-flap-cell::after {
  background: rgba(44, 41, 38, 0.18);
  height: 0.5px;
}
.board-flap-cell.landed {
  color: var(--board-ink);
  font-weight: 600;
}
.board-flap-cell.is-blank {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}
.board-flap-cell.is-blank::after { display: none; }

/* Rank cells — bare characters, dim until landed */
.board-rank .board-flap-cell {
  min-width: 18px;
  height: 26px;
  padding: 0 1px;
  font-size: 14px;
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}
.board-rank .board-flap-cell::after { display: none; }

/* Name cells — TRULY chromeless. Reset the base .flap-cell layout (which
   is display:flex) so cells flow as inline text characters. The flap
   animation still runs; the landed text reads like ordinary prose. */
.board-name .board-flap-cell {
  all: unset;
  display: inline;
  color: var(--board-ink-soft);
  transition: color 0.18s ease;
  font: inherit;
  letter-spacing: inherit;
  white-space: pre;
}
.board-name .board-flap-cell::after { display: none; }
.board-name .board-flap-cell.landed {
  color: var(--board-ink);
}

/* IATA code cells — the headline identifier, larger and crisper */
.board-code .board-flap-cell {
  min-width: 28px;
  height: 38px;
  padding: 0 3px;
  font-size: 20px;
  font-weight: 600;
  letter-spacing: 0;
  background: #f7efdd;
  border-color: rgba(44, 41, 38, 0.14);
  box-shadow:
    0 1px 0 rgba(44, 41, 38, 0.06),
    inset 0 -1px 0 rgba(44, 41, 38, 0.08);
}
.board-code .board-flap-cell.landed { color: var(--board-ink); }

/* On-time % cells — status-tinted once landed */
.board-ontime .board-flap-cell {
  min-width: 26px;
  height: 36px;
  padding: 0 2px;
  font-size: 21px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.board-ontime.board-status-green .board-flap-cell.landed { color: var(--green); }
.board-ontime.board-status-amber .board-flap-cell.landed { color: var(--amber); }
.board-ontime.board-status-red   .board-flap-cell.landed { color: var(--red); }
.board-ontime.board-status-none  .board-flap-cell.landed { color: var(--board-ink-faint); }

/* Status dot — warm palette, matches site */
.board-status-dot {
  width: 11px;
  height: 11px;
  border-radius: 999px;
  justify-self: center;
  background: var(--board-ink-faint);
}
.board-dot-green { background: var(--green); }
.board-dot-amber { background: var(--amber); }
.board-dot-red   { background: var(--red); }
.board-dot-none  { background: transparent; box-shadow: inset 0 0 0 1px var(--board-rule); }

/* Name slot — holds the flap-text target + the optional inline caveat.
   The flap writer (renderFlap) only overwrites the .board-name child;
   the caveat sits as a sibling so it survives re-renders. */
.board-name-slot {
  display: flex;
  align-items: baseline;
  gap: 0;
  min-width: 0;
  overflow: hidden;
}
.board-name-slot .board-name { flex-shrink: 1; }

/* Low-sample inline caveat on Board rows — "Honolulu · limited sample" */
.board-caveat {
  flex-shrink: 0;
  font-size: 12px;
  font-weight: 500;
  color: var(--amber);
  opacity: 0.78;
  margin-left: 10px;
  letter-spacing: 0.01em;
  white-space: nowrap;
  line-height: 1.2;
}
.board-caveat::before {
  content: "·";
  margin-right: 8px;
  color: var(--text-3);
  opacity: 0.55;
}

/* States */
.board-loading,
.board-empty {
  color: var(--text-3);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-align: center;
  padding: 64px 20px;
}
.board-panel.board-empty {
  background: var(--board-panel-bg);
  border-radius: var(--radius);
}
.board-disclaimer {
  font-size: 12px;
  color: var(--text-3);
  text-align: center;
  margin-top: 16px;
}
.board-shell { min-height: 420px; }

/* ══════════════════════════════════════════════════════════════════════ */
/* Filter controls — unified mono family scoped to .board-controls so the */
/* live /airports and /rankings pages' filters stay unchanged.            */
/* ══════════════════════════════════════════════════════════════════════ */

/* Region dropdown trigger */
.board-controls .sort-btn,
.board-controls .region-trigger {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--board-ink);
  background: var(--surface);
  border: 1px solid rgba(44, 41, 38, 0.14);
  border-radius: 6px;
  padding: 0 14px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.board-controls .sort-btn:hover,
.board-controls .region-trigger:hover {
  background: var(--board-hover);
  border-color: rgba(44, 41, 38, 0.26);
  color: var(--board-ink);
}
.board-controls .region-trigger.has-value {
  background: var(--board-ink);
  border-color: var(--board-ink);
  color: var(--surface);
}
.board-controls .region-trigger.has-value:hover {
  background: var(--board-ink);
  border-color: var(--board-ink);
  color: var(--surface);
}
.board-controls .region-trigger.has-value .region-caret {
  color: rgba(253, 252, 249, 0.65);
}
.board-controls .region-caret {
  font-size: 10px;
  color: var(--board-ink-faint);
}

/* Region menu — mono dropdown */
.board-controls .region-menu {
  background: var(--surface);
  border: 1px solid rgba(44, 41, 38, 0.14);
  border-radius: 6px;
  padding: 4px;
  min-width: 200px;
  box-shadow: 0 8px 24px rgba(44, 41, 38, 0.1);
}
.board-controls .region-option {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 9px 12px;
  border-radius: 3px;
  color: var(--board-ink-dim);
}
.board-controls .region-option:hover {
  background: var(--board-hover);
  color: var(--board-ink);
}
.board-controls .region-option.active {
  background: rgba(44, 41, 38, 0.08);
  color: var(--board-ink);
  font-weight: 600;
}

/* Segmented (Major/All) — thin rectangular toggle */
.board-controls .segmented-board {
  position: relative;
  display: inline-flex;
  height: 36px;
  padding: 0;
  background: var(--surface);
  border: 1px solid rgba(44, 41, 38, 0.14);
  border-radius: 6px;
  grid-template-columns: none;
  overflow: hidden;
  isolation: isolate;
}
.board-controls .segmented-board .segmented-btn {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--board-ink-faint);
  padding: 0 16px;
  min-width: 72px;
  height: 100%;
  background: transparent;
  border: 0;
  border-radius: 0;
  cursor: pointer;
  position: relative;
  z-index: 2;
  grid-column: auto;
  transition: color 0.2s ease;
}
.board-controls .segmented-board .segmented-btn:hover { color: var(--board-ink); }
.board-controls .segmented-board .segmented-btn.active {
  color: var(--surface);
  font-weight: 600;
}
.board-controls .segmented-board .segmented-thumb {
  position: absolute;
  top: 0; bottom: 0;
  left: 0;
  width: 50%;
  background: var(--board-ink);
  border-radius: 0;
  transition: transform 0.28s var(--ease-out);
  box-shadow: none;
  z-index: 1;
}
.board-controls .segmented-board .segmented-thumb[data-pos="1"] {
  transform: translateX(100%);
}

/* Best/Worst tabs — identical family to segmented */
.board-tabs {
  position: relative;
  display: inline-flex;
  grid-template-columns: none;
  height: 36px;
  padding: 0;
  background: var(--surface);
  border: 1px solid rgba(44, 41, 38, 0.14);
  border-radius: 6px;
  width: auto;
  min-height: 36px;
  overflow: hidden;
  isolation: isolate;
}
.board-tab {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--board-ink-faint);
  padding: 0 16px;
  min-width: 72px;
  height: 100%;
  background: transparent;
  border: 0;
  border-radius: 0;
  cursor: pointer;
  position: relative;
  z-index: 2;
  transition: color 0.2s ease;
}
.board-tab:hover { color: var(--board-ink); }
.board-tab.active {
  color: var(--surface);
  font-weight: 600;
}
.board-tabs-thumb {
  position: absolute;
  top: 0; bottom: 0;
  left: 0;
  width: 50%;
  background: var(--board-ink);
  border-radius: 0;
  box-shadow: none;
  transition: transform 0.28s var(--ease-out);
  z-index: 1;
}
.board-tabs-thumb[data-pos="1"] { transform: translateX(100%); }

/* Airlines / Airports type switch — the primary control on Rankings.
   Same mono family as the other filter chips, a touch more prominent
   (stronger border + darker active thumb) so it reads as the view switch. */
.board-type-switch {
  position: relative;
  display: inline-flex;
  height: 36px;
  padding: 0;
  background: var(--surface);
  border: 1px solid rgba(44, 41, 38, 0.22);
  border-radius: 6px;
  overflow: hidden;
  isolation: isolate;
}
.board-type-btn {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
  padding: 0 18px;
  min-width: 86px;
  height: 100%;
  background: transparent;
  border: 0;
  border-radius: 0;
  cursor: pointer;
  position: relative;
  z-index: 2;
  transition: color 0.2s ease;
}
.board-type-btn:hover { color: var(--text); }
.board-type-btn.active {
  color: var(--surface);
  font-weight: 600;
}
.board-type-thumb {
  position: absolute;
  top: 0; bottom: 0;
  left: 0;
  width: 50%;
  background: var(--board-ink);
  transition: transform 0.28s var(--ease-out);
  z-index: 1;
}
.board-type-thumb[data-pos="1"] { transform: translateX(100%); }

/* Filter strip — quieter than the primary type switch. Tighter padding,
   smaller type, shorter pills so five controls breathe inside a 780px page. */
.board-controls-filters .sort-btn,
.board-controls-filters .region-trigger {
  height: 30px;
  font-size: 10px;
  letter-spacing: 0.12em;
  padding: 0 12px;
  gap: 8px;
}
.board-controls-filters .segmented-board,
.board-controls-filters .board-tabs {
  height: 30px;
  min-height: 30px;
}
.board-controls-filters .segmented-board .segmented-btn,
.board-controls-filters .board-tab {
  height: 30px;
  font-size: 10px;
  letter-spacing: 0.12em;
  padding: 0 12px;
  min-width: 60px;
}

/* Push Best/Worst to the right edge of its row */
.board-controls-filters > .board-tabs { margin-left: auto; }

@media (prefers-reduced-motion: reduce) {
  .board-tabs-thumb,
  .board-flap-cell,
  .board-header-glyph { transition: none; animation: none; }
}

/* Mobile: collapse the status dot; keep rank / code / name / %. */
@media (max-width: 720px) {
  .flap-board-page { padding: 72px 12px 60px; }
  .board-panel-inner { padding: 16px 12px 10px; }
  .board-columns-airport,
  .board-columns-airline,
  .board-row {
    grid-template-columns: 40px 82px 1fr 94px;
    gap: 12px;
  }
  .board-row { padding: 14px 6px; }
  .board-columns > span:nth-child(5),
  .board-row .board-status-dot { display: none; }
  .board-columns > span:nth-child(4) { text-align: right; }
  .board-name { font-size: 16px; }
  .board-code .board-flap-cell { min-width: 22px; height: 30px; font-size: 16px; }
  .board-ontime .board-flap-cell { min-width: 20px; height: 28px; font-size: 17px; }
  .board-rank .board-flap-cell { min-width: 14px; height: 22px; font-size: 12px; }
  .board-controls { gap: 6px; }
  .board-controls .segmented-board .segmented-btn,
  .board-controls .board-tab,
  .board-controls .board-type-btn { min-width: 56px; padding: 0 12px; }
  .board-controls-filters > .board-tabs { margin-left: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* SITE FOOTER — "personal note" disclaimer at the bottom of every page       */
/* ═══════════════════════════════════════════════════════════════════════════ */

.site-footer {
  position: relative;
  z-index: 50;
  background: var(--bg);
  border-top: 1px solid var(--border);
  padding: 56px 24px 80px;
  color: var(--text);
}
.site-footer-inner {
  max-width: 680px;
  margin: 0 auto;
}
.site-footer-divider {
  text-align: center;
  font-family: var(--mono);
  color: var(--text-3);
  letter-spacing: 0.2em;
  margin-bottom: 28px;
  font-size: 16px;
}
.site-footer-title {
  font-family: 'Kalam', cursive;
  font-weight: 700;
  font-size: 30px;
  line-height: 1.2;
  margin: 0 0 20px;
  color: var(--text);
}
.site-footer-body p {
  font-family: 'Inter', sans-serif;
  font-size: 16px;
  line-height: 1.6;
  margin: 0 0 14px;
  color: var(--text);
}
.site-footer-body p:last-child { margin-bottom: 0; }
.site-footer-body a {
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.site-footer-body a:hover { color: var(--hero-accent); }
.site-footer-body em { font-style: italic; }

@media (max-width: 600px) {
  .site-footer { padding: 40px 20px 60px; }
  .site-footer-title { font-size: 26px; }
  .site-footer-body p { font-size: 15px; }
}

/* Homepage: no disclaimer at all. Explore: replaced with click-to-open. */
body.is-home .site-footer,
body.is-explore .site-footer { display: none; }

/* ── Click-to-open trigger (Explore only) ────────────────────────────────── */
.disclaimer-trigger {
  display: none;
  position: fixed;
  bottom: 16px;
  right: 16px;
  z-index: 60;
  font-family: 'Kalam', cursive;
  font-weight: 700;
  font-size: 14px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 8px 16px;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(12, 12, 24, 0.10);
  transition: transform 160ms var(--ease-out), box-shadow 160ms var(--ease-out), color 160ms ease;
}
.disclaimer-trigger:hover {
  color: var(--hero-accent);
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(12, 12, 24, 0.14);
}
/* Explore folds the disclaimer into the legend pill (see .legend-disclaimer)
   to keep it off the slide-in airline panel. */
.legend-disclaimer {
  font-family: 'Kalam', cursive;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--text-2);
  background: transparent;
  border: 0;
  border-left: 1px solid var(--border);
  padding: 0 0 0 10px;
  margin-left: 4px;
  cursor: pointer;
  transition: color 160ms ease;
}
.legend-disclaimer:hover { color: var(--hero-accent); }

/* ── Modal ────────────────────────────────────────────────────────────────── */
.disclaimer-modal {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  opacity: 0;
  transition: opacity 200ms ease;
}
.disclaimer-modal.is-open { opacity: 1; }
.disclaimer-modal[hidden] { display: none; }
.disclaimer-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 18, 16, 0.45);
  backdrop-filter: blur(2px);
}
.disclaimer-modal-card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 40px 32px 32px;
  max-width: 640px;
  width: 100%;
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  box-shadow: 0 24px 60px rgba(12, 12, 24, 0.30);
  transform: translateY(8px);
  transition: transform 200ms var(--ease-out);
}
.disclaimer-modal.is-open .disclaimer-modal-card { transform: translateY(0); }
.disclaimer-modal-close {
  position: absolute;
  top: 10px;
  right: 12px;
  width: 32px;
  height: 32px;
  border: none;
  background: transparent;
  font-size: 22px;
  line-height: 1;
  color: var(--text-2);
  cursor: pointer;
  border-radius: 50%;
  transition: background 160ms ease, color 160ms ease;
}
.disclaimer-modal-close:hover { background: var(--bg); color: var(--text); }
.disclaimer-modal-content .site-footer-title { margin-top: 0; }

/* ── Explore: 1-stop itineraries panel ──────────────────────────────────
 * Sits below the direct-flight rankings inside .explore-panel-body.
 * Three-position toggle filters the list client-side; data ships from
 * the per-origin shard pre-warmed when the user picks an origin. */
.explore-itineraries {
  margin-top: 24px;
  padding-top: 18px;
  border-top: 1px dashed var(--border);
}
/* Collapsed state: hide the loaded body, show only the CTA. The body still
 * loads in the background so expanding feels instant. */
.explore-itineraries .itin-expand-cta { display: none; }
.explore-itineraries.is-collapsed .itin-body { display: none; }
.explore-itineraries.is-collapsed .itin-expand-cta { display: flex; }
/* Empty state: route has neither direct flights nor 1-stops. Hide the CTA
 * so we don't dangle a "+" that opens to an "empty" message. */
.explore-itineraries.is-empty .itin-expand-cta { display: none; }
.itin-expand-cta {
  width: 100%;
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: 10px;
  font: inherit; font-size: 13px; font-weight: 500;
  color: var(--text-2);
  cursor: pointer;
  transition: background 160ms ease, border-color 160ms ease, color 160ms ease;
}
.itin-expand-cta:hover {
  background: var(--bg);
  border-color: color-mix(in srgb, var(--text-3) 50%, var(--border));
  color: var(--text);
}
.itin-expand-icon {
  position: relative;
  display: inline-flex;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--border);
  font-size: 0;
  color: transparent;
  transition: background 160ms ease, border-color 160ms ease;
}
.itin-expand-icon::before,
.itin-expand-icon::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  background: var(--text);
  border-radius: 1px;
  transition: background 160ms ease;
}
.itin-expand-icon::before { width: 10px; height: 1.5px; transform: translate(-50%, -50%); }
.itin-expand-icon::after  { width: 1.5px; height: 10px; transform: translate(-50%, -50%); }
.itin-expand-cta:hover .itin-expand-icon {
  background: var(--text); border-color: var(--text);
}
.itin-expand-cta:hover .itin-expand-icon::before,
.itin-expand-cta:hover .itin-expand-icon::after {
  background: var(--surface);
}
.itin-expand-label { line-height: 1.2; }
.itin-loading,
.itin-empty {
  font-size: 12px; color: var(--text-3); text-align: center;
  padding: 16px 8px;
  letter-spacing: 0.02em;
}
.itin-header {
  display: flex; flex-direction: column; gap: 10px;
  margin-bottom: 10px; padding: 0 4px;
}
.itin-title {
  font-size: 13px; font-weight: 600; color: var(--text);
  letter-spacing: 0.04em; text-transform: uppercase;
}
.itin-toggle {
  display: flex;
  border: 1px solid var(--border); border-radius: 9px;
  background: var(--surface); padding: 3px; gap: 2px;
}
.itin-toggle button {
  flex: 1;
  border: none; background: transparent;
  font: inherit; font-size: 11px; font-weight: 500;
  color: var(--text-2); padding: 6px 8px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 160ms ease, color 160ms ease;
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  letter-spacing: 0.01em;
}
.itin-toggle button:hover:not(:disabled):not(.active) { background: var(--bg); color: var(--text); }
.itin-toggle button.active {
  background: var(--text); color: var(--surface);
  box-shadow: 0 1px 2px rgba(12, 12, 24, 0.08);
}
.itin-toggle button:disabled {
  opacity: 0.4; cursor: not-allowed;
}
.itin-count {
  font-family: var(--mono); font-size: 10px;
  padding: 1px 5px; border-radius: 4px;
  background: color-mix(in srgb, currentColor 12%, transparent);
}
.itin-toggle button.active .itin-count {
  background: color-mix(in srgb, var(--surface) 22%, transparent);
}
.itin-list { display: flex; flex-direction: column; gap: 6px; }

/* Hub-first row: a single button per hub. Click drills into the "via X"
 * panel, which shows both legs' rankings side-by-side. */
.itin-row {
  display: grid;
  grid-template-columns: auto auto 1fr auto auto;
  align-items: center;
  gap: 10px;
  padding: 11px 14px 11px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  cursor: pointer;
  font: inherit;
  text-align: left;
  width: 100%;
  transition: background 160ms ease, border-color 160ms ease, transform 120ms ease;
}
.itin-row:hover {
  background: var(--bg);
  border-color: color-mix(in srgb, var(--text-3) 50%, var(--border));
}
.itin-row:active { transform: translateY(1px); }
.itin-row-via { color: var(--text-3); font-size: 11px; letter-spacing: 0.02em; }
/* Fixed width so the next column (time + ticket badge) always starts at
 * the same x across rows — cities like "Minneapolis" no longer push the
 * time past a column with "Detroit". 110px fits everything in our hub
 * set including longer names like "Frankfurt" / "Dallas". Anything
 * unusually long wraps to a second line gracefully. */
.itin-row-hub {
  display: inline-flex; flex-direction: column; gap: 1px;
  width: 110px;
  min-width: 0;
}
.itin-row-hub-code {
  font-family: var(--mono); font-weight: 700; letter-spacing: 0.06em;
  color: var(--text); font-size: 14px;
}
.itin-row-hub-city {
  font-size: 11px; color: var(--text-2); letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.itin-row-meta {
  display: inline-flex; flex-direction: column; align-items: flex-start;
  gap: 4px; min-width: 0;
}
.itin-row-time {
  font-family: var(--mono); font-size: 13px; font-weight: 700;
  color: var(--text); letter-spacing: 0.02em;
}
.itin-row-freq {
  font-size: 11px; color: var(--text-2); font-weight: 500;
  letter-spacing: 0.01em;
}
.itin-row-wait {
  font-size: 10.5px; color: var(--amber); font-weight: 500;
  letter-spacing: 0.01em;
}
.itin-row-arrow {
  color: var(--text-3); font-size: 18px; line-height: 1;
  transition: color 120ms ease, transform 120ms ease;
}
.itin-row:hover .itin-row-arrow {
  color: var(--text); transform: translateX(2px);
}

.itin-tag {
  font-size: 9.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
  padding: 3px 6px; border-radius: 4px;
  white-space: nowrap;
  display: inline-block;
}
.itin-tag-same {
  background: color-mix(in srgb, var(--green) 15%, transparent);
  color: color-mix(in srgb, var(--green) 80%, var(--text));
}
.itin-tag-alliance {
  background: color-mix(in srgb, var(--amber) 18%, transparent);
  color: color-mix(in srgb, var(--amber) 75%, var(--text));
}
.itin-tag-mixed {
  background: color-mix(in srgb, var(--text-3) 18%, transparent);
  color: var(--text-2);
}
.itin-dow {
  display: inline-flex; gap: 2px;
}
.itin-dow-cell {
  width: 14px; height: 14px;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 9px; font-weight: 600;
  border-radius: 3px;
  letter-spacing: 0;
}
.itin-dow-cell.on {
  background: color-mix(in srgb, var(--green) 22%, transparent);
  color: color-mix(in srgb, var(--green) 75%, var(--text));
}
.itin-dow-cell.off {
  background: var(--bg);
  color: rgba(44, 41, 38, 0.25);
}

/* Hub panel: drilldown view shown when user picks a hub row.
 * Layout: header with PDX → BOS → MAD route, summary chip, then the two
 * legs stacked. Each leg reuses .winner-card / .airline-list from the
 * existing route ranking renderer. */
/* Hub view header row: back button, route title, and the panel's
 * absolute close button (top:24px) all share one horizontal axis. The
 * 44px right padding reserves space so the title can't crash into the
 * absolute X. */
.hub-header {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 28px;
  padding-right: 44px;
  margin-bottom: 14px;
}
.hub-header .hub-route-title {
  margin: 0;
  padding: 0;
  flex: 1;
  min-width: 0;
  align-items: center;
}

.hub-route-title {
  display: inline-flex; align-items: baseline; gap: 8px;
  font-size: 22px; font-weight: 600; letter-spacing: -0.01em;
  margin: 4px 0 0; padding: 0 4px;
}
.hub-route-title .code {
  font-family: var(--mono); font-size: 22px; letter-spacing: 0.04em;
}
.hub-route-title .hub-route-via { color: var(--amber); }
.hub-route-arrow { color: var(--text-3); font-weight: 300; font-size: 18px; }
.hub-leg { margin-bottom: 18px; }
.hub-leg-header {
  display: flex; align-items: baseline; gap: 10px;
  margin-bottom: 8px; padding: 0 4px;
}
.hub-leg-num {
  font-size: 10px; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
  padding: 3px 6px;
  border: 1px solid var(--border);
  border-radius: 3px;
}
.hub-leg-route {
  font-size: 14px; font-weight: 600;
  display: inline-flex; align-items: baseline; gap: 6px;
}
.hub-leg-route .code {
  font-family: var(--mono); letter-spacing: 0.04em;
}
.hub-leg-body { min-height: 80px; }
/* Tighter ranking inside hub legs — they're stacked, so save vertical space.
 * Suppress the inner route header entirely: the .hub-leg-header above
 * already says "Leg 1 · MAD → JED" so the larger duplicate route +
 * airline-count line was just visual noise. */
.hub-leg .results-header { display: none; }
.hub-leg .winner-card { padding: 12px 14px; margin-bottom: 8px; }
.hub-leg .click-hint { display: none; }
.hub-leg .disclaimer { display: none; }

@media (max-width: 600px) {
  .itin-row {
    grid-template-columns: auto 1fr auto;
    row-gap: 6px;
    padding: 10px 12px;
  }
  .itin-row-meta { grid-column: 1 / -1; flex-direction: row; align-items: center; gap: 8px; }
  .itin-dow { grid-column: 1 / -1; justify-content: flex-start; }
  .itin-row-arrow { grid-row: 1; grid-column: 3; }
  .itin-toggle button { font-size: 10px; padding: 6px 4px; }
  .hub-route-title { font-size: 18px; }
  .hub-route-title .code { font-size: 18px; }
}

/* ── Long-wait bucket (≥24hr layovers) ─────────────────────────────────
 * Hidden behind a "+" toggle by default. Auto-opens only when the visible
 * lane is empty. Inside, we show the wait time on each row so the user
 * can decide whether the connection is rescuable. */
.itin-long-wait {
  margin-top: 10px;
  border-top: 1px dashed var(--border);
  padding-top: 12px;
}
.itin-long-toggle {
  width: 100%;
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px;
  background: transparent;
  border: 1px dashed var(--border);
  border-radius: 8px;
  font: inherit; font-size: 12px; font-weight: 500;
  color: var(--text-2);
  cursor: pointer;
  transition: background 160ms ease, color 160ms ease, border-color 160ms ease;
}
.itin-long-toggle:hover {
  background: var(--bg);
  color: var(--text);
  border-color: color-mix(in srgb, var(--text-3) 50%, var(--border));
}
.itin-long-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--border);
  font-family: var(--mono); font-size: 13px; font-weight: 600;
  color: var(--text-2);
  transition: transform 160ms ease;
}
.itin-long-wait.is-open .itin-long-icon { transform: rotate(45deg); color: var(--text); }
.itin-long-body { display: none; margin-top: 8px; flex-direction: column; gap: 6px; }
.itin-long-wait.is-open .itin-long-body { display: flex; }
.itin-long-helper {
  font-size: 11px; color: var(--text-3); padding: 0 4px 4px;
  line-height: 1.4;
}
/* Long-wait rows pick up a subtle amber tint to signal "warning" state. */
.itin-long-body .itin-row {
  background: color-mix(in srgb, var(--amber) 4%, var(--surface));
}

/* ── Hub-panel typical-trip breakdown ──────────────────────────────────
 * Headline number + leg1 + layover + leg2 below. Subdued part times let
 * the total stand out; the layover gets a warning color when ≥24hr. */
.hub-trip {
  margin: 14px 0 16px;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
}
.hub-trip-headline {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.hub-trip-label {
  font-size: 13px; font-weight: 500;
  color: var(--text-3);
}
.hub-trip-total {
  font-family: var(--mono); font-size: 26px; font-weight: 700;
  color: var(--text); letter-spacing: 0.01em;
}
.hub-trip-parts {
  display: flex; flex-direction: column; gap: 4px;
}
.hub-trip-part {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px;
}
.hub-trip-part-route {
  font-size: 14px; color: var(--text-2);
  display: inline-flex; align-items: baseline; gap: 6px;
}
.hub-trip-part-route .code {
  font-family: var(--mono); letter-spacing: 0.04em;
  color: var(--text);
}
.hub-trip-part-time {
  font-family: var(--mono); font-size: 14px; font-weight: 600;
  color: var(--text-2); letter-spacing: 0.01em;
}
.hub-trip-part-wait .hub-trip-part-label { color: var(--text-3); font-style: italic; }
.hub-trip-note {
  margin-top: 10px;
  font-size: 11px; color: var(--text-3);
  line-height: 1.4;
  font-style: italic;
}

/* Synthesized-route indicator on hub rows. The row gets a dashed border
 * to read as "approximate" without screaming; meta column gets a small
 * italic tag explaining the flight time is estimated. */
.itin-row-synth {
  font-size: 9.5px; font-style: italic;
  color: var(--text-3);
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.itin-row.is-synth { border-style: dashed; }

/* Hub-panel fallback when route_stats has no data for a leg (synthesized
 * route — we know the airlines operate it but lack performance stats).
 * Lists airlines we know without pretending to have on-time numbers. */
.hub-leg-fallback {
  padding: 12px 14px;
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: 10px;
}
.hub-leg-fallback-note {
  font-size: 11.5px; color: var(--text-2);
  line-height: 1.5; margin-bottom: 10px;
}
.hub-leg-fallback-list {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.hub-leg-fallback-airline {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 12px; font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text);
  padding: 4px 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.hub-leg-fallback-hint {
  margin-top: 10px;
  font-size: 10.5px; color: var(--text-3);
  font-style: italic;
}

/* Connection-panel "operator" line under the trip headline — surfaces
 * the airline(s) the panel is featuring when the user came from the
 * Single airline / Alliance tab. Reuses the existing itin-tag color
 * tokens so single-airline reads green and alliance reads amber. */
.hub-trip-operator {
  display: flex; align-items: center; gap: 8px;
  margin-top: 10px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-2);
  flex-wrap: wrap;
}
.hub-trip-operator-pill {
  display: inline-block;
  padding: 3px 7px;
  border-radius: 4px;
  font-weight: 600;
  font-size: 10px; letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}
.hub-trip-operator[data-pin="same"] .hub-trip-operator-pill {
  background: color-mix(in srgb, var(--green) 15%, transparent);
  color: color-mix(in srgb, var(--green) 80%, var(--text));
}
.hub-trip-operator[data-pin="alliance"] .hub-trip-operator-pill {
  background: color-mix(in srgb, var(--amber) 18%, transparent);
  color: color-mix(in srgb, var(--amber) 75%, var(--text));
}
.hub-trip-operator-text { font-size: 12px; color: var(--text-2); }

/* Pinned-winner accent — when the connection panel pins a featured
 * airline (matches the user's tab choice) instead of the on-time
 * leader, accent the winner card so it reads as "this is your pick"
 * rather than "this is the best". Subtle: a left-border stripe and a
 * recolored label. */
.winner-card[data-pin="same"] {
  border-left: 3px solid var(--green);
}
.winner-card[data-pin="same"] .winner-label {
  color: color-mix(in srgb, var(--green) 80%, var(--text));
}
.winner-card[data-pin="alliance"] {
  border-left: 3px solid var(--amber);
}
.winner-card[data-pin="alliance"] .winner-label {
  color: color-mix(in srgb, var(--amber) 80%, var(--text));
}

/* Synth-leg fallback chip: highlight the pinned airline so the user's
 * tab choice still surfaces even when route_stats has no data. */
.hub-leg-fallback-airline.is-pin.pin-same {
  border-color: color-mix(in srgb, var(--green) 60%, var(--border));
  background: color-mix(in srgb, var(--green) 12%, var(--bg));
}
.hub-leg-fallback-airline.is-pin.pin-alliance {
  border-color: color-mix(in srgb, var(--amber) 60%, var(--border));
  background: color-mix(in srgb, var(--amber) 12%, var(--bg));
}

/* ── Alliance pill ────────────────────────────────────────────────────────
 * Tiny membership badge attached to airline names everywhere. The base
 * variant is unobtrusive (works on the leaderboard / route rankings).
 * In connection mode, .is-match lifts the badge with the alliance's tab
 * accent and .is-other dims it so the user sees at a glance which
 * carriers form a single-ticket pair across two legs.
 */
.alliance-pill {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 999px;
  font-family: var(--system, -apple-system), sans-serif;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  vertical-align: 1px;
  white-space: nowrap;
  background: color-mix(in srgb, var(--text-3) 14%, transparent);
  color: var(--text-2);
  border: 1px solid color-mix(in srgb, var(--text-3) 22%, transparent);
}
.alliance-pill-sm { font-size: 9px; padding: 0 5px; }

/* Per-alliance brand tints — used only in the .is-match (alliance-mode)
 * variant so neutral views stay neutral. Colors picked from each
 * alliance's published brand palette; tone-mapped for our light surface. */
.alliance-pill.is-match {
  border-color: transparent;
  color: #fff;
}
.alliance-pill.is-match.alliance-pill-oneworld      { background: #2c5cab; }
.alliance-pill.is-match.alliance-pill-star_alliance { background: #1f5e8c; }
.alliance-pill.is-match.alliance-pill-skyteam       { background: #0a76a8; }

.alliance-pill.is-other {
  opacity: 0.55;
}

/* Connection-mode row state: in alliance pin mode, alliance-matched rows
 * get a faint left tint and unmatched rows are dimmed. The matched rows
 * remain primary in the visual hierarchy because they're grouped first
 * AND tinted; the dim is a secondary cue, not a hide. */
.airline-row.alliance-match {
  border-left: 2px solid color-mix(in srgb, var(--amber) 50%, transparent);
}
.airline-row.alliance-other {
  opacity: 0.78;
}
.airline-row.alliance-other:hover { opacity: 1; }

/* ═══════════════════════════════════════════════════════════════════════════
 * CONNECTION-ROW v2 PREVIEW (toggle in connection panel header)
 *
 * Compact layout: name + IATA + DOW only. Hides on-time %, avg delay,
 * flight-count caption. Caveat ("limited sample") becomes a leading "!"
 * glyph with the same tooltip. Click target unchanged → opens detail
 * modal. Easy revert: localStorage key flight-check-connection-row-design.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* Two-column grid: name takes available width, DOW chart pinned right
 * with a fixed-ish auto. Single row (override .has-dow's grid-rows). */
.airline-row.compact {
  grid-template-columns: 1fr auto;
  grid-template-rows: auto;
  padding: 12px 16px;
  align-items: center;
}
.airline-row.compact .row-primary,
.airline-row.compact .row-sub,
.airline-row.compact .dow-label {
  display: none;
}
/* In compact mode the DOW strip lives inline on the right where the
 * v1 chevron normally goes — kill the chevron rather than try to slot
 * both. Cursor + hover already convey clickability. */
.airline-row.compact.clickable::after {
  content: none;
}
.airline-row.compact.clickable {
  padding-right: 14px;
}
/* Pull DOW strip inline-right instead of full-width-below. Strip the
 * dashed top border + top margin/padding the v1 strip uses for
 * separation under the row body — those exist to break the strip from
 * the row above; in compact mode the strip IS the row, no separation
 * needed. */
.airline-row.compact .airline-row-dow {
  grid-column: 2;
  grid-row: 1;
  margin-top: 0;
  padding-top: 0;
  border-top: none;
  align-self: center;
  justify-self: end;
}
.airline-row.compact .row-name {
  font-size: 14px;
  display: inline-flex;
  align-items: baseline;
  flex-wrap: nowrap;
  gap: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Compact rows mute the alliance pill except in the matched-alliance
 * group — there it stays branded so the cross-leg pairing signal
 * remains the visual focus. */
.airline-row.compact .alliance-pill {
  background: transparent;
  border-color: color-mix(in srgb, var(--text-3) 30%, transparent);
  color: var(--text-3);
  opacity: 0.7;
}
.airline-row.compact.alliance-match .alliance-pill {
  background: color-mix(in srgb, var(--amber) 14%, transparent);
  border-color: color-mix(in srgb, var(--amber) 30%, transparent);
  color: var(--text-2);
  opacity: 1;
}

/* Explore-panel scope override — collapse the rank column so the name
 * gets the full freed space (mirrors the no-rank rule). */
.explore-panel .airline-row.compact {
  grid-template-columns: 1fr auto;
  padding: 10px 14px;
}


/* Grouped rest list inside the connection panel. Header introduces each
 * pool ("Other Oneworld carriers" vs "Other airlines on this route") so
 * the user understands why two carriers from the same route are
 * separated. The hint clarifies the practical meaning of the split:
 * single-ticket vs. separate booking. */
.airline-list-group { margin-top: 14px; }
.airline-list-group:first-of-type { margin-top: 8px; }
.airline-list-group-header {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; padding: 0 4px;
  margin-bottom: 8px;
}
.airline-list-group-title {
  font-size: 11px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-2);
}
.airline-list-group-hint {
  font-size: 10.5px; color: var(--text-3); font-style: italic;
}
.airline-list-group[data-group="alliance-others"] .airline-list-group-title {
  color: var(--text-3);
}

/* Synth-leg fallback grouping — mirrors the airline-list-group pattern
 * for the chip-list view. Same visual language so the user sees the
 * same partition logic whether or not we have route_stats data. */
.hub-leg-fallback-group { margin-top: 10px; }
.hub-leg-fallback-group:first-of-type { margin-top: 0; }
.hub-leg-fallback-group-title {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-2);
  margin-bottom: 6px;
}
.hub-leg-fallback-group-hint {
  font-weight: 400; text-transform: none; letter-spacing: 0;
  color: var(--text-3); font-style: italic;
  margin-left: 6px;
}
.hub-leg-fallback-airline.alliance-other { opacity: 0.6; }
.hub-leg-fallback-airline.alliance-match {
  border-color: color-mix(in srgb, var(--amber) 50%, var(--border));
}

/* ═══════════════════════════════════════════════════════════════════════════
 * MOBILE / TOUCH APPENDIX
 * Self-contained block appended at the end of the cascade so it overrides
 * earlier rules only when the conditions match. Strictly scoped to:
 *   - @media (max-width: 600px)  ← phone layout
 *   - @media (hover: none)       ← touch-device behavior
 *   - body.has-touch             ← runtime touch class set in app.js boot
 *   - touch-only CSS properties (touch-action, -webkit-tap-highlight-color,
 *     overscroll-behavior, env(safe-area-inset-*)) which are no-ops on
 *     desktop pointer devices.
 *
 * IMPORTANT: nothing in this block changes desktop visuals. If you find a
 * desktop pixel changing after editing here, that rule has leaked outside
 * its scope — fix the selector, don't widen the breakpoint.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ── Touch-only behavior (any viewport) ─────────────────────────────────── */
body {
  -webkit-tap-highlight-color: transparent;
}
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
@media (hover: none) {
  body { overscroll-behavior-y: none; }

  /* Permanent touch affordances: row arrows that were hover-only become
     persistently faintly visible so touch users see the row is tappable. */
  .airline-row.clickable::after { opacity: 0.4 !important; }

  /* Row hover backgrounds become :active feedback so taps register
     visually. We're not editing the original :hover rules — these are
     additive selectors that fire alongside them. */
  .airline-row:active,
  .flight-row:active,
  .dest-row:active,
  .hub-row:active,
  .region-option:active,
  .dropdown-item:active,
  .winner-card:active,
  .board-row:active { background: var(--board-hover, #f4f1eb); }
}

/* Suppress double-tap-zoom on tap targets. No effect on desktop pointer. */
.go-btn,
.nav-link,
.board-tab,
.airline-row,
.dest-row,
.hub-row,
.region-option,
.segmented-btn,
.dropdown-item,
.board-row,
.pagination-btn,
.hero-toggle-btn,
.oracle-token,
.explore-panel-close,
.disclaimer-trigger { touch-action: manipulation; }

/* ── Phone breakpoint — global shell (≤ 600px) ──────────────────────────── */
@media (max-width: 600px) {
  /* Hide the entire brand stack (logo + tagline) and the floating "why?"
     link on phones. The logo overlapped the centered nav and there's no
     room for both — the nav itself is sufficient identity. URL/refresh
     still goes home; the "why" page stays reachable from the disclaimer
     footer. */
  .brand-stack { display: none; }
  .why-link { display: none; }

  /* Nav: respect notch on landscape iPhones; tighten link padding. */
  nav { top: calc(8px + var(--safe-top)); }
  .nav-link { padding: 6px 12px; min-height: 36px; display: inline-flex; align-items: center; }

  /* Disclaimer trigger pill: lift above home indicator. */
  .disclaimer-trigger {
    bottom: calc(16px + var(--safe-bottom));
    right: calc(16px + var(--safe-right));
    min-height: 36px;
  }

  /* Pagination + segmented buttons: tap-target. */
  .pagination-btn,
  .pagination-page { min-height: var(--tap); display: inline-flex; align-items: center; justify-content: center; }
  .segmented-btn,
  .board-tab { min-height: var(--tap); }

  /* Dropdown items meet HIG minimum. */
  .dropdown-item { min-height: var(--tap); }

  /* Region option in filter menus. */
  .region-option { min-height: 40px; display: flex; align-items: center; }
}

/* ═════════════════════════════════════════════════════════════════════════
 * PHONE LAYOUT — page-specific (≤ 600px)
 * ═════════════════════════════════════════════════════════════════════════ */

/* ── Homepage / Routes hero ─────────────────────────────────────────────── */
@media (max-width: 600px) {
  .glow-box {
    padding: 32px 18px 22px;
    border-radius: 18px;
    border-width: 3px;
    max-width: 100%;
  }
  .sentence-main {
    font-size: clamp(20px, 5.6vw, 26px);
    line-height: 1.55;
    gap: 8px;
  }
  /* Airport input on hero stays centered & readable. 17px+ font defeats
     iOS Safari's auto-zoom-on-focus behavior for inputs. */
  .glow-box .airport-input {
    width: 4.6em;
    font-size: 17px;
    padding: 8px 10px;
  }
  /* Go button: full-width, tap-target height. */
  .hero-cta-row { width: 100%; }
  .hero-cta-row .go-btn,
  .glow-box .go-btn {
    width: 100%;
    max-width: 280px;
    min-height: var(--tap);
    font-size: 16px;
    padding: 12px 20px;
  }
  /* Dropdown autocomplete fits within the hero card on phones. */
  .dropdown {
    min-width: 200px;
    max-width: calc(100vw - 48px);
    max-height: 50vh;
  }
  /* Theme toggle: smaller pill, lift above home indicator. */
  .hero-theme-toggle {
    left: calc(14px + var(--safe-left));
    bottom: calc(14px + var(--safe-bottom));
    gap: 4px;
  }
  .hero-toggle-btn { padding: 6px 10px; font-size: 12px; }
}

/* ── Rankings (flap-board) ──────────────────────────────────────────────── */
@media (max-width: 600px) {
  .flap-board-page {
    padding: 64px 12px calc(56px + var(--safe-bottom));
  }
  .board-panel-inner { padding: 14px 10px 10px; }

  /* 4-col grid: rank / code / name / on-time%. The status dot is already
     hidden at ≤720px — keep that. The crucial bit is `minmax(0, 1fr)`
     on the name column so ellipsis can actually engage inside a grid. */
  .board-columns-airport,
  .board-columns-airline,
  .board-row {
    grid-template-columns: 30px 56px minmax(0, 1fr) 64px;
    gap: 10px;
  }
  .board-row { padding: 12px 4px; min-height: var(--tap); }
  .board-name {
    font-size: 15px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
  }
  .board-code .board-flap-cell { min-width: 18px; height: 26px; font-size: 14px; }
  .board-ontime .board-flap-cell { min-width: 18px; height: 26px; font-size: 16px; }
  .board-rank .board-flap-cell { min-width: 13px; height: 20px; font-size: 11px; }

  /* Tighter header: shrink title, drop the redundant subtitle. */
  .board-intro { margin-bottom: 12px; }
  .board-title { line-height: 1.2; }
  .board-subtitle { display: none; }

  /* Inert rules left for future reuse — see CLAUDE.md. */
  .board-row.is-expanded {
    grid-template-columns: 30px 56px minmax(0, 1fr) 64px;
    grid-template-rows: auto auto;
    row-gap: 6px;
    padding-bottom: 14px;
  }
  .board-row.is-expanded .board-name { white-space: normal; overflow: visible; }
  .board-row .board-row-detail {
    display: none;
    grid-column: 2 / -1;
    font-size: 12px;
    color: var(--board-ink-dim, var(--text-2));
    line-height: 1.4;
  }
  .board-row.is-expanded .board-row-detail { display: block; }

  /* Filters: two compact rows that actually fit a 360px viewport — no
     horizontal scroll. Row 1 = type switch (Airlines/Airports), full
     width. Row 2 = region pill + scope (if airline) + sort tabs,
     evenly distributed. Each pill shrinks to fit; nothing overflows. */
  .board-controls {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 12px 0 14px;
  }
  .board-controls-primary {
    width: 100%;
  }
  .board-controls-primary > * { width: 100%; }
  .board-controls-filters {
    display: flex;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 6px;
    width: 100%;
  }
  /* Each filter takes equal-ish share of the row and can shrink. */
  .board-controls-filters > * {
    flex: 1 1 0;
    min-width: 0;
  }
  /* Type switch (Airlines/Airports) — full-width, slightly taller. */
  .board-controls .board-type-switch {
    display: flex;
    width: 100%;
    min-height: 38px;
  }
  .board-controls .board-type-switch > * {
    flex: 1 1 0;
    justify-content: center;
  }
  /* Pills small but tappable (32–36px). */
  .board-controls .segmented-board,
  .board-controls .board-tabs {
    min-height: 36px;
    width: 100%;
    /* Override the desktop 164px fixed width so the pill flexes. */
    min-width: 0;
  }
  .board-controls .segmented-board .segmented-btn,
  .board-controls .board-tab,
  .board-controls .board-type-btn {
    min-height: 32px;
    padding: 0 8px;
    font-size: 11px;
    letter-spacing: 0.06em;
  }
  /* Region dropdown wrapper + trigger: shrink + ellipsis so a long name
     like "North America" doesn't overflow the pill. */
  .board-controls .region-dropdown { width: 100%; min-width: 0; }
  .board-controls .region-trigger {
    width: 100%;
    min-height: 36px;
    padding: 0 10px;
    font-size: 11px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    justify-content: space-between;
  }
}

/* ── Explore (map + bottom sheet) ───────────────────────────────────────── */
/* The existing @media (max-width: 820px) block already turns the panel
 * into a bottom sheet at 72% height. These phone rules refine that into
 * a true Apple-style bottom sheet with snap states + drag handle, plus
 * tighten overlays so they don't fight the map. */
@media (max-width: 600px) {
  .explore-root {
    height: calc(100vh - 56px);
    margin-top: 56px;
  }
  /* Route ticker as a centered floating chip (not a stretched bar). */
  .explore-ticker {
    top: calc(8px + var(--safe-top));
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    width: max-content;
    max-width: calc(100% - 24px);
    padding: 9px 14px;
  }
  .explore-ticker-sentence {
    flex-wrap: nowrap;
    justify-content: center;
    gap: 8px;
    font-size: 15px;
  }
  /* Drop the long "I want to fly ✈ from" prefix on phones — there's no
     room and the inputs already say what to do. */
  .explore-ticker .explore-ticker-label:first-child { display: none; }
  /* Push input above iOS auto-zoom threshold (≥17px). */
  .explore-ticker .airport-input {
    font-size: 17px;
    width: 60px;
    padding: 4px 6px;
  }

  /* Hide the Top Hubs overlay on phones entirely. The map is the
     primary surface; hubs add cognitive load. Discoverability is
     preserved on tablet/desktop where the existing 820px rules apply. */
  .explore-hub-overlay { display: none !important; }

  /* Compact legend; lift above home indicator. */
  .explore-legend {
    left: 10px;
    bottom: calc(10px + var(--safe-bottom));
    padding: 5px 9px;
    gap: 4px 8px;
    font-size: 10px;
  }
  .explore-legend .legend-title { display: none; }

  /* Bottom sheet — Apple-style with snap states.
     The JS sets `data-sheet-state` to "peek" | "half" | "full" on the
     panel and sets a CSS var --sheet-y for in-flight drag offsets.
     When data-sheet-state is set, transforms come from those vars; the
     820px rules above set translateY(100%) for the hidden state, which
     this block overrides via the data-sheet-state attribute. */
  .explore-panel {
    height: calc(100vh - 56px - var(--safe-top));
    border-radius: 18px 18px 0 0;
    padding: 14px 14px calc(28px + var(--safe-bottom));
    box-shadow: 0 -10px 36px rgba(12, 12, 24, 0.14);
    transition: transform 280ms cubic-bezier(0.22, 1, 0.36, 1);
    will-change: transform;
  }
  .explore-panel[data-sheet-state="peek"] { transform: translateY(calc(100% - 96px)); }
  .explore-panel[data-sheet-state="half"] { transform: translateY(50%); }
  .explore-panel[data-sheet-state="full"] { transform: translateY(0); }
  /* Keep `.is-open` working as a coarse "panel exists/visible" flag for
     code that listens; on phones the data-sheet-state attribute does
     the real positioning work. Compound `.is-open[data-sheet-state]`
     also matches so the snap-state transforms beat the existing
     `.is-open { transform: translateX(0) }` rule from the desktop block. */
  .explore-panel.is-open[data-sheet-state="peek"] { transform: translateY(calc(100% - 96px)); }
  .explore-panel.is-open[data-sheet-state="half"] { transform: translateY(50%); }
  .explore-panel.is-open[data-sheet-state="full"] { transform: translateY(0); }
  /* Dragging: needs higher specificity than .is-open[data-sheet-state="X"]
     (which is 30) so the live drag transform wins. Adding `.is-open`
     keeps these at 30 too — source order makes them win. */
  .explore-panel[data-dragging="true"],
  .explore-panel.is-open[data-dragging="true"] {
    transition: none;
    transform: translateY(var(--sheet-y, 0));
  }

  /* Drag handle at the top of the sheet — Apple's signature 36×4 pill. */
  .explore-panel-handle {
    display: block;
    width: 38px;
    height: 5px;
    margin: 2px auto 10px;
    border-radius: 999px;
    background: rgba(44, 41, 38, 0.22);
    cursor: grab;
    touch-action: none;
  }
  .explore-panel[data-dragging="true"] .explore-panel-handle { cursor: grabbing; }

  /* Disclaimer pill repositions when sheet is open so it doesn't overlap
     the sheet content. Body class is toggled by the gesture handler. */
  body.is-explore.is-sheet-half .disclaimer-trigger,
  body.is-explore.is-sheet-full .disclaimer-trigger { display: none; }

  /* "See N destinations" pill — phone-only affordance to pull up the
     bottom sheet when the user has picked an origin but no destination.
     Centered above the home indicator; lifts gently on tap. */
  .explore-show-panel {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    bottom: calc(20px + var(--safe-bottom));
    z-index: 18;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    padding: 10px 18px;
    border: none;
    border-radius: 999px;
    background: var(--text);
    color: var(--surface);
    font-family: 'Inter', sans-serif;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: -0.01em;
    box-shadow: 0 8px 24px rgba(12, 12, 24, 0.22);
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
  }
  .explore-show-panel[hidden] { display: none; }
  .explore-show-panel:active { transform: translateX(-50%) translateY(1px); }
  .explore-show-panel-chevron {
    font-family: 'Inter', sans-serif;
    font-size: 16px;
    line-height: 1;
    font-weight: 600;
  }
  /* Hide when the sheet is already open (user dragged it up) so it
     doesn't sit on top of sheet content. */
  body.is-sheet-half .explore-show-panel,
  body.is-sheet-full .explore-show-panel { display: none; }
}

/* Drag handle + show-panel pill hidden on desktop & tablet — phone-only. */
@media (min-width: 601px) {
  .explore-panel-handle { display: none; }
  .explore-show-panel { display: none !important; }
}

/* ── Oracle (8-ball) ─────────────────────────────────────────────────────
 * Single .oracle-prompt element renders as flowing prose on desktop AND
 * as a stacked labeled form on phone. The trick: connector words sit
 * inside .oracle-prompt-connector spans and synthetic labels sit inside
 * .oracle-prompt-label spans. Each token-group is wrapped in
 * .oracle-prompt-row, which is `display: contents` on desktop (children
 * inherit the parent's prose flex layout) and `display: grid` on phone
 * (becomes a labeled row).
 * ─────────────────────────────────────────────────────────────────────── */

/* Default (desktop): prose mode. Synthetic labels hidden, rows transparent. */
.oracle-prompt-label { display: none; }
.oracle-prompt-row { display: contents; }

@media (max-width: 600px) {
  .oracle-page {
    padding: calc(96px + var(--safe-top)) 16px calc(48px + var(--safe-bottom));
  }
  .oracle-headline { margin-bottom: 18px; }

  /* Phone: stack the prompt as a vertical labeled form. */
  .oracle-prompt {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin: 0 auto 24px;
    max-width: 360px;
    font-size: 16px;
    line-height: 1.4;
    text-align: left;
  }
  /* Hide the prose connector words ("I am flying from", "to", etc.). */
  .oracle-prompt-connector { display: none; }
  .oracle-prompt-label { display: block; }
  .oracle-prompt-row {
    display: grid;
    grid-template-columns: 56px minmax(0, 1fr);
    align-items: center;
    gap: 12px;
  }
  .oracle-prompt-label {
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 400;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-3);
  }
  .oracle-prompt-row .oracle-pop-wrap { width: 100%; display: block; }
  .oracle-prompt-row .oracle-token {
    width: 100%;
    min-height: var(--tap);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    text-align: center;
    box-sizing: border-box;
  }
  .oracle-prompt-row .oracle-token.is-airport { width: 100%; }
  .oracle-prompt-row .airport-input {
    width: 100%;
    font-size: 17px;
    padding: 10px 12px;
    text-align: center;
  }

  /* Popovers as a centered bottom-anchored sheet on phone. */
  .oracle-popover {
    position: fixed !important;
    left: 16px !important;
    right: 16px !important;
    top: auto !important;
    bottom: calc(16px + var(--safe-bottom)) !important;
    min-width: 0 !important;
    max-width: calc(100vw - 32px) !important;
    max-height: 60vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    transform: none !important;
  }

  /* Slider thumb size meets HIG. */
  .oracle-scale input[type="range"]::-webkit-slider-thumb { width: 28px; height: 28px; }
  .oracle-scale input[type="range"]::-moz-range-thumb { width: 28px; height: 28px; }
}

/* ── Anti-overflow safety (≤ 600px) ─────────────────────────────────────── */
/* Catch-all: kill any horizontal scroll on the body that might leak from
 * a wide grandchild. body already has overflow-x: hidden globally, but
 * defensive belt-and-braces. */
@media (max-width: 600px) {
  html, body { max-width: 100%; }
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* WELCOME OVERLAY — first-visit intro on `/`                                 */
/* ═══════════════════════════════════════════════════════════════════════════ */

.welcome-overlay {
  position: fixed; inset: 0; z-index: 260;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  /* No background scrim and no backdrop-filter. A scrim covers the area
     around nav/brand chrome (transparent or translucent), tinting them
     grey. Backdrop-filter does the same via blur sampling. The blurred
     .map-canvas + card drop-shadow already give the card enough
     separation. */
  background: transparent;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s var(--ease-out);
}
.welcome-overlay.is-open { opacity: 1; pointer-events: auto; }

/* Keep nav and chrome interactive (above the overlay's pointer-events
   layer) while welcoming. They remain visually unmodified — the
   overlay has no scrim, so no tint to defend against. */
body.is-welcoming nav,
body.is-welcoming .brand-stack,
body.is-welcoming .why-link {
  z-index: 270;
}

.welcome-card {
  position: relative;
  width: 100%;
  max-width: 480px;
  padding: 44px 36px 36px;
  background: var(--surface);
  border: 1px solid rgba(44, 41, 38, 0.08);
  border-radius: 18px;
  box-shadow:
    0 28px 80px rgba(0, 0, 0, 0.16),
    0 8px 24px rgba(0, 0, 0, 0.06);
  text-align: center;
  transform: scale(0.96) translateY(8px);
  transition: transform 0.5s var(--ease-out);
}
.welcome-overlay.is-open .welcome-card { transform: scale(1) translateY(0); }

.welcome-line {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 17px;
  line-height: 1.55;
  color: var(--text);
  margin: 0 0 14px;
  text-wrap: balance;
}
.welcome-line strong { font-weight: 700; }
.welcome-line.is-closer {
  margin-top: 26px;
  margin-bottom: 28px;
}

.welcome-word {
  display: inline-block;
  opacity: 0;
  transform: translateY(8px);
  animation: welcome-word-in 0.55s var(--ease-out) forwards;
  animation-delay: var(--d, 0ms);
  will-change: transform, opacity;
}

.welcome-cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: #fff;
  background: var(--text);
  border: none;
  border-radius: 999px;
  padding: 12px 26px;
  min-height: var(--tap);
  cursor: pointer;
  opacity: 0;
  transform: translateY(10px);
  animation: welcome-word-in 0.6s var(--ease-out) forwards;
  animation-delay: var(--d, 0ms);
  transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
.welcome-cta:hover {
  background: #1a1714;
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}
.welcome-cta:focus-visible {
  outline: 2px solid var(--hero-accent);
  outline-offset: 3px;
}
.welcome-cta-arrow {
  display: inline-block;
  transition: transform 0.2s var(--ease-out);
}
.welcome-cta:hover .welcome-cta-arrow { transform: translateX(3px); }

@keyframes welcome-word-in {
  to { opacity: 1; transform: translateY(0); }
}
/* Hover-time button transitions still need `animation-name: none` once the
   entrance is done — the `forwards` fill-mode keeps the final state, and
   the .18s transition rules kick in on top for hover. */

/* While welcoming: blur the map and hide every other UI surface so the
   card stands alone. Removing the body class kicks them all back in
   together via a single shared transition. */
.map-canvas {
  transition: filter 0.8s var(--ease-out), transform 0.8s var(--ease-out);
}
body.is-welcoming .map-canvas {
  filter: blur(10px);
  transform: scale(1.02); /* hides blur edge bleed at viewport edges */
}

.explore-ticker,
.explore-legend,
.explore-hub-overlay,
.explore-panel,
.explore-show-panel {
  transition: opacity 0.6s var(--ease-out), transform 0.6s var(--ease-out);
}
body.is-welcoming .explore-ticker,
body.is-welcoming .explore-legend,
body.is-welcoming .explore-hub-overlay,
body.is-welcoming .explore-panel,
body.is-welcoming .explore-show-panel {
  opacity: 0;
  pointer-events: none;
  transform: translateY(-4px);
}

@media (prefers-reduced-motion: reduce) {
  .welcome-overlay,
  .welcome-card,
  .welcome-word,
  .welcome-cta,
  .map-canvas,
  body.is-welcoming .explore-ticker,
  body.is-welcoming .explore-legend,
  body.is-welcoming .explore-hub-overlay {
    transition: none;
    animation: none;
  }
  .welcome-word, .welcome-cta { opacity: 1; transform: none; }
  body.is-welcoming .map-canvas { transform: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* PREDICT PICKER PAGE (/predict) — three apps on a desktop                    */
/* ═══════════════════════════════════════════════════════════════════════════ */

.predict-desk {
  max-width: 980px;
  margin: 0 auto;
  padding: 96px 24px 96px;
}
.predict-desk-intro {
  margin-bottom: 56px;
  text-align: center;
}
.predict-desk-title {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  font-weight: 700;
  font-size: 38px;
  letter-spacing: -0.022em;
  color: var(--text);
  margin: 0 0 8px;
}
.predict-desk-sub {
  margin: 0 auto;
  max-width: 520px;
  font-size: 15px;
  color: var(--text-2);
}
.predict-apps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;
  align-items: start;
  justify-items: center;
}
.predict-app {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  text-decoration: none;
  color: inherit;
  padding: 16px 12px 14px;
  border-radius: 14px;
  max-width: 270px;
  cursor: pointer;
  transition:
    transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1),
    background 180ms ease-out;
}
.predict-app:hover { background: rgba(44, 41, 38, 0.04); }
.predict-app:hover .predict-app-icon { transform: translateY(-4px) scale(1.04); }
.predict-app:hover .predict-app-icon::after { transform: translateX(-50%) scaleX(1.15); opacity: 0.55; }
.predict-app:active .predict-app-icon { transform: translateY(0) scale(0.98); }
.predict-app-icon {
  position: relative;
  display: block;
  width: 144px;
  height: 144px;
  margin-bottom: 14px;
  transition: transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1);
  will-change: transform;
}
/* Soft contact shadow under each icon — grounds the "object" on the desk
   surface without adding a card border. */
.predict-app-icon::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -6px;
  width: 70%;
  height: 10px;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at center,
    rgba(40, 30, 20, 0.28) 0%,
    rgba(40, 30, 20, 0.10) 45%,
    rgba(40, 30, 20, 0) 75%);
  filter: blur(2px);
  opacity: 0.4;
  transition: transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 220ms ease-out;
  pointer-events: none;
}
.predict-app-icon img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  -webkit-user-drag: none;
  user-select: none;
}
.predict-app-name {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
  margin-bottom: 4px;
}
.predict-app-caption {
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-2);
  max-width: 240px;
  white-space: nowrap;
}

@media (max-width: 720px) {
  .predict-desk { padding: 72px 20px 80px; }
  .predict-desk-intro { margin-bottom: 36px; }
  .predict-apps { grid-template-columns: 1fr; gap: 28px; }
  .predict-app-icon { width: 120px; height: 120px; }
}
/* ═════════════════════════════════════════════════════════════════════════
 * style-v2.css — Sitewide v2 design language (Snow Leopard / Aqua, ~2009).
 *
 * Every rule is scoped under `html[data-design="v2"]` so the file is inert
 * when v2 is not active. Toggle via the v1/v2 pair at the right end of the
 * nav bar (sets data-design on <html> and persists in localStorage).
 *
 * Direction: cool gray page bg (#E8EAED), white surfaces with hairline
 * borders + soft drop shadows, Aqua-blue selection + glossy CTA, Lucida
 * Grande sitewide. Saturation pulled to Aqua-tier (not neon). Personality
 * preserved via the flap-cell animation, round Aqua-pearl status dots,
 * and a hint of overshoot easing on press → release transitions.
 *
 * v1 styling in style.css is untouched. Delete this file to remove v2.
 * ═════════════════════════════════════════════════════════════════════════ */

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

:root[data-design="v2"] {
  /* Surfaces — buttery off-white, Venn of cream + yellow + white */
  --v2-bg:           #F8F5ED;
  --v2-bg-deep:      #ECE7D8;
  --v2-surface:      #FFFFFF;
  --v2-surface-2:    #F2EDE0;

  /* Aqua gloss — canonical raised-surface gradient */
  --v2-gloss:        linear-gradient(to bottom, #FFFFFF 0%, #F1EDE3 100%);
  --v2-gloss-hover:  linear-gradient(to bottom, #FFFFFF 0%, #F6F2E8 100%);
  --v2-gloss-press:  linear-gradient(to bottom, #DEDACE 0%, #ECE7D8 100%);

  /* Primary accent — Aqua blue (Snow Leopard era) */
  --v2-aqua:         #3D80DF;
  --v2-aqua-hi:      #5C9FE8;
  --v2-aqua-lo:      #2D6BC9;
  --v2-aqua-press-hi:#1F4F9C;
  --v2-aqua-press-lo:#3B6FBE;
  --v2-aqua-glow:    rgba(61, 128, 223, 0.30);

  --v2-aqua-default: linear-gradient(to bottom, #5C9FE8 0%, #2D6BC9 100%);
  --v2-aqua-press:   linear-gradient(to bottom, #1F4F9C 0%, #3B6FBE 100%);
  --v2-aqua-hover:   linear-gradient(to bottom, #6EAEEC 0%, #3F7AD3 100%);

  /* Fun accent — warm gold (Snow Leopard "default button" gold). Used for
     random-dest buttons. Pairs with the Aqua blue primary like the
     yellow-and-blue pencil shape of the period. */
  --v2-fun:          #F3B91F;
  --v2-fun-default:  linear-gradient(to bottom, #FBE07A 0%, #F3B91F 100%);
  --v2-fun-hover:    linear-gradient(to bottom, #FFEB8E 0%, #F8C72F 100%);
  --v2-fun-press:    linear-gradient(to bottom, #C99115 0%, #E5AC32 100%);
  --v2-fun-glow:     rgba(243, 185, 31, 0.36);

  /* Ink — warm-leaning charcoal to match cream bg */
  --v2-ink:          #2A2622;
  --v2-ink-2:        #6B665E;
  --v2-ink-3:        #A09A8E;
  --v2-ink-inverse:  #FFFFFF;

  /* Borders (hairlines by default) */
  --v2-border:        rgba(42, 38, 34, 0.16);
  --v2-border-strong: rgba(42, 38, 34, 0.32);
  --v2-border-soft:   rgba(42, 38, 34, 0.08);

  /* Shadows (soft Aqua drops, never hard offset) */
  --v2-shadow-sm:    0 1px 1px rgba(0, 0, 0, 0.08);
  --v2-shadow:       0 1px 2px rgba(0, 0, 0, 0.10),
                     0 4px 12px rgba(0, 0, 0, 0.05);
  --v2-shadow-lg:    0 2px 6px rgba(0, 0, 0, 0.12),
                     0 12px 28px rgba(0, 0, 0, 0.08);
  --v2-shadow-xl:    0 4px 12px rgba(0, 0, 0, 0.15),
                     0 24px 48px rgba(0, 0, 0, 0.12);

  --v2-bevel-hi:        inset 0 1px 0 rgba(255, 255, 255, 0.6);
  --v2-bevel-hi-blue:   inset 0 1px 0 rgba(255, 255, 255, 0.4);
  --v2-press-inset:     inset 0 1px 2px rgba(0, 0, 0, 0.18);
  --v2-aqua-press-inset:inset 0 1px 2px rgba(0, 0, 0, 0.25),
                        inset 0 -1px 0 rgba(255, 255, 255, 0.10);

  --v2-focus-ring:   0 0 0 3px var(--v2-aqua-glow);

  /* Status accents — vivid (so c-green/c-amber/c-red read against cream) */
  --v2-green:        #1A8E4A;
  --v2-green-hi:     #2EA85F;
  --v2-amber:        #D89817;
  --v2-amber-hi:     #E5AC32;
  --v2-red:          #D8392E;
  --v2-red-hi:       #E36158;

  --v2-pill-green:   linear-gradient(to bottom, #2EA85F 0%, #1A8E4A 100%);
  --v2-pill-amber:   linear-gradient(to bottom, #E5AC32 0%, #D89817 100%);
  --v2-pill-red:     linear-gradient(to bottom, #E36158 0%, #D8392E 100%);

  /* Hero (deep night + horizon band) */
  --v2-hero-bg:      #15192A;
  --v2-hero-band:    #C9483B;
  --v2-hero-screen:  #F4F0E5;
  --v2-hero-frame:   #2A2722;
  --v2-hero-accent:  #E26C42;

  /* Geometry */
  --v2-radius:       4px;
  --v2-radius-card:  8px;
  --v2-radius-pill:  999px;

  /* Type — Lucida Grande for body, Inter for displays/headings */
  --v2-sans:         'Lucida Grande', 'Lucida Sans Unicode',
                     'Helvetica Neue', 'Segoe UI', sans-serif;
  --v2-display:      'Inter', -apple-system, BlinkMacSystemFont,
                     'Helvetica Neue', sans-serif;
  --v2-mono:         'Monaco', 'Andale Mono', 'Courier New', monospace;

  /* Easing */
  --v2-ease:         cubic-bezier(0.4, 0, 0.2, 1);
  --v2-ease-spring:  cubic-bezier(0.5, 1.6, 0.4, 1);

  /* Status helpers */
  --v2-status-good:  #1A8E4A;
  --v2-status-warn:  #D89817;
  --v2-status-bad:   #D8392E;
  --v2-status-muted: #A09A8E;

  /* Type scale — Apple HIG-aligned semantic roles. Use these tokens
   * instead of hardcoded px so the scale stays consistent. */
  --v2-text-display:    38px;   /* page hero, oracle headline, why title */
  --v2-text-title-1:    26px;   /* large section heading (modal-title-text) */
  --v2-text-title-2:    22px;   /* secondary heading */
  --v2-text-title-3:    19px;   /* hero metric numerals (modal-stat-value) */
  --v2-text-headline:   17px;   /* emphasized body, list-row primary text */
  --v2-text-body:       14px;   /* default body, CTA label */
  --v2-text-callout:    13px;   /* secondary body, CTA fallback */
  --v2-text-label:      12px;   /* control labels, button text */
  --v2-text-meta:       11px;   /* metadata, table column headers */
  --v2-text-caption:    10px;   /* tiny uppercase unit labels */

  /* Spacing scale (8pt base). Use --v2-space-* on new layout work
   * instead of raw px. */
  --v2-space-1:    4px;
  --v2-space-2:    8px;
  --v2-space-3:   12px;
  --v2-space-4:   16px;
  --v2-space-5:   20px;
  --v2-space-6:   24px;
  --v2-space-7:   32px;
  --v2-space-8:   40px;
  --v2-space-9:   48px;
  --v2-space-10:  64px;

  /* Tracking */
  --v2-tracking-display: -0.025em;
  --v2-tracking-tight:   -0.015em;
  --v2-tracking-normal:   0;
  --v2-tracking-wide:     0.06em;
  --v2-tracking-wider:    0.10em;
}

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

html[data-design="v2"] {
  font-family: var(--v2-sans);
  font-size: 14px;
  line-height: 1.45;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--v2-ink);
  background: var(--v2-bg);
  -webkit-font-smoothing: antialiased;
}
html[data-design="v2"] body { background: var(--v2-bg); }

/* Re-point universal status helpers to v2 accents */
html[data-design="v2"] .c-green { color: var(--v2-status-good); }
html[data-design="v2"] .c-amber { color: var(--v2-status-warn); }
html[data-design="v2"] .c-red   { color: var(--v2-status-bad); }
html[data-design="v2"] .c-muted { color: var(--v2-status-muted); }

/* No headers in caps — sweep every heading/kicker/label class so v1's
 * inherited `text-transform: uppercase` doesn't bleed through. v2 reads
 * sentence case sitewide. */
html[data-design="v2"] .board-title,
html[data-design="v2"] .board-subtitle,
html[data-design="v2"] .board-kicker,
html[data-design="v2"] .board-header-label,
html[data-design="v2"] .board-header-meta,
html[data-design="v2"] .board-columns,
html[data-design="v2"] .board-columns span,
html[data-design="v2"] .why-title,
html[data-design="v2"] .why-link,
html[data-design="v2"] .oracle-headline,
html[data-design="v2"] .oracle-prompt-label,
html[data-design="v2"] .oracle-mode-toggle,
html[data-design="v2"] .modal-title,
html[data-design="v2"] .modal-title-text,
html[data-design="v2"] .modal-kicker,
html[data-design="v2"] .modal-stat-label,
html[data-design="v2"] .modal-caveat,
html[data-design="v2"] .winner-label,
html[data-design="v2"] .winner-metric-label,
html[data-design="v2"] .row-primary-label,
html[data-design="v2"] .row-metric-label,
html[data-design="v2"] .list-header-label,
html[data-design="v2"] .controls-label,
html[data-design="v2"] .route-section-label,
html[data-design="v2"] .rc-grade-caption,
html[data-design="v2"] .rc-form,
html[data-design="v2"] .rc-field-label,
html[data-design="v2"] .hub-overlay-title,
html[data-design="v2"] .hub-route-title,
html[data-design="v2"] .hub-trip-headline,
html[data-design="v2"] .hub-trip-label,
html[data-design="v2"] .hub-leg-num,
html[data-design="v2"] .hub-leg-header,
html[data-design="v2"] .hub-row-name,
html[data-design="v2"] .itin-title,
html[data-design="v2"] .itin-tag,
html[data-design="v2"] .itin-row-synth,
html[data-design="v2"] .itin-count,
html[data-design="v2"] .explore-panel-title,
html[data-design="v2"] .explore-panel-kicker,
html[data-design="v2"] .explore-ticker-label,
html[data-design="v2"] .explore-ticker-sentence,
html[data-design="v2"] .legend-title,
html[data-design="v2"] .legend-disclaimer,
html[data-design="v2"] .site-footer-title,
html[data-design="v2"] .disclaimer-trigger,
html[data-design="v2"] .hero-toggle-btn,
html[data-design="v2"] .design-toggle-btn,
html[data-design="v2"] .flight-time-label,
html[data-design="v2"] .flight-date-label,
html[data-design="v2"] .nav-link,
html[data-design="v2"] .sentence-main,
html[data-design="v2"] .sentence-sub,
html[data-design="v2"] .row-name,
html[data-design="v2"] .row-code,
html[data-design="v2"] .row-sub,
html[data-design="v2"] .row-rank,
html[data-design="v2"] .winner-code,
html[data-design="v2"] .dest-row-code,
html[data-design="v2"] .dest-row-city,
html[data-design="v2"] .results-route .code,
html[data-design="v2"] .modal-code-tile,
html[data-design="v2"] .modal-code,
html[data-design="v2"] .results-count,
html[data-design="v2"] .results-meta,
html[data-design="v2"] .dow-label,
html[data-design="v2"] .dow-letter,
html[data-design="v2"] .dot-note,
html[data-design="v2"] .row-caveat,
html[data-design="v2"] .click-hint,
html[data-design="v2"] .no-results .big,
html[data-design="v2"] .no-results .sub {
  text-transform: none;
}

/* Page transition scrim */
html[data-design="v2"] .page-cream-overlay { background: var(--v2-bg); }

/* ── Brand stack ────────────────────────────────────────────────────────── */

html[data-design="v2"] .brand-logo:hover { transform: none; opacity: 0.6; }
html[data-design="v2"] .brand-tagline { color: var(--v2-ink-2); }
html[data-design="v2"] .brand-tagline-link { color: var(--v2-aqua); font-weight: 500; }
html[data-design="v2"] body.is-home .brand-tagline {
  color: rgba(255, 255, 255, 0.85);
  text-shadow: none;
}
html[data-design="v2"] body.is-home .brand-tagline-link {
  color: #fff;
  text-decoration: underline;
}
html[data-design="v2"] body.is-home .brand-logo-img { filter: invert(1); }
:root[data-hero-theme="day"] html[data-design="v2"] body.is-home .brand-tagline {
  color: rgba(29, 29, 31, 0.78);
}
:root[data-hero-theme="day"] html[data-design="v2"] body.is-home .brand-logo-img {
  filter: none;
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * NAV — the load-bearing piece                                              *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] nav {
  background: var(--v2-gloss);
  border: 1px solid var(--v2-border-strong);
  border-radius: var(--v2-radius-pill);
  box-shadow: var(--v2-shadow), var(--v2-bevel-hi);
  padding: 3px;
  gap: 0;
  overflow: hidden;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
html[data-design="v2"] nav.dark {
  background: linear-gradient(to bottom,
    rgba(255, 255, 255, 0.10) 0%,
    rgba(255, 255, 255, 0.04) 100%);
  border-color: rgba(255, 255, 255, 0.18);
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.4),
              inset 0 1px 0 rgba(255, 255, 255, 0.12);
}
:root[data-hero-theme="day"] html[data-design="v2"] nav.dark {
  background: linear-gradient(to bottom,
    rgba(255, 255, 255, 0.30) 0%,
    rgba(255, 255, 255, 0.16) 100%);
  border-color: rgba(0, 0, 0, 0.18);
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.18),
              inset 0 1px 0 rgba(255, 255, 255, 0.4);
}

/* Hide v1's animated indicator pill — v2 uses static pressed-state styling */
html[data-design="v2"] .nav-indicator { display: none; }

html[data-design="v2"] .nav-link {
  position: relative;
  z-index: 1;
  padding: 6px 18px;
  font-size: 13px;
  font-weight: 500;
  font-family: var(--v2-sans);
  text-decoration: none;
  border-radius: calc(var(--v2-radius-pill) - 3px);
  color: var(--v2-ink);
  background: transparent;
  border: 1px solid transparent;
  transition: background 120ms var(--v2-ease),
              color 120ms var(--v2-ease),
              box-shadow 140ms var(--v2-ease-spring);
  user-select: none;
  cursor: pointer;
}
html[data-design="v2"] .nav-link:hover {
  background: rgba(255, 255, 255, 0.5);
  color: var(--v2-ink);
}
html[data-design="v2"] .nav-link:active {
  background: var(--v2-gloss-press);
  box-shadow: var(--v2-press-inset);
  transform: translateY(0.5px);
}

/* Active (selected, persistent) — Aqua-blue gloss pressed-key */
html[data-design="v2"] .nav-link.active {
  background: var(--v2-aqua-default);
  border-color: var(--v2-border-strong);
  color: var(--v2-ink-inverse);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.22);
  box-shadow:
    var(--v2-bevel-hi-blue),
    inset 0 -1px 0 rgba(0, 0, 0, 0.10),
    0 1px 2px rgba(0, 0, 0, 0.18);
}
html[data-design="v2"] .nav-link.active:active {
  background: var(--v2-aqua-press);
  box-shadow: var(--v2-aqua-press-inset);
  transform: translateY(0.5px);
}

/* Dark-mode (hero) variant */
html[data-design="v2"] nav.dark .nav-link {
  color: rgba(255, 255, 255, 0.7);
}
html[data-design="v2"] nav.dark .nav-link:hover {
  background: rgba(255, 255, 255, 0.10);
  color: #fff;
}
html[data-design="v2"] nav.dark .nav-link.active {
  background: var(--v2-aqua-default);
  border-color: rgba(0, 0, 0, 0.4);
  color: #fff;
}
:root[data-hero-theme="day"] html[data-design="v2"] nav.dark .nav-link {
  color: rgba(29, 29, 31, 0.72);
}
:root[data-hero-theme="day"] html[data-design="v2"] nav.dark .nav-link.active {
  color: #fff;
}

/* ── v1/v2 toggle inside the nav (same anatomy as nav-link) ─────────────── */

html[data-design="v2"] .design-toggle {
  margin-left: 6px;
  padding: 0;
  border: none;
  background: transparent;
  border-radius: 0;
  display: inline-flex;
  align-items: stretch;
  position: relative;
}
html[data-design="v2"] .design-toggle::before {
  content: "";
  position: absolute;
  top: 4px; bottom: 4px; left: -3px;
  width: 1px;
  background: var(--v2-border);
}
html[data-design="v2"] nav.dark .design-toggle::before {
  background: rgba(255, 255, 255, 0.16);
}
html[data-design="v2"] .design-toggle-btn {
  padding: 6px 10px;
  font-size: 10px;
  font-family: var(--v2-mono);
  letter-spacing: 0.10em;
  font-weight: 600;
  border-radius: calc(var(--v2-radius-pill) - 3px);
  color: var(--v2-ink-2);
  background: transparent;
  box-shadow: none;
  border: 1px solid transparent;
  transition: background 120ms var(--v2-ease),
              color 120ms var(--v2-ease),
              box-shadow 140ms var(--v2-ease-spring);
  cursor: pointer;
}
html[data-design="v2"] .design-toggle-btn:hover {
  background: rgba(255, 255, 255, 0.5);
  color: var(--v2-ink);
}
html[data-design="v2"] .design-toggle-btn[aria-pressed="true"] {
  background: var(--v2-aqua-default);
  border-color: var(--v2-border-strong);
  color: var(--v2-ink-inverse);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.22);
  box-shadow:
    var(--v2-bevel-hi-blue),
    inset 0 -1px 0 rgba(0, 0, 0, 0.10),
    0 1px 2px rgba(0, 0, 0, 0.18);
}
html[data-design="v2"] nav.dark .design-toggle-btn {
  color: rgba(255, 255, 255, 0.62);
}
html[data-design="v2"] nav.dark .design-toggle-btn:hover {
  background: rgba(255, 255, 255, 0.10);
  color: #fff;
}
html[data-design="v2"] nav.dark .design-toggle-btn[aria-pressed="true"] {
  color: #fff;
  background: var(--v2-aqua-default);
  border-color: rgba(0, 0, 0, 0.4);
}

/* ── Why link (top-right corner) ────────────────────────────────────────── */

html[data-design="v2"] .why-link {
  font-family: var(--v2-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: none;
  color: var(--v2-ink);
  background: var(--v2-gloss);
  border: 1px solid var(--v2-border-strong);
  border-radius: var(--v2-radius);
  padding: 4px 10px;
  box-shadow: var(--v2-shadow-sm), var(--v2-bevel-hi);
  text-decoration: none;
  font-weight: 500;
  transition: background 100ms var(--v2-ease),
              box-shadow 140ms var(--v2-ease-spring);
}
html[data-design="v2"] .why-link:hover { background: var(--v2-gloss-hover); }
html[data-design="v2"] .why-link:active {
  background: var(--v2-gloss-press);
  box-shadow: var(--v2-press-inset);
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * UNIVERSAL BUTTON RECIPES (B-white, B-blue, B-red)                         *
 * ═════════════════════════════════════════════════════════════════════════ */

/* B-white — base for every button that isn't a CTA or destructive */
html[data-design="v2"] .go-btn,
html[data-design="v2"] .sort-btn,
html[data-design="v2"] .segmented-btn,
html[data-design="v2"] .board-tab,
html[data-design="v2"] .board-type-btn,
html[data-design="v2"] .pagination-btn,
html[data-design="v2"] .pagination-page,
html[data-design="v2"] .rc-expand-btn,
html[data-design="v2"] .hub-retry,
html[data-design="v2"] .disclaimer-trigger,
html[data-design="v2"] .itin-toggle button,
html[data-design="v2"] .region-trigger,
html[data-design="v2"] .itin-long-toggle,
html[data-design="v2"] .random-dest-btn,
html[data-design="v2"] .hero-toggle-btn,
html[data-design="v2"] .explore-back,
html[data-design="v2"] .explore-panel-close,
html[data-design="v2"] .itin-expand-cta,
html[data-design="v2"] .sort-toggle-btn,
html[data-design="v2"] .sort-dir-btn,
html[data-design="v2"] .hub-tab {
  background: var(--v2-gloss);
  color: var(--v2-ink);
  border: 1px solid var(--v2-border-strong);
  border-radius: var(--v2-radius);
  padding: 5px 12px;
  font-family: var(--v2-sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
  box-shadow: var(--v2-shadow-sm), var(--v2-bevel-hi);
  transition: background 100ms var(--v2-ease),
              border-color 100ms var(--v2-ease),
              box-shadow 140ms var(--v2-ease-spring),
              transform 140ms var(--v2-ease-spring),
              color 100ms var(--v2-ease);
  cursor: pointer;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  text-transform: none;
}

html[data-design="v2"] .go-btn:hover,
html[data-design="v2"] .sort-btn:hover,
html[data-design="v2"] .segmented-btn:hover,
html[data-design="v2"] .board-tab:hover,
html[data-design="v2"] .board-type-btn:hover,
html[data-design="v2"] .pagination-btn:hover:not(.disabled),
html[data-design="v2"] .pagination-page:hover,
html[data-design="v2"] .rc-expand-btn:hover,
html[data-design="v2"] .hub-retry:hover,
html[data-design="v2"] .disclaimer-trigger:hover,
html[data-design="v2"] .itin-toggle button:hover,
html[data-design="v2"] .region-trigger:hover,
html[data-design="v2"] .hero-toggle-btn:hover,
html[data-design="v2"] .explore-back:hover,
html[data-design="v2"] .explore-panel-close:hover,
html[data-design="v2"] .itin-expand-cta:hover,
html[data-design="v2"] .sort-toggle-btn:hover,
html[data-design="v2"] .sort-dir-btn:hover,
html[data-design="v2"] .hub-tab:hover {
  background: var(--v2-gloss-hover);
  border-color: rgba(0, 0, 0, 0.42);
  box-shadow:
    var(--v2-bevel-hi),
    0 2px 4px rgba(0, 0, 0, 0.10),
    0 6px 14px rgba(0, 0, 0, 0.06);
  transform: translateY(-1px);
}

html[data-design="v2"] .go-btn:active,
html[data-design="v2"] .sort-btn:active,
html[data-design="v2"] .segmented-btn:active,
html[data-design="v2"] .board-tab:active,
html[data-design="v2"] .board-type-btn:active,
html[data-design="v2"] .pagination-btn:active,
html[data-design="v2"] .pagination-page:active,
html[data-design="v2"] .rc-expand-btn:active,
html[data-design="v2"] .disclaimer-trigger:active,
html[data-design="v2"] .hub-retry:active,
html[data-design="v2"] .hub-tab:active {
  background: var(--v2-gloss-press);
  box-shadow: var(--v2-press-inset);
  transform: translateY(0);
  border-color: rgba(0, 0, 0, 0.42);
}

/* B-blue — Aqua-blue default-button gradient. Used by CTA + every active toggle */
html[data-design="v2"] .go-btn,
html[data-design="v2"] .sort-btn.active,
html[data-design="v2"] .segmented-btn.active,
html[data-design="v2"] .board-tab.active,
html[data-design="v2"] .board-type-btn.active,
html[data-design="v2"] .pagination-page.active,
html[data-design="v2"] .itin-toggle button.active,
html[data-design="v2"] .hero-toggle-btn.active,
html[data-design="v2"] .hub-tab.is-active {
  background: var(--v2-aqua-default);
  border-color: var(--v2-border-strong);
  color: var(--v2-ink-inverse);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.22);
  box-shadow:
    var(--v2-bevel-hi-blue),
    inset 0 -1px 0 rgba(0, 0, 0, 0.10),
    0 1px 2px rgba(0, 0, 0, 0.18);
}
html[data-design="v2"] .go-btn:hover,
html[data-design="v2"] .sort-btn.active:hover,
html[data-design="v2"] .segmented-btn.active:hover,
html[data-design="v2"] .board-tab.active:hover,
html[data-design="v2"] .board-type-btn.active:hover,
html[data-design="v2"] .pagination-page.active:hover,
html[data-design="v2"] .itin-toggle button.active:hover,
html[data-design="v2"] .hero-toggle-btn.active:hover,
html[data-design="v2"] .hub-tab.is-active:hover {
  background: var(--v2-aqua-hover);
  color: #fff;
}
html[data-design="v2"] .go-btn:active,
html[data-design="v2"] .sort-btn.active:active,
html[data-design="v2"] .segmented-btn.active:active,
html[data-design="v2"] .board-tab.active:active,
html[data-design="v2"] .board-type-btn.active:active,
html[data-design="v2"] .pagination-page.active:active,
html[data-design="v2"] .itin-toggle button.active:active,
html[data-design="v2"] .hero-toggle-btn.active:active {
  background: var(--v2-aqua-press);
  box-shadow: var(--v2-aqua-press-inset);
}

/* CTA gets bigger padding + bolder weight + reset transform animations from v1 */
html[data-design="v2"] .go-btn {
  font-size: 14px;
  font-weight: 600;
  padding: 8px 20px;
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
html[data-design="v2"] .go-btn.visible {
  opacity: 1;
  transform: none;
}
html[data-design="v2"] .go-btn:disabled,
html[data-design="v2"] .hero-cta-row .go-btn:disabled {
  background: var(--v2-surface-2);
  color: var(--v2-ink-3);
  border-color: var(--v2-border);
  text-shadow: none;
  box-shadow: none;
  cursor: not-allowed;
}
html[data-design="v2"] .go-arrow { font-weight: 600; }

/* Disclaimer trigger — quiet, no neon yellow */
html[data-design="v2"] .disclaimer-trigger {
  font-family: var(--v2-mono);
  text-transform: none;
  letter-spacing: 0.08em;
  font-size: 10px;
}

/* B-red — Aqua red dot close button */
html[data-design="v2"] .modal-close,
html[data-design="v2"] .disclaimer-modal-close {
  background: var(--v2-pill-red);
  color: var(--v2-ink-inverse);
  border: 1px solid rgba(0, 0, 0, 0.32);
  border-radius: 50%;
  width: 22px;
  height: 22px;
  font-size: 12px;
  font-family: var(--v2-sans);
  font-weight: 600;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.22);
  box-shadow: var(--v2-bevel-hi-blue),
              0 1px 1px rgba(0, 0, 0, 0.18);
  cursor: pointer;
  transition: background 100ms var(--v2-ease),
              box-shadow 140ms var(--v2-ease-spring);
}
html[data-design="v2"] .modal-close:hover,
html[data-design="v2"] .disclaimer-modal-close:hover {
  background: linear-gradient(to bottom, #ED7E76 0%, #D14B41 100%);
  color: #fff;
}
html[data-design="v2"] .modal-close:active,
html[data-design="v2"] .disclaimer-modal-close:active {
  background: linear-gradient(to bottom, #B63329 0%, #C8443A 100%);
  box-shadow: var(--v2-press-inset);
}

/* Disabled pagination */
html[data-design="v2"] .pagination-btn.disabled {
  opacity: 0.4;
  box-shadow: none;
  cursor: not-allowed;
}
html[data-design="v2"] .pagination-ellipsis {
  color: var(--v2-ink-3);
  font-family: var(--v2-mono);
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * SEGMENTED CONTROLS — frame around B-white/B-blue children                 *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .segmented,
html[data-design="v2"] .board-tabs,
html[data-design="v2"] .board-type-switch,
html[data-design="v2"] .sort-group,
html[data-design="v2"] .itin-toggle,
html[data-design="v2"] .hub-tabs {
  background: var(--v2-gloss);
  border: 1px solid var(--v2-border-strong);
  border-radius: var(--v2-radius);
  box-shadow: var(--v2-shadow-sm), var(--v2-bevel-hi);
  padding: 0;
  gap: 0;
  position: relative;
  overflow: hidden;
}

/* Hide animated thumbs — v2 uses static state styling */
html[data-design="v2"] .segmented-thumb,
html[data-design="v2"] .board-tabs-thumb,
html[data-design="v2"] .board-type-thumb {
  display: none;
}

/* Children of segmented frames lose their own border + shadow + radius */
html[data-design="v2"] .segmented .segmented-btn,
html[data-design="v2"] .board-tabs .board-tab,
html[data-design="v2"] .board-type-switch .board-type-btn,
html[data-design="v2"] .sort-group .sort-btn,
html[data-design="v2"] .itin-toggle button,
html[data-design="v2"] .hub-tabs .hub-tab {
  border-radius: 0;
  border: none;
  border-right: 1px solid var(--v2-border);
  box-shadow: none;
  background: transparent;
  margin: 0;
}
html[data-design="v2"] .segmented .segmented-btn:last-child,
html[data-design="v2"] .board-tabs .board-tab:last-child,
html[data-design="v2"] .board-type-switch .board-type-btn:last-child,
html[data-design="v2"] .sort-group .sort-btn:last-child,
html[data-design="v2"] .itin-toggle button:last-child,
html[data-design="v2"] .hub-tabs .hub-tab:last-child {
  border-right: none;
}
html[data-design="v2"] .segmented .segmented-btn:hover,
html[data-design="v2"] .board-tabs .board-tab:hover,
html[data-design="v2"] .board-type-switch .board-type-btn:hover,
html[data-design="v2"] .sort-group .sort-btn:hover,
html[data-design="v2"] .itin-toggle button:hover,
html[data-design="v2"] .hub-tabs .hub-tab:hover {
  background: rgba(255, 255, 255, 0.5);
}
html[data-design="v2"] .segmented .segmented-btn.active,
html[data-design="v2"] .board-tabs .board-tab.active,
html[data-design="v2"] .board-type-switch .board-type-btn.active,
html[data-design="v2"] .sort-group .sort-btn.active,
html[data-design="v2"] .itin-toggle button.active,
html[data-design="v2"] .hub-tabs .hub-tab.is-active {
  background: var(--v2-aqua-default);
  color: var(--v2-ink-inverse);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.22);
  box-shadow:
    var(--v2-bevel-hi-blue),
    inset 0 -1px 0 rgba(0, 0, 0, 0.10);
}

/* Explore page: Most popular / Most on time toggle (sort-toggle pill).
 * v1 wraps two .sort-toggle-btn around an animated .sort-toggle-pill.
 * In v2: hide the sliding pill; the active button itself wears the
 * electric-green B-blue treatment. */
html[data-design="v2"] .sort-toggle {
  background: var(--v2-gloss);
  border: 1px solid var(--v2-border-strong);
  border-radius: var(--v2-radius-pill);
  box-shadow: var(--v2-shadow-sm), var(--v2-bevel-hi);
  padding: 3px;
  isolation: isolate;
}
html[data-design="v2"] .sort-toggle-pill { display: none; }
html[data-design="v2"] .sort-toggle-btn {
  position: relative;
  z-index: 1;
  border: 1px solid transparent;
  background: transparent;
  padding: 6px 14px;
  font-family: var(--v2-sans);
  font-size: 13px;
  font-weight: 500;
  color: var(--v2-ink-2);
  border-radius: var(--v2-radius-pill);
  box-shadow: none;
  cursor: pointer;
  transition: background 120ms var(--v2-ease),
              color 120ms var(--v2-ease),
              box-shadow 140ms var(--v2-ease-spring);
  white-space: nowrap;
}
html[data-design="v2"] .sort-toggle-btn:hover {
  background: rgba(255, 255, 255, 0.6);
  color: var(--v2-ink);
}
html[data-design="v2"] .sort-toggle-btn.is-active {
  background: var(--v2-aqua-default);
  border-color: var(--v2-border-strong);
  color: var(--v2-ink-inverse);
  font-weight: 600;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.18);
  box-shadow:
    var(--v2-bevel-hi-blue),
    inset 0 -1px 0 rgba(0, 0, 0, 0.10),
    0 1px 2px rgba(0, 0, 0, 0.18);
}

html[data-design="v2"] .sort-dir-arrow,
html[data-design="v2"] .sort-dir-label {
  font-family: var(--v2-mono);
  color: var(--v2-ink);
}

/* Random destination button — gold gloss, dark ink (Snow Leopard's default
 * action accent). Pairs with the Aqua blue primary like a yellow #2 pencil
 * pairs with a blue ballpoint. */
html[data-design="v2"] .random-dest-btn {
  background: var(--v2-fun-default);
  color: var(--v2-ink);
  border: 1px solid color-mix(in srgb, var(--v2-fun) 60%, var(--v2-ink) 40%);
  border-radius: var(--v2-radius-pill);
  padding: 6px 14px;
  font-family: var(--v2-sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    inset 0 -1px 0 rgba(0, 0, 0, 0.06),
    0 1px 2px rgba(180, 120, 0, 0.22);
  cursor: pointer;
  transition: background 120ms var(--v2-ease),
              box-shadow 140ms var(--v2-ease-spring),
              transform 140ms var(--v2-ease-spring);
}
html[data-design="v2"] .random-dest-btn:hover {
  background: var(--v2-fun-hover);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    inset 0 -1px 0 rgba(0, 0, 0, 0.06),
    0 2px 6px rgba(180, 120, 0, 0.28);
  transform: translateY(-1px);
}
html[data-design="v2"] .random-dest-btn:active {
  background: var(--v2-fun-press);
  color: var(--v2-ink);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.18);
  transform: translateY(0);
}
html[data-design="v2"] .random-dest-btn:focus-visible {
  outline: none;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    0 0 0 3px var(--v2-fun-glow);
}
html[data-design="v2"] .random-dest-icon {
  color: var(--v2-ink);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * INPUTS                                                                    *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .airport-input {
  background: var(--v2-surface);
  border: 1px solid var(--v2-border-strong);
  border-radius: var(--v2-radius);
  padding: 6px 12px;
  font-family: var(--v2-mono);
  font-size: 14px;
  font-weight: 600;
  color: var(--v2-ink);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.06);
  transition: box-shadow 120ms var(--v2-ease),
              border-color 120ms var(--v2-ease);
}
html[data-design="v2"] .airport-input::placeholder { color: var(--v2-ink-3); }
html[data-design="v2"] .airport-input:focus {
  outline: none;
  border-color: var(--v2-aqua);
  box-shadow: var(--v2-focus-ring),
              inset 0 1px 2px rgba(0, 0, 0, 0.06);
}

html[data-design="v2"] .compact-bar {
  background: var(--v2-surface);
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius-card);
  box-shadow: var(--v2-shadow), var(--v2-bevel-hi);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
html[data-design="v2"] .compact-bar-sentence,
html[data-design="v2"] .compact-bar-sentence > span {
  color: var(--v2-ink);
  font-family: var(--v2-sans);
}
html[data-design="v2"] .compact-bar .airport-input {
  background: var(--v2-surface);
}
html[data-design="v2"] .compact-bar .airport-input:focus {
  border-color: var(--v2-aqua);
  box-shadow: var(--v2-focus-ring),
              inset 0 1px 2px rgba(0, 0, 0, 0.06);
}

/* Dropdown — Snow Leopard menu (Aqua selection on hover) */
html[data-design="v2"] .dropdown {
  background: var(--v2-surface);
  border: 1px solid var(--v2-border-strong);
  border-radius: var(--v2-radius);
  box-shadow: var(--v2-shadow-lg);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
html[data-design="v2"] .dropdown-item {
  padding: 8px 12px;
  border-bottom: 1px solid var(--v2-border-soft);
  color: var(--v2-ink);
  border-radius: 0;
  font-family: var(--v2-sans);
}
html[data-design="v2"] .dropdown-item:first-child,
html[data-design="v2"] .dropdown-item:last-child { border-radius: 0; }
html[data-design="v2"] .dropdown-item:last-child { border-bottom: none; }
html[data-design="v2"] .dropdown-item:hover,
html[data-design="v2"] .dropdown-item.highlighted {
  background: var(--v2-aqua);
  color: var(--v2-ink-inverse);
}
html[data-design="v2"] .dropdown-item:hover .name,
html[data-design="v2"] .dropdown-item.highlighted .name,
html[data-design="v2"] .dropdown-item:hover .code,
html[data-design="v2"] .dropdown-item.highlighted .code { color: inherit; }
html[data-design="v2"] .dropdown-item .code {
  font-family: var(--v2-mono);
  font-weight: 600;
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * FLAP CELLS — context table (preserve v1 structural intent)                *
 * ═════════════════════════════════════════════════════════════════════════ */

/* Base — used in .board-ontime cells and any unscoped .board-flap-cell.
 * Warmer to match the cream page bg; soft hairline so adjacent cells
 * (e.g. the digits in "91%") read as a continuous strip, not boxes. */
html[data-design="v2"] .board-flap-cell {
  background: linear-gradient(to bottom, #FCF8EE 0%, #F0EAD8 100%);
  border: 1px solid rgba(42, 38, 34, 0.10);
  border-radius: 3px;
  color: var(--v2-ink-2);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55),
              inset 0 -1px 0 rgba(0, 0, 0, 0.03);
}
html[data-design="v2"] .board-flap-cell.landed {
  color: var(--v2-ink);
}
html[data-design="v2"] .board-flap-cell.is-blank {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}
html[data-design="v2"] .board-flap-cell.is-blank::after { display: none; }

/* Hairline split inside the tile — softer than v1 */
html[data-design="v2"] .board-flap-cell::after {
  background: rgba(0, 0, 0, 0.12);
}

/* Rank cells — chromeless, plain text */
html[data-design="v2"] .board-rank .board-flap-cell {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}
html[data-design="v2"] .board-rank .board-flap-cell::after { display: none; }

/* Name cells — TRULY inline (preserve v1's all: unset trick) */
html[data-design="v2"] .board-name .board-flap-cell {
  all: unset;
  display: inline;
  color: var(--v2-ink-2);
  font: inherit;
  letter-spacing: inherit;
  white-space: pre;
  transition: color 180ms var(--v2-ease);
}
html[data-design="v2"] .board-name .board-flap-cell::after { display: none; }
html[data-design="v2"] .board-name .board-flap-cell.landed { color: var(--v2-ink); }

/* IATA code cells — slightly warmer + bolder than the on-time tiles, to
 * read as the headline identifier. Border still soft so adjacent cells
 * blend into a continuous "code chip" strip (DY reads as one identifier
 * rather than two separate boxes). */
html[data-design="v2"] .board-code .board-flap-cell {
  background: linear-gradient(to bottom, #FFFAEC 0%, #F4ECCB 100%);
  border-color: rgba(42, 38, 34, 0.14);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.65),
              inset 0 -1px 0 rgba(42, 38, 34, 0.06);
}
html[data-design="v2"] .board-code .board-flap-cell.landed { color: var(--v2-ink); }

/* On-time % — base tile, color changes by status */
html[data-design="v2"] .board-ontime.board-status-green .board-flap-cell.landed { color: var(--v2-status-good); }
html[data-design="v2"] .board-ontime.board-status-amber .board-flap-cell.landed { color: var(--v2-status-warn); }
html[data-design="v2"] .board-ontime.board-status-red   .board-flap-cell.landed { color: var(--v2-status-bad); }
html[data-design="v2"] .board-ontime.board-status-none  .board-flap-cell.landed { color: var(--v2-ink-3); }

/* Top-3 board ranks — preserve v1's gold/silver/bronze ink */
html[data-design="v2"] .board-row.board-top-1 .board-rank .board-flap-cell.landed { color: #B8860B; }
html[data-design="v2"] .board-row.board-top-2 .board-rank .board-flap-cell.landed { color: #8E8E93; }
html[data-design="v2"] .board-row.board-top-3 .board-rank .board-flap-cell.landed { color: #A0522D; }

/* RC contexts — preserve v1's chromeless flap cells. `color: inherit`
 * is critical: the parent .rc-row-value gets a `.c-green/.c-amber/.c-red`
 * class via JS (rcOnTimeClass / cc), and the grade letter parent gets a
 * `--rc-grade-color` CSS var. The flap cells must inherit that color so
 * the digits actually paint green/amber/red — setting `color: var(--v2-ink)`
 * here was killing the report-card status coloring. */
html[data-design="v2"] .rc-row-value .flap-cell,
html[data-design="v2"] .rc-row-value .flap-cell.landed,
html[data-design="v2"] .rc-row-value .board-flap-cell,
html[data-design="v2"] .rc-row-value .board-flap-cell.landed,
html[data-design="v2"] .rc-card-code .flap-cell,
html[data-design="v2"] .rc-card-code .flap-cell.landed,
html[data-design="v2"] .rc-card-code .board-flap-cell,
html[data-design="v2"] .rc-card-code .board-flap-cell.landed,
html[data-design="v2"] .rc-grade-letter .flap-cell,
html[data-design="v2"] .rc-grade-letter .flap-cell.landed,
html[data-design="v2"] .rc-grade-letter .board-flap-cell,
html[data-design="v2"] .rc-grade-letter .board-flap-cell.landed {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: inherit;
}
html[data-design="v2"] .rc-row-value .flap-cell::after,
html[data-design="v2"] .rc-row-value .board-flap-cell::after,
html[data-design="v2"] .rc-card-code .flap-cell::after,
html[data-design="v2"] .rc-card-code .board-flap-cell::after,
html[data-design="v2"] .rc-grade-letter .flap-cell::after,
html[data-design="v2"] .rc-grade-letter .board-flap-cell::after {
  display: none;
}

/* Winner-metric / row-primary contexts — chromeless flap cells (text
 * only). `color: inherit` so the .c-green/.c-amber/.c-red on the parent
 * value passes through to the digits inside. */
html[data-design="v2"] .winner-metric-value .flap-cell,
html[data-design="v2"] .winner-metric-value .board-flap-cell,
html[data-design="v2"] .row-primary-value .flap-cell,
html[data-design="v2"] .row-primary-value .board-flap-cell,
html[data-design="v2"] .row-metric-value .flap-cell,
html[data-design="v2"] .row-metric-value .board-flap-cell {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: inherit;
}

/* Hero flap cells (NOT board-flap-cell) — dark gradient when on dark hero */
html[data-design="v2"] .flap-cell:not(.board-flap-cell) {
  background: linear-gradient(to bottom, #2F2D32 0%, #1F1D22 100%);
  color: var(--v2-hero-screen);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 3px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * BOARD / RANKINGS                                                          *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .flap-board-page,
html[data-design="v2"] .rankings-page,
html[data-design="v2"] .airports-page,
html[data-design="v2"] .routes-page,
html[data-design="v2"] .results-page,
html[data-design="v2"] .reportcard-page,
html[data-design="v2"] .oracle-page,
html[data-design="v2"] .why-page,
html[data-design="v2"] .explore-root {
  background: var(--v2-bg);
}

html[data-design="v2"] .board-shell { background: var(--v2-bg); }

html[data-design="v2"] .board-panel {
  background: var(--v2-surface);
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius-card);
  box-shadow: var(--v2-shadow-lg);
  padding: 24px;
}
html[data-design="v2"] .board-panel-inner { background: transparent; }

html[data-design="v2"] .board-row {
  border-bottom: 1px solid var(--v2-border-soft);
  background: transparent;
  border-radius: 0;
  transition: background 100ms var(--v2-ease);
}
html[data-design="v2"] .board-row:hover { background: rgba(0, 0, 0, 0.025); }

/* Header strip — clean, transparent, dashed bottom rule (no Snow Leopard
 * titlebar gradient). Reads as a contextual breadcrumb above the board. */
html[data-design="v2"] .board-header-strip {
  background: transparent;
  color: var(--v2-ink-2);
  border-radius: 0;
  border-bottom: 1px dashed rgba(42, 38, 34, 0.18);
  box-shadow: none;
  font-family: var(--v2-sans);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
}
html[data-design="v2"] .board-header-label,
html[data-design="v2"] .board-header-meta {
  font-family: var(--v2-sans);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}
html[data-design="v2"] .board-header-label { color: var(--v2-ink); }
html[data-design="v2"] .board-header-meta  { color: var(--v2-ink-3); }
html[data-design="v2"] .board-header-glyph { color: var(--v2-status-good); }

/* Column headers — also drop mono caps. Sentence case + sans, muted. */
html[data-design="v2"] .board-columns {
  font-family: var(--v2-sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--v2-ink-3);
}

html[data-design="v2"] .board-title {
  font-family: var(--v2-display);
  font-weight: 700;
  font-size: 38px;
  line-height: 1.15;
  letter-spacing: -0.028em;
  color: var(--v2-ink);
}
html[data-design="v2"] .board-subtitle {
  font-size: 15px;
  color: var(--v2-ink-2);
  margin-top: 4px;
}
html[data-design="v2"] .board-kicker {
  font-family: var(--v2-mono);
  text-transform: none;
  letter-spacing: 0.10em;
  color: var(--v2-ink-2);
  font-size: 11px;
}
html[data-design="v2"] .board-disclaimer {
  color: var(--v2-ink-3);
  font-size: 12px;
}
html[data-design="v2"] .board-loading,
html[data-design="v2"] .board-empty {
  color: var(--v2-ink-2);
  font-family: var(--v2-mono);
}
/* Low-sample inline caveat on Board rows ("Honolulu · limited sample").
 * v1 sets ::before content to "·" (typographic interpunct) — v2 must NOT
 * paint a background or border-radius on top of that, otherwise it
 * renders as an Aqua circle blob over the character. */
html[data-design="v2"] .board-caveat {
  color: var(--v2-status-warn);
  font-family: var(--v2-sans);
  font-size: 12px;
  font-weight: 500;
  opacity: 0.85;
  font-style: italic;
}
html[data-design="v2"] .board-caveat::before {
  background: none;
  border-radius: 0;
  color: var(--v2-ink-3);
  opacity: 0.6;
}

/* Status dot — Aqua pearl (round, hairline, gradient fill) */
html[data-design="v2"] .board-status-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.22);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4),
              0 0.5px 1px rgba(0, 0, 0, 0.06);
  background: var(--v2-status-muted);
}
html[data-design="v2"] .board-dot-green { background: var(--v2-pill-green); }
html[data-design="v2"] .board-dot-amber { background: var(--v2-pill-amber); }
html[data-design="v2"] .board-dot-red   { background: var(--v2-pill-red); }
html[data-design="v2"] .board-dot-none  { background: var(--v2-status-muted); }

/* Region dropdown */
html[data-design="v2"] .region-dropdown { border-radius: var(--v2-radius); }
html[data-design="v2"] .region-trigger {
  background: var(--v2-gloss);
  color: var(--v2-ink);
  font-family: var(--v2-sans);
  font-weight: 500;
}
html[data-design="v2"] .region-menu {
  border-radius: var(--v2-radius);
  border: 1px solid var(--v2-border-strong);
  box-shadow: var(--v2-shadow-lg);
  background: var(--v2-surface);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
html[data-design="v2"] .region-option {
  border-bottom: 1px solid var(--v2-border-soft);
  border-radius: 0;
  color: var(--v2-ink);
}
html[data-design="v2"] .region-option:last-child { border-bottom: none; }
html[data-design="v2"] .region-option:hover,
html[data-design="v2"] .region-option.active {
  background: var(--v2-aqua);
  color: var(--v2-ink-inverse);
}
html[data-design="v2"] .region-caret { color: var(--v2-ink-2); }

/* ═════════════════════════════════════════════════════════════════════════ *
 * AIRLINE / DEST ROWS                                                        *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .airline-list { background: var(--v2-surface); }
html[data-design="v2"] .airline-list::after { opacity: 0.04; }

html[data-design="v2"] .airline-row,
html[data-design="v2"] .dest-row {
  border-bottom: 1px solid var(--v2-border-soft);
  background: transparent;
  border-radius: 0;
  transition: background 100ms var(--v2-ease);
}
html[data-design="v2"] .airline-row:last-child,
html[data-design="v2"] .dest-row:last-child { border-bottom: none; }
html[data-design="v2"] .airline-row.clickable:hover,
html[data-design="v2"] .dest-row:hover {
  background: rgba(0, 0, 0, 0.025);
}
html[data-design="v2"] .airline-row.has-dow { border-bottom-style: solid; }

/* Plain text only — NOT pills */
html[data-design="v2"] .row-rank {
  font-family: var(--v2-mono);
  font-size: 15px;
  font-weight: 500;
  color: var(--v2-ink-3);
  text-align: center;
  background: none;
  border: none;
  box-shadow: none;
  padding: 0;
}
html[data-design="v2"] .airline-row.top-1 .row-rank { color: #B8860B; }
html[data-design="v2"] .airline-row.top-2 .row-rank { color: #8E8E93; }
html[data-design="v2"] .airline-row.top-3 .row-rank { color: #A0522D; }

html[data-design="v2"] .row-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--v2-ink);
  letter-spacing: -0.005em;
}
html[data-design="v2"] .row-code {
  font-family: var(--v2-mono);
  font-weight: 400;
  color: var(--v2-ink-3);
  font-size: 12px;
  letter-spacing: 0.04em;
  background: none;
  border: none;
  box-shadow: none;
  padding: 0;
}
html[data-design="v2"] .row-sub { color: var(--v2-ink-3); font-size: 13px; }
html[data-design="v2"] .row-sub .c-green { color: var(--v2-status-good); }
html[data-design="v2"] .row-sub .c-amber { color: var(--v2-status-warn); }
html[data-design="v2"] .row-sub .c-red { color: var(--v2-status-bad); }

html[data-design="v2"] .row-primary,
html[data-design="v2"] .row-metric { background: none; border: none; padding-top: 0; padding-bottom: 0; }
/* No `color:` here — let .c-green/.c-amber/.c-red pass through when JS adds them */
html[data-design="v2"] .row-primary-value,
html[data-design="v2"] .row-metric-value {
  font-family: var(--v2-mono);
  font-weight: 600;
  background: none;
  border: none;
  box-shadow: none;
  padding: 0;
}
html[data-design="v2"] .row-primary-label,
html[data-design="v2"] .row-metric-label {
  font-family: var(--v2-mono);
  text-transform: none;
  letter-spacing: 0.06em;
  color: var(--v2-ink-3);
  font-weight: 600;
  font-size: 10px;
}
html[data-design="v2"] .row-nodata { color: var(--v2-ink-3); font-family: var(--v2-sans); font-style: italic; }
/* Caveat: small amber "!" icon. Tooltip surfaces the full text. v2
 * uses status-warn so it ties into the rest of the warning palette. */
html[data-design="v2"] .row-caveat {
  background: color-mix(in srgb, var(--v2-status-warn) 22%, transparent);
  color: color-mix(in srgb, var(--v2-status-warn) 90%, var(--v2-ink));
  font-family: var(--v2-mono);
  font-style: normal;
  font-weight: 700;
  opacity: 1;
}
html[data-design="v2"] .row-caveat::before {
  content: none;
}

/* Winner card */
html[data-design="v2"] .winner-card {
  background: var(--v2-surface);
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius-card);
  box-shadow: var(--v2-shadow);
  padding: 20px 24px;
  transform-origin: 50% 100%;
  transition: transform 200ms var(--v2-ease-spring),
              box-shadow 200ms var(--v2-ease-spring);
}
html[data-design="v2"] .winner-card::after { opacity: 0.04; }
html[data-design="v2"] .winner-card:hover {
  transform: rotate(-0.4deg) translateY(-2px);
  box-shadow: var(--v2-shadow-lg);
  background: var(--v2-surface);
}
html[data-design="v2"] .winner-card:active {
  transform: rotate(-0.2deg) translateY(0);
  box-shadow: var(--v2-shadow);
}
html[data-design="v2"] .winner-code {
  font-family: var(--v2-mono);
  color: var(--v2-ink);
  background: none;
  border: none;
  padding: 0;
}
html[data-design="v2"] .winner-label {
  font-family: var(--v2-sans);
  text-transform: none;
  letter-spacing: 0.04em;
  font-weight: 500;
  color: var(--v2-ink-2);
  font-size: 11px;
}
html[data-design="v2"] .winner-metric-label {
  font-family: var(--v2-mono);
  letter-spacing: 0.06em;
  color: var(--v2-ink-3);
  font-size: 10px;
  font-weight: 600;
  text-transform: none;
}
html[data-design="v2"] .winner-metric-value {
  font-family: var(--v2-mono);
  font-weight: 600;
  /* No color — let .c-* pass through */
}

/* Airline row with DOW strip — keep v1 layout, just repaint */
html[data-design="v2"] .airline-row-dow { border-top-color: var(--v2-border-soft); }
html[data-design="v2"] .dow-label {
  color: var(--v2-ink-3);
  font-size: 11px;
  font-family: var(--v2-sans);
  font-weight: 500;
  letter-spacing: 0;
}
html[data-design="v2"] .dow-letter {
  font-family: var(--v2-mono);
  color: var(--v2-ink-3);
}

/* DOW dots — preserve v1's --dot-color/--dot-fill/--dot-ring cascade */
html[data-design="v2"] .dow-dot {
  --dot-color: rgba(0, 0, 0, 0.32);
  --dot-fill: transparent;
  --dot-ring: transparent;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1.5px solid var(--dot-color);
  background: var(--dot-fill);
  box-shadow: 0 0 0 2px var(--dot-ring),
              inset 0 1px 0 rgba(255, 255, 255, 0.4),
              0 0.5px 1px rgba(0, 0, 0, 0.05);
  transition: background 200ms var(--v2-ease),
              border-color 200ms var(--v2-ease),
              box-shadow 200ms var(--v2-ease);
}
html[data-design="v2"] .dow-dot-green { --dot-color: var(--v2-status-good); }
html[data-design="v2"] .dow-dot-amber { --dot-color: var(--v2-status-warn); }
html[data-design="v2"] .dow-dot-red   { --dot-color: var(--v2-status-bad); }
html[data-design="v2"] .dow-dot-none  { --dot-color: rgba(0, 0, 0, 0.45); }
html[data-design="v2"] .dow-dot-off {
  --dot-color: rgba(0, 0, 0, 0.18);
  --dot-fill: transparent;
}
/* freq-1/2/3 + is-best — v1 rules use color-mix on --dot-color, work as-is */

html[data-design="v2"] .dot-note {
  color: var(--v2-ink-3);
  font-family: var(--v2-sans);
  font-size: 11px;
  letter-spacing: 0;
  font-style: italic;
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * LIST CONTROLS                                                              *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .list-header {
  background: var(--v2-bg-deep);
  border-top: 1px solid var(--v2-border);
  border-bottom: 1px solid var(--v2-border);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
}
html[data-design="v2"] .list-header-label {
  color: var(--v2-ink-2);
  font-family: var(--v2-mono);
  letter-spacing: 0.10em;
  text-transform: none;
  font-weight: 600;
  font-size: 11px;
}
html[data-design="v2"] .controls,
html[data-design="v2"] .controls-airports {
  color: var(--v2-ink-2);
  font-family: var(--v2-mono);
}
html[data-design="v2"] .controls-sep { color: var(--v2-ink-3); }
html[data-design="v2"] .controls-label {
  font-family: var(--v2-mono);
  text-transform: none;
  letter-spacing: 0.08em;
  color: var(--v2-ink-3);
  font-weight: 600;
}

/* Pagination wrapper */
html[data-design="v2"] .pagination { gap: 6px; }

/* Results header */
html[data-design="v2"] .results-route .code {
  font-family: var(--v2-mono);
  font-weight: 600;
  color: var(--v2-ink);
}
html[data-design="v2"] .results-route .arrow { color: var(--v2-ink-2); }
html[data-design="v2"] .results-count,
html[data-design="v2"] .results-meta {
  color: var(--v2-ink-2);
  font-family: var(--v2-sans);
  font-size: 13px;
  font-weight: 500;
}

/* Random destination button (inherits B-white) */
html[data-design="v2"] .random-dest-icon { color: var(--v2-ink); }

/* Dest row */
html[data-design="v2"] .dest-row-code {
  font-family: var(--v2-mono);
  font-weight: 600;
  color: var(--v2-ink);
}
html[data-design="v2"] .dest-row-city { color: var(--v2-ink); }
html[data-design="v2"] .dest-row-sub { color: var(--v2-ink-3); font-size: 12px; }
html[data-design="v2"] .dest-row-metric {
  font-family: var(--v2-mono);
  font-weight: 600;
  /* No color — let .c-* pass through */
}

/* Route page bits */
html[data-design="v2"] .route-codes,
html[data-design="v2"] .route-codes .code {
  font-family: var(--v2-mono);
  color: var(--v2-ink);
}
html[data-design="v2"] .route-section-label {
  font-family: var(--v2-mono);
  letter-spacing: 0.10em;
  text-transform: none;
  color: var(--v2-ink-2);
  font-weight: 600;
  font-size: 11px;
}
html[data-design="v2"] .route-section-label.worst { color: var(--v2-status-bad); }

/* ═════════════════════════════════════════════════════════════════════════ *
 * HERO PAGE                                                                  *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .hero-layer {
  background: linear-gradient(
    to bottom,
    var(--v2-hero-bg) 0%,
    var(--v2-hero-bg) 65%,
    var(--v2-hero-band) 65%,
    var(--v2-hero-band) 70%,
    var(--v2-hero-bg) 70%,
    var(--v2-hero-bg) 100%
  ) !important;
}
html[data-design="v2"] .hero-layer::before { display: none; }
html[data-design="v2"] .hero-layer::after { opacity: 0.06; }
:root[data-hero-theme="day"] html[data-design="v2"] .hero-layer {
  background: linear-gradient(
    to bottom,
    #5BAFE5 0%, #5BAFE5 65%,
    var(--v2-amber) 65%, var(--v2-amber) 70%,
    #5BAFE5 70%, #5BAFE5 100%
  ) !important;
}

/* Glow box — iTunes 9 picture-frame */
html[data-design="v2"] .glow-box {
  background: var(--v2-hero-screen);
  border: 4px solid var(--v2-hero-frame);
  border-radius: var(--v2-radius-card);
  box-shadow:
    0 12px 40px rgba(0, 0, 0, 0.5),
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    0 0 80px 20px rgba(255, 240, 220, 0.10);
  padding: 48px 56px 28px;
}
html[data-design="v2"] .glow-box::after { opacity: 0.08; }

html[data-design="v2"] .sentence-main {
  font-family: var(--v2-display);
  font-weight: 700;
  font-size: clamp(24px, 4.2vw, 32px);
  letter-spacing: -0.025em;
  color: var(--v2-ink);
}
html[data-design="v2"] .sentence-sub {
  color: var(--v2-hero-accent);
  font-weight: 600;
  font-family: var(--v2-display);
  font-size: clamp(14px, 2vw, 18px);
  letter-spacing: -0.01em;
}

/* Hero theme toggle (bottom-left day/night pill) */
html[data-design="v2"] .hero-theme-toggle {
  background: var(--v2-gloss);
  border: 1px solid var(--v2-border-strong);
  border-radius: var(--v2-radius);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: var(--v2-shadow), var(--v2-bevel-hi);
  padding: 0;
  gap: 0;
  overflow: hidden;
}
html[data-design="v2"] .hero-toggle-btn {
  border-radius: 0;
  border: none;
  border-right: 1px solid var(--v2-border);
  background: transparent;
  color: var(--v2-ink-2);
  font-family: var(--v2-mono);
  text-transform: none;
  letter-spacing: 0.10em;
  font-size: 11px;
  font-weight: 600;
  padding: 6px 14px;
  box-shadow: none;
}
html[data-design="v2"] .hero-toggle-btn:last-child { border-right: none; }
html[data-design="v2"] .hero-toggle-btn:hover {
  background: rgba(255, 255, 255, 0.5);
  color: var(--v2-ink);
}
html[data-design="v2"] .hero-toggle-btn.active {
  background: var(--v2-aqua-default);
  color: var(--v2-ink-inverse);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.22);
  box-shadow:
    var(--v2-bevel-hi-blue),
    inset 0 -1px 0 rgba(0, 0, 0, 0.10);
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * ORACLE                                                                     *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .oracle-headline {
  font-family: var(--v2-display);
  font-weight: 700;
  color: var(--v2-ink);
  font-size: 38px;
  letter-spacing: -0.022em;
  line-height: 1.2;
}
html[data-design="v2"] .oracle-sentence {
  font-family: var(--v2-display);
  font-weight: 700;
  color: var(--v2-ink);
  font-size: 26px;
  letter-spacing: -0.022em;
  line-height: 1.2;
}
html[data-design="v2"] .oracle-sentence strong { font-weight: 800; }

/* 8-ball — leave v1's masterful radial sphere alone, just nudge the cream */
html[data-design="v2"] .oracle-eightball-circle {
  background: #FBFAF4;
}
html[data-design="v2"] .oracle-eightball-icon {
  color: var(--v2-ink);
  font-family: var(--v2-mono);
}

/* Oracle scale — keep v1's green→amber→red gradient track + triangle marker */
html[data-design="v2"] .oracle-scale-axis {
  color: var(--v2-ink-3);
  font-family: var(--v2-mono);
}

/* Tokens — preserve v1's --token-bg cascade */
html[data-design="v2"] .oracle-token {
  color: var(--v2-ink);
  background: var(--token-bg, rgba(0, 0, 0, 0.06));
  border-radius: var(--v2-radius);
  font-family: var(--v2-sans);
}
html[data-design="v2"] .oracle-token:hover {
  background: var(--token-hover-bg, var(--token-bg));
  transform: translateY(-1px);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.10);
}
html[data-design="v2"] .oracle-token:focus-visible {
  outline: 2px solid var(--v2-aqua);
  outline-offset: 2px;
  box-shadow: var(--v2-focus-ring);
}
html[data-design="v2"] .oracle-token.is-empty { color: var(--v2-ink-3); }

/* Token variants stay close to v1's hue palette but slightly more Aqua */
html[data-design="v2"] .oracle-token.is-airport {
  --token-bg: rgba(118, 180, 225, 0.36);
  --token-hover-bg: rgba(118, 180, 225, 0.5);
}
html[data-design="v2"] .oracle-token.is-airport:focus {
  --token-bg: rgba(118, 180, 225, 0.55);
  box-shadow: 0 0 0 2px rgba(118, 180, 225, 0.6);
}

/* Token popover — Snow Leopard menu */
html[data-design="v2"] .oracle-popover {
  background: var(--v2-surface);
  border: 1px solid var(--v2-border-strong);
  border-radius: var(--v2-radius);
  box-shadow: var(--v2-shadow-lg);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
html[data-design="v2"] .oracle-popover-item {
  border-bottom: 1px solid var(--v2-border-soft);
  border-radius: 0;
  color: var(--v2-ink);
}
html[data-design="v2"] .oracle-popover-item:last-child { border-bottom: none; }
html[data-design="v2"] .oracle-popover-item:hover,
html[data-design="v2"] .oracle-popover-item.active,
html[data-design="v2"] .oracle-popover-item.kbd-highlighted {
  background: var(--v2-aqua);
  color: var(--v2-ink-inverse);
}
html[data-design="v2"] .oracle-popover-code {
  font-family: var(--v2-mono);
  font-weight: 600;
}
html[data-design="v2"] .oracle-popover-hint {
  font-family: var(--v2-mono);
  color: var(--v2-ink-3);
  font-size: 11px;
}

/* "Don't know your flight number?" link — text link, not a button.
 * v2 explicitly overrides v1's dotted underline + the universal B-white
 * treatment that this element used to inherit. */
html[data-design="v2"] .oracle-mode-toggle {
  display: block;
  margin: 16px auto 0;
  background: transparent;
  border: none;
  box-shadow: none;
  padding: 6px 10px;
  font-family: var(--v2-sans);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--v2-aqua);
  text-decoration: underline;
  text-decoration-style: solid;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  cursor: pointer;
  transition: color 120ms var(--v2-ease), text-decoration-color 120ms var(--v2-ease);
}
html[data-design="v2"] .oracle-mode-toggle:hover {
  background: transparent;
  color: var(--v2-aqua-press-hi);
  text-decoration-thickness: 2px;
  box-shadow: none;
  transform: none;
}
html[data-design="v2"] .oracle-mode-toggle:focus-visible {
  outline: 2px solid var(--v2-aqua);
  outline-offset: 3px;
  border-radius: var(--v2-radius);
}
html[data-design="v2"] .oracle-source {
  color: var(--v2-ink-2);
  font-family: var(--v2-mono);
  font-size: 12px;
}
html[data-design="v2"] .oracle-source em {
  font-style: italic;
  color: var(--v2-ink);
  font-weight: 500;
}
html[data-design="v2"] .oracle-error {
  background: var(--v2-pill-red);
  color: var(--v2-ink-inverse);
  border: 1px solid rgba(0, 0, 0, 0.32);
  border-radius: var(--v2-radius);
  padding: 8px 12px;
  box-shadow: var(--v2-shadow-sm),
              var(--v2-bevel-hi-blue);
  font-weight: 500;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
}
html[data-design="v2"] .oracle-hint {
  font-family: var(--v2-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--v2-ink-3);
}
html[data-design="v2"] .oracle-prompt-label {
  font-family: var(--v2-mono);
  letter-spacing: 0.10em;
  text-transform: none;
  color: var(--v2-ink-2);
  font-size: 11px;
}
html[data-design="v2"] .oracle-prompt-tail {
  font-family: var(--v2-sans);
  color: var(--v2-ink-2);
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * EXPLORE PAGE                                                               *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .explore-ticker {
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius-pill);
  box-shadow: var(--v2-shadow), var(--v2-bevel-hi);
  backdrop-filter: blur(12px) saturate(150%);
  -webkit-backdrop-filter: blur(12px) saturate(150%);
}
/* Ticker label — match v1: sans, sentence-case, normal weight, inherits 17px */
html[data-design="v2"] .explore-ticker-label {
  font-family: var(--v2-sans);
  text-transform: none;
  letter-spacing: 0;
  color: var(--v2-ink-2);
  font-weight: 400;
  font-size: 17px;
}
html[data-design="v2"] .explore-ticker-sentence {
  font-family: var(--v2-sans);
  font-weight: 500;
  font-size: 17px;
  letter-spacing: -0.005em;
  color: var(--v2-ink);
}
/* Inline mini-input inside the ticker — keep v1's underline-only treatment */
html[data-design="v2"] .explore-ticker .airport-input {
  font-family: var(--v2-mono);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-align: center;
  padding: 4px 6px;
  width: 70px;
  border: none;
  border-bottom: 1.5px solid var(--v2-border-strong);
  background: transparent;
  border-radius: 0;
  box-shadow: none;
}
html[data-design="v2"] .explore-ticker .airport-input:focus {
  border-bottom-color: var(--v2-aqua);
  box-shadow: 0 1px 0 0 var(--v2-aqua);
}

html[data-design="v2"] .explore-panel {
  background: var(--v2-surface);
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius-card);
  box-shadow: var(--v2-shadow-lg);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
html[data-design="v2"] .explore-panel-header {
  border-bottom: 1px solid var(--v2-border);
}
html[data-design="v2"] .explore-panel-kicker {
  font-family: var(--v2-mono);
  text-transform: none;
  letter-spacing: 0.10em;
  color: var(--v2-ink-2);
  font-size: 11px;
}
html[data-design="v2"] .explore-panel-title {
  font-family: var(--v2-display);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: -0.022em;
  color: var(--v2-ink);
}
html[data-design="v2"] .explore-panel-sub { color: var(--v2-ink-2); }

html[data-design="v2"] .explore-legend {
  background: var(--v2-surface);
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius);
  box-shadow: var(--v2-shadow-sm);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
html[data-design="v2"] .legend-title {
  font-family: var(--v2-mono);
  letter-spacing: 0.10em;
  text-transform: none;
  color: var(--v2-ink-2);
  font-size: 11px;
}

/* Legend dots — Aqua pearls */
html[data-design="v2"] .explore-legend .legend-dot {
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.22);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4);
}
html[data-design="v2"] .explore-legend .legend-green .legend-dot { background: var(--v2-pill-green); }
html[data-design="v2"] .explore-legend .legend-amber .legend-dot { background: var(--v2-pill-amber); }
html[data-design="v2"] .explore-legend .legend-red .legend-dot { background: var(--v2-pill-red); }
html[data-design="v2"] .explore-legend .legend-none .legend-dot { background: rgba(0, 0, 0, 0.32); }
/* Legend chips are a dot + label in a flex row — DON'T wrap them in a
 * pill. v2 originally tried `border-radius: 50%` on the chip wrapper,
 * which painted a horrid oval around each "Great / Mixed / Poor / No
 * data" group. Just let the small color dot do the indicating. */
html[data-design="v2"] .legend-chip {
  border: none;
  border-radius: 0;
  background: none;
  padding: 0;
}
html[data-design="v2"] .legend-disclaimer {
  font-family: var(--v2-mono);
  font-size: 11px;
  color: var(--v2-ink-3);
}

html[data-design="v2"] .explore-tooltip {
  background: linear-gradient(to bottom, #4a4a52 0%, #2c2c34 100%);
  color: var(--v2-ink-inverse);
  border: 1px solid rgba(0, 0, 0, 0.5);
  border-radius: var(--v2-radius);
  box-shadow: var(--v2-shadow-lg),
              inset 0 1px 0 rgba(255, 255, 255, 0.10);
  font-family: var(--v2-sans);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.3);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
html[data-design="v2"] .explore-tooltip-code {
  font-family: var(--v2-mono);
  font-weight: 600;
  color: var(--v2-ink-inverse);
}
html[data-design="v2"] .explore-tooltip-city,
html[data-design="v2"] .explore-tooltip-meta,
html[data-design="v2"] .explore-tooltip-stats { color: rgba(255, 255, 255, 0.92); }
html[data-design="v2"] .explore-arrow { color: var(--v2-ink-2); }

/* ═════════════════════════════════════════════════════════════════════════ *
 * HUB OVERLAY                                                                *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .hub-overlay-list {
  background: var(--v2-surface);
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius-card);
  box-shadow: var(--v2-shadow-lg);
}
html[data-design="v2"] .hub-overlay-title {
  font-family: var(--v2-display);
  font-weight: 700;
  font-size: 24px;
  letter-spacing: -0.022em;
  color: var(--v2-ink);
}
html[data-design="v2"] .hub-overlay-empty,
html[data-design="v2"] .hub-overlay-loading {
  color: var(--v2-ink-2);
  font-family: var(--v2-mono);
}
html[data-design="v2"] .hub-row {
  border-bottom: 1px solid var(--v2-border-soft);
  background: transparent;
  border-radius: 0;
}
html[data-design="v2"] .hub-row:last-child { border-bottom: none; }
html[data-design="v2"] .hub-row:hover { background: rgba(0, 0, 0, 0.025); }
html[data-design="v2"] .hub-row-code {
  font-family: var(--v2-mono);
  font-weight: 600;
}
html[data-design="v2"] .hub-row-sub,
html[data-design="v2"] .hub-trip-note { color: var(--v2-ink-3); font-family: var(--v2-mono); }

html[data-design="v2"] .hub-route-title {
  font-family: var(--v2-display);
  font-weight: 700;
  font-size: 24px;
  letter-spacing: -0.022em;
  color: var(--v2-ink);
}
html[data-design="v2"] .hub-route-title .code,
html[data-design="v2"] .hub-leg-route .code,
html[data-design="v2"] .hub-trip-part-route .code {
  font-family: var(--v2-mono);
  font-weight: 700;
}
html[data-design="v2"] .hub-route-via,
html[data-design="v2"] .hub-route-arrow { color: var(--v2-ink-2); }

/* .hub-leg is a NAKED WRAPPER in v1 (just margin) — the inner .winner-card
 * carries the chrome. Don't wrap it in a panel: that creates a tight
 * card-inside-card double-border on every leg. .hub-trip is the only
 * one of these that should look like a real card. */
html[data-design="v2"] .hub-trip {
  border: 1px solid var(--v2-border-soft);
  border-radius: var(--v2-radius-card);
  background: var(--v2-surface-2);
}
html[data-design="v2"] .hub-leg-header {
  color: var(--v2-ink-2);
  font-family: var(--v2-mono);
}

/* hub-leg-num — small mono caps chip with hairline border (per v1 structure) */
html[data-design="v2"] .hub-leg-num {
  background: var(--v2-gloss);
  color: var(--v2-ink-2);
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius);
  font-family: var(--v2-mono);
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0.08em;
  box-shadow: var(--v2-bevel-hi);
}
html[data-design="v2"] .hub-leg-fallback {
  border: 1px dashed var(--v2-border-strong);
  border-radius: var(--v2-radius);
  background: var(--v2-surface-2);
}
html[data-design="v2"] .hub-leg-fallback-airline {
  font-family: var(--v2-mono);
  color: var(--v2-ink);
}
html[data-design="v2"] .hub-leg-fallback-note,
html[data-design="v2"] .hub-leg-fallback-hint { color: var(--v2-ink-3); }

html[data-design="v2"] .hub-trip-headline {
  font-family: var(--v2-display);
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--v2-ink);
}
html[data-design="v2"] .hub-trip-total,
html[data-design="v2"] .hub-trip-label,
html[data-design="v2"] .hub-trip-part-time,
html[data-design="v2"] .hub-trip-part-wait {
  font-family: var(--v2-mono);
  color: var(--v2-ink-2);
}
/* .hub-trip-part is a flex row INSIDE the .hub-trip card — not its own
 * card. Wrapping each row in a white sub-card created the "fussy little
 * boxes inside the cream parent" look. Leave the row chromeless; let
 * the parent .hub-trip card carry the framing. */
html[data-design="v2"] .hub-trip-part {
  border: none;
  background: transparent;
  padding: 2px 0;
}

/* Connection-panel "operator" line: surfaces the airline(s) the panel
 * is featuring when the user came from the Single airline / Alliance
 * tab. Uses the existing v2 status tokens — same-airline = good
 * (green), alliance = warn (amber). Reads as a quiet annotation on
 * the trip headline card, not as a separate component. */
html[data-design="v2"] .hub-trip-operator {
  display: flex; align-items: center; gap: 8px;
  margin-top: 10px;
  flex-wrap: wrap;
  font-family: var(--v2-sans);
  font-size: 12px;
  line-height: 1.45;
  color: var(--v2-ink-2);
}
html[data-design="v2"] .hub-trip-operator-pill {
  display: inline-block;
  padding: 3px 7px;
  border-radius: 4px;
  font-family: var(--v2-sans);
  font-weight: 600;
  font-size: 10px; letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}
html[data-design="v2"] .hub-trip-operator[data-pin="same"] .hub-trip-operator-pill {
  background: color-mix(in srgb, var(--v2-status-good) 18%, transparent);
  color: color-mix(in srgb, var(--v2-status-good) 80%, var(--v2-ink));
}
html[data-design="v2"] .hub-trip-operator[data-pin="alliance"] .hub-trip-operator-pill {
  background: color-mix(in srgb, var(--v2-status-warn) 22%, transparent);
  color: color-mix(in srgb, var(--v2-status-warn) 75%, var(--v2-ink));
}
html[data-design="v2"] .hub-trip-operator-text { color: var(--v2-ink-2); }

/* Pinned winner card — accent the leg's featured row when the panel
 * is pinning by tab choice rather than on-time leader. Quiet left-
 * border stripe, recolored label. Doesn't fight the existing winner
 * styling. */
html[data-design="v2"] .winner-card[data-pin="same"] {
  border-left: 3px solid var(--v2-status-good);
}
html[data-design="v2"] .winner-card[data-pin="same"] .winner-label {
  color: color-mix(in srgb, var(--v2-status-good) 80%, var(--v2-ink));
}
html[data-design="v2"] .winner-card[data-pin="alliance"] {
  border-left: 3px solid var(--v2-status-warn);
}
html[data-design="v2"] .winner-card[data-pin="alliance"] .winner-label {
  color: color-mix(in srgb, var(--v2-status-warn) 80%, var(--v2-ink));
}

/* Synth-leg fallback chip — highlight pinned airline. */
html[data-design="v2"] .hub-leg-fallback-airline.is-pin.pin-same {
  border-color: color-mix(in srgb, var(--v2-status-good) 60%, var(--v2-border-strong));
  background: color-mix(in srgb, var(--v2-status-good) 12%, var(--v2-surface-2));
}
html[data-design="v2"] .hub-leg-fallback-airline.is-pin.pin-alliance {
  border-color: color-mix(in srgb, var(--v2-status-warn) 60%, var(--v2-border-strong));
  background: color-mix(in srgb, var(--v2-status-warn) 12%, var(--v2-surface-2));
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * ITINERARIES                                                                *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .itin-list {
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius-card);
  background: var(--v2-surface);
  box-shadow: var(--v2-shadow);
  overflow: hidden;
}
html[data-design="v2"] .itin-row {
  border-bottom: 1px solid var(--v2-border-soft);
  background: transparent;
  border-radius: 0;
  box-shadow: none;
  transition: background 100ms var(--v2-ease);
}
html[data-design="v2"] .itin-row:last-child { border-bottom: none; }
html[data-design="v2"] .itin-row:hover {
  background: rgba(0, 0, 0, 0.025);
  transform: none;
  box-shadow: none;
}
html[data-design="v2"] .itin-row.is-synth {
  background: repeating-linear-gradient(
    45deg,
    var(--v2-surface) 0 6px,
    rgba(0, 0, 0, 0.025) 6px 12px
  );
}
html[data-design="v2"] .itin-row-arrow,
html[data-design="v2"] .itin-row-via { color: var(--v2-ink-2); }
html[data-design="v2"] .itin-row-hub-code {
  color: var(--v2-ink);
  font-weight: 700;
}
html[data-design="v2"] .itin-row-hub-city { color: var(--v2-ink-2); }
html[data-design="v2"] .itin-row-time,
html[data-design="v2"] .itin-row-freq,
html[data-design="v2"] .itin-row-wait {
  color: var(--v2-ink-2);
}
html[data-design="v2"] .itin-row-synth {
  color: var(--v2-ink-3);
  font-family: var(--v2-mono);
  font-size: 10px;
}
html[data-design="v2"] .itin-count {
  color: var(--v2-ink-2);
  font-family: var(--v2-mono);
  font-size: 11px;
}
html[data-design="v2"] .itin-header { border-bottom: 1px solid var(--v2-border); }
html[data-design="v2"] .itin-title {
  font-family: var(--v2-display);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.018em;
  color: var(--v2-ink);
}
html[data-design="v2"] .itin-loading,
html[data-design="v2"] .itin-empty {
  color: var(--v2-ink-2);
  font-family: var(--v2-mono);
}
html[data-design="v2"] .itin-expand-icon { color: var(--v2-ink-2); }
html[data-design="v2"] .itin-expand-label { color: var(--v2-ink); }

/* Itin tags — preserve v1's color-mix tinted style (more readable, less neon) */
html[data-design="v2"] .itin-tag {
  border-radius: var(--v2-radius);
  font-family: var(--v2-sans);
  font-weight: 600;
  font-size: 10px;
  letter-spacing: 0.06em;
}
html[data-design="v2"] .itin-tag-same {
  background: color-mix(in srgb, var(--v2-status-good) 18%, transparent);
  color: color-mix(in srgb, var(--v2-status-good) 80%, var(--v2-ink));
}
html[data-design="v2"] .itin-tag-alliance {
  background: color-mix(in srgb, var(--v2-status-warn) 22%, transparent);
  color: color-mix(in srgb, var(--v2-status-warn) 75%, var(--v2-ink));
}
html[data-design="v2"] .itin-tag-mixed {
  background: rgba(0, 0, 0, 0.06);
  color: var(--v2-ink-2);
}

/* DOW cells — keep v1 size, repaint with v2 colors */
html[data-design="v2"] .itin-dow-cell {
  font-family: var(--v2-mono);
  border-radius: 3px;
}
html[data-design="v2"] .itin-dow-cell.on {
  background: color-mix(in srgb, var(--v2-status-good) 25%, transparent);
  color: color-mix(in srgb, var(--v2-status-good) 75%, var(--v2-ink));
}
html[data-design="v2"] .itin-dow-cell.off {
  background: var(--v2-bg);
  color: rgba(0, 0, 0, 0.25);
}

/* Long-wait collapsible */
html[data-design="v2"] .itin-long-wait {
  border: 1px solid var(--v2-border-soft);
  border-radius: var(--v2-radius);
  background: var(--v2-surface-2);
}
html[data-design="v2"] .itin-long-wait.is-open { border-color: var(--v2-border); }
html[data-design="v2"] .itin-long-icon { color: var(--v2-ink-2); }
html[data-design="v2"] .itin-long-helper {
  color: var(--v2-ink-3);
  font-family: var(--v2-mono);
  font-size: 11px;
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * MODALS                                                                     *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .modal-overlay {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
html[data-design="v2"] .modal-backdrop,
html[data-design="v2"] .disclaimer-modal-backdrop {
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
html[data-design="v2"] .modal-panel,
html[data-design="v2"] .disclaimer-modal-card {
  background: var(--v2-surface);
  border: 1px solid var(--v2-border-strong);
  border-radius: var(--v2-radius-card);
  box-shadow: var(--v2-shadow-xl);
}

/* Snow Leopard titlebar */
html[data-design="v2"] .modal-header {
  background: linear-gradient(to bottom, #F0F2F5 0%, #DEE3E9 100%);
  border-bottom: 1px solid var(--v2-border);
  border-radius: var(--v2-radius-card) var(--v2-radius-card) 0 0;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
}
html[data-design="v2"] .modal-kicker {
  font-family: var(--v2-mono);
  text-transform: none;
  letter-spacing: 0.10em;
  color: var(--v2-ink-2);
  font-size: 11px;
}
html[data-design="v2"] .modal-title { font-weight: 700; color: var(--v2-ink); }
html[data-design="v2"] .modal-title-text {
  font-family: var(--v2-display);
  font-weight: 700;
  font-size: 26px;
  line-height: 1.15;
  letter-spacing: -0.025em;
}
html[data-design="v2"] .modal-subtitle { color: var(--v2-ink-2); }

/* Modal stats row — drop the v1 vertical dividers (read as a spreadsheet)
 * and switch labels from mono caps to sans. The numbers stay mono with
 * .c-* status colors, but with cleaner labels and breathing room they
 * read as a single set rather than a fragmented table. */
html[data-design="v2"] .modal-stats {
  border-bottom: 1px solid var(--v2-border-soft);
  padding: 18px 28px;
  gap: 8px;
}
html[data-design="v2"] .modal-stat {
  border-left: none;
  padding: 4px 14px;
}
html[data-design="v2"] .modal-stat:first-child { padding-left: 0; }
html[data-design="v2"] .modal-stat:last-child  { padding-right: 0; }
html[data-design="v2"] .modal-stat-label {
  font-family: var(--v2-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--v2-ink-3);
}
html[data-design="v2"] .modal-stat-value {
  font-family: var(--v2-mono);
  font-weight: 600;
  font-size: 19px;
  letter-spacing: -0.005em;
  /* No color — let .c-green / .c-amber / .c-red pass through */
}
/* 5-cell airport modal — tighter padding so the row fits in 560px width */
html[data-design="v2"] .modal-stats-5 .modal-stat { padding: 4px 8px; }
html[data-design="v2"] .modal-stats-5 .modal-stat:first-child { padding-left: 0; }
html[data-design="v2"] .modal-stats-5 .modal-stat:last-child  { padding-right: 0; }
html[data-design="v2"] .modal-stats-5 .modal-stat-value { font-size: 17px; }

/* Modal code-tile — preserve v1's flap-board tile look (cream paper) */
html[data-design="v2"] .modal-code-tile {
  background: linear-gradient(to bottom, #FFFFFF 0%, #E8EAED 100%);
  border: 1px solid var(--v2-border-strong);
  border-radius: 3px;
  font-family: var(--v2-mono);
  font-weight: 600;
  color: var(--v2-ink);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8),
              0 1px 0 rgba(0, 0, 0, 0.05);
}
html[data-design="v2"] .modal-code-tile::after {
  background: rgba(0, 0, 0, 0.12);
}

/* Modal caveat */
html[data-design="v2"] .modal-caveat {
  background: color-mix(in srgb, var(--v2-status-warn) 15%, transparent);
  color: color-mix(in srgb, var(--v2-status-warn) 75%, var(--v2-ink));
  border: 1px solid color-mix(in srgb, var(--v2-status-warn) 35%, transparent);
  border-radius: var(--v2-radius);
}
html[data-design="v2"] .modal-caveat-dot {
  background: var(--v2-status-warn);
  border-radius: 50%;
}

/* Flight rows inside modal */
html[data-design="v2"] .flight-row { border-bottom: 1px solid var(--v2-border-soft); }
html[data-design="v2"] .flight-row:last-child { border-bottom: none; }
html[data-design="v2"] .flight-row:hover { background: rgba(0, 0, 0, 0.02); }
html[data-design="v2"] .flight-num {
  font-family: var(--v2-mono);
  font-weight: 600;
}
html[data-design="v2"] .flight-time-value {
  font-family: var(--v2-mono);
  /* No color — inherit so .c-* on parents passes through */
}
html[data-design="v2"] .flight-time-label {
  font-family: var(--v2-mono);
  color: var(--v2-ink-3);
  text-transform: none;
  letter-spacing: 0.08em;
}
html[data-design="v2"] .flight-arrow { color: var(--v2-ink-3); }
html[data-design="v2"] .flight-date-label {
  color: var(--v2-ink-2);
  font-family: var(--v2-mono);
  text-transform: none;
  letter-spacing: 0.08em;
  font-size: 11px;
}

/* Flight delay badge — Pill-status (Aqua-tier gradient) */
html[data-design="v2"] .flight-delay {
  border-radius: var(--v2-radius);
  border: 1px solid rgba(0, 0, 0, 0.18);
  font-family: var(--v2-mono);
  font-weight: 600;
  padding: 2px 6px;
  box-shadow: var(--v2-bevel-hi);
}
html[data-design="v2"] .flight-delay.c-green {
  background: var(--v2-pill-green);
  color: #fff;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.18);
}
html[data-design="v2"] .flight-delay.c-amber {
  background: var(--v2-pill-amber);
  color: var(--v2-ink);
}
html[data-design="v2"] .flight-delay.c-red {
  background: var(--v2-pill-red);
  color: #fff;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.18);
}
html[data-design="v2"] .flight-delay.c-muted {
  background: var(--v2-surface-2);
  color: var(--v2-ink-3);
  box-shadow: none;
}

/* Disclaimer modal */
html[data-design="v2"] .disclaimer-modal-content {
  font-family: var(--v2-sans);
  color: var(--v2-ink);
}
html[data-design="v2"] .disclaimer-modal-content a {
  color: var(--v2-aqua);
  font-weight: 500;
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * REPORT CARD                                                                *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .rc-card {
  background: var(--v2-surface);
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius-card);
  box-shadow: var(--v2-shadow-lg);
  transform-origin: 50% 100%;
  transition: transform 200ms var(--v2-ease-spring),
              box-shadow 200ms var(--v2-ease-spring);
}
html[data-design="v2"] .rc-card:hover {
  transform: rotate(-0.4deg) translateY(-2px);
  box-shadow: var(--v2-shadow-xl);
}
/* Give the divider real breathing room — v1's 18px reads tight in v2
 * because the border is darker (var(--v2-border) at 16% vs v1's 6%) and
 * the headline type sits taller. Bumping to 24px both sides keeps the
 * route header from looking like it's sitting on the line. */
html[data-design="v2"] .rc-card-head {
  border-bottom: 1px solid var(--v2-border);
  padding-bottom: 24px;
  margin-bottom: 24px;
}
html[data-design="v2"] .rc-card-route .code {
  font-family: var(--v2-mono);
  font-weight: 700;
  color: var(--v2-ink);
}
html[data-design="v2"] .rc-card-flight,
html[data-design="v2"] .rc-card-meta,
html[data-design="v2"] .rc-source {
  color: var(--v2-ink-2);
  font-family: var(--v2-mono);
}
html[data-design="v2"] .rc-grade-letter {
  font-family: var(--v2-display);
  font-weight: 800;
  letter-spacing: -0.04em;
}
html[data-design="v2"] .rc-grade-caption {
  font-family: var(--v2-mono);
  letter-spacing: 0.10em;
  text-transform: none;
  color: var(--v2-ink-2);
  font-size: 10px;
  font-weight: 600;
}
html[data-design="v2"] .rc-row { border-bottom: 1px solid var(--v2-border-soft); }
html[data-design="v2"] .rc-row:last-child { border-bottom: none; }
html[data-design="v2"] .rc-row-label { color: var(--v2-ink-2); }
html[data-design="v2"] .rc-row-value {
  font-family: var(--v2-mono);
  font-weight: 600;
  /* No color — let .c-* pass through */
}
html[data-design="v2"] .rc-row-leader { border-bottom: 1px dotted var(--v2-border); }
/* These are form rows on the picker, not list-item dividers — no border. */
html[data-design="v2"] .rc-flight-row,
html[data-design="v2"] .rc-route-row { border-bottom: none; }
html[data-design="v2"] .rc-arrow { color: var(--v2-ink-2); }
html[data-design="v2"] .rc-caveat {
  color: var(--v2-ink-3);
  font-family: var(--v2-mono);
  font-size: 11px;
}
html[data-design="v2"] .rc-form,
html[data-design="v2"] .rc-field-label {
  font-family: var(--v2-mono);
  text-transform: none;
  letter-spacing: 0.08em;
  color: var(--v2-ink-2);
  font-size: 11px;
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * WHY / FOOTER                                                               *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .why-page {
  background: var(--v2-bg);
  font-family: var(--v2-sans);
}
html[data-design="v2"] .why-title {
  font-family: var(--v2-display);
  font-weight: 800;
  font-size: 38px;
  line-height: 1.1;
  letter-spacing: -0.032em;
  color: var(--v2-ink);
}
html[data-design="v2"] .why-content,
html[data-design="v2"] .why-content p {
  color: var(--v2-ink);
  line-height: 1.6;
  font-weight: 400;
}
html[data-design="v2"] .why-content a {
  color: var(--v2-aqua);
  font-weight: 500;
}
html[data-design="v2"] .why-sign-off {
  /* Inherits font-family from .why-content (sans body copy) — was
     previously --v2-mono which made the sign-off feel disconnected
     from the paragraphs above it. */
  color: var(--v2-ink-2);
}

html[data-design="v2"] .site-footer {
  background: var(--v2-bg-deep);
  border-top: 1px solid var(--v2-border);
  font-family: var(--v2-sans);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
}
html[data-design="v2"] .site-footer-divider {
  color: transparent;
  height: 0;
  border-top: 1px solid var(--v2-border);
  width: 80px;
  margin: 0 0 24px;
}
html[data-design="v2"] .site-footer-title {
  font-family: var(--v2-display);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: -0.022em;
  text-transform: none;
  color: var(--v2-ink);
}
html[data-design="v2"] .site-footer-body { color: var(--v2-ink); }
html[data-design="v2"] .site-footer-body a {
  color: var(--v2-aqua);
  font-weight: 500;
}
html[data-design="v2"] .site-footer-body a:hover { text-decoration: underline; }
html[data-design="v2"] .site-footer-body em {
  font-style: italic;
  color: var(--v2-aqua);
  background: transparent;
  padding: 0;
  font-weight: 500;
}
html[data-design="v2"] .disclaimer,
html[data-design="v2"] .site-footer-body p {
  color: var(--v2-ink);
  font-family: var(--v2-sans);
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * MISC                                                                       *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .loading,
html[data-design="v2"] .no-results {
  color: var(--v2-ink-2);
  font-family: var(--v2-mono);
}
html[data-design="v2"] .spinner {
  border: 3px solid var(--v2-border);
  border-top-color: var(--v2-aqua);
  border-radius: 50%;
}
html[data-design="v2"] .typewriter-cursor { color: var(--v2-aqua); }
html[data-design="v2"] .no-results .big {
  font-weight: 700;
  color: var(--v2-ink);
  font-family: var(--v2-display);
  letter-spacing: -0.018em;
}
html[data-design="v2"] .no-results .sub {
  color: var(--v2-ink-2);
  font-family: var(--v2-sans);
}
html[data-design="v2"] .click-hint {
  font-family: var(--v2-sans);
  color: var(--v2-ink-3);
}

/* Disclaimer footer text inside the explore panel had extra 16px
 * horizontal padding from the v1 base — the panel already provides
 * its own gutter, so the doubled inset made the lines visibly indented
 * compared to surrounding content. Zero out the side padding so they
 * align with siblings; keep top/bottom for vertical rhythm. Scoped to
 * the explore panel because .disclaimer also appears on bare-page
 * contexts (no parent gutter) where the 16px IS the gutter. */
html[data-design="v2"] .explore-panel .disclaimer {
  padding-left: 0;
  padding-right: 0;
  /* v1 .disclaimer is text-align: center for full-width contexts. In the
   * explore panel the disclaimer sits in the same gutter as left-aligned
   * siblings ("Click any airline...", section headers), so center
   * alignment reads as wrongly-indented. Match the column. */
  text-align: left;
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * FIRST-VISIT WELCOME OVERLAY                                                *
 * v1 hardcodes Inter on .welcome-line / .welcome-cta. Override here so the   *
 * popup wears the Lucida Grande body + Aqua-blue CTA the rest of v2 uses.    *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .welcome-card {
  background: var(--v2-surface);
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius-card);
  box-shadow: var(--v2-shadow-xl);
}
html[data-design="v2"] .welcome-line {
  font-family: var(--v2-sans);
  color: var(--v2-ink);
}
html[data-design="v2"] .welcome-line strong {
  font-weight: 700;
  color: var(--v2-ink);
}
html[data-design="v2"] .welcome-cta {
  font-family: var(--v2-sans);
  font-weight: 600;
  letter-spacing: 0;
  background: var(--v2-aqua-default);
  color: var(--v2-ink-inverse);
  border: 1px solid var(--v2-border-strong);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.22);
  box-shadow:
    var(--v2-bevel-hi-blue),
    inset 0 -1px 0 rgba(0, 0, 0, 0.10),
    0 1px 2px rgba(0, 0, 0, 0.18);
}
html[data-design="v2"] .welcome-cta:hover {
  background: var(--v2-aqua-hover);
  color: #fff;
  transform: translateY(-1px);
  box-shadow:
    var(--v2-bevel-hi-blue),
    inset 0 -1px 0 rgba(0, 0, 0, 0.10),
    0 4px 10px rgba(0, 0, 0, 0.18);
}
html[data-design="v2"] .welcome-cta:active {
  background: var(--v2-aqua-press);
  transform: translateY(0);
  box-shadow: var(--v2-aqua-press-inset);
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * MOBILE BREAKPOINTS                                                         *
 * v1 has explicit mobile font-size reductions for headings; v2's bigger     *
 * desktop sizes override them via specificity, so we re-apply the mobile    *
 * reductions here at the matching breakpoints.                              *
 * ═════════════════════════════════════════════════════════════════════════ */

@media (max-width: 720px) {
  html[data-design="v2"] .modal-title-text { font-size: 22px; }
  html[data-design="v2"] .oracle-sentence { font-size: 22px; }
  html[data-design="v2"] .hub-overlay-title { font-size: 20px; }
  html[data-design="v2"] .hub-route-title { font-size: 18px; }
  html[data-design="v2"] .explore-panel-title { font-size: 19px; }
  html[data-design="v2"] .itin-title { font-size: 16px; }
  html[data-design="v2"] .site-footer-title { font-size: 19px; }
  /* Modal stats — already-tight 5-cell row needs to shrink further so it
   * doesn't clip at narrower widths. */
  html[data-design="v2"] .modal-stats { padding: 14px 20px; }
  html[data-design="v2"] .modal-stat { padding: 4px 10px; }
  html[data-design="v2"] .modal-stat-value { font-size: 17px; }
  html[data-design="v2"] .modal-stats-5 .modal-stat-value { font-size: 15px; }
}

@media (max-width: 600px) {
  html[data-design="v2"] .board-title { line-height: 1.2; }
  html[data-design="v2"] .modal-title-text { font-size: 20px; }
  html[data-design="v2"] .oracle-sentence { font-size: 20px; }
  html[data-design="v2"] .hub-overlay-title { font-size: 18px; }
  html[data-design="v2"] .modal-stats { padding: 12px 16px; flex-wrap: wrap; gap: 4px 6px; }
  html[data-design="v2"] .modal-stats-5 .modal-stat { padding: 4px 6px; min-width: 80px; flex: 1 1 auto; }
  html[data-design="v2"] nav { gap: 0; padding: 3px; }
  html[data-design="v2"] .nav-link { padding: 6px 14px; font-size: 12px; }
  html[data-design="v2"] .design-toggle-btn { padding: 6px 8px; font-size: 9px; }
  html[data-design="v2"] .modal-panel,
  html[data-design="v2"] .disclaimer-modal-card {
    box-shadow: var(--v2-shadow-lg);
  }
  html[data-design="v2"] .glow-box {
    padding: 32px 24px 20px;
    border-width: 3px;
  }
  html[data-design="v2"] .winner-card,
  html[data-design="v2"] .rc-card,
  html[data-design="v2"] .board-panel,
  html[data-design="v2"] .explore-panel {
    box-shadow: var(--v2-shadow);
  }
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * TOUCH-DEVICE HOVER GATING                                                  *
 * On iOS/Android, :hover sticks after a tap until the user taps elsewhere.  *
 * v2's hover lifts/tilts/shadow growth become permanently-applied "stuck"   *
 * states. Reset every hover transform + shadow growth to its default on     *
 * non-hover devices so taps feedback via :active only.                       *
 * ═════════════════════════════════════════════════════════════════════════ */

@media (hover: none) {
  html[data-design="v2"] .nav-link:hover,
  html[data-design="v2"] .design-toggle-btn:hover,
  html[data-design="v2"] .why-link:hover,
  html[data-design="v2"] .winner-card:hover,
  html[data-design="v2"] .rc-card:hover,
  html[data-design="v2"] .predict-app:hover,
  html[data-design="v2"] .go-btn:hover,
  html[data-design="v2"] .sort-btn:hover,
  html[data-design="v2"] .segmented-btn:hover,
  html[data-design="v2"] .board-tab:hover,
  html[data-design="v2"] .board-type-btn:hover,
  html[data-design="v2"] .pagination-btn:hover:not(.disabled),
  html[data-design="v2"] .pagination-page:hover,
  html[data-design="v2"] .rc-expand-btn:hover,
  html[data-design="v2"] .hub-retry:hover,
  html[data-design="v2"] .disclaimer-trigger:hover,
  html[data-design="v2"] .itin-toggle button:hover,
  html[data-design="v2"] .region-trigger:hover,
  html[data-design="v2"] .hero-toggle-btn:hover,
  html[data-design="v2"] .explore-back:hover,
  html[data-design="v2"] .explore-panel-close:hover,
  html[data-design="v2"] .itin-expand-cta:hover,
  html[data-design="v2"] .sort-toggle-btn:hover,
  html[data-design="v2"] .sort-dir-btn:hover,
  html[data-design="v2"] .hub-tab:hover,
  html[data-design="v2"] .random-dest-btn:hover,
  html[data-design="v2"] .modal-close:hover,
  html[data-design="v2"] .disclaimer-modal-close:hover,
  html[data-design="v2"] .oracle-token:hover,
  html[data-design="v2"] .oracle-eightball[data-ready="true"]:hover {
    transform: none;
  }
  /* For surfaces that grow their shadow on hover, snap back to the
   * default shadow so they don't sit in a "lifted" state after tap. */
  html[data-design="v2"] .winner-card:hover,
  html[data-design="v2"] .rc-card:hover {
    box-shadow: var(--v2-shadow);
  }
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * REDUCED MOTION                                                             *
 * ═════════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  html[data-design="v2"] *,
  html[data-design="v2"] *::before,
  html[data-design="v2"] *::after {
    transition-duration: 0ms !important;
    animation-duration: 0ms !important;
  }
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * PREDICT PICKER PAGE (/predict) — three apps on a desktop                  *
 * ═════════════════════════════════════════════════════════════════════════ */

html[data-design="v2"] .predict-desk { background: var(--v2-bg); }
html[data-design="v2"] .predict-desk-title {
  font-family: var(--v2-display);
  color: var(--v2-ink);
}
html[data-design="v2"] .predict-desk-sub {
  font-family: var(--v2-sans);
  color: var(--v2-ink-2);
}
html[data-design="v2"] .predict-app:hover {
  background: rgba(42, 38, 34, 0.05);
}
html[data-design="v2"] .predict-app-name {
  font-family: var(--v2-display);
  color: var(--v2-ink);
}
html[data-design="v2"] .predict-app-caption {
  font-family: var(--v2-sans);
  color: var(--v2-ink-2);
}

/* ═════════════════════════════════════════════════════════════════════════ *
 * v2 TYPOGRAPHY & SPACING POLISH (2026-05-04)                               *
 *                                                                            *
 * Final pass on the v2 design language. Goals:                              *
 *   1. Hit-target floors — Apple HIG (44pt on touch, 32pt min on desktop). *
 *   2. Uncramp the modal stat row (4px vertical pad → 12px breathing).     *
 *   3. Scale hero numerals on phones via clamp() so they don't crowd       *
 *      adjacent labels at narrow widths.                                    *
 *   4. Card-stack rhythm onto the 8pt grid.                                 *
 *                                                                            *
 * Lives at the end of the file so source order beats the older mobile      *
 * breakpoint reductions where the new clamps subsume them.                  *
 * ═════════════════════════════════════════════════════════════════════════ */

/* ── Hit-target floors ──────────────────────────────────────────────────── */

html[data-design="v2"] .go-btn,
html[data-design="v2"] .sort-btn,
html[data-design="v2"] .segmented-btn,
html[data-design="v2"] .board-tab,
html[data-design="v2"] .board-type-btn,
html[data-design="v2"] .pagination-btn,
html[data-design="v2"] .pagination-page,
html[data-design="v2"] .rc-expand-btn,
html[data-design="v2"] .hub-retry,
html[data-design="v2"] .itin-toggle button,
html[data-design="v2"] .region-trigger,
html[data-design="v2"] .itin-long-toggle,
html[data-design="v2"] .random-dest-btn,
html[data-design="v2"] .hero-toggle-btn,
html[data-design="v2"] .explore-back,
html[data-design="v2"] .explore-panel-close,
html[data-design="v2"] .itin-expand-cta,
html[data-design="v2"] .sort-toggle-btn,
html[data-design="v2"] .sort-dir-btn,
html[data-design="v2"] .hub-tab {
  min-height: 30px;
}

/* CTA bumps a tier higher — feels deliberate, not button-y small */
html[data-design="v2"] .go-btn {
  min-height: 36px;
  padding: 9px 22px;
}

/* Inputs: tap-friendly even on desktop. Compact-bar variant stays
 * one notch tighter so the inline ticker doesn't grow vertically. */
html[data-design="v2"] .airport-input {
  min-height: 36px;
  padding: 8px 12px;
}
html[data-design="v2"] .compact-bar .airport-input {
  min-height: 32px;
  padding: 6px 10px;
}

/* Touch-mode: every interactive surface clears the 44pt iOS floor */
@media (hover: none) and (pointer: coarse) {
  html[data-design="v2"] .go-btn,
  html[data-design="v2"] .sort-btn,
  html[data-design="v2"] .segmented-btn,
  html[data-design="v2"] .board-tab,
  html[data-design="v2"] .board-type-btn,
  html[data-design="v2"] .pagination-btn,
  html[data-design="v2"] .pagination-page,
  html[data-design="v2"] .rc-expand-btn,
  html[data-design="v2"] .random-dest-btn,
  html[data-design="v2"] .hub-retry,
  html[data-design="v2"] .itin-toggle button,
  html[data-design="v2"] .hero-toggle-btn,
  html[data-design="v2"] .hub-tab,
  html[data-design="v2"] .explore-back,
  html[data-design="v2"] .explore-panel-close,
  html[data-design="v2"] .itin-expand-cta,
  html[data-design="v2"] .sort-toggle-btn,
  html[data-design="v2"] .sort-dir-btn,
  html[data-design="v2"] .region-trigger,
  html[data-design="v2"] .airport-input,
  html[data-design="v2"] .compact-bar .airport-input {
    min-height: var(--tap);
  }
}

/* ── Modal stat row — uncramp the vertical squeeze ──────────────────────── */

/* 4px top/bottom padding on the stat cells made the modal stats row read as
 * a spreadsheet pinched against the divider. 12px gives Apple-sheet
 * breathing room. */
html[data-design="v2"] .modal-stat            { padding: 12px 14px; }
html[data-design="v2"] .modal-stats-5 .modal-stat { padding: 10px 8px; }

@media (max-width: 720px) {
  html[data-design="v2"] .modal-stat            { padding: 10px 10px; }
  html[data-design="v2"] .modal-stats-5 .modal-stat { padding: 8px 6px; }
}
@media (max-width: 600px) {
  html[data-design="v2"] .modal-stats-5 .modal-stat { padding: 8px 6px; min-width: 72px; }
}

/* ── Hero numerals — clamp() instead of fixed px so they scale ──────────── */

/* The mobile @720px / @600px overrides above gave us 17px/15px floors;
 * clamp() collapses those into a single fluid rule and adds a smooth
 * desktop ceiling. Source order means this wins over the older static
 * media-query font-size rules. */
html[data-design="v2"] .modal-stat-value {
  font-size: clamp(16px, 2.4vw, var(--v2-text-title-3));
}
html[data-design="v2"] .modal-stats-5 .modal-stat-value {
  font-size: clamp(14px, 2vw, var(--v2-text-headline));
}

html[data-design="v2"] .modal-title-text {
  font-size: clamp(20px, 3.4vw, var(--v2-text-title-1));
}

/* Note: .winner-metric-value intentionally NOT given a clamp here —
 * the explore-panel hero numbers have their own context-specific 22px
 * rule (.explore-panel .winner-metric-value) that any v2-scoped clamp
 * would override by specificity, blowing the layout past wrap width. */

/* ── Card-stack rhythm onto the 8pt grid ────────────────────────────────── */

html[data-design="v2"] .winner-card { margin-bottom: var(--v2-space-6); }
html[data-design="v2"] .winner-card:last-child { margin-bottom: 0; }
