/* ============================================================
   Layover — DXB Exit Planner
   Dark atmospheric glass. Emerald accent. Departure-board mono.
   ============================================================ */

:root {
  /* One family (Archivo, normal width — the expanded wdth axis read as
     "stretched text" in QA) carries display AND body; hierarchy comes from
     weight (800 display / 400-500 body). IBM Plex Mono does all data work. */
  --font-display: "Archivo", system-ui, sans-serif;
  --font-body: "Archivo", system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, monospace;

  /* Small/body/meta type scale. Headings use their own clamp()s and are
     a separate, already-consistent tier — this scale is for the badge/
     label/caption/body text that used to drift across ~40 ad hoc values. */
  --fs-3xs: 0.64rem;  /* tiny badges/pills */
  --fs-2xs: 0.7rem;   /* uppercase labels/eyebrows */
  --fs-xs: 0.76rem;    /* captions/hints */
  --fs-sm: 0.875rem;   /* secondary body text */
  --fs-base: 1rem;     /* primary body text (16px readability floor) */
  --fs-md: 1.125rem;   /* emphasized inline values */
  --fs-lg: 1.2rem;     /* small standalone card headings */

  --bg: #0a1411;
  --bg-lift: #0e1a16;
  --card: rgba(19, 36, 30, 0.55);
  --card-strong: rgba(24, 44, 37, 0.72);
  --stroke: rgba(255, 255, 255, 0.09);
  --stroke-soft: rgba(255, 255, 255, 0.05);
  --highlight: rgba(255, 255, 255, 0.12);

  --text: #e9f4ee;
  --muted: #93ada2;
  /* Lightened from #5f7d71 (same hue, ~156°) to clear WCAG AA 4.5:1 for
     normal text against both --bg (5.8:1) and the --card composite (5.4:1) —
     the original measured 3.85-4.15:1 and was still used for real content
     (field hints, disclaimers, footer note), not pure decoration. */
  --faint: #7a9689;

  --accent: #35c98e;
  --accent-rgb: 53, 201, 142;
  --accent-deep: #178a5e;
  --accent-ghost: rgba(53, 201, 142, 0.12);

  --ok: #35c98e;
  --warn: #e8b44a;
  --risk: #e86a5e;

  --seg-exit: #2b6653;
  --seg-outside: #35c98e;
  --seg-buffer: #1c3a30;

  --shadow-card: 0 18px 50px -18px rgba(0, 0, 0, 0.55);
  --shadow-hover: 0 26px 60px -20px rgba(0, 0, 0, 0.65), 0 0 0 1px rgba(53, 201, 142, 0.18);
  --radius: 20px;
  --radius-sm: 12px;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);
  /* Echo of the logo's ribbon gradient (deep green → lime). Used sparingly:
     CTA, buffer fills, map pins, QR. The logo stays the only 3D object. */
  --grad-brand: linear-gradient(140deg, #12694c, #35c98e 55%, #7ed957);

  /* Semantic color split (Patch 1.5): green = places & positive status,
     amber = movement/transit (legs, travel chips, map routes). */
  --transit: #e8b44a;
  --transit-soft: rgba(232, 180, 74, 0.35);
}

/* The .mono utility the markup always used but never had a rule for — clock
   digits, plan times, chips etc. silently fell back to the body sans. */
.mono { font-family: var(--font-mono); }

/* Scrollbar hidden globally (full-bleed sections rely on --sbw, which reads 0 here). */
html, body {
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* IE */
}
html::-webkit-scrollbar,
body::-webkit-scrollbar { display: none; /* Chrome, Safari */ }


* { box-sizing: border-box; margin: 0; padding: 0; }
[hidden] { display: none !important; }

/* Flicker fix: a shared (?s=) or restore (?nat=) link tags <html> (see the
   inline script in index.html <head>) BEFORE first paint, so the hero/topbar
   never flash before the loading splash appears. app.js's revealApp() removes
   the class once the splash is up (or the plan has rendered). The opaque splash
   covers the page during boot; this just guarantees no hero frame slips through
   before it. Normal loads (no query params) are unaffected. */
html.snapshot-boot main, html.snapshot-boot .topbar,
html.restoring main, html.restoring .topbar { visibility: hidden; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  transition: background 0.5s ease, color 0.5s ease;
  overflow-x: hidden;
}

/* ---------- Single page backdrop (one hero image behind everything) ---------- */
.page-bg {
  position: fixed;
  inset: 0;
  z-index: -2;
  background: url("assets/images/layover-hero-alt.png") center 30% / cover no-repeat #0a1411;
}
/* Base readability overlay */
.page-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(4, 9, 7, 0.55), rgba(4, 9, 7, 0.35));
}
/* Progressive darkening as you scroll into the results (scroll-driven, no JS) */
.page-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: #050b08;
  opacity: 0.3; /* static fallback */
}
@supports (animation-timeline: scroll()) {
  .page-bg::before {
    opacity: 0;
    animation: page-dim linear both;
    animation-timeline: scroll(root);
  }
  @keyframes page-dim {
    0% { opacity: 0; }
    35% { opacity: 0.5; }
    100% { opacity: 0.72; }
  }
}

/* ---------- Splash: once-per-session animated feature intro ---------- */
.splash {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  background: #060d09;
  cursor: pointer;
  transition: opacity 350ms ease;
}
.splash.leaving { opacity: 0; pointer-events: none; }
.splash-inner { display: grid; justify-items: center; gap: 14px; text-align: center; padding: 24px; }
.splash-logo {
  height: 84px;
  margin-bottom: 14px;
  filter: drop-shadow(0 0 16px rgba(233, 244, 238, 0.22));
  animation: splash-logo-in 800ms var(--ease-out-strong) both;
}
@keyframes splash-logo-in {
  from { opacity: 0; transform: translateY(12px) scale(0.96); filter: blur(6px) drop-shadow(0 0 16px rgba(233, 244, 238, 0)); }
  to { opacity: 1; transform: translateY(0) scale(1); filter: blur(0) drop-shadow(0 0 16px rgba(233, 244, 238, 0.22)); }
}
.splash-line {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2.8vw, 1.65rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
  opacity: 0;
  transform: translateY(14px);
  filter: blur(5px);
  /* Readable pace: one line every 900ms */
  animation: splash-line-in 700ms var(--ease-out-strong) forwards;
  animation-delay: calc(700ms + var(--i, 0) * 900ms);
}
.splash-line:nth-of-type(2), .splash-line:nth-of-type(4) { color: var(--accent); }
@keyframes splash-line-in {
  to { opacity: 1; transform: translateY(0); filter: blur(0); }
}
.splash-status { display: flex; gap: 18px; min-height: 16px; margin-top: 16px; }
.splash-status .live-badge {
  opacity: 0;
  animation: splash-line-in 500ms ease forwards 3600ms;
}
.splash-skip {
  font-family: var(--font-mono);
  font-size: var(--fs-3xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
  margin-top: 22px;
  opacity: 0;
  animation: splash-line-in 500ms ease forwards 2200ms;
}
/* Bottom progress: communicates the auto-advance without a countdown */
.splash-progress {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--grad-brand);
  transform-origin: left;
  transform: scaleX(0);
  animation: splash-progress 7100ms linear forwards;
}
@keyframes splash-progress {
  to { transform: scaleX(1); }
}

/* ---------- Gate: email + Turnstile bot-block screen ---------- */
.gate {
  position: fixed;
  inset: 0;
  z-index: 90; /* below splash's z-index:100 */
  display: grid;
  place-items: center;
  background: rgba(6, 13, 9, 0.86);
  backdrop-filter: blur(6px);
  padding: 24px;
  transition: opacity 300ms ease;
}
.gate.leaving { opacity: 0; pointer-events: none; }
.gate-card {
  max-width: 420px; width: 100%;
  animation: gate-card-in 260ms var(--ease-out-strong);
}
@keyframes gate-card-in {
  from { opacity: 0; transform: scale(0.96) translateY(8px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}
.gate-card h2 { font-family: var(--font-display); font-size: var(--fs-lg); font-weight: 700; margin: 6px 0 8px; }
.gate-sub { color: var(--muted); font-size: var(--fs-base); margin-bottom: 20px; }
.gate-card form > * + * { margin-top: 16px; }
#turnstile-widget { display: flex; justify-content: center; }

/* ---------- Atmosphere ---------- */
.atmosphere {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}
.haze { position: absolute; border-radius: 50%; filter: blur(90px); opacity: 0.55; }
.haze-a {
  width: 60vw; height: 60vw; min-width: 480px; min-height: 480px;
  top: -22vw; right: -14vw;
  background: radial-gradient(circle, rgba(23, 138, 94, 0.35), transparent 65%);
  animation: drift 26s ease-in-out infinite alternate;
}
.haze-b {
  width: 46vw; height: 46vw; min-width: 380px; min-height: 380px;
  bottom: -18vw; left: -12vw;
  background: radial-gradient(circle, rgba(18, 78, 82, 0.4), transparent 65%);
  animation: drift 32s ease-in-out infinite alternate-reverse;
}
.haze-c {
  width: 30vw; height: 30vw; min-width: 260px; min-height: 260px;
  top: 40%; left: 55%;
  background: radial-gradient(circle, rgba(53, 201, 142, 0.12), transparent 70%);
  animation: drift 22s ease-in-out infinite alternate;
}
@keyframes drift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to { transform: translate3d(4vw, 3vh, 0) scale(1.08); }
}

/* ---------- Layout shell ---------- */
main { max-width: 1180px; margin: 0 auto; padding: 0 clamp(18px, 4vw, 40px); }

/* Topbar floats over the hero photograph — always light-on-dark. */
/* Same container width + padding as .hero-inner so the logo sits flush
   with the form card's left edge. */
.topbar {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 20;
  max-width: 1180px;
  margin: 0 auto;
  padding: clamp(18px, 3vw, 28px) clamp(18px, 4vw, 40px);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.topbar .brand-name { color: #f2f8f4; }
.topbar .brand-tag { background: rgba(10, 20, 16, 0.45); border-color: rgba(255, 255, 255, 0.2); color: #7ce3b1; }
/* Right-aligned by .topbar's justify-content: space-between — no extra
   flex plumbing needed. Truncates instead of crowding brand-tag on narrow
   viewports, since .topbar has no other responsive handling. */
.header-greeting {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.2rem, 1.5vw, 1.45rem);
  color: #f2f8f4;
  max-width: min(45vw, 260px);
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
@media (max-width: 640px) {
  .header-greeting { font-size: var(--fs-md); max-width: 40vw; }
}
.brand {
  display: flex; align-items: center; gap: 10px;
  text-decoration: none; color: var(--text);
}
/* Ribbon logo: light halo keeps the dark-green sections legible on dark bg;
   40px so the Arabic tail stays readable. */
.brand-logo {
  height: 50px; width: auto; display: block;
  filter: drop-shadow(0 0 10px rgba(233, 244, 238, 0.28)) drop-shadow(0 1px 2px rgba(0, 0, 0, 0.4));
}
.brand-logo[hidden] { display: none; }
.brand-name { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-lg); letter-spacing: -0.01em; }
.brand-name[hidden] { display: none; }
.brand-tag {
  font-family: var(--font-mono); font-size: var(--fs-2xs); font-weight: 600;
  color: var(--accent); border: 1px solid var(--stroke);
  padding: 2px 7px; border-radius: 6px; letter-spacing: 0.08em;
  background: var(--accent-ghost);
}


/* ---------- Hero (full-bleed photograph, first viewport holds the CTA) ---------- */
.hero {
  position: relative;
  width: calc(100vw - var(--sbw, 0px));
  margin-left: calc(50% - (100vw - var(--sbw, 0px)) / 2);
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* Floor must clear the absolutely-positioned topbar (up to ~78px of padding
     + logo) with breathing room, or the eyebrow slides under the logo. */
  padding: clamp(96px, 11vh, 120px) 0 clamp(20px, 4vh, 56px);
  padding-bottom: max(clamp(20px, 4vh, 56px), env(safe-area-inset-bottom));
}
/* The photograph lives on .page-bg now — the hero is transparent over it. */
.hero-inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 clamp(18px, 4vw, 40px);
  display: grid;
  grid-template-columns: minmax(0, 700px) minmax(280px, 340px);
  gap: clamp(28px, 4vw, 56px);
  align-items: stretch;
}
@media (max-width: 1023px) {
  .hero-inner { grid-template-columns: 1fr; }
  .hero-aside { display: none; } /* atmospheric widgets are desktop garnish */
}
/* Hero copy sits on the photograph — always light, both themes. */
.hero .eyebrow { color: #7ce3b1; }
.hero h1 { color: #f4faf6; text-shadow: 0 2px 24px rgba(0, 0, 0, 0.35); }
.hero .hero-sub { color: rgba(233, 244, 238, 0.82); }
.hero .sub-deals { font-style: normal; color: #7ce3b1; }

/* Hero entry choreography (load-once, per spec timings) */
.hero-fx { opacity: 0; animation: hero-in var(--fx-dur, 300ms) var(--ease-out-strong) var(--fx-delay, 0ms) both; }
.fx-1 { --fx-dur: 200ms; --fx-delay: 0ms; --fx-rise: 8px; }
.fx-2 { --fx-dur: 300ms; --fx-delay: 100ms; --fx-rise: 12px; }
.fx-3 { --fx-dur: 250ms; --fx-delay: 200ms; --fx-rise: 8px; }
.fx-4 { --fx-dur: 350ms; --fx-delay: 300ms; --fx-rise: 16px; }
@keyframes hero-in {
  from { opacity: 0; transform: translateY(var(--fx-rise, 12px)); }
  to { opacity: 1; transform: translateY(0); }
}
.eyebrow {
  font-family: var(--font-mono); font-size: var(--fs-2xs); font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 14px;
}
.hero h1 {
  font-family: var(--font-display);
  /* Expanded Archivo is wider than the old Sora: no hard <br> — text-wrap:
     balance picks even lines at every viewport (3 at desktop, 2 when the
     short-viewport override shrinks it). Slope tuned so the longest balanced
     line clears the 700px column at 1470w and the 563px column at 1024w. */
  font-size: clamp(3rem, 5vw + 0.9rem, 5.75rem);
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -0.03em;
  text-wrap: balance;
  margin-bottom: 20px;
}
.hero-sub {
  color: var(--muted);
  font-size: clamp(1.12rem, 2vw, 1.35rem);
  max-width: 600px;
  margin-bottom: 28px;
}
/* ---------- Glass cards ---------- */
.glass {
  position: relative;
  background: var(--card);
  border: 1px solid var(--stroke);
  border-radius: var(--radius);
  backdrop-filter: blur(22px) saturate(150%);
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  box-shadow: var(--shadow-card), inset 0 1px 0 var(--highlight);
  transition: transform 0.35s var(--ease-out), box-shadow 0.35s var(--ease-out), background 0.5s ease;
}
/* Bokeh overlay removed by design decision (Patch 1.2): it added mid-tone
   noise under card text and cost contrast. Glass stays clean. */

/* ---------- Grain (single fixed layer, never on scrolling containers) ---------- */
.grain-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
  background-image:
    url("assets/images/grain.png"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: cover, 160px 160px;
  background-blend-mode: overlay;
  mix-blend-mode: overlay;
  opacity: 0.05;
}
.card { padding: clamp(20px, 3.5vw, 32px); }

/* ---------- Form ---------- */
.form-card { max-width: 720px; }
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 24px;
  margin-bottom: 26px;
}
.field-wide { grid-column: 1 / -1; }
.field label, .field > label, .checkbox-text {
  display: block;
  font-size: var(--fs-sm); font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--muted);
  margin-bottom: 8px;
}
.field-hint { margin-top: 6px; font-size: var(--fs-xs); color: var(--faint); }

/* Chrome autofill paints its own pale background — keep the dark theme. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px var(--bg-lift) inset;
  -webkit-text-fill-color: var(--text);
  caret-color: var(--text);
}

/* Inline labels on the three short fields (nationality/date/time) reclaim
   ~55px of hero height so the CTA + departure board fit one screen. */
.field-inline { display: flex; align-items: center; gap: 12px; }
.field-inline > label { margin-bottom: 0; flex: 0 0 auto; white-space: nowrap; }
.field-inline > .combobox, .field-inline > .picker { flex: 1 1 auto; min-width: 0; }
/* One shared control height across the row trio — the sans input and the
   mono picker values have different natural line-heights otherwise. */
.field-inline .combobox input, .field-inline .picker-toggle { height: 46px; }
@media (max-width: 640px) {
  .field-inline { display: block; }
  .field-inline > label { margin-bottom: 8px; white-space: normal; }
}

input[type="time"], input[type="number"], input[type="email"], input[type="text"], select, #share-url {
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  color: var(--text);
  background: var(--bg-lift);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  padding: 11px 14px;
  width: 100%;
  outline: none;
  transition: border-color 0.25s ease, box-shadow 0.25s ease, background 0.25s ease;
  appearance: none;
  -webkit-appearance: none;
}
select { font-family: var(--font-body); cursor: pointer; }
input:focus-visible, select:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ghost);
}
input[type="time"]::-webkit-calendar-picker-indicator { filter: invert(0.7); cursor: pointer; }

.select-wrap { position: relative; }
.select-wrap::after {
  content: "";
  position: absolute; right: 15px; top: 50%;
  width: 8px; height: 8px;
  border-right: 1.6px solid var(--muted);
  border-bottom: 1.6px solid var(--muted);
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none;
}

.duration-row { display: flex; gap: 10px; }
.duration-unit {
  flex: 1; display: flex; align-items: center; gap: 8px;
  background: var(--bg-lift);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  padding-right: 12px;
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
}
.duration-unit:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ghost); }
.duration-unit input { border: none; background: none; box-shadow: none !important; padding-right: 0; min-width: 0; }
.duration-unit span { font-size: var(--fs-xs); color: var(--faint); font-weight: 500; }

/* Segmented controls */
.segmented {
  position: relative;
  display: flex;
  background: var(--bg-lift);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  padding: 3px;
}
.segment { flex: 1; position: relative; z-index: 1; cursor: pointer; }
.segment input { position: absolute; opacity: 0; pointer-events: none; }
.segment span {
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-base); font-weight: 600;
  line-height: 1;
  /* Asymmetric padding corrects the font's line-box leading: with
     line-height: 1, a font's descent reserve (below the baseline) is
     larger than its ascent-above-cap-height reserve, so equal top/bottom
     padding reads as more whitespace below the glyphs than above.
     NOTE: this box is align-items:center, so the top/bottom padding delta
     only shifts the glyphs by HALF the delta — a small (13/11) delta was
     imperceptible. 15/9 gives a ~3px downward nudge to optically center. */
  padding: 15px 20px 9px;
  color: var(--muted);
  border-radius: 9px;
  transition: color 0.25s ease, transform 140ms var(--ease-out-strong);
}
.segment:active span { transform: scale(0.95); }
.segment input:checked + span { color: var(--text); }
.segment input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: -2px; }
.segment-thumb {
  position: absolute;
  top: 3px; bottom: 3px; left: 3px;
  background: var(--accent-ghost);
  border: 1px solid var(--accent);
  border-radius: 9px;
  transition: left 0.3s var(--ease-out), width 0.3s var(--ease-out);
}

/* Checkbox */
.checkbox-row {
  display: flex; align-items: center; gap: 12px;
  cursor: pointer; user-select: none;
  padding: 2px 0;
}
.checkbox-row input { position: absolute; opacity: 0; pointer-events: none; }
.checkbox-box {
  width: 22px; height: 22px; flex-shrink: 0;
  border: 1.5px solid var(--stroke);
  border-radius: 7px;
  background: var(--bg-lift);
  display: grid; place-items: center;
  color: var(--bg);
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.15s ease;
}
.checkbox-box svg { width: 12px; height: 10px; opacity: 0; transform: scale(0.5); transition: opacity 0.2s ease, transform 0.2s var(--ease-out); }
.checkbox-row input:checked + .checkbox-box { background: var(--accent); border-color: var(--accent); }
.checkbox-row input:checked + .checkbox-box svg { opacity: 1; transform: scale(1); }
.checkbox-row input:focus-visible + .checkbox-box { box-shadow: 0 0 0 3px var(--accent-ghost); }
.checkbox-row:active .checkbox-box { transform: scale(0.9); }
.checkbox-row .checkbox-text { margin-bottom: 0; color: var(--text); font-weight: 500; font-size: var(--fs-base); }
.checkbox-hint { display: block; font-size: var(--fs-xs); font-weight: 400; color: var(--faint); margin-top: 2px; }
/* Smart Gates require a biometric passport — row greys out when that's unchecked. */
.checkbox-row.disabled { opacity: 0.45; pointer-events: none; }

/* Primary button */
.btn-primary {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-display);
  font-size: var(--fs-base); font-weight: 600;
  color: #06231a;
  background: var(--grad-brand);
  border: none; border-radius: 14px;
  padding: 14px 26px;
  cursor: pointer;
  box-shadow: 0 10px 30px -10px rgba(53, 201, 142, 0.5);
  transition: transform 0.2s var(--ease-out), box-shadow 0.25s ease, filter 0.2s ease;
}
.btn-primary svg { width: 15px; height: 15px; transition: transform 0.25s var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .btn-primary:hover { transform: translateY(-2px); box-shadow: 0 16px 36px -10px rgba(53, 201, 142, 0.55); }
  .btn-primary:hover svg { transform: translateX(3px); }
}
.btn-primary:active { transform: translateY(0) scale(0.97); }
.btn-primary:focus-visible { outline: 2px solid var(--text); outline-offset: 3px; }
.btn-primary[disabled] { filter: saturate(0.4) brightness(0.8); cursor: wait; }

/* Primary CTA + the decorative "ticket deals" status pill on one line
   (stacks on narrow viewports). */
.cta-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
/* Loading state: label swaps to "Fetching last-minute ticket deals" and the
   button breathes — a slow opacity swell for as long as the fetch runs
   (the scale-pop version read as jumpy). */
.btn-primary.fetching { animation: cta-breathe 1600ms ease-in-out infinite; }
@keyframes cta-breathe {
  50% { opacity: 0.72; }
}
@media (prefers-reduced-motion: reduce) {
  .btn-primary.fetching { animation: none; opacity: 0.85; }
}

.form-error { margin-top: 14px; color: var(--risk); font-size: var(--fs-sm); font-weight: 500; }

/* ---------- Results (photographic bands with scroll reveal) ---------- */
.results { padding-bottom: 0; }
/* Bands are translucent tints over the single fixed backdrop — no per-band
   photos, no seams, no reveal choreography. */
.band {
  position: relative;
  width: calc(100vw - var(--sbw, 0px));
  margin-left: calc(50% - (100vw - var(--sbw, 0px)) / 2);
  padding: clamp(32px, 6vh, 64px) 0;
  background: rgba(5, 12, 9, 0.4);
}
.band-inner {
  position: relative;
  z-index: 1;
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 clamp(18px, 4vw, 40px);
  display: grid;
  /* minmax(0, …) stops wide children (carousel track) inflating the column */
  grid-template-columns: minmax(0, 1fr);
  gap: 22px;
}
/* Copy sitting directly on band photography — always light. */
.band .spots-head h2 { color: #f4faf6; }
.band .spots-sub { color: rgba(233, 244, 238, 0.75); }

.band-inner > * { animation: rise 0.6s var(--ease-out) both; }
.band-inner > *:nth-child(2) { animation-delay: 0.08s; }
.band-inner > *:nth-child(3) { animation-delay: 0.16s; }
@keyframes rise {
  from { opacity: 0; transform: translateY(22px); }
  to { opacity: 1; transform: translateY(0); }
}

.panel-eyebrow {
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--faint); margin-bottom: 6px;
}

/* Visa card */
.visa-head { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; flex-wrap: wrap; }
.visa-badge {
  font-family: var(--font-mono); font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  padding: 5px 12px; border-radius: 999px;
  border: 1px solid;
}
.visa-badge.badge-ok { color: var(--ok); border-color: var(--ok); background: rgba(53, 201, 142, 0.1); }
.visa-badge.badge-warn { color: var(--warn); border-color: var(--warn); background: rgba(232, 180, 74, 0.1); }
.visa-badge.badge-risk { color: var(--risk); border-color: var(--risk); background: rgba(232, 106, 94, 0.1); }
.visa-card h2 { font-family: var(--font-display); font-size: clamp(1.15rem, 2.4vw, 1.45rem); font-weight: 700; letter-spacing: -0.01em; }
.visa-note { color: var(--muted); max-width: 640px; font-size: var(--fs-md); }
.visa-extras { display: grid; gap: 10px; margin-top: 14px; }
.visa-extras:empty { display: none; }
.extra-note {
  font-size: var(--fs-base);
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--stroke);
  background: var(--bg-lift);
  color: var(--muted);
}
.extra-note.tone-warn { border-color: rgba(232, 180, 74, 0.4); color: var(--warn); }
.extra-note.tone-info { border-color: rgba(53, 201, 142, 0.3); color: var(--text); }
.extra-note a { color: var(--accent); font-weight: 600; }
.disclaimer {
  margin-top: 16px;
  font-size: var(--fs-xs);
  color: var(--faint);
  border-top: 1px solid var(--stroke-soft);
  padding-top: 12px;
}

/* Window card: the tool's headline result — the one card allowed to be loud.
   Accent border + glow + tinted fill so it outranks every sibling card.
   Yellow was considered and rejected: amber = warning in this system, and the
   headline is a positive result. */
.window-card {
  border-color: rgba(53, 201, 142, 0.42);
  background: linear-gradient(150deg, rgba(22, 48, 38, 0.8), rgba(12, 28, 22, 0.68));
  box-shadow:
    0 18px 50px -18px rgba(0, 0, 0, 0.55),
    0 0 44px -10px rgba(53, 201, 142, 0.32),
    inset 0 1px 0 rgba(255, 255, 255, 0.14);
}
.window-card .panel-eyebrow { color: var(--accent); }
.window-time {
  font-family: var(--font-mono);
  font-size: clamp(2.4rem, 6.4vw, 3.8rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--accent);
  margin-bottom: 24px;
  text-shadow: 0 0 28px rgba(53, 201, 142, 0.35);
}
.window-time small { font-size: 0.4em; color: var(--muted); font-weight: 500; letter-spacing: 0; }
@media (max-width: 640px) {
  .window-time small { display: block; margin-top: 8px; }
}

/* Timeline bar: three proportional segments, all text inside, min-width floors. */
.timeline-bar {
  display: flex;
  width: 100%;
  height: 52px;
  border-radius: 10px;
  overflow: hidden;
  gap: 2px;
  margin-bottom: 22px;
}
.timeline-segment {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0 14px;
  white-space: nowrap;
  min-width: 0;
  transition: flex-basis 400ms var(--ease-out);
}
.seg-exit {
  background: rgba(255, 255, 255, 0.07);
  flex: 0 0 max(9%, 90px);
  min-width: 90px;
  border-radius: 10px 0 0 10px;
}
.seg-outside {
  background: rgba(var(--accent-rgb), 0.3);
  border: 1px solid rgba(var(--accent-rgb), 0.55);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
  flex: 1;
}
.seg-buffer {
  background: rgba(255, 255, 255, 0.07);
  flex: 0 0 max(11%, 100px);
  min-width: 100px;
  border-radius: 0 10px 10px 0;
}
.seg-label {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.5;
}
.seg-value {
  font-size: 15px;
  font-weight: 700;
  color: #fff;
}
.seg-outside .seg-value { color: #4be08a; text-shadow: 0 0 12px rgba(var(--accent-rgb), 0.45); }
.seg-outside .seg-label { opacity: 0.7; }

.window-clocks {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  border-top: 1px solid var(--stroke-soft);
  padding-top: 18px;
}
.clock-item { min-width: 0; }
.clock-item .clock-label { font-size: var(--fs-2xs); color: var(--faint); letter-spacing: 0.08em; text-transform: uppercase; }
.clock-item .clock-value { font-family: var(--font-mono); font-size: var(--fs-md); font-weight: 600; }
@media (max-width: 640px) {
  .window-clocks { grid-template-columns: repeat(2, 1fr); }
}
.terminal-note { margin-top: 16px; font-size: var(--fs-sm); color: var(--warn); }

/* ---------- Experience cards ---------- */
.spots-head { margin: 8px 0 18px; }
.spots-head h2 {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 3vw, 1.7rem);
  font-weight: 700; letter-spacing: -0.02em;
}
.spots-sub { color: var(--muted); font-size: var(--fs-base); margin-top: 4px; }

/* 3 columns desktop, 2 tablet, 1 mobile — holds up to 6 cards. */
.spots-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}
@media (max-width: 1023px) {
  .spots-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .spots-grid { grid-template-columns: 1fr; }
}
/* Exactly 4 picks (short-window cap) forms a lopsided 3+1 row in the default
   3-col grid — switch to a centered 2x2 block instead, once there's room. */
@media (min-width: 1024px) {
  .spots-block[data-count="4"] .spots-grid { grid-template-columns: repeat(2, 1fr); max-width: 720px; }
}

.spot-card {
  display: flex; flex-direction: column;
  padding: 22px;
  position: relative;
  /* Staggered entrance; per-card index set inline as --i at render */
  opacity: 0;
  transform: translateY(10px);
  animation: card-in 300ms var(--ease-out-strong) forwards;
  animation-delay: calc(var(--i, 0) * 55ms);
}
@keyframes card-in {
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .spot-card { transform: none; animation: card-fade 200ms ease forwards; }
  @keyframes card-fade { to { opacity: 1; } }
}
/* card-in's `forwards` fill-mode holds `transform`/`opacity` indefinitely,
   which silently blocks :hover/:active from ever changing transform again —
   app.js adds this class on animationend to release the property back to
   the normal cascade once the entrance has played. */
.spot-card.entered { animation: none; opacity: 1; transform: none; }
@media (hover: hover) and (pointer: fine) {
  .spot-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4), inset 0 1px 0 var(--highlight);
    transition: transform 200ms var(--ease-out-strong), box-shadow 200ms ease;
  }
  /* Pointer-tracked spotlight border: the border lights up under the cursor
     (--mx/--my set by JS). Feedback that the card is live, not decoration. */
  .spot-card::before {
    content: "";
    position: absolute;
    inset: -1px;
    border-radius: inherit;
    padding: 1px;
    background: radial-gradient(220px circle at var(--mx, 50%) var(--my, 50%),
      rgba(126, 217, 87, 0.55), rgba(53, 201, 142, 0.12) 45%, transparent 70%);
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    mask-composite: exclude;
    opacity: 0;
    transition: opacity 250ms ease;
    pointer-events: none;
  }
  .spot-card:hover::before { opacity: 1; }
}
.spot-card:active { transform: scale(0.98); transition: transform 140ms var(--ease-out-strong); }
.spot-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 8px; }
.spot-card h3 {
  font-family: var(--font-display);
  font-size: var(--fs-md); font-weight: 700;
  letter-spacing: -0.01em; line-height: 1.25;
}
.price-flag {
  flex-shrink: 0;
  font-family: var(--font-mono); font-size: var(--fs-3xs); font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  padding: 4px 9px; border-radius: 999px;
  border: 1px solid var(--stroke);
  color: var(--muted);
}
.price-flag.is-free { color: var(--accent); border-color: rgba(53, 201, 142, 0.4); }
.spot-desc { font-size: var(--fs-sm); color: rgba(233, 244, 238, 0.82); margin-bottom: 16px; flex-grow: 1; }

.travel-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.travel-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 500;
  padding: 6px 11px; border-radius: 9px;
  background: var(--bg-lift);
  border: 1px solid var(--stroke);
  color: var(--text);
}
.travel-chip svg { width: 13px; height: 13px; color: var(--transit); }
.travel-chip .na { color: var(--faint); }

.leaveby {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  padding: 13px 15px;
  border-radius: var(--radius-sm);
  background: var(--bg-lift);
  border: 1px solid var(--stroke);
  margin-bottom: 14px;
}
.leaveby-label { font-size: var(--fs-2xs); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--faint); }
.leaveby-time { font-family: var(--font-mono); font-size: 1.35rem; font-weight: 600; }
.leaveby-mode { font-size: var(--fs-2xs); color: var(--transit); }

/* Confidence block */
.confidence { margin-bottom: 16px; }
.confidence-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.confidence-state { font-size: var(--fs-sm); font-weight: 600; display: inline-flex; align-items: center; gap: 7px; }
.confidence-state .dot-emoji { font-size: var(--fs-xs); }
.confidence-buffer { font-family: var(--font-mono); font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.conf-ok .confidence-state { color: var(--ok); }
.conf-warn .confidence-state { color: var(--warn); }
.conf-risk .confidence-state { color: var(--risk); }

.buffer-track {
  height: 7px;
  border-radius: 99px;
  background: var(--bg-lift);
  border: 1px solid var(--stroke-soft);
  overflow: hidden;
}
.buffer-fill {
  height: 100%;
  width: 100%;
  border-radius: 99px;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 500ms var(--ease-out-strong) 350ms;
}
.conf-ok .buffer-fill { background: linear-gradient(90deg, var(--accent-deep), var(--ok) 70%, #7ed957); }
.conf-warn .buffer-fill { background: linear-gradient(90deg, #a97812, var(--warn)); }
.conf-risk .buffer-fill { background: linear-gradient(90deg, #99392f, var(--risk)); }

.spot-links { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; border-top: 1px solid var(--stroke-soft); padding-top: 14px; }
/* Booking pill: the primary action on a card — heavier than the Maps text link. */
.btn-book {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 16px;
  border: 1px solid var(--accent);
  border-radius: 20px;
  box-shadow: 0 0 10px rgba(var(--accent-rgb), 0.25);
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease;
}
.btn-book span { transition: transform 0.2s var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .btn-book:hover {
    background: var(--accent);
    color: #06231a;
    box-shadow: 0 0 14px rgba(var(--accent-rgb), 0.45);
    opacity: 1;
    transform: none; /* pills don't slide like text links */
  }
  .btn-book:hover span { transform: translateX(2px); }
}
.btn-book:active { transform: scale(0.97); }
/* Secondary variant: free spot with a website — same shape, clearly quieter. */
.btn-visit {
  border-color: rgba(255, 255, 255, 0.18);
  box-shadow: none;
  color: rgba(255, 255, 255, 0.55);
  font-weight: 600;
}
@media (hover: hover) and (pointer: fine) {
  .btn-visit:hover {
    background: none;
    border-color: rgba(255, 255, 255, 0.45);
    color: rgba(255, 255, 255, 0.9);
    box-shadow: none;
  }
}
.spot-links a {
  font-size: var(--fs-sm); font-weight: 600;
  color: var(--accent);
  text-decoration: none;
  display: inline-flex; align-items: center; gap: 5px;
  transition: opacity 0.2s ease, transform 0.2s var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .spot-links a:hover { opacity: 0.8; transform: translateX(2px); }
}
.spot-links a:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
.spot-links svg { width: 12px; height: 12px; }

.spot-note { font-size: var(--fs-xs); color: var(--faint); margin-top: 10px; }
.taxi-status { margin-top: 14px; font-size: var(--fs-sm); color: var(--warn); }

/* ---------- Combo suggestions ---------- */
.combos-row {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  padding-bottom: 8px;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}
.combo-pill {
  flex: 0 0 auto;
  min-width: 260px;
  padding: 16px 20px;
  border-radius: 16px;
  display: grid;
  gap: 6px;
}
.combo-more {
  border: 1px dashed var(--stroke);
  background: none;
  color: var(--faint);
  font-size: var(--fs-sm);
  display: flex; align-items: center;
  max-width: 220px;
}
.combo-names { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-base); color: #f4faf6; }
.combo-names em { font-style: normal; color: var(--accent); }
.combo-meta { font-size: var(--fs-xs); color: rgba(233, 244, 238, 0.72); }

/* ---------- Map ---------- */
.map-wrap { padding: 8px; }
#map {
  width: 100%;
  height: 400px;
  border-radius: calc(var(--radius) - 6px);
  background: #0a0f0a;
  position: relative;
  z-index: 1;
}
.leaflet-container a.leaflet-popup-close-button { color: var(--muted); }

.spot-card.highlighted {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), 0 0 30px -6px rgba(53, 201, 142, 0.55), var(--shadow-card);
}

/* ---------- Inside airport ---------- */
.inside-card h2 { font-family: var(--font-display); font-size: var(--fs-lg); font-weight: 700; margin-bottom: 6px; letter-spacing: -0.01em; }
.inside-card > p { color: var(--muted); font-size: var(--fs-base); max-width: 620px; }
.inside-list { list-style: none; margin-top: 18px; display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
.inside-list li {
  padding: 14px 16px;
  border-radius: var(--radius-sm);
  background: var(--bg-lift);
  border: 1px solid var(--stroke);
  font-size: var(--fs-sm);
  transition: transform 0.25s var(--ease-out), border-color 0.25s ease;
}
@media (hover: hover) and (pointer: fine) {
  .inside-list li:hover { transform: translateY(-2px); border-color: rgba(53, 201, 142, 0.35); }
}
.inside-list b { display: block; font-weight: 600; margin-bottom: 2px; }
.inside-list span { color: var(--muted); font-size: var(--fs-sm); }

/* ---------- Share ---------- */
.share-card { display: grid; gap: 18px; }
.share-copy h3 { font-family: var(--font-display); font-size: var(--fs-md); font-weight: 700; margin-bottom: 4px; }
.share-copy p { color: var(--muted); font-size: var(--fs-sm); max-width: 540px; }
.share-row { display: flex; gap: 10px; flex-wrap: wrap; }
#share-url { flex: 1; min-width: 200px; font-size: var(--fs-sm); color: var(--muted); }
.btn-copy {
  font-family: var(--font-body); font-size: var(--fs-sm); font-weight: 600;
  color: var(--accent);
  background: var(--accent-ghost);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 11px 20px;
  cursor: pointer;
  transition: transform 0.2s var(--ease-out), background 0.25s ease;
  white-space: nowrap;
}
@media (hover: hover) and (pointer: fine) {
  .btn-copy:hover { background: rgba(53, 201, 142, 0.2); }
}
.btn-copy:active { transform: scale(0.95); }
.btn-copy:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.btn-copy.copied { color: #06231a; background: var(--accent); }

/* ---------- Footer ---------- */
.footer {
  max-width: 1180px; margin: 0 auto;
  padding: 0 clamp(18px, 4vw, 40px) 44px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}
.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 28px;
  padding-top: 30px;
  border-top: 1px solid var(--stroke-soft);
}
.footer-nav a {
  font-family: var(--font-mono); font-size: var(--fs-2xs); font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); text-decoration: none;
  transition: color 200ms ease;
}
.footer-nav a:hover, .footer-nav a:focus-visible { color: var(--accent); }
.footer-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px 32px;
  flex-wrap: wrap;
}
.footer-note { font-size: var(--fs-xs); color: var(--faint); max-width: 560px; }
.footer-credit {
  flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs); font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--muted);
  text-decoration: none;
  border: 1px solid var(--stroke);
  border-radius: 999px;
  padding: 8px 16px;
  transition: color 200ms ease, border-color 200ms ease, background 200ms ease;
}
.footer-credit strong { font-weight: 600; color: var(--text); transition: color 200ms ease; }
.footer-credit svg { width: 10px; height: 10px; color: var(--faint); transition: transform 200ms var(--ease-out-strong), color 200ms ease; }
@media (hover: hover) and (pointer: fine) {
  .footer-credit:hover { border-color: rgba(53, 201, 142, 0.45); background: var(--accent-ghost); color: var(--accent); }
  .footer-credit:hover strong, .footer-credit:hover svg { color: var(--accent); }
  .footer-credit:hover svg { transform: translate(1px, -1px); }
}
.footer-credit:active { transform: scale(0.97); }

/* ---------- Reveal on load ---------- */
.reveal { animation: rise 0.7s var(--ease-out) both; }
.delay-1 { animation-delay: 0.1s; }
.delay-2 { animation-delay: 0.2s; }
.delay-3 { animation-delay: 0.3s; }

/* ---------- Nationality combobox ---------- */
.combobox { position: relative; }
.combobox input[type="text"] {
  font-family: var(--font-body);
  font-size: var(--fs-base);
  color: var(--text);
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  padding: 11px 14px;
  width: 100%;
  outline: none;
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
}
.combobox input[type="text"]:focus-visible { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ghost); }
.combobox input::placeholder { color: var(--faint); }
.combo-list {
  position: absolute;
  top: calc(100% + 6px); left: 0; right: 0;
  z-index: 40;
  max-height: 240px;
  overflow-y: auto;
  list-style: none;
  padding: 6px;
  border-radius: var(--radius-sm);
  /* Near-opaque: form fields behind must not read through. */
  background: rgba(10, 18, 12, 0.97);
  border: 1px solid rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: var(--shadow-card);
  animation: pop-in 0.22s var(--ease-out);
}
.combo-list li {
  padding: 9px 12px;
  border-radius: 8px;
  font-size: var(--fs-base);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, transform 140ms var(--ease-out-strong);
}
@media (hover: hover) and (pointer: fine) {
  .combo-list li:hover { background: rgba(255, 255, 255, 0.04); }
}
.combo-list li:active { transform: scale(0.97); }
.combo-list li.is-active { background: var(--accent-ghost); color: var(--accent); }
.combo-list .combo-empty { color: var(--faint); cursor: default; }
@media (hover: hover) and (pointer: fine) {
  .combo-list .combo-empty:hover { background: none; color: var(--faint); }
}

/* ---------- Picker popovers (date + time) ---------- */
.picker { position: relative; }
.picker-toggle {
  /* Value + icon centered as a group (not value-left / icon-pinned-right) so
     the field rhymes with the centered segmented pills below and drops the
     dead gap between a short value and the trailing icon. */
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%;
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  color: var(--text);
  background: var(--bg-lift);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  padding: 11px 14px;
  cursor: pointer;
  text-align: left;
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
}
.picker-toggle svg { width: 15px; height: 15px; color: var(--faint); flex-shrink: 0; }
.picker-toggle:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ghost); }
.picker-toggle[aria-expanded="true"] { border-color: var(--accent); }
#date-display { font-family: var(--font-body); font-weight: 500; }

.picker-pop {
  position: absolute;
  top: calc(100% + 6px); left: 0;
  z-index: 40;
  min-width: 100%;
  border-radius: var(--radius-sm);
  /* Near-opaque: form fields behind must not read through. */
  background: rgba(10, 18, 12, 0.97);
  border: 1px solid rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: var(--shadow-card);
  padding: 10px;
  animation: pop-in 0.22s var(--ease-out);
}
@keyframes pop-in {
  from { opacity: 0; transform: translateY(-4px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
/* Exit is snappier than the entrance (asymmetric enter/exit: the system
   responding to a close should feel immediate, not choreographed). */
.picker-pop.leaving, .combo-list.leaving {
  animation: pop-out 150ms var(--ease-out) forwards;
}
@keyframes pop-out {
  from { opacity: 1; transform: translateY(0) scale(1); }
  to { opacity: 0; transform: translateY(-4px) scale(0.98); }
}

/* Calendar */
.cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.cal-title { font-family: var(--font-display); font-size: var(--fs-sm); font-weight: 600; }
.cal-nav {
  width: 28px; height: 28px;
  border: 1px solid var(--stroke); border-radius: 8px;
  background: none; color: var(--text);
  font-size: 1rem; line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.15s var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .cal-nav:hover:not(:disabled) { background: var(--accent-ghost); }
}
.cal-nav:active:not(:disabled) { transform: scale(0.92); }
.cal-nav:disabled { opacity: 0.3; cursor: default; }
.cal-week { display: grid; grid-template-columns: repeat(7, 1fr); margin-bottom: 4px; }
.cal-week span { text-align: center; font-size: var(--fs-3xs); font-weight: 600; letter-spacing: 0.08em; color: var(--faint); }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cal-cell {
  aspect-ratio: 1;
  min-width: 30px;
  display: grid; place-items: center;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--text);
  background: none; border: 1px solid transparent; border-radius: 8px;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, transform 140ms var(--ease-out-strong);
}
@media (hover: hover) and (pointer: fine) {
  .cal-cell:hover:not(:disabled):not(.cal-blank) { background: var(--accent-ghost); }
}
.cal-cell:active:not(:disabled):not(.cal-blank) { transform: scale(0.92); }
.cal-cell:disabled { color: var(--faint); opacity: 0.35; cursor: default; }
.cal-cell.is-today { border-color: var(--stroke); }
.cal-cell.is-selected { background: var(--accent); color: #06231a; font-weight: 600; }
.cal-blank { cursor: default; }

/* Time columns */
.time-pop { display: flex; gap: 6px; min-width: 0; width: 172px; }
.time-col {
  flex: 1;
  max-height: 216px;
  overflow-y: auto;
  display: flex; flex-direction: column; gap: 2px;
  scrollbar-width: thin;
}
.time-col button {
  font-family: var(--font-mono); font-size: var(--fs-base);
  color: var(--text);
  background: none; border: none; border-radius: 8px;
  padding: 8px 0;
  cursor: pointer;
  transition: background 0.15s ease, transform 140ms var(--ease-out-strong);
}
@media (hover: hover) and (pointer: fine) {
  .time-col button:hover { background: var(--accent-ghost); }
}
.time-col button:active { transform: scale(0.94); }
.time-col button.is-selected { background: var(--accent); color: #06231a; font-weight: 600; }

/* ---------- DXB clock pill + layover confirmation ---------- */
.form-meta {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  /* This row is the pickers' result: keep it tight to them above, but leave
     real air below so "Departure terminal" reads as a new group, not clamped
     against the layover line. */
  margin: -8px 0 10px;
}
.form-meta:not(:has(.layover-confirm:not(:empty))) { display: none; }
.layover-confirm { font-size: var(--fs-base); font-weight: 500; color: var(--text); }
.layover-confirm:empty { display: none; }
.layover-confirm.is-invalid { color: var(--risk); }
.layover-duration {
  color: var(--accent);
  font-weight: 700;
  font-size: 1.05em;
}

/* ---------- Estimated-taxi live dot ---------- */
.live-dot {
  color: var(--ok);
  font-size: 0.55rem;
  margin-left: 5px;
  vertical-align: 1px;
  animation: live-pulse 2.2s ease-in-out infinite;
  cursor: help;
}
@keyframes live-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* ---------- Hero widgets: terminal clock + split-flap board ---------- */
.hero-aside {
  display: flex;
  flex-direction: column;
  gap: 18px;
  justify-content: space-between;
  align-items: stretch;
  min-width: 0;
}
/* Re-assert after the base rule: widgets are desktop-only garnish. */
@media (max-width: 1023px) {
  .hero-aside { display: none; }
}
.widget-clock {
  padding: 20px 22px;
  border-radius: var(--radius);
  background: rgba(8, 17, 13, 0.55);
  border: 1px solid rgba(124, 227, 177, 0.28);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  box-shadow: 0 18px 50px -18px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.clock-digits {
  font-size: 2rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: #7ce3b1;
  font-variant-numeric: tabular-nums;
}
.clock-digits .clock-secs { opacity: 0.45; font-size: 0.7em; }
.clock-label {
  margin-top: 4px;
  font-size: var(--fs-3xs); font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(233, 244, 238, 0.6);
}
.clock-tz { margin-top: 2px; font-size: var(--fs-2xs); color: rgba(233, 244, 238, 0.4); }

/* ---------- Daylight (sun-arc) widget ---------- */
/* Same opaque glass as .widget-clock so the hero photo can't read through the
   text. The sun uses the app's existing amber/warn family, not a new accent. */
.widget-sun {
  padding: 14px 18px;
  border-radius: var(--radius);
  background: rgba(8, 17, 13, 0.55);
  border: 1px solid rgba(124, 227, 177, 0.22);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  box-shadow: 0 18px 50px -18px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.sun-arc { width: 100%; height: auto; display: block; overflow: visible; }
/* Solid hairline guide (the old 2/5 dash pattern scaled into chunky beads
   that read as broken, especially at night when nothing covered it). */
.sun-track { fill: none; stroke: rgba(233, 244, 238, 0.14); stroke-width: 1.25; stroke-linecap: round; }
.sun-horizon-tick { stroke: rgba(233, 244, 238, 0.3); stroke-width: 1.25; stroke-linecap: round; }
/* Stroke color is driven inline by renderSunWidget() (amber by day, night
   blue for the moon trail); this is only the pre-JS default. */
.sun-elapsed { fill: none; stroke: var(--warn); stroke-width: 2.5; stroke-linecap: round; opacity: 0.9; }
/* Glyph glow comes from the SVG radial-gradient halos in the markup. */
.moon-glyph path { fill: #dfe7f7; }
.widget-sun.night .sun-note { color: #9fb4dc; }
.sun-times {
  display: flex; justify-content: space-between;
  margin-top: 6px;
  font-family: var(--font-mono); font-size: var(--fs-2xs);
  color: rgba(233, 244, 238, 0.55);
}
.sun-note { margin-top: 8px; font-size: var(--fs-xs); font-weight: 600; color: var(--warn); }
.sun-label {
  margin-top: 2px;
  font-size: var(--fs-3xs); font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(233, 244, 238, 0.6);
}

.widget-board {
  padding: 14px;
  height: 126px; /* 4 rows × 20px + 3 gaps × 6px + 2 × 14px padding */
  overflow: hidden;
  border-radius: var(--radius);
  background: #0a0f0a;
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 18px 50px -18px rgba(0, 0, 0, 0.6);
  display: grid;
  gap: 6px;
  perspective: 600px;
}
.board-row { display: flex; gap: 2px; min-width: 0; }
.flap {
  flex: 1 1 0;
  min-width: 0;
  height: 20px;
  display: grid;
  place-items: center;
  overflow: hidden;
  font-family: var(--font-mono);
  font-size: var(--fs-3xs);
  font-weight: 600;
  color: #e8b44a;
  background: #101710;
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 3px;
  transform-style: preserve-3d;
  transition: transform 45ms ease-out;
}
.flap.flipping { transform: rotateX(-90deg); transition-timing-function: ease-in; }
.flap.st-ok { color: #35c98e; }
.flap.st-warn { color: #e8b44a; }
.flap.st-risk { color: #e86a5e; }

/* ---------- Short-viewport compression (CTA stays in first screen) ---------- */
@media (max-height: 860px) {
  .hero { justify-content: flex-start; }
  /* vh-scaled so the hero grows into the reclaimed bottom space on ~800-860px
     viewports but still shrinks toward the mins on genuinely short screens
     (the max-height:740px block below catches the rest). */
  .hero h1 { font-size: clamp(2.8rem, 6vh, 3.6rem); margin-bottom: clamp(14px, 2.2vh, 22px); }
  .eyebrow { margin-bottom: 12px; }
  .hero-sub { font-size: clamp(0.95rem, 2vh, 1.2rem); margin-bottom: clamp(16px, 2.8vh, 28px); }
  .form-card { padding: 18px; }
  .form-grid { gap: 12px 16px; margin-bottom: 16px; }
}
@media (max-height: 740px) {
  .hero-sub { display: none; }
  .form-card {
    display: flex; flex-direction: column;
    max-height: calc(100dvh - 230px);
  }
  .form-grid { overflow-y: auto; min-height: 0; flex: 1 1 auto; padding-right: 4px; }
  /* An open popover must not be clipped by the internal scroll container. */
  body.pop-open .form-card { max-height: none; }
  body.pop-open .form-grid { overflow: visible; }
}

/* ---------- Results header row + weather pill ---------- */
.spots-head-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.spots-head-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
/* Compact variant of .segmented for an inline capsule row next to a heading,
   rather than the full-size form control used for Terminal/Bags. */
.segmented-sm .segment span { padding: 7px 14px; font-size: var(--fs-sm); }
.weather-pill {
  flex-shrink: 0;
  padding: 8px 14px;
  border-radius: 999px;
  font-size: var(--fs-sm);
  color: #f4faf6;
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid var(--stroke);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

/* ---------- Card extras: number, add-to-plan, badges, F&B note ---------- */
.spot-top { align-items: flex-start; }
.card-num {
  flex-shrink: 0;
  width: 22px; height: 22px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(var(--accent-rgb), 0.15);
  border: 1px solid rgba(var(--accent-rgb), 0.4);
  color: var(--accent);
  font-size: var(--fs-2xs); font-weight: 600;
  margin-top: 2px;
}
.spot-card h3 { flex: 1; }
.add-plan-btn {
  flex-shrink: 0;
  width: 26px; height: 26px;
  border-radius: 50%;
  border: 1px solid var(--stroke);
  background: var(--bg-lift);
  color: var(--text);
  font-size: 0.95rem; line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease, transform 0.15s var(--ease-out);
}
.add-plan-btn:active { transform: scale(0.9); }
.add-plan-btn.in-plan { background: var(--accent); border-color: var(--accent); color: #0a1a0c; }
@media (hover: hover) and (pointer: fine) {
  .add-plan-btn:hover { border-color: var(--accent); color: var(--accent); }
  .add-plan-btn.in-plan:hover { color: #0a1a0c; }
}
.spot-card.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), 0 0 24px -6px rgba(var(--accent-rgb), 0.5), var(--shadow-card);
}
.card-badges { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.badge {
  display: inline-block;
  border-radius: 12px;
  padding: 3px 10px;
  font-size: 11px; font-weight: 600;
}
.badge-warned {
  background: rgba(232, 180, 74, 0.1);
  border: 1px solid rgba(232, 180, 74, 0.35);
  color: var(--warn);
}
.badge-heat {
  background: rgba(232, 106, 94, 0.1);
  border: 1px solid rgba(232, 106, 94, 0.35);
  color: var(--risk);
}
.badge-ramadan {
  background: rgba(255, 165, 0, 0.12);
  border: 1px solid rgba(255, 165, 0, 0.3);
  color: rgba(255, 200, 80, 0.9);
}
.fb-note { font-size: var(--fs-xs); color: var(--warn); margin: -8px 0 12px; }

/* ---------- Secondary carousel ---------- */
.carousel-block { min-width: 0; }
.carousel-shell { display: flex; align-items: center; gap: 10px; min-width: 0; }
.car-arrow {
  flex-shrink: 0;
  width: 36px; height: 36px;
  border-radius: 50%;
  border: 1px solid var(--stroke);
  background: var(--card);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: var(--text);
  font-size: 1.15rem; line-height: 1;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}
@media (hover: hover) and (pointer: fine) {
  .car-arrow:hover { border-color: var(--accent); color: var(--accent); }
}
.car-arrow:active { transform: scale(0.92); }
.carousel-viewport { overflow: hidden; width: 100%; min-width: 0; }
.carousel-track {
  display: flex;
  gap: 12px;
  width: max-content;
  will-change: transform;
}
.car-tile {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px;
  border-radius: 14px;
  background: var(--card);
  border: 1px solid var(--stroke);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.car-name { font-size: var(--fs-sm); font-weight: 600; color: #f4faf6; white-space: nowrap; }
.car-travel { font-size: var(--fs-2xs); color: rgba(232, 180, 74, 0.85); white-space: nowrap; }
.car-badge {
  font-size: var(--fs-3xs); font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 999px;
  white-space: nowrap;
}
.car-green { color: var(--ok); border: 1px solid rgba(53, 201, 142, 0.4); }
.car-amber { color: var(--warn); border: 1px solid rgba(232, 180, 74, 0.4); }
.car-red { color: var(--risk); border: 1px solid rgba(232, 106, 94, 0.4); }
.car-grey { color: var(--faint); border: 1px solid var(--stroke); }

/* ---------- My plan ---------- */
.plan-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 4px; flex-wrap: wrap; }
.plan-head-tools { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.plan-block h2 { font-family: var(--font-display); font-size: clamp(1.3rem, 3vw, 1.7rem); font-weight: 700; letter-spacing: -0.02em; }

/* Single, persistent signal that plan estimates use live traffic data —
   replaces the old per-leg "(live)" tags, which only appeared on some legs
   and read as "the rest must not be live." Sits at the far end of the
   heading row (space-between) rather than crowding the "My plan" title, and
   stays small/quiet so it reads as ambient reassurance, not a headline
   claim. Breathes gently to register as a live signal rather than static text. */
.plan-live-pill {
  font-family: var(--font-mono);
  font-size: var(--fs-3xs); font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--warn);
  background: rgba(232, 180, 74, 0.12);
  border: 1px solid rgba(232, 180, 74, 0.35);
  border-radius: 999px;
  padding: 4px 10px;
  line-height: 1.3;
  white-space: nowrap;
  animation: planLivePillBreathe 3.2s ease-in-out infinite;
}
@keyframes planLivePillBreathe {
  0%, 100% { background: rgba(232, 180, 74, 0.12); border-color: rgba(232, 180, 74, 0.35); }
  50% { background: rgba(232, 180, 74, 0.22); border-color: rgba(232, 180, 74, 0.55); }
}
@media (prefers-reduced-motion: reduce) {
  .plan-live-pill { animation: none; }
}

/* Total/spare time is the single most important number in this section —
   give it the same hero-stat treatment as the top-of-page window countdown
   (big mono digits, glowing per state) instead of a line of gray body text. */
#plan-feasibility { margin-top: 6px; }
.plan-stat-row { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.plan-stat-value {
  font-family: var(--font-mono);
  font-size: clamp(1.5rem, 3.4vw, 2.05rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.01em;
  transition: color 500ms ease, text-shadow 500ms ease;
  color: var(--ok);
  text-shadow: 0 0 20px rgba(53, 201, 142, 0.35);
}
.plan-stat-caption { font-size: var(--fs-sm); color: var(--muted); font-weight: 500; }
#plan-feasibility[data-band="amber"] .plan-stat-value {
  color: var(--warn);
  text-shadow: 0 0 20px rgba(232, 180, 74, 0.45);
}
#plan-feasibility[data-band="red"] .plan-stat-value {
  color: var(--risk);
  text-shadow: 0 0 26px rgba(232, 106, 94, 0.6);
}
.plan-timeline { list-style: none; margin: 16px 0; display: grid; gap: 8px; }
.plan-step { font-size: var(--fs-base); color: var(--muted); }
.plan-step .mono { color: var(--accent); font-weight: 600; margin-right: 8px; }
.plan-anchor { color: var(--text); font-weight: 500; }
/* Travel legs: amber = transit. Flowing dashed connector + mode chip. */
.plan-leg {
  position: relative;
  padding: 4px 0 4px 30px;
}
.plan-leg::before {
  content: "";
  position: absolute;
  left: 14px; top: -8px; bottom: -8px;
  width: 2px;
  background-image: linear-gradient(to bottom, var(--transit-soft) 55%, transparent 55%);
  background-size: 2px 10px;
  animation: dash-flow 1.4s linear infinite;
}
@keyframes dash-flow {
  to { background-position-y: 10px; }
}
@media (prefers-reduced-motion: reduce) {
  .plan-leg::before { animation: none; }
}
.leg-chip {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs); font-weight: 500;
  color: var(--text);
  background: var(--bg-lift);
  border: 1px solid var(--transit-soft);
  border-radius: 999px;
  padding: 6px 14px;
}
.leg-chip svg { width: 14px; height: 14px; color: var(--transit); flex-shrink: 0; }
.plan-spot {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  background: var(--bg-lift);
  border: 1px solid var(--stroke);
  transition: border-color 200ms ease, transform 200ms var(--ease-out-strong);
}
@media (hover: hover) and (pointer: fine) {
  .plan-spot:hover { border-color: rgba(255, 255, 255, 0.18); transform: translateX(3px); }
}
.plan-spot-name { flex: 1; color: var(--text); font-weight: 600; }
.plan-visit { font-size: var(--fs-xs); color: var(--accent); } /* place time = green */
.plan-arrows { display: flex; gap: 4px; }
.plan-arrows button {
  width: 24px; height: 24px;
  border-radius: 6px;
  border: 1px solid var(--stroke);
  background: none; color: var(--text);
  cursor: pointer; font-size: 0.8rem; line-height: 1;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.plan-arrows button:disabled { opacity: 0.25; cursor: default; }
@media (hover: hover) and (pointer: fine) {
  .plan-arrows button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
  .plan-arrows .plan-remove:hover { border-color: var(--risk); color: var(--risk); }
}
/* Nearby suggestions: spots close to the chosen route that fit the spare time */
.plan-nearby {
  margin-top: 18px;
  border-top: 1px solid var(--stroke-soft);
  padding-top: 14px;
  margin-bottom: 14px;
}
.nearby-title { font-size: var(--fs-xs); color: var(--muted); margin-bottom: 10px; }
.nearby-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.nearby-chip {
  display: inline-flex; align-items: baseline; gap: 8px;
  font-family: var(--font-body);
  font-size: var(--fs-xs); font-weight: 600;
  color: var(--text);
  background: var(--bg-lift);
  border: 1px solid var(--stroke);
  border-radius: 999px;
  padding: 6px 14px;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}
.nearby-chip span { font-family: var(--font-mono); font-size: var(--fs-3xs); font-weight: 500; color: var(--faint); }
@media (hover: hover) and (pointer: fine) {
  .nearby-chip:hover { border-color: var(--accent); color: var(--accent); }
}
.nearby-chip:active { transform: scale(0.97); }

.plan-actions { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.plan-clear {
  background: none; border: none;
  font-size: var(--fs-sm); font-weight: 600;
  cursor: pointer; padding: 0;
  text-decoration: underline;
  text-underline-offset: 3px;
  color: var(--risk); transition: opacity 0.2s ease;
}
.plan-clear.confirming { opacity: 0.75; }
.plan-optimize {
  display: inline-flex; align-items: center;
  background: var(--accent-ghost);
  border: 1px solid rgba(var(--accent-rgb), 0.4);
  border-radius: 999px;
  padding: 7px 14px;
  font-size: var(--fs-sm); font-weight: 600;
  color: var(--accent);
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}
@media (hover: hover) and (pointer: fine) {
  .plan-optimize:hover { background: rgba(var(--accent-rgb), 0.2); border-color: var(--accent); }
}
.plan-optimize-note { margin-top: 8px; font-size: var(--fs-xs); color: var(--warn); }

/* ---------- Map pins, popups, edge fade ---------- */
.dxb-pin {
  background: rgba(var(--accent-rgb), 0.12);
  border: 1.5px solid var(--accent);
  border-radius: 20px;
  padding: 5px 12px;
  font-size: 11px; font-weight: 700; color: var(--accent);
  position: relative; white-space: nowrap;
  font-family: var(--font-mono);
}
.dxb-pulse {
  position: absolute; inset: -5px; border-radius: 24px;
  border: 1.5px solid rgba(var(--accent-rgb), 0.35);
  animation: ring-pulse 2.5s ease-out infinite;
}
@keyframes ring-pulse {
  0% { transform: scale(1); opacity: 0.7; }
  100% { transform: scale(1.5); opacity: 0; }
}
.spot-pin {
  width: 28px; height: 28px;
  background: linear-gradient(140deg, #00a860, #7ed957); color: #0a1a0c;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 12px;
  font-family: var(--font-mono);
  box-shadow: 0 0 8px rgba(var(--accent-rgb), 0.5);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.spot-pin.active {
  transform: scale(1.35);
  box-shadow: 0 0 18px rgba(var(--accent-rgb), 0.8);
}
/* Context dots: every other spot in the database, dimmed, status-tinted */
.spot-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, 0.35);
  background: rgba(120, 140, 130, 0.75);
  box-shadow: 0 0 6px rgba(0, 0, 0, 0.4);
}
.spot-dot.dot-green { background: rgba(53, 201, 142, 0.8); border-color: rgba(53, 201, 142, 0.5); }
.spot-dot.dot-amber { background: rgba(232, 180, 74, 0.8); border-color: rgba(232, 180, 74, 0.5); }
.spot-dot.dot-red { background: rgba(232, 106, 94, 0.8); border-color: rgba(232, 106, 94, 0.5); }
.spot-dot.dot-grey { background: rgba(110, 125, 118, 0.7); border-color: rgba(255, 255, 255, 0.25); }
#map {
  -webkit-mask-image: radial-gradient(ellipse 90% 90% at 50% 50%, black 55%, transparent 100%);
  mask-image: radial-gradient(ellipse 90% 90% at 50% 50%, black 55%, transparent 100%);
  /* Darken the light Voyager tiles ~18% so the map doesn't read as a brightness island. */
  filter: brightness(0.82) contrast(1.08) saturate(0.9);
}
.glass-popup .leaflet-popup-content-wrapper {
  background: rgba(10, 24, 14, 0.85);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid rgba(var(--accent-rgb), 0.2);
  border-radius: 10px;
  padding: 12px;
  color: var(--text);
}
.glass-popup .leaflet-popup-tip { background: rgba(10, 24, 14, 0.85); }
.glass-popup .leaflet-popup-content { margin: 0; font-family: var(--font-body); font-size: var(--fs-sm); line-height: 1.6; }
.glass-popup a { color: var(--accent); }
.popup-travel { color: var(--muted); font-size: var(--fs-xs); }
.popup-pill {
  display: inline-block;
  font-size: var(--fs-3xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  padding: 2px 8px; border-radius: 999px; margin: 4px 0;
}
.popup-ok { color: var(--ok); border: 1px solid rgba(53, 201, 142, 0.4); }
.popup-warn { color: var(--warn); border: 1px solid rgba(232, 180, 74, 0.4); }
.popup-risk { color: var(--risk); border: 1px solid rgba(232, 106, 94, 0.4); }
.popup-add-btn {
  font-family: var(--font-body);
  font-size: var(--fs-2xs); font-weight: 600;
  color: var(--accent);
  background: none;
  border: 1px solid rgba(53, 201, 142, 0.4);
  border-radius: 999px;
  padding: 3px 10px;
  margin: 2px 0 4px;
  cursor: pointer;
}
.popup-add-btn.in-plan { color: var(--bg); background: var(--accent); border-color: var(--accent); }

/* ---------- Share: QR next to copy ---------- */
.share-body { display: flex; gap: 24px; align-items: center; flex-wrap: wrap; }
.share-body .share-row { flex: 1; min-width: 240px; }
.share-qr { display: grid; justify-items: center; gap: 8px; }
#qr-container {
  width: 240px;
  height: 240px;
  margin: 0 auto;
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 0 30px rgba(var(--accent-rgb), 0.25);
}
#qr-container svg, #qr-container img, #qr-container canvas { display: block; width: 100%; height: 100%; }
.qr-label {
  font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--faint);
}

/* Edge blurs removed: the single fixed backdrop has no section seams. */

/* ---------- Time picker: no visible scrollbar ---------- */
.time-col {
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.time-col::-webkit-scrollbar { display: none; }

/* ---------- Home-screen weather widget (matches clock/board glass) ---------- */
.weather-widget {
  /* Same opaque glass as .widget-clock: the hero photo must not read through the text. */
  background: rgba(8, 17, 13, 0.72);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--radius);
  padding: 18px 22px;
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  box-shadow: 0 18px 50px -18px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.weather-main { display: flex; align-items: center; }
.weather-icon {
  display: inline-flex; flex-shrink: 0;
  width: 26px; height: 26px;
  margin-right: 8px;
  color: #7ce3b1;
}
.weather-icon svg { width: 100%; height: 100%; }
.weather-temp {
  font-size: 2rem;
  font-weight: 600;
  color: #7ce3b1;
  font-variant-numeric: tabular-nums;
}
.weather-condition {
  font-size: var(--fs-sm);
  color: var(--text);
  margin-left: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.weather-detail {
  display: flex;
  gap: 16px;
  margin-top: 8px;
  font-size: var(--fs-xs);
  color: var(--text);
}
.weather-heat { margin-top: 8px; font-size: var(--fs-xs); font-weight: 600; color: var(--warn); }
.weather-label {
  margin-top: 10px;
  font-size: var(--fs-3xs); font-weight: 600;
  letter-spacing: 0.18em;
  color: rgba(233, 244, 238, 0.45);
  text-transform: uppercase;
}

/* ---------- Live-data indicators (hero aside, above the clock) ---------- */
.live-strip {
  display: flex;
  gap: 18px;
  justify-content: flex-end;
  padding-right: 4px;
}
.live-strip:empty { display: none; }
.live-badge {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs); font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(124, 227, 177, 0.85);
}
.live-badge::before {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 6px rgba(var(--accent-rgb), 0.7);
  animation: live-pulse 2.2s ease-in-out infinite;
}
.live-badge.pending { color: var(--muted); animation: live-pulse 1.1s ease-in-out infinite; }
.live-badge.pending::before { background: var(--muted); box-shadow: none; animation: none; }

/* ---------- Plan toggles on carousel tiles ---------- */
.car-plan-btn { width: 22px; height: 22px; font-size: 0.85rem; }

/* ---------- Plan toggles on combo pills ---------- */
.combo-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
.combo-add {
  font-family: var(--font-body);
  font-size: var(--fs-xs); font-weight: 600;
  color: var(--muted);
  background: var(--bg-lift);
  border: 1px solid var(--stroke);
  border-radius: 999px;
  padding: 5px 12px;
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}
@media (hover: hover) and (pointer: fine) {
  .combo-add:hover { border-color: var(--accent); color: var(--accent); }
}
.combo-add.in-plan {
  background: rgba(var(--accent-rgb), 0.15);
  border-color: var(--accent);
  color: var(--accent);
}

/* ---------- My plan: badges, links, warning pulse ---------- */
.plan-spot { display: grid; gap: 8px; }
.plan-spot-main { display: flex; align-items: center; gap: 12px; }
.plan-badge {
  flex-shrink: 0;
  font-size: var(--fs-3xs); font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase;
  padding: 2px 8px; border-radius: 999px;
  border: 1px solid;
}
.plan-badge-ok { color: var(--ok); border-color: rgba(53, 201, 142, 0.4); }
.plan-badge-warn { color: var(--warn); border-color: rgba(232, 180, 74, 0.4); }
.plan-badge-risk { color: var(--risk); border-color: rgba(232, 106, 94, 0.4); }

/* Weather advisory pills — same pill shape as .plan-badge, filled so they
   stand out at a glance instead of reading as another line of body text. */
.plan-weather-note { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.weather-tip {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--warn);
  background: rgba(232, 180, 74, 0.12);
  border: 1px solid rgba(232, 180, 74, 0.35);
  border-radius: 999px;
  padding: 5px 12px;
  line-height: 1.3;
}

/* ---------- Results-page risk coloring (whole-plan spare-time signal) ----------
   A single aggregate state (green/amber/red), set via #results[data-risk],
   cascades a shared fade across every surface below — distinct from each
   spot's own comfortable/tight/risky badge, which is a separate per-spot
   signal and untouched by this. */
.spot-card, .car-tile, .combo-pill, .plan-block {
  transition: border-color 500ms ease, box-shadow 500ms ease, background-color 500ms ease;
}
#results[data-risk="green"] .spot-card,
#results[data-risk="green"] .car-tile,
#results[data-risk="green"] .combo-pill,
#results[data-risk="green"] .plan-block {
  border-color: rgba(53, 201, 142, 0.35);
}
#results[data-risk="amber"] .spot-card,
#results[data-risk="amber"] .car-tile,
#results[data-risk="amber"] .combo-pill,
#results[data-risk="amber"] .plan-block {
  border-color: rgba(232, 180, 74, 0.7);
  background-color: rgba(232, 180, 74, 0.05);
  box-shadow: 0 0 0 1px rgba(232, 180, 74, 0.4), 0 0 22px -6px rgba(232, 180, 74, 0.4);
}
/* Red needs to read as an alarm, not a tint — a visible border, a warm
   background wash, and an outer glow, not just a 1px color shift. */
#results[data-risk="red"] .spot-card,
#results[data-risk="red"] .car-tile,
#results[data-risk="red"] .combo-pill,
#results[data-risk="red"] .plan-block {
  border-color: var(--risk);
  background-color: rgba(232, 106, 94, 0.08);
  box-shadow: 0 0 0 1.5px rgba(232, 106, 94, 0.85), 0 0 30px -4px rgba(232, 106, 94, 0.6);
}
/* "My Plan" is the one actionable surface — give it a slow breathing glow
   so going over-budget is unmissable without pulsing every card at once. */
#results[data-risk="red"] .plan-block {
  animation: riskPulseGlow 2.6s ease-in-out infinite;
}
@keyframes riskPulseGlow {
  0%, 100% { box-shadow: 0 0 0 1.5px rgba(232, 106, 94, 0.85), 0 0 30px -4px rgba(232, 106, 94, 0.6); }
  50% { box-shadow: 0 0 0 1.5px rgba(232, 106, 94, 1), 0 0 46px 4px rgba(232, 106, 94, 0.85); }
}
@media (prefers-reduced-motion: reduce) {
  #results[data-risk="red"] .plan-block { animation: none; }
}
/* Best-effort smooth fade for the map's route lines: Leaflet updates stroke
   via setStyle()/setAttribute, and current browsers still transition a
   presentation attribute when a CSS transition targets that property. */
.leaflet-interactive { transition: stroke 500ms ease, stroke-width 500ms ease, stroke-opacity 500ms ease, filter 500ms ease; }
.leaflet-risk-tail { filter: drop-shadow(0 0 5px rgba(232, 106, 94, 0.9)); }

.plan-spot-links { display: flex; gap: 12px; align-items: center; }
.plan-link { font-size: var(--fs-xs); font-weight: 600; text-decoration: none; }
.plan-book {
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 999px;
  padding: 3px 12px;
  box-shadow: 0 0 8px rgba(var(--accent-rgb), 0.25);
}
.plan-book-grey {
  color: rgba(255, 255, 255, 0.55);
  border-color: rgba(255, 255, 255, 0.18);
  box-shadow: none;
}
.plan-maps { color: var(--faint); }
@media (hover: hover) and (pointer: fine) {
  .plan-maps:hover { color: var(--accent); }
}
.plan-warning-icon {
  display: inline-block;
  animation: warnPulse 2s ease-in-out infinite;
}
@keyframes warnPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}
@media (prefers-reduced-motion: reduce) {
  .plan-warning-icon { animation: none; }
}

/* ---------- Section heading scroll reveals ---------- */
.section-heading {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 400ms var(--ease-out-strong), transform 400ms var(--ease-out-strong);
}
.section-heading.heading-visible {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .section-heading { opacity: 1; transform: none; transition: none; }
}

/* ---------- Departure board: BOARDING reads amber ---------- */
.flap.flight-status-boarding { color: var(--warn); }

/* ---------- Press feedback on every clickable element ---------- */
.btn-book:active,
.btn-copy:active,
.combo-add:active,
.plan-arrows button:active,
.plan-link:active,
.plan-clear:active,
.plan-optimize:active,
.picker-toggle:active,
.spot-links a:active {
  transform: scale(0.97);
  transition: transform 140ms var(--ease-out-strong);
}

/* ---------- Responsive ---------- */
@media (max-width: 640px) {
  .form-grid { grid-template-columns: 1fr; }
  .btn-primary { width: 100%; justify-content: center; }
  .clock-item { text-align: left; }
}

/* ============================================================
   Content pages — About / Creator / Privacy / Terms / FAQ.
   Reuses .glass/.card for section panels and .eyebrow/.btn-primary
   from the main app so these read as the same product, not a bolt-on.
   ============================================================ */
.content-page {
  position: relative;
  z-index: 1;
  max-width: 760px;
  margin: 0 auto;
  padding: clamp(120px, 15vh, 156px) clamp(18px, 4vw, 40px) clamp(60px, 8vh, 90px);
  display: flex;
  flex-direction: column;
  gap: 36px;
}
.content-page .page-head { display: flex; flex-direction: column; gap: 12px; }
.content-page .page-head h1 {
  font-family: var(--font-display);
  font-size: clamp(2.1rem, 4vw, 2.9rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  color: #f4faf6;
}
.content-page .page-head > p { color: var(--muted); font-size: var(--fs-md); max-width: 60ch; }
.content-page section.glass { display: flex; flex-direction: column; gap: 16px; }
.content-page h2 {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--text);
}
.content-page p, .content-page li { color: var(--muted); font-size: var(--fs-sm); line-height: 1.7; max-width: 68ch; }
.content-page strong { color: var(--text); }
.content-page a { color: var(--accent); font-weight: 600; }
/* .content-page a's color/specificity would otherwise win over .btn-primary
   and paint its label accent-green-on-green — nearly invisible against the
   button's own gradient at some points, plus an unwanted <a> underline. */
.content-page a.btn-primary { color: #06231a; text-decoration: none; }
.content-page .updated-note { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--faint); letter-spacing: 0.04em; }
.content-page ol.plain-list, .content-page ul.plain-list {
  display: flex; flex-direction: column; gap: 10px; padding-left: 20px;
}

.eyebrow-label {
  font-family: var(--font-mono); font-size: var(--fs-2xs); font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent);
  display: flex; align-items: center; gap: 8px;
}
.icon-tile {
  width: 40px; height: 40px; border-radius: 10px;
  display: grid; place-items: center; flex-shrink: 0;
  background: var(--accent-ghost); color: var(--accent);
}
.icon-tile svg { width: 20px; height: 20px; }

/* Creator page: bio stats row */
.stat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px 16px; }
@media (min-width: 640px) { .stat-grid { grid-template-columns: repeat(4, 1fr); } }
.stat-grid .stat-value { font-family: var(--font-mono); font-size: var(--fs-lg); font-weight: 700; color: var(--text); }
.stat-grid .stat-label { font-size: var(--fs-xs); color: var(--faint); margin-top: 2px; }

/* Creator page: "other things built" card */
.link-card {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 16px 20px; border: 1px solid var(--stroke); border-radius: var(--radius-sm);
  text-decoration: none !important; color: inherit;
  transition: border-color 200ms ease, background 200ms ease, transform 200ms var(--ease-out);
}
.link-card:hover { border-color: rgba(53, 201, 142, 0.45); background: var(--accent-ghost); transform: translateY(-1px); }
.link-card .link-card-title { display: flex; align-items: center; gap: 8px; font-weight: 700; color: var(--text) !important; font-size: var(--fs-base); }
.link-card .link-card-title svg { width: 14px; height: 14px; color: var(--faint); }
.link-card .link-card-sub { color: var(--muted); font-size: var(--fs-sm); margin-top: 4px; }
.link-card .link-card-arrow { color: var(--faint); transition: transform 200ms var(--ease-out), color 200ms ease; flex-shrink: 0; }
.link-card:hover .link-card-arrow { color: var(--accent); transform: translateX(3px); }

/* FAQ accordion — same frosted-glass treatment as .glass so answer text
   (var(--muted), audited for AA contrast against var(--card)) stays readable
   over the busy hero photo instead of sitting on bare 9%-opacity borders. */
.faq-item {
  background: var(--card);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  backdrop-filter: blur(22px) saturate(150%);
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  box-shadow: var(--shadow-card), inset 0 1px 0 var(--highlight);
  overflow: hidden;
}
.faq-item + .faq-item { margin-top: 12px; }
.faq-item summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 16px 20px; font-family: var(--font-display); font-weight: 700; color: var(--text);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+"; font-size: 1.3rem; line-height: 1; color: var(--accent); flex-shrink: 0; transition: transform 200ms ease;
}
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item .faq-answer { padding: 0 20px 18px; color: var(--muted); font-size: var(--fs-sm); line-height: 1.7; max-width: 68ch; }

/* ============================================================
   404 page — reuses the existing .widget-board/.flap split-flap
   component (see initDepartureBoard() in app.js) at hero scale,
   driven by GSAP instead of the ambient widget's setTimeout loop.
   ============================================================ */
.notfound {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 26px;
  padding: clamp(110px, 15vh, 150px) 20px 60px;
}
.notfound .eyebrow { text-align: center; font-size: clamp(0.95rem, 2vw, 1.15rem); }
.board-hero {
  height: auto;
  padding: clamp(10px, 2vw, 18px);
  perspective: 900px;
  display: flex;
  justify-content: center;
  background: transparent;
  border: none;
  box-shadow: none;
}
.board-hero .board-row { justify-content: center; gap: clamp(4px, 1vw, 7px); flex-wrap: wrap; }
.board-hero .flap {
  flex: 0 0 auto;
  width: clamp(26px, 6vw, 50px);
  height: clamp(38px, 8.5vw, 68px);
  font-size: clamp(1.05rem, 2.8vw, 1.9rem);
  border-radius: 7px;
}
.board-hero .flap.is-space { background: transparent; border-color: transparent; }
/* GSAP drives this board's flip directly (rotationX) — the ambient widget's
   CSS transition would otherwise double up with the timeline's own easing. */
.board-hero .flap { transition: none; }
.notfound-sub {
  color: var(--muted);
  font-size: clamp(1rem, 2vw, 1.2rem);
  max-width: 480px;
  opacity: 0;
  transform: translateY(10px);
}
.notfound .btn-primary { opacity: 0; transform: translateY(10px); }
@media (prefers-reduced-motion: reduce) {
  .notfound-sub, .notfound .btn-primary { opacity: 1; transform: none; }
}

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