/* ============================================================
   ASTER — design system
   "The quiet travel advisor." An editorial, warm-light luxury
   language: paper-white surfaces that float rather than sit in
   boxes, a single champagne-gold accent used sparingly, a serif
   display face paired with a spacious grotesque for body copy,
   and depth built from soft warm shadows and generous whitespace
   rather than borders or colour blocks.

   Palette      — warm ivory ground, near-black warm ink, one gold
   Type         — Fraunces (display/editorial) + Inter (UI/body)
   Spacing      — 4/8/12/16/24/32/48/64/96/128 scale
   Radius       — 10 / 18 / 28, pill for chips & badges only
   Shadows      — soft, warm-tinted, large & diffuse ("paper lift")
   Motion       — calm ease-out curves, reveal-on-scroll, no bounce
   ============================================================ */

@view-transition {
  navigation: auto;
}

:root {
  /* ---- surfaces & ground ---- */
  --bg: #FAF6EF;
  --bg-alt: #F1E9DA;
  --surface: #FFFFFF;
  --surface-soft: #FCFAF5;
  --surface-sunk: #F5F0E6;

  /* ---- ink ---- */
  --text: #241F19;
  --text-soft: #6E6558;
  --text-muted: #A79C8A;
  --text-on-accent: #2A1D0F;

  /* ---- borders ---- */
  --border: rgba(36,31,25,0.08);
  --border-strong: rgba(36,31,25,0.14);

  /* ---- accent: champagne gold ---- */
  --accent: #A9804A;
  --accent-bright: #C9A467;
  --accent-hover: #8E6C3E;
  --accent-soft: rgba(169,128,74,0.10);
  --accent-soft-strong: rgba(169,128,74,0.18);

  /* ---- semantic ---- */
  --ok: #6F8F63;
  --ok-soft: rgba(111,143,99,0.12);
  --warning: #B07C33;
  --warning-soft: rgba(176,124,51,0.12);
  --danger: #A65B49;
  --danger-soft: rgba(166,91,73,0.12);

  /* ---- radius ---- */
  --radius-sm: 10px;
  --radius: 18px;
  --radius-lg: 28px;
  --radius-pill: 999px;

  /* ---- shadow: soft, warm, diffuse ---- */
  --shadow-sm: 0 1px 2px rgba(40,30,16,0.05), 0 6px 16px -10px rgba(40,30,16,0.10);
  --shadow-card: 0 1px 3px rgba(40,30,16,0.05), 0 22px 44px -26px rgba(40,30,16,0.18);
  --shadow-card-lg: 0 2px 6px rgba(40,30,16,0.06), 0 36px 72px -30px rgba(40,30,16,0.24);

  /* ---- motion ---- */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-soft: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-micro: 0.2s;
  --dur-standard: 0.45s;
  --dur-page: 0.7s;

  /* ---- type ---- */
  --font-display: "Fraunces", Georgia, serif;
  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* ---- spacing scale ---- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;
  --space-10: 128px;

  --gutter: 32px;

  /* Real, measured height of .site-nav (see static/search.js
     syncNavHeightVar()) -- the sticky search summary bar's `top` offset
     reads this instead of 0, so it docks directly under the nav with no
     gap and no overlap. This fallback (used before JS has measured the
     real value, and on any page that never calls syncNavHeightVar) is a
     close estimate of .site-nav's actual rendered height: 26px padding
     top + 26px padding bottom + ~1px border + the brand text's line box. */
  --nav-height: 83px;
}

* { box-sizing: border-box; }

html { color-scheme: light; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-feature-settings: "ss01" on, "cv11" on;
  font-size: 15.5px;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  position: relative;
}

/* A near-invisible paper grain across the whole app — the kind of detail
   that separates "warm off-white" from a flat colour swatch. Pure CSS,
   no external image, effectively free to render. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.035;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}

main {
  max-width: 900px;
  margin: 0 auto;
  padding: 8px var(--gutter) 96px;
  position: relative;
  z-index: 1;
  animation: pageIn var(--dur-page) var(--ease) both;
}
main.wide { max-width: 1080px; }
/* The search page needs more room than a normal editorial page: the
   conversation thread and the composer both use the same wide column
   (see .conversation-thread / .composer) instead of being squeezed into a
   narrower editorial width. */
main.search-main { max-width: 1440px; }

@keyframes pageIn {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes cardIn {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes softPulse {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 1; }
}
@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}
@keyframes floatIn {
  from { opacity: 0; transform: translateY(24px) scale(0.99); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

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

/* ---- Reveal-on-scroll: any element with .reveal starts hidden/offset and
   is promoted to .is-visible by an IntersectionObserver (see base.html).
   Falls back to always-visible if JS never runs. ---- */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.8s var(--ease-soft), transform 0.8s var(--ease-soft);
}
.reveal.is-visible { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; }
}

/* ============================================================
   Navigation
   ============================================================ */
.site-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 26px var(--gutter);
  background: rgba(250,246,239,0.78);
  backdrop-filter: blur(16px) saturate(1.1);
  -webkit-backdrop-filter: blur(16px) saturate(1.1);
  position: sticky;
  top: 0;
  z-index: 30;
  border-bottom: 1px solid transparent;
  transition: border-color 0.4s ease, background 0.4s ease;
}
.brand {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: 21px;
  letter-spacing: 0.01em;
  color: var(--text);
  text-decoration: none;
}
.nav-links a {
  position: relative;
  color: var(--text-soft);
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 500;
  margin-left: 36px;
  padding-bottom: 4px;
  transition: color 0.25s ease;
}
.nav-links a::after {
  content: "";
  position: absolute;
  left: 0; right: 100%; bottom: 0;
  height: 1px;
  background: var(--accent);
  transition: right 0.35s var(--ease);
}
.nav-links a:hover { color: var(--text); }
.nav-links a.active { color: var(--accent); }
.nav-links a.active::after, .nav-links a:hover::after { right: 0; }

.nav-email {
  margin-left: 36px;
  font-size: 13px;
  color: var(--text-muted);
}
.nav-logout-form { display: inline-block; margin-left: 18px; }
.nav-logout-btn {
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text-soft);
  cursor: pointer;
  transition: color 0.25s ease;
}
.nav-logout-btn:hover { color: var(--accent); }

/* ============================================================
   Auth pages (login / signup) — reuses .panel + the standard input styling,
   just narrower and centred, since it's a single short form rather than a
   multi-section profile page.
   ============================================================ */
.auth-panel { max-width: 420px; margin: 0 auto; }
/* Sentence-case, not the all-caps/letter-spaced label style used on dense
   settings forms elsewhere (profile etc.) -- a short two-field login/signup
   form reads better with quieter, normal-case labels. Scoped to .auth-panel
   only, so this doesn't change label styling anywhere else in the app. */
.auth-panel label { text-transform: none; letter-spacing: normal; font-size: 13.5px; color: var(--text); font-weight: 600; }
.auth-panel .auth-submit { width: 100%; margin-top: 24px; }
.auth-switch { font-size: 13.5px; color: var(--text-soft); margin: 22px 0 0; text-align: center; }
.auth-switch a { color: var(--accent); font-weight: 600; text-decoration: none; }
.auth-switch a:hover { color: var(--accent-hover); }

.auth-divider { display: flex; align-items: center; gap: 14px; margin: 22px 0; color: var(--text-muted); font-size: 12px; }
.auth-divider::before, .auth-divider::after { content: ""; flex: 1; height: 1px; background: var(--border-strong); }

/* "Continue without an account" -- must read as a real, equally-legitimate
   option, not a disabled/greyed-out afterthought, so it gets the same
   full-width solid-border secondary button treatment as any other
   secondary action in the app, not a plain text link. */
.auth-panel .auth-guest { width: 100%; text-align: center; }

.site-footer {
  text-align: center;
  font-size: 11.5px;
  color: var(--text-muted);
  padding: 56px 24px 64px;
  letter-spacing: 0.01em;
  position: relative;
  z-index: 1;
}

/* ============================================================
   Buttons
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 28px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-weight: 600;
  font-family: var(--font-body);
  text-decoration: none;
  cursor: pointer;
  border: 1px solid transparent;
  letter-spacing: 0.01em;
  transition: transform var(--dur-micro) var(--ease), box-shadow var(--dur-micro) var(--ease),
              background var(--dur-micro) var(--ease), border-color var(--dur-micro) var(--ease),
              color var(--dur-micro) var(--ease);
}
.btn-primary { background: var(--accent-bright); color: var(--text-on-accent); box-shadow: var(--shadow-sm); }
.btn-primary:hover { background: var(--accent); transform: translateY(-2px); box-shadow: 0 14px 30px -10px rgba(169,128,74,0.45); }
.btn-primary:active { transform: translateY(0); }
.btn-secondary { background: var(--surface); color: var(--text); border-color: var(--border-strong); }
.btn-secondary:hover { border-color: var(--accent); color: var(--accent); transform: translateY(-2px); box-shadow: var(--shadow-sm); }
.btn-ghost { background: transparent; color: var(--text-soft); padding: 8px 4px; }
.btn-ghost:hover { color: var(--accent); }
.btn:disabled { opacity: 0.4; cursor: default; transform: none; box-shadow: none; }
.btn-lg { padding: 17px 34px; font-size: 15.5px; border-radius: var(--radius-sm); }

/* ============================================================
   Hero
   ============================================================ */
.hero { padding: 84px 0 72px; position: relative; }
.hero-kicker {
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--accent); margin: 0 0 24px;
}
.hero h1 {
  font-family: var(--font-display);
  font-size: 60px;
  font-weight: 500;
  line-height: 1.08;
  margin: 0 0 24px;
  letter-spacing: -0.015em;
  color: var(--text);
  max-width: 760px;
}
.hero-lede {
  font-family: var(--font-display);
  font-size: 26px; font-weight: 400; font-style: italic; color: var(--text-soft);
  margin: 0 0 30px; letter-spacing: -0.005em;
}
.hero-emphasis { color: var(--accent); font-weight: 500; }
.hero-sub { font-size: 16.5px; color: var(--text-soft); line-height: 1.8; max-width: 520px; margin: 0 0 44px; }
.hero-actions { display: flex; gap: 16px; flex-wrap: wrap; align-items: center; }

.hero-art {
  position: absolute;
  top: 8px; right: -12px;
  width: 340px;
  opacity: 0.9;
  pointer-events: none;
}
.hero-art svg { width: 100%; height: auto; }
@media (max-width: 980px) { .hero-art { display: none; } }

/* ============================================================
   How it works / editorial steps
   ============================================================ */
.how-it-works { padding: 40px 0 64px; }
.how-it-works h2 { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.14em; color: var(--text-muted); margin-bottom: 36px; }
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px 40px; }
.step { padding: 0; transition: transform 0.4s var(--ease); }
.step:hover { transform: translateY(-3px); }
.step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent);
  font-family: var(--font-display); font-size: 13px; font-weight: 600; margin-bottom: 20px;
}
.step h3 { font-family: var(--font-display); font-size: 19px; font-weight: 500; margin: 0 0 10px; color: var(--text); }
.step p { font-size: 13.5px; color: var(--text-soft); line-height: 1.75; margin: 0; }

/* ============================================================
   Page headers
   ============================================================ */
.page-header { padding: 56px 0 32px; }
.page-header h1 { font-family: var(--font-display); font-size: 38px; font-weight: 500; margin: 0 0 10px; letter-spacing: -0.015em; }
.page-sub { color: var(--text-soft); font-size: 15px; margin: 0; line-height: 1.7; max-width: 540px; }
.page-sub + .page-sub { margin-top: 8px; }
.profile-storage-note { font-size: 13px; color: var(--text-muted); }
.page-header.compact { padding: 40px 0 24px; }
.page-header.compact h1 { font-size: 27px; }

/* ============================================================
   Panels & cards — "floating paper": no border by default, soft
   diffuse shadow instead, generous internal padding.
   ============================================================ */
.panel {
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: 36px;
  margin-bottom: 28px;
  box-shadow: var(--shadow-card);
}
.panel.compact { padding: 20px 24px; }

label { display: block; font-size: 12px; color: var(--text-soft); font-weight: 600; margin: 24px 0 9px; letter-spacing: 0.03em; text-transform: uppercase; }
label:first-of-type { margin-top: 0; }
.hint-inline { font-weight: 400; color: var(--text-muted); font-size: 12px; text-transform: none; letter-spacing: 0; }

input[type=number], input[type=text], input[type=date], input[type=email], input[type=password], select {
  width: 100%;
  padding: 13px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  font-size: 14.5px;
  font-family: inherit;
  color: var(--text);
  background: var(--surface-soft);
  transition: border-color var(--dur-micro) ease, box-shadow var(--dur-micro) ease, background var(--dur-micro) ease;
}
input::placeholder { color: var(--text-muted); }
input:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--surface);
  box-shadow: 0 0 0 4px var(--accent-soft);
}
select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none'><path d='M5.5 8L10 12.2 14.5 8' stroke='%236E6558' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 38px;
}
.hint { font-size: 12px; color: var(--text-muted); margin-top: 7px; line-height: 1.6; }

/* Range sliders: replace the browser-default track with a slim gold-fill
   track and a small round thumb — one of the few controls we can't fully
   swap for a custom widget without extra JS, so it gets the most styling
   attention of any native input. */
input[type=range] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 20px;
  background: transparent;
  margin: 4px 0 0;
}
input[type=range]::-webkit-slider-runnable-track {
  height: 3px; border-radius: 3px;
  background: linear-gradient(90deg, var(--accent-bright), var(--border-strong));
}
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--accent);
  margin-top: -6.5px;
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-micro) ease;
}
input[type=range]::-webkit-slider-thumb:hover { transform: scale(1.15); }
input[type=range]::-moz-range-track { height: 3px; border-radius: 3px; background: var(--border-strong); }
input[type=range]::-moz-range-progress { height: 3px; border-radius: 3px; background: var(--accent-bright); }
input[type=range]::-moz-range-thumb {
  width: 14px; height: 14px; border-radius: 50%; background: var(--surface); border: 2px solid var(--accent);
}

/* ============================================================
   Segmented control — the primary replacement for radio groups /
   selects wherever we can avoid native browser chrome entirely.
   ============================================================ */
.segmented {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  background: var(--surface-sunk);
  border-radius: var(--radius-sm);
  padding: 4px;
}
.segmented button {
  flex: 1;
  min-width: 74px;
  background: transparent;
  border: none;
  border-radius: 7px;
  color: var(--text-soft);
  font-size: 13px;
  font-weight: 500;
  font-family: inherit;
  padding: 10px 12px;
  cursor: pointer;
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease, box-shadow var(--dur-micro) ease;
}
.segmented button:hover { color: var(--text); }
.segmented button.active { background: var(--surface); color: var(--text); font-weight: 600; box-shadow: var(--shadow-sm); }

/* ============================================================
   Aster Hotels UX Phase 3: Conversational Hotel Discovery -- the
   concierge entry point that replaces the old "Complete your trip /
   Explore hotels / Tell Aster about your ideal stay" flow. Styled as a
   small piece of premium, hero-like UI -- generous spacing, the display
   typeface for the heading, a large soft-focus input, real pill chips,
   and a gentle entrance animation -- deliberately NOT another search
   form, even though every element underneath still drives the exact
   same conversational backend Phase 4 already built (runHotelPlanning
   Turn / hotelConversationState / showHotelPreferenceSummary). See
   appendHotelPlanningSection() in search.js.
   ============================================================ */
.hotel-concierge-section {
  padding: 30px 32px 32px;
  border-radius: var(--radius-lg);
  background: linear-gradient(165deg, var(--accent-soft), var(--surface) 68%);
  box-shadow: var(--shadow-card);
  animation: floatIn 0.55s var(--ease) both;
}
.hotel-concierge-title {
  font-family: var(--font-display);
  font-size: 27px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--text);
  margin-bottom: 8px;
}
.hotel-concierge-subtitle {
  font-size: 14.5px;
  color: var(--text-soft);
  max-width: 46em;
  line-height: 1.55;
  margin-bottom: 24px;
}
.hotel-concierge-inputwrap { margin-bottom: 18px; }
.hotel-concierge-input {
  display: block;
  width: 100%;
  min-height: 104px;
  resize: vertical;
  padding: 19px 22px;
  border-radius: var(--radius);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  font-family: inherit;
  font-size: 15.5px;
  line-height: 1.55;
  color: var(--text);
  box-shadow: var(--shadow-sm);
  transition: border-color var(--dur-micro) ease, box-shadow var(--dur-micro) ease;
}
.hotel-concierge-input::placeholder { color: var(--text-soft); }
.hotel-concierge-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft), var(--shadow-sm);
}
.hotel-concierge-input:disabled { opacity: 0.65; cursor: default; }

.hotel-concierge-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  margin-bottom: 26px;
}
.hotel-concierge-chip {
  background: var(--surface-sunk);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  color: var(--text-soft);
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  padding: 8px 16px;
  cursor: pointer;
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease,
              border-color var(--dur-micro) ease, transform var(--dur-micro) ease;
}
.hotel-concierge-chip:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-soft);
  transform: translateY(-1px);
}
.hotel-concierge-chip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.hotel-concierge-cta { padding: 16px 32px; font-size: 15px; }
.hotel-concierge-cta:disabled { opacity: 0.7; cursor: not-allowed; transform: none; }

@media (max-width: 700px) {
  .hotel-concierge-section { padding: 22px 18px 24px; }
  .hotel-concierge-title { font-size: 21px; }
  .hotel-concierge-cta { width: 100%; }
}

/* ============================================================
   Aster Hotels Phase 2: Destination Area Recommendations -- the
   contextual "complete your trip" continuation shown after a flight
   search, never a standalone page. See appendHotelPlanningSection() in
   search.js.
   ============================================================ */
.hotel-planning-section { padding-top: 4px; }
.hotel-planning-prompt { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.hotel-planning-heading { font-size: 16px; font-weight: 700; color: var(--text); }
.hotel-planning-subtext { font-size: 14px; color: var(--text-soft); margin-bottom: 6px; }

.hotel-planning-form { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.hotel-planning-form label { font-size: 12.5px; font-weight: 600; color: var(--text-soft); margin-top: 10px; }
.hotel-segmented.segmented button { min-width: 0; flex: 1 1 auto; }

.chip-multiselect { display: flex; flex-wrap: wrap; gap: 6px; }
.chip-multiselect button {
  background: var(--surface-sunk);
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--text-soft);
  font-size: 12.5px;
  font-family: inherit;
  font-weight: 500;
  padding: 7px 13px;
  cursor: pointer;
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease, border-color var(--dur-micro) ease;
}
.chip-multiselect button:hover { color: var(--text); }
.chip-multiselect button.chip-selected { background: var(--accent); border-color: var(--accent); color: var(--surface); font-weight: 600; }

.hotel-planning-error { color: var(--danger, #c0392b); font-size: 13px; }

.hotel-planning-submit-btn { align-self: flex-start; margin-top: 6px; }

.hotel-area-heading { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-soft); margin-bottom: 6px; }
.hotel-area-name { font-size: 19px; font-weight: 700; color: var(--text); }
.hotel-area-description { font-size: 14px; color: var(--text-soft); margin: 4px 0 10px; }
.hotel-area-subheading { font-size: 12.5px; font-weight: 600; color: var(--text-soft); margin-top: 12px; margin-bottom: 4px; }
.hotel-area-reasons, .hotel-area-tradeoffs, .hotel-area-alternatives { margin: 0; padding-left: 18px; font-size: 13.5px; color: var(--text); }
.hotel-area-reasons li, .hotel-area-tradeoffs li, .hotel-area-alternatives li { margin-bottom: 3px; }
.hotel-area-continue-btn { margin-top: 14px; }
.hotel-area-continue-btn:disabled { opacity: 0.55; cursor: not-allowed; }
.hotel-area-limitations { font-size: 11.5px; color: var(--text-soft); margin-top: 8px; }
.hotel-area-unsupported { font-size: 14px; color: var(--text-soft); }

/* ============================================================
   Aster Hotels Phase 4: AI Stay Planner (Preference Discovery). The
   traveller describes their ideal stay in one line to the SAME Ask Aster
   thread (see startHotelPlanningConversation() in search.js) instead of
   filling out .hotel-planning-form's segmented controls above (left
   untouched, just no longer the entry point) -- these styles cover the
   live, removable preference chips and the "Here's what I'm looking for"
   summary panel that appears once enough is known.
   ============================================================ */
.hotel-chip-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 4px 0 16px;
  padding: 0 2px;
}
.hotel-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--accent-soft);
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--text);
  font-size: 12.5px;
  font-weight: 600;
  font-family: inherit;
  padding: 6px 8px 6px 13px;
  cursor: default;
  opacity: 0;
  transform: translateY(4px) scale(0.96);
  animation: hotelChipIn var(--dur-micro) ease forwards;
  transition: background var(--dur-micro) ease, border-color var(--dur-micro) ease;
}
@keyframes hotelChipIn {
  to { opacity: 1; transform: translateY(0) scale(1); }
}
/* A "tentative" (medium-confidence) chip reads as less certain than a
   confirmed one -- dashed border, softer text -- without hiding it: only
   HIGH-confidence signals ever auto-apply to a recommendation (see
   hotel_preference_extraction.py), so this visual distinction matters:
   the traveller should be able to tell, at a glance, which chips are
   already shaping their recommendation and which are just a guess so far. */
.hotel-chip-medium {
  background: transparent;
  border: 1px dashed var(--border-strong);
  color: var(--text-soft);
}
.hotel-chip-high:hover, .hotel-chip-medium:hover { border-color: var(--accent); }
.hotel-chip-label { line-height: 1.2; }
.hotel-chip-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  font-size: 13px;
  line-height: 1;
  color: inherit;
  opacity: 0.6;
  cursor: pointer;
  transition: opacity var(--dur-micro) ease, background var(--dur-micro) ease;
}
.hotel-chip-remove:hover { opacity: 1; background: rgba(0,0,0,0.08); }

.hotel-summary-bubble { max-width: 100%; }
.hotel-summary-heading { font-size: 16px; font-weight: 700; color: var(--text); margin-bottom: 10px; }
.hotel-summary-list { margin: 0 0 4px; padding-left: 18px; font-size: 14px; color: var(--text); }
.hotel-summary-list li { margin-bottom: 4px; }
.hotel-summary-empty { font-size: 13.5px; color: var(--text-soft); margin-bottom: 4px; }
.hotel-summary-actions { display: flex; gap: 10px; margin-top: 14px; }
.hotel-summary-result { margin-top: 14px; }

/* ============================================================
   Aster Core Phase 5: Recommendation Intelligence Engine -- shared
   additive card sections (renderRecommendationAnalysis in search.js).
   Used by both the area-recommendation card (.hotel-area-analysis) and
   the dev hotel cards (.dev-hotel-analysis) below -- one set of rules,
   both prefixes, since the two attribute-selector patterns are
   identical. Never redesigns either card: this only ever ADDS a small
   block (score/stars/strength/verdict/confidence/regret) between the
   existing name and description.
   ============================================================ */
.hotel-area-analysis, .dev-hotel-analysis {
  margin: 8px 0 12px;
  padding: 10px 12px;
  background: var(--surface-sunk);
  border-radius: 10px;
}
.hotel-area-score-row, .dev-hotel-score-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
.hotel-area-score, .dev-hotel-score {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
}
.hotel-area-stars, .dev-hotel-stars {
  color: var(--accent-bright);
  font-size: 13px;
  letter-spacing: 1px;
}
.hotel-area-strength, .dev-hotel-strength {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--text);
}
.hotel-area-strength-strong, .dev-hotel-strength-strong,
.hotel-area-strength-recommended, .dev-hotel-strength-recommended {
  background: var(--accent-bright);
  color: var(--text-on-accent);
}
.hotel-area-strength-not_recommended, .dev-hotel-strength-not_recommended {
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--text-soft);
}
.hotel-area-verdict, .dev-hotel-verdict {
  font-size: 13.5px;
  color: var(--text);
  margin-top: 8px;
  line-height: 1.45;
}
.hotel-area-meta-row, .dev-hotel-meta-row {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 8px;
  font-size: 12px;
  color: var(--text-soft);
}
.hotel-area-regret-high, .dev-hotel-regret-high { color: var(--danger, #c0392b); font-weight: 600; }
.hotel-area-regret-medium, .dev-hotel-regret-medium { color: var(--accent); font-weight: 600; }

/* ============================================================
   Aster Hotels Phase 3: development-only mocked hotel-search preview.
   Never shown outside dev mode / without a live provider -- see
   hotelContinueEnabled() in search.js. Deliberately minimal: no image
   carousel, no map, no booking button (see the Phase 3 spec's
   "Development hotel card" section).
   ============================================================ */
.hotel-search-mount { margin-top: 14px; }
.dev-hotel-banner {
  display: inline-block;
  background: var(--surface-sunk);
  color: var(--text-soft);
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 4px 10px;
  border-radius: 999px;
  margin-bottom: 10px;
}
.dev-hotel-loading, .dev-hotel-error { font-size: 13.5px; color: var(--text-soft); }
.dev-hotel-cards { display: flex; flex-direction: column; gap: 12px; }
.dev-hotel-card {
  border: 1px solid var(--surface-sunk);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
}
.dev-hotel-category {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--accent);
  margin-bottom: 4px;
}
.dev-hotel-name { font-size: 15.5px; font-weight: 700; color: var(--text); }
.dev-hotel-area { font-size: 12.5px; color: var(--text-soft); margin-bottom: 6px; }
.dev-hotel-price { font-size: 14px; color: var(--text); margin-bottom: 2px; }
.dev-hotel-rating, .dev-hotel-room, .dev-hotel-cancellation { font-size: 12.5px; color: var(--text-soft); }
.dev-hotel-amenities { font-size: 12px; color: var(--text-soft); margin-top: 6px; text-transform: capitalize; }
.dev-hotel-reasons, .dev-hotel-tradeoffs { margin: 8px 0 0; padding-left: 18px; font-size: 12.5px; }
.dev-hotel-reasons li { color: var(--text); margin-bottom: 2px; }
.dev-hotel-tradeoffs li { color: var(--text-soft); margin-bottom: 2px; }
.dev-hotel-limitations { font-size: 11px; color: var(--text-soft); margin-top: 10px; }

/* Property Details / RoomOffer enrichment -- rendered only when a property
   carries a non-empty room_offers array (opt-in server-side, see
   HOTEL_PROPERTY_DETAILS_ENRICHMENT / renderRoomOffersSection in
   search.js). Deliberately reuses the same visual language as the rest of
   the dev hotel card (same borders/text-soft/accent tokens) rather than
   introducing a new style -- this is one more section on the existing
   card, not a redesign. */
.dev-hotel-room-offers { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--surface-sunk); }
.dev-hotel-room-offers-title {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--text-soft);
  margin-bottom: 6px;
}
.dev-hotel-room-offer { padding: 7px 0; border-bottom: 1px solid var(--surface-sunk); }
.dev-hotel-room-offer:last-child { border-bottom: none; }
.dev-hotel-room-offer-desc { font-size: 13px; font-weight: 600; color: var(--text); }
.dev-hotel-room-offer-price { font-size: 12.5px; color: var(--text); margin-top: 2px; }
.dev-hotel-room-offer-meta { font-size: 12px; color: var(--text-soft); margin-top: 2px; }
.dev-hotel-room-offer-source { font-size: 11px; color: var(--text-soft); margin-top: 2px; }
.dev-hotel-room-offer-cta {
  display: inline-block;
  margin-top: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  text-decoration: none;
}
.dev-hotel-room-offer-cta:hover { text-decoration: underline; }
.dev-hotel-room-offers-more summary {
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  margin-top: 6px;
  list-style: none;
}
.dev-hotel-room-offers-more summary::-webkit-details-marker { display: none; }
.dev-hotel-room-offers-more[open] summary { margin-bottom: 4px; }

.profile-panel { padding-top: 12px; }
.profile-section { padding: 30px 0; position: relative; }
.profile-section::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--border) 15%, var(--border) 85%, transparent);
}
.profile-section:first-child { padding-top: 6px; }
.profile-section:first-child::before { display: none; }
.profile-section h3 {
  font-family: var(--font-display);
  font-size: 17px; font-weight: 500; font-style: italic;
  color: var(--text); margin: 0 0 4px;
}

/* Conditional loyalty sub-fields (programme tier / manual alliance /
   manual alliance-equivalent status) -- hidden until the traveller's
   programme choice makes them relevant, same show/hide convention as
   .autocomplete-list.show elsewhere in this file. */
.loyalty-subfield { display: none; }
.loyalty-subfield.show { display: block; }

.dual-slider { margin-top: 20px; }
.dual-slider-labels { display: flex; justify-content: space-between; font-size: 12.5px; color: var(--text-soft); margin-bottom: 8px; font-weight: 500; }

.save-confirm {
  margin-left: 16px;
  font-size: 13px;
  color: var(--ok);
  opacity: 0;
  transition: opacity 0.4s ease;
}
.save-confirm.show { opacity: 1; }

.search-row { display: grid; grid-template-columns: 1fr 1fr auto; gap: 16px; }
.field-narrow { max-width: 116px; }
.checkbox-row { display: flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--text-soft); margin: 18px 0 0; font-weight: 400; }
.checkbox-row input { width: auto; accent-color: var(--accent); }

.autocomplete-field { position: relative; }
.autocomplete-list {
  position: absolute;
  top: 100%; left: 0; right: 0;
  background: var(--surface);
  border-radius: 14px;
  margin-top: 10px;
  max-height: 220px;
  overflow-y: auto;
  z-index: 20;
  display: none;
  box-shadow: var(--shadow-card-lg);
  animation: dropIn 0.2s var(--ease);
}
@keyframes dropIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }
.autocomplete-list.show { display: block; }
.autocomplete-item { padding: 12px 16px; cursor: pointer; font-size: 13.5px; transition: background 0.15s ease; }
.autocomplete-item:hover { background: var(--accent-soft); }
.autocomplete-item .code { font-weight: 700; margin-right: 8px; color: var(--accent); }
.autocomplete-item .city { color: var(--text-soft); }

.plan-panel { background: linear-gradient(180deg, var(--accent-soft), var(--surface) 70%); }
.plan-row { display: flex; gap: 12px; }
.plan-row input[type=text] { flex: 1; margin: 0; }
.plan-row .btn { flex-shrink: 0; margin: 0; }
.plan-status { font-size: 13px; color: var(--text-muted); margin-top: 12px; min-height: 0; line-height: 1.6; }
.plan-status:empty { margin-top: 0; }
.plan-status.active { color: var(--ok); }
.plan-status.warning { color: var(--accent); }
.plan-status.error { color: var(--danger); }

.chip-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.chip {
  background: var(--surface);
  border: 1px solid var(--border-strong);
  color: var(--text-soft);
  font-size: 12.5px;
  font-weight: 500;
  padding: 8px 15px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: border-color var(--dur-micro) ease, color var(--dur-micro) ease, background var(--dur-micro) ease, transform var(--dur-micro) ease;
}
.chip:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); transform: translateY(-1px); }

.checkbox-field { display: flex; align-items: flex-end; padding-bottom: 10px; }
.checkbox-field .checkbox-row { margin: 0; }

#manualDetails { margin-top: 20px; }
#manualDetails summary {
  cursor: pointer; font-size: 13px; color: var(--text-muted); list-style: none; user-select: none;
  transition: color 0.15s ease;
}
#manualDetails summary::-webkit-details-marker { display: none; }
#manualDetails summary::before { content: "› "; color: var(--accent); }
#manualDetails[open] summary::before { content: "⌄ "; }
#manualDetails summary:hover { color: var(--text-soft); }
#manualDetails .search-row { margin-top: 18px; }
#manualDetails .search-row:first-of-type { margin-top: 20px; }

/* ============================================================
   Consultant recommendation — the editorial "hero pick": one clear
   recommendation, concise reasoning, magazine-style hierarchy.
   ============================================================ */
.consultant-pick {
  background: linear-gradient(165deg, var(--accent-soft), var(--surface) 55%);
  border-radius: var(--radius-lg);
  padding: 36px 40px;
  margin-bottom: 24px;
  box-shadow: var(--shadow-card-lg);
  animation: floatIn 0.7s var(--ease) both;
  transition: background 0.6s ease;
}
.consultant-pick.loading { background: var(--surface); box-shadow: var(--shadow-card); }
.consultant-loading { font-size: 13.5px; color: var(--text-muted); animation: softPulse 1.7s ease-in-out infinite; }
.consultant-badge {
  display: inline-block;
  background: var(--accent-bright);
  color: var(--text-on-accent);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 6px 15px;
  border-radius: var(--radius-pill);
  margin-bottom: 20px;
}
.consultant-summary { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 6px 16px; margin-bottom: 16px; }
.consultant-airline { font-family: var(--font-display); font-size: 25px; font-weight: 500; color: var(--text); letter-spacing: -0.01em; }
.consultant-meta { font-size: 13px; color: var(--text-soft); flex-basis: 100%; margin-top: -6px; }
.consultant-price { font-family: var(--font-display); font-size: 26px; font-weight: 500; color: var(--text); white-space: nowrap; }
.consultant-headline {
  font-family: var(--font-display); font-style: italic; font-size: 17px; color: var(--text-soft);
  margin-bottom: 20px; line-height: 1.55; padding-bottom: 20px; border-bottom: 1px solid var(--border);
}
.consultant-block { margin-bottom: 18px; }
.consultant-block h4 { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-muted); margin: 0 0 10px; }
.consultant-block .pro { color: var(--ok); font-size: 13.5px; margin-bottom: 8px; line-height: 1.65; }
.consultant-compare { font-size: 13px; color: var(--text-soft); margin-bottom: 16px; line-height: 1.7; }
.consultant-verdict { font-size: 13.5px; margin-bottom: 20px; }
.consultant-verdict h4 { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-muted); margin: 0 0 8px; }
.consultant-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.consultant-actions .btn { padding: 11px 20px; font-size: 13px; }

.data-limitations { margin-top: 18px; }
.data-limitations summary { cursor: pointer; font-size: 12px; color: var(--text-muted); list-style: none; user-select: none; }
.data-limitations summary::-webkit-details-marker { display: none; }
.data-limitations summary::before { content: "› "; color: var(--accent); }
.data-limitations[open] summary::before { content: "⌄ "; }
.data-limitations p { font-size: 12px; color: var(--text-muted); line-height: 1.7; margin: 10px 0 0; }

.flags { margin-top: 16px; display: flex; flex-direction: column; gap: 7px; }
.flag { font-size: 12.5px; padding: 9px 13px; border-radius: 10px; line-height: 1.6; display: flex; gap: 8px; align-items: flex-start; }
.flag-amber { color: var(--warning); background: var(--warning-soft); }
.flag-red { color: var(--danger); background: var(--danger-soft); font-weight: 500; }

.lounge-tip {
  font-size: 12.5px;
  color: var(--text-soft);
  background: var(--surface-sunk);
  border-radius: 10px;
  padding: 10px 13px;
  margin-top: 14px;
  line-height: 1.65;
}
.lounge-icon { color: var(--accent); font-style: normal; }

#searchBtn { margin-top: 22px; }
.profile-warning {
  margin-top: 18px; font-size: 13px; color: var(--accent);
  background: var(--accent-soft); padding: 13px 16px; border-radius: var(--radius-sm);
}
.profile-warning a { color: var(--accent); font-weight: 600; }

.results-summary { font-size: 13.5px; color: var(--text-soft); margin-bottom: 22px; line-height: 1.65; }
.results-heading {
  font-family: var(--font-display); font-style: italic; font-size: 17px; font-weight: 500;
  color: var(--text); margin-bottom: 10px; padding: 0 2px;
}

.btn-sm { padding: 9px 18px; font-size: 12.5px; }

/* Guest-only "Save trip" -- sits under a results card, quiet but not
   hidden. The only place a guest is ever sent toward /login, and only
   because they asked to save something. */
.save-trip-row { margin-top: 16px; padding: 0 2px; }
.save-trip-btn { text-decoration: none; }

/* Non-blocking "create an account" nudge shown once per tab after a
   recommendation renders (see maybeShowAccountBanner in search.js) --
   deliberately styled like an informational note, not a modal or anything
   that competes visually with the results above it. */
.account-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  margin-top: 20px; padding: 16px 20px; border-radius: var(--radius-sm);
  background: var(--accent-soft); border: 1px solid var(--border-strong);
}
.account-banner-text { font-size: 13.5px; color: var(--text); line-height: 1.6; }
.account-banner-actions { display: flex; gap: 10px; flex-shrink: 0; }
@media (max-width: 560px) {
  .account-banner { flex-direction: column; align-items: stretch; }
  .account-banner-actions { justify-content: flex-end; }
}

/* Shown once, directly under the replayed results, when reopening a guest
   chat (see appendStaleResultsBanner in search.js) whose most recent turn
   was a search -- prices and availability may have moved on since it ran.
   Styled like .account-banner (same quiet informational-note treatment)
   but on the warm surface-sunk background used elsewhere for "worth a
   second look" notices, not the accent tint reserved for account nudges. */
.stale-results-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  margin-top: 20px; padding: 16px 20px; border-radius: var(--radius-sm);
  background: var(--surface-sunk); border: 1px solid var(--border-strong);
}
.stale-results-text { font-size: 13.5px; color: var(--text-soft); line-height: 1.6; }
@media (max-width: 560px) {
  .stale-results-banner { flex-direction: column; align-items: stretch; }
}

/* ============================================================
   Flight cards — floating paper, no border, soft lift on hover.
   ============================================================ */
.flight-card {
  border-radius: var(--radius);
  padding: 26px 28px;
  margin-bottom: 18px;
  position: relative;
  background: var(--surface);
  box-shadow: var(--shadow-card);
  animation: cardIn var(--dur-standard) var(--ease) both;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.flight-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-card-lg); }
.flight-card.best { background: linear-gradient(165deg, var(--ok-soft), var(--surface) 55%); }
.badge-best {
  position: absolute; top: -12px; left: 22px;
  background: var(--ok); color: #F6FBF4; font-size: 10.5px; font-weight: 700; letter-spacing: 0.04em;
  padding: 5px 14px; border-radius: var(--radius-pill); box-shadow: var(--shadow-sm);
}
.flight-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; }
.flight-name { font-family: var(--font-display); font-size: 18px; font-weight: 500; color: var(--text); letter-spacing: -0.005em; }
.flight-route { font-size: 12px; color: var(--text-muted); margin-top: 6px; letter-spacing: 0.02em; }
.flight-times { font-size: 13px; color: var(--text-soft); margin-top: 6px; }
.flight-price { font-family: var(--font-display); font-size: 22px; font-weight: 500; white-space: nowrap; color: var(--text); }

.score-wrap { display: flex; align-items: center; gap: 10px; margin-top: 18px; }
.score-bar { flex: 1; height: 3px; background: var(--border); border-radius: 4px; overflow: hidden; }
.score-fill { height: 100%; background: linear-gradient(90deg, var(--accent-bright), var(--ok)); transition: width 0.8s var(--ease); }
.score-label { font-size: 12px; font-weight: 700; color: var(--accent); min-width: 74px; text-align: right; }

.flight-tags { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 18px; }
.tag { font-size: 11px; background: var(--surface-sunk); color: var(--text-soft); padding: 5px 12px; border-radius: var(--radius-pill); }

.flight-reason { font-size: 13.5px; margin-top: 18px; line-height: 1.75; color: var(--text-soft); }
.flight-reason b { color: var(--accent); font-weight: 600; }
.caveat { font-size: 12.5px; color: var(--accent); background: var(--accent-soft); padding: 9px 13px; border-radius: 9px; margin-top: 12px; display: inline-block; }

/* Fix 7: the only badges Aster ever shows for a journey's stop pattern --
   "Nonstop both ways" / "Nonstop outbound" / "Nonstop return" / "N stops
   each way" -- only rendered when accurate for BOTH directions. */
.journey-badge {
  display: inline-block;
  font-size: 11px; font-weight: 600; letter-spacing: 0.03em;
  color: var(--ok); background: var(--ok-soft);
  padding: 4px 11px; border-radius: var(--radius-pill);
  margin-top: 8px;
}
.flight-reason.route-note, .route-note { color: var(--text-muted); font-size: 12.5px; }
.flight-reason.profile-note { color: var(--accent); margin-top: 8px; }
.flight-reason.carrier-note { color: var(--text-muted); margin-top: 6px; font-size: 12.5px; }
.flight-reason.loyalty-note { color: var(--accent); margin-top: 6px; font-size: 12.5px; }
.route-facts p { margin: 0; }

.combo-booking-group { font-size: 13px; margin-top: 8px; line-height: 1.75; }
.combo-booking-group strong { color: var(--text-soft); font-weight: 600; margin-right: 8px; }
.combo-booking-group:first-child { margin-top: 0; }

/* ---- Alternative-itinerary section: always visually separate from the
   requested-airport results, never mixed into the same card list. ---- */
.alt-section { margin-top: 24px; padding-top: 24px; border-top: 1px solid var(--border); }
.alt-warning {
  font-size: 13px; color: var(--warning); background: var(--warning-soft);
  padding: 11px 15px; border-radius: var(--radius-sm); margin-bottom: 14px; line-height: 1.6; font-weight: 500;
}
.alt-explanation { font-size: 13.5px; color: var(--text-soft); line-height: 1.75; margin-bottom: 16px; }
.alt-card { border: 1px solid var(--border-strong); box-shadow: var(--shadow-sm); }
.alt-legs { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 18px; }
.alt-leg { background: var(--surface-sunk); border-radius: 12px; padding: 14px 16px; }
.alt-leg-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.07em; color: var(--text-muted); font-weight: 700; margin-bottom: 7px; }
.alt-leg-route { font-size: 12.5px; color: var(--text-soft); margin-bottom: 5px; }
.alt-leg-meta { font-size: 12.5px; color: var(--text-soft); }
.alt-leg-price { font-size: 14.5px; font-weight: 700; color: var(--text); margin-top: 7px; }
.alt-compare { font-size: 13px; color: var(--ok); margin-top: 16px; font-weight: 500; }
@media (max-width: 700px) {
  .alt-legs { grid-template-columns: 1fr; }
}

.book-link { margin-top: 18px; }
.book-link a { font-size: 13px; color: var(--accent); font-weight: 600; text-decoration: none; margin-right: 16px; transition: color var(--dur-micro) ease; }
.book-link a:hover { color: var(--accent-hover); }
.book-link button { background: none; border: none; color: var(--accent); font-size: 13px; font-weight: 600; cursor: pointer; padding: 0; transition: color var(--dur-micro) ease; }
.book-link button:hover { color: var(--accent-hover); }

/* Product Audit Pass 2 (P0-5): flight selection. .flight-selected marks
   whichever card matches the current canonical selectedFlight (see
   search.js's own state-machine comment) -- applied/removed only through
   refreshSelectedFlightHighlighting so it can never show a card as
   selected that the underlying state disagrees with. */
.flight-select-row { margin-top: 18px; }
.select-flight-btn.is-selected { background: var(--ok-soft); color: var(--ok); border-color: var(--ok); }
.flight-card.flight-selected, .cabin-primary-card.flight-selected {
  border: 1.5px solid var(--ok);
  box-shadow: 0 0 0 3px var(--ok-soft);
}

.state-msg { font-size: 14px; color: var(--text-soft); padding: 18px 0; }
.state-msg.error { color: var(--danger); }
.state-detail { font-size: 12px; color: var(--text-muted); margin-top: 8px; word-break: break-word; }

/* ============================================================
   Loading shimmer (skeleton state, used while a search is running)
   ============================================================ */
.skeleton {
  border-radius: var(--radius);
  background: linear-gradient(90deg, var(--surface-sunk) 25%, var(--surface) 50%, var(--surface-sunk) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.8s ease-in-out infinite;
}

/* ============================================================
   Chat search UI
   ============================================================ */
/* No boxed panel here on purpose: the conversation (messages + results)
   shares the composer's own wide column instead of sitting in a separate
   white card above it. When chat-thread is empty and the profile-warning
   banner is hidden, this wrapper has no background/padding/border of its
   own to show, so it takes up zero visible space until there's actually a
   message to display. */
.conversation-thread {
  display: flex;
  flex-direction: column;
  width: min(100% - 48px, 1600px);
  margin: 0 auto;
}
/* One-page scrolling: the browser document is the only vertical scroll
   context on the results page -- this used to be `max-height: 68vh;
   overflow-y: auto`, which turned the whole conversation/results area into
   its own fixed-height scrollable pane (the "trapped in a box" feel).
   Diagnosis for the record: this rule -- not a wrapping card/background --
   was the actual nested-scrollbar owner; #chatThread is where every
   rendered message and result (recommendation banner, cabin tabs, primary
   card, alternatives) gets appended (see appendAssistantBubble() and
   renderCabinResults()/renderFlatResults() in search.js), so its overflow
   setting controlled scrolling for the entire results experience. */
.chat-thread {
  display: flex;
  flex-direction: column;
  gap: 18px;
  height: auto;
  max-height: none;
  overflow: visible;
  padding: 4px 4px 8px;
}
.chat-row { display: flex; animation: cardIn 0.35s var(--ease) both; }
.chat-row.user { justify-content: flex-end; }
.chat-row.assistant { justify-content: flex-start; }

.chat-bubble {
  max-width: 82%;
  padding: 15px 19px;
  border-radius: 18px;
  font-size: 14.5px;
  line-height: 1.7;
}
.chat-bubble.user {
  background: var(--accent-bright);
  color: var(--text-on-accent);
  font-weight: 500;
  border-bottom-right-radius: 5px;
}
.chat-bubble.assistant {
  background: var(--surface-sunk);
  color: var(--text);
  border-bottom-left-radius: 5px;
}
.chat-bubble.assistant.error { color: var(--danger); background: var(--danger-soft); }
.chat-bubble.assistant.warning { color: var(--accent); background: var(--accent-soft); }
.chat-bubble.assistant.thinking { color: var(--text-muted); background: transparent; }
.chat-bubble.assistant.thinking .thinking-dots { animation: softPulse 1.5s ease-in-out infinite; }
.chat-bubble i { color: var(--text-soft); font-style: italic; }
.chat-bubble .chip-row { margin-top: 14px; margin-bottom: 0; }
.chat-note { font-size: 12px; color: var(--accent); margin-top: 9px; }

.chat-bubble.results-bubble {
  max-width: 100%;
  width: 100%;
  background: transparent;
  padding: 0;
}
.results-summary-line { font-size: 13px; color: var(--text-soft); margin-bottom: 18px; padding: 0 2px; }
.results-cards { display: flex; flex-direction: column; }
.flight-context { font-size: 11px; color: var(--text-muted); margin-top: 5px; }

/* Weather-led destination discovery results (Open-Meteo historical-weather
   feature) -- deliberately styled as a plainer, quieter variant of
   .flight-card rather than a second competing visual language: same
   surface/radius/shadow conventions, no new colours introduced. The
   attribution/caveat lines at the end of the section use the same muted
   text treatment as .flight-context so the "this is historical, not a
   forecast" note reads as a factual footnote, not a warning. */
.weather-destination-cards { display: flex; flex-direction: column; }
.weather-destination-card {
  border-radius: var(--radius);
  padding: 22px 26px;
  margin-bottom: 16px;
  background: var(--surface);
  box-shadow: var(--shadow-card);
}
.weather-destination-name {
  font-family: var(--font-display); font-style: italic; font-size: 16px; font-weight: 500;
  color: var(--text); margin-bottom: 12px;
}
.weather-conditions-heading, .weather-flights-heading {
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--text-muted); margin-bottom: 4px;
}
.weather-conditions-reasons { font-size: 13.5px; color: var(--text-soft); line-height: 1.6; margin-bottom: 12px; }
.weather-conditions-unavailable { font-size: 13.5px; color: var(--text-soft); line-height: 1.6; margin-bottom: 12px; }
.weather-conditions-caveat { font-size: 11.5px; color: var(--text-muted); margin-top: -8px; margin-bottom: 12px; }
.weather-flights-line { font-size: 13.5px; color: var(--text-soft); margin-bottom: 12px; }
.weather-destination-why { font-size: 12.5px; color: var(--text-muted); font-style: italic; }
.weather-forecast-caveat { font-size: 12px; color: var(--text-muted); margin-top: 4px; padding: 0 2px; }
.weather-attribution { font-size: 11px; color: var(--text-muted); margin-top: 6px; padding: 0 2px; }

/* ============================================================
   Conversation composer — a wide, minimal, "floating" interaction surface
   rather than a boxed form field. No card, no background fill, no heavy
   border: a hairline divider under the input is the only resting-state
   cue, turning gold with a soft glow on focus.

   Structural rule (this is the whole point of this block): the TEXTAREA
   is the visible composer. There is no separate wrapper sized larger than
   its content -- .composer is a plain `position: relative` box that is
   exactly as tall as the textarea inside it. The Send button and the
   example hint are `position: absolute` overlays anchored to the
   textarea's bottom-right / bottom-left corners, living inside the
   textarea's own reserved bottom padding (see .composer-input) rather
   than occupying separate flex rows that would otherwise add dead space
   below a short, one-line-tall input.

   Conversation composer container: sits directly below .conversation-thread
   and shares its exact width (90%, capped at 1300px, centred) -- messages,
   results and the input all live in one continuous wide column now, not a
   boxed panel above a separate input. ---- */
.composer {
  position: relative;
  width: min(100% - 48px, 1600px);
  margin: 48px auto 0;
  border-bottom: 1px solid var(--border);
  transition: border-color 0.3s var(--ease-soft), box-shadow 0.3s var(--ease-soft);
}
.composer:focus-within {
  border-bottom-color: var(--accent);
  box-shadow: 0 1px 0 0 var(--accent), 0 18px 30px -26px var(--accent-soft-strong);
}
/* The textarea fills the entire visible composer -- width, and (via the
   JS-enforced minimum below) height. Extra bottom padding (~90px) keeps
   typed text clear of the absolutely-positioned hint/Send overlay; that
   padding is blank content-box space, not a separate wrapper, so it only
   ever appears when the textarea is genuinely that tall. */
.composer-input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin: 0;
  padding: 22px 26px 92px 26px;
  min-height: 180px;
  max-height: 40vh;
  border: none;
  outline: none;
  background: transparent;
  resize: none;
  overflow-y: hidden;
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
  color: var(--text);
  transition: height 0.12s ease;
}
.composer-input:focus { outline: none; box-shadow: none; }
.composer-input::placeholder { color: var(--text-muted); line-height: 1.65; }
/* One subtle, single-line example, anchored inside the textarea's bottom
   padding rather than flowing as its own row -- so it reads as part of the
   same writing surface instead of a detached line underneath it. */
.composer-hint {
  position: absolute;
  left: 24px;
  bottom: 26px;
  font-size: 12.5px;
  color: var(--text-muted);
  margin: 0;
  padding: 0;
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
  max-width: calc(100% - 140px);
  overflow: hidden;
  text-overflow: ellipsis;
}
.composer-send {
  position: absolute;
  right: 24px;
  bottom: 24px;
  border-radius: var(--radius-pill);
  padding: 12px 26px;
  font-size: 13.5px;
}

.chip-row.clarification-row { margin-bottom: 8px; }
.chip-clarify {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}
.chip-clarify:hover { background: var(--accent-bright); color: var(--text-on-accent); border-color: var(--accent-bright); }

.loc-suggest {
  position: absolute;
  top: 100%; left: 0; right: 0;
  background: var(--surface);
  border-radius: 14px;
  margin-top: 10px;
  max-height: 240px;
  overflow-y: auto;
  z-index: 25;
  display: none;
  box-shadow: var(--shadow-card-lg);
  animation: dropIn 0.2s var(--ease);
}
.loc-suggest.show { display: block; }
.loc-suggest-item { padding: 11px 16px; cursor: pointer; font-size: 13.5px; color: var(--text); transition: background 0.15s ease; }
.loc-suggest-item:hover { background: var(--accent-soft); }
.loc-suggest-item .loc-type {
  display: inline-block; font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-muted); background: var(--surface-sunk); border-radius: 4px;
  padding: 1px 7px; margin-right: 9px; vertical-align: middle;
}

/* ============================================================
   Journeys — the two entry points into search: a structured form (Journey
   A) and Aster's conversational planner (Journey B, the pre-existing
   composer, just relabelled and relocated into its own panel here). Both
   panels are equally legitimate, but the structured panel reads as the
   primary/larger one on desktop since it's the more immediately
   recognisable option for a first-time visitor.
   ============================================================ */
/* Shared wide-canvas width recipe for every top-level results-page block
   (.journeys, .search-summary-bar, #editSearchMount, #askAsterMount,
   .conversation-thread, .composer) -- `min(100% - 48px, 1600px)` instead of
   the old `90%` (which needlessly narrowed the page further as viewports
   got wider) capped at 1440px. A fixed 48px side gutter reads as
   comfortable at any width, and 1600px gives flight cards real room on a
   wide desktop screen without the page ever feeling edge-to-edge. */
.journeys {
  width: min(100% - 48px, 1600px);
  margin: 40px auto 0;
}

/* ---- Results mode: compact summary bar + Edit search / Ask Aster ----
   Mounted instead of .journeys once a search has actually run (see
   enterResultsMode() in search.js) -- shares .journeys' width so the page
   reads as one consistent column in either mode.

   IMPORTANT: this rule is deliberately written as `:not([hidden])`, not a
   bare `.search-summary-bar { display: flex; ... }`. The browser's built-in
   `[hidden] { display: none }` rule lives in the user-agent stylesheet,
   which is ALWAYS beaten by any normal rule in an author stylesheet
   (this file) regardless of selector specificity -- so an unconditional
   `display: flex` here would silently defeat `el.hidden = true` and leave
   the bar visible no matter what. Scoping the layout declarations to
   `:not([hidden])` means there's no competing author rule for the browser
   to prefer over `[hidden]` in the first place.

   Sticky: docks directly under the site nav (top: var(--nav-height), a
   real measured value -- see syncNavHeightVar() in search.js -- not 0,
   which would tuck it underneath/behind the nav instead of below it).
   Checked every ancestor between this element and <body> for the usual
   sticky-breakers (overflow other than visible, transform, filter,
   contain: paint) -- main.search-main, body and html currently set none
   of these, so sticky works without any structural change. The background
   + blur + border + shadow exist so page content scrolling up underneath
   never shows through while it's pinned. */
.search-summary-bar:not([hidden]) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.search-summary-bar {
  position: sticky;
  top: var(--nav-height);
  z-index: 20;
  width: min(100% - 48px, 1600px);
  margin: 24px auto 0;
  padding: 16px 22px;
  background: rgba(255,255,255,0.86);
  backdrop-filter: blur(14px) saturate(1.1);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.summary-bar-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.summary-bar-route { font-family: var(--font-display); font-size: 16.5px; font-weight: 500; color: var(--text); letter-spacing: -0.01em; }
.summary-bar-code { font-family: var(--font-body); font-size: 12px; font-weight: 500; color: var(--text-muted); letter-spacing: 0.02em; }
.summary-bar-details { font-size: 12.5px; color: var(--text-soft); }
.summary-bar-actions { display: flex; gap: 8px; flex-shrink: 0; }
.summary-edit-btn, .summary-ask-btn { padding: 9px 18px; font-size: 12.5px; }

/* #editSearchMount / #askAsterMount are plain empty containers -- invisible
   by default with no CSS of their own, so there's nothing to fight when
   search.js mounts/unmounts real content into them (see openEditSearch(),
   openAskAster() in search.js). Sharing .journeys' width keeps the
   re-expanded planning interface visually aligned with the summary bar
   above it. */
#editSearchMount, #askAsterMount { width: min(100% - 48px, 1600px); margin: 0 auto; }
#editSearchMount .journeys { margin-top: 14px; }

/* Fake an "auto height" open/close transition with two-keyframe animations
   (max-height can't be transitioned to `auto` directly) -- the 2000px
   ceiling is comfortably above the form's real height, so nothing is ever
   actually clipped; it only matters for how the animation interpolates.
   `overflow: hidden` is scoped to the two transient `.journeys-opening` /
   `.journeys-closing` classes ONLY (added/removed by openEditSearch() /
   closeEditSearch() in search.js right as each animation starts/ends) --
   never a permanent property of the mounted form. A permanent
   `overflow: hidden` here would silently clip the form's own contents in
   its resting state, which is exactly the kind of nested inner-viewport
   behaviour this whole redesign removes; scoping it to the animation
   window means the settled, normal-flow form has no overflow rule on it
   at all. */
#editSearchMount .journeys.journeys-opening { animation: editSearchExpand 0.32s var(--ease) both; overflow: hidden; }
#editSearchMount .journeys.journeys-closing { animation: editSearchCollapse 0.28s var(--ease) both; overflow: hidden; }

.structured-actions { display: flex; gap: 10px; }
.structured-actions .structured-submit { flex: 1; }
.structured-cancel { border-radius: var(--radius-sm); padding: 14px 20px; font-size: 14.5px; }

/* Ask Aster's compact follow-up panel -- built fresh by openAskAster() each
   time it's opened, so this only ever needs to style whatever's currently
   mounted, never manage a persistent hidden/shown state itself. */
.ask-aster-panel {
  margin-top: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 16px 20px;
  animation: cardIn 0.3s var(--ease) both;
}
.ask-aster-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-soft);
  margin-bottom: 12px;
}
.ask-aster-close {
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
}
.ask-aster-close:hover { color: var(--text); }
.ask-aster-panel-row { display: flex; align-items: center; gap: 10px; }
.ask-aster-input {
  flex: 1;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 12px 20px;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--text);
  background: var(--surface-sunk);
  outline: none;
  transition: border-color 0.2s var(--ease-soft);
}
.ask-aster-input:focus { border-color: var(--accent); }
.ask-aster-panel .btn { flex-shrink: 0; border-radius: var(--radius-pill); padding: 12px 22px; font-size: 13px; }

@media (max-width: 700px) {
  .search-summary-bar:not([hidden]) { flex-direction: column; align-items: stretch; text-align: left; gap: 10px; }
  .summary-bar-actions { flex-direction: column; }
  .summary-edit-btn, .summary-ask-btn { width: 100%; }
  .structured-actions { flex-direction: column; }
}
.journeys-intro { margin-bottom: 28px; }
.journeys-title {
  font-family: var(--font-display);
  font-size: 34px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--text);
  margin: 0 0 8px;
}
.journeys-lede { font-size: 15.5px; color: var(--text-soft); margin: 0; max-width: 640px; }

.journeys-panels {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}
@media (max-width: 900px) {
  .journeys-panels { grid-template-columns: 1fr; }
}

.journey-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: 28px 28px 32px;
}
.journey-panel-head { margin-bottom: 20px; }
.journey-panel-head h2 {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 500;
  color: var(--text);
  margin: 0 0 6px;
}
.journey-panel-head p { font-size: 13.5px; color: var(--text-soft); margin: 0; line-height: 1.6; }

/* Journey B's composer, relocated from a full-width page element into this
   narrower panel column -- only spacing changes here, .composer/.composer-*
   themselves (and every bit of JS that drives them) are untouched. */
.journey-panel-assisted .composer { width: 100%; max-width: none; margin: 0; }
.journey-panel-assisted .composer-input { min-height: 220px; padding-bottom: 78px; }
.journey-panel-assisted .composer-send { right: 16px; bottom: 16px; padding: 10px 22px; }

/* ---- Structured search form ---- */
.structured-form { display: flex; flex-direction: column; gap: 16px; }
.structured-row { display: flex; gap: 12px; }
.structured-row-locations { align-items: flex-end; }
.structured-field { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; position: relative; }
.structured-field label,
.structured-row > label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.structured-input {
  width: 100%;
  box-sizing: border-box;
  padding: 12px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-soft);
  font-family: var(--font-body);
  font-size: 14.5px;
  color: var(--text);
  transition: border-color var(--dur-micro) ease, box-shadow var(--dur-micro) ease;
}
.structured-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.structured-input::placeholder { color: var(--text-muted); }

.structured-swap {
  flex: none;
  width: 36px;
  height: 36px;
  margin-bottom: 12px;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text-soft);
  font-size: 15px;
  cursor: pointer;
  transition: color var(--dur-micro) ease, border-color var(--dur-micro) ease, transform var(--dur-micro) ease;
}
.structured-swap:hover { color: var(--accent); border-color: var(--accent); transform: rotate(180deg); }

.structured-suggest {
  position: absolute;
  top: 100%; left: 0; right: 0;
  margin-top: 6px;
  background: var(--surface);
  border-radius: 12px;
  max-height: 220px;
  overflow-y: auto;
  z-index: 25;
  display: none;
  box-shadow: var(--shadow-card-lg);
  animation: dropIn 0.2s var(--ease);
}
.structured-suggest.show { display: block; }
.structured-suggest-item { padding: 10px 14px; cursor: pointer; font-size: 13.5px; color: var(--text); transition: background 0.15s ease; }
.structured-suggest-item:hover, .structured-suggest-item.highlighted { background: var(--accent-soft); }
.structured-suggest-empty { padding: 10px 14px; font-size: 13px; color: var(--text-muted); }

.structured-checkbox-label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  color: var(--text-soft);
  cursor: pointer;
}
.structured-checkbox { accent-color: var(--accent); width: 16px; height: 16px; cursor: pointer; }

.structured-stepper {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  background: var(--surface-sunk);
  border-radius: var(--radius-sm);
  padding: 6px 10px;
  width: fit-content;
}
.structured-stepper-btn {
  width: 28px; height: 28px;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: border-color var(--dur-micro) ease, color var(--dur-micro) ease;
}
.structured-stepper-btn:hover { border-color: var(--accent); color: var(--accent); }
.structured-stepper-value { min-width: 18px; text-align: center; font-size: 14px; font-weight: 600; color: var(--text); }

.structured-cabin button { min-width: 0; font-size: 12px; padding: 10px 6px; }

.structured-error {
  font-size: 13px;
  color: var(--danger);
  background: var(--danger-soft);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
}

.structured-submit { width: 100%; border-radius: var(--radius-sm); padding: 14px; font-size: 14.5px; }

@media (max-width: 520px) {
  .structured-row { flex-wrap: wrap; }
  .structured-row-locations { flex-wrap: nowrap; }
}

/* ============================================================
   Custom date-range calendar (static/date_picker.js) -- a popover anchored
   under the Departure/Return fields it replaces. Two months side by side
   above 700px, one month at or below it (matches the app's existing mobile
   breakpoint everywhere else). Selected-range highlighting mirrors the
   familiar "pick start, pick end" pattern of most flight-search calendars.
   ============================================================ */
.structured-row-dates { position: relative; }
.date-picker-popover {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  z-index: 40;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card-lg, var(--shadow-card));
  padding: 18px 20px 16px;
}
.date-picker-header { display: flex; align-items: flex-start; gap: 8px; }
.date-picker-nav {
  flex-shrink: 0;
  width: 30px; height: 30px;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-soft);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.date-picker-nav:hover { border-color: var(--accent); color: var(--accent); }
.date-picker-months { display: flex; gap: 24px; flex: 1; justify-content: center; }
.date-picker-month { min-width: 0; flex: 1; max-width: 260px; }
.date-picker-month-head {
  font-family: var(--font-display);
  font-size: 14.5px;
  font-weight: 500;
  color: var(--text);
  text-align: center;
  margin-bottom: 10px;
}
.date-picker-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  margin-bottom: 4px;
}
.date-picker-weekdays span {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  text-align: center;
}
.date-picker-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.date-picker-day {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  border-radius: 8px;
  font-family: inherit;
  font-size: 12.5px;
  color: var(--text);
  cursor: pointer;
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease;
}
.date-picker-day:hover:not(:disabled) { background: var(--surface-sunk); }
.date-picker-day-pad { visibility: hidden; cursor: default; }
.date-picker-day-disabled { color: var(--text-muted); opacity: 0.4; cursor: default; }
.date-picker-day-today { font-weight: 700; color: var(--accent); }
.date-picker-day-start, .date-picker-day-end {
  background: var(--accent-bright);
  color: var(--text-on-accent);
  font-weight: 600;
}
.date-picker-day-inrange { background: var(--accent-soft); }
.date-picker-day-focus { box-shadow: 0 0 0 2px var(--accent); }
.date-picker-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.date-picker-summary { font-size: 12.5px; color: var(--text-soft); }
.date-picker-footer-actions { display: flex; gap: 8px; flex-shrink: 0; }
.date-picker-clear, .date-picker-done {
  border: none;
  border-radius: var(--radius-pill);
  padding: 8px 16px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
}
.date-picker-clear { background: transparent; color: var(--text-soft); }
.date-picker-clear:hover { color: var(--text); }
.date-picker-done { background: var(--accent-bright); color: var(--text-on-accent); }

@media (max-width: 700px) {
  .date-picker-popover { left: -4px; right: -4px; padding: 16px 14px 14px; }
  .date-picker-months { gap: 0; }
  .date-picker-month { max-width: none; }
}

/* ============================================================
   Trips panel — a slide-out drawer (not a permanent docked sidebar) listing
   past conversations. Opens over the page from the left; the wide composer
   layout underneath is untouched while it's closed.
   ============================================================ */
.trips-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  color: var(--text-soft);
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  padding: 9px 18px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  margin: 28px 0 0;
  transition: border-color var(--dur-micro) ease, color var(--dur-micro) ease, transform var(--dur-micro) ease;
}
.trips-trigger:hover { border-color: var(--accent); color: var(--accent); transform: translateY(-1px); }

.trips-overlay {
  position: fixed;
  inset: 0;
  background: rgba(36, 31, 25, 0.32);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s var(--ease-soft);
  z-index: 60;
}
.trips-overlay.show { opacity: 1; pointer-events: auto; }

.trips-panel {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 320px;
  max-width: 86vw;
  background: var(--surface);
  box-shadow: var(--shadow-card-lg);
  z-index: 61;
  padding: 28px 22px;
  display: flex;
  flex-direction: column;
  transform: translateX(-100%);
  transition: transform 0.35s var(--ease);
  overflow-y: auto;
}
.trips-panel.open { transform: translateX(0); }
.trips-panel-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; }
.trips-panel-header h2 { font-family: var(--font-display); font-size: 20px; font-weight: 500; margin: 0; }
.trips-close {
  background: none; border: none; cursor: pointer; font-size: 22px; line-height: 1;
  color: var(--text-muted); padding: 2px 6px; transition: color var(--dur-micro) ease;
}
.trips-close:hover { color: var(--text); }
.trips-new { width: 100%; margin-bottom: 22px; padding: 12px 16px; font-size: 13.5px; }

.trips-list { display: flex; flex-direction: column; gap: 4px; }
.trips-item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  font-family: inherit;
  font-size: 13.5px;
  color: var(--text-soft);
  cursor: pointer;
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease;
}
.trips-item:hover { background: var(--surface-sunk); color: var(--text); }
.trips-item.active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.trips-item-title { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trips-empty { font-size: 13px; color: var(--text-muted); padding: 10px 4px; line-height: 1.6; }
.trips-empty a { color: var(--accent); font-weight: 600; text-decoration: none; }
.trips-empty a:hover { color: var(--accent-hover); }

/* Guest-only additions to the panel above: a delete button beside each
   saved trip, and a footer explaining where the data lives with a way to
   wipe it. Everything else in the panel (.trips-item, .trips-empty, the
   trigger/overlay/close chrome) is shared unchanged with the account-based
   version -- see guestChatItemHtml / loadGuestChatsList in search.js. */
.trips-item-row { display: flex; align-items: center; gap: 2px; }
.trips-item-row .trips-item { flex: 1; min-width: 0; }
.trips-item-delete {
  flex-shrink: 0; background: none; border: none; cursor: pointer;
  width: 28px; height: 28px; border-radius: var(--radius-sm);
  font-size: 16px; line-height: 1; color: var(--text-muted);
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease;
}
.trips-item-delete:hover { background: var(--surface-sunk); color: var(--danger); }

.trips-guest-footer {
  margin-top: auto;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}
.trips-guest-note { font-size: 12px; color: var(--text-muted); line-height: 1.6; margin: 0 0 12px; }
.trips-clear-all {
  width: 100%; background: none; border: 1px solid var(--border-strong); cursor: pointer;
  font-family: inherit; font-size: 12.5px; color: var(--text-muted);
  padding: 10px 14px; border-radius: var(--radius-sm);
  transition: border-color var(--dur-micro) ease, color var(--dur-micro) ease;
}
.trips-clear-all:hover { border-color: var(--danger); color: var(--danger); }

@media (max-width: 700px) {
  .trips-trigger { margin-top: 20px; }
  .trips-panel { width: 88vw; padding: 22px 18px; }
}

/* ============================================================
   Cabin-based results — the private-advisor "shortlist" experience:
   one overall pick, four cabin tabs, one primary recommendation per
   cabin, alternatives collapsed, feedback controls underneath.
   ============================================================ */

.cabin-overall {
  background: linear-gradient(165deg, var(--accent-soft), var(--surface) 60%);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 28px 32px;
  margin-bottom: 24px;
  box-shadow: var(--shadow-sm);
  animation: floatIn 0.6s var(--ease) both;
  transition: background 0.5s ease;
}
.cabin-overall.loading { background: var(--surface); }
.cabin-overall-badge {
  display: inline-block;
  background: var(--accent-bright);
  color: var(--text-on-accent);
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 6px 14px; border-radius: var(--radius-pill); margin-bottom: 16px;
}
.cabin-overall-headline {
  font-family: var(--font-display); font-weight: 500; font-size: 22px;
  color: var(--text); margin: 0 0 10px; letter-spacing: -0.01em; line-height: 1.3;
}
.cabin-overall-reason { font-size: 14px; color: var(--text-soft); line-height: 1.7; margin: 0 0 6px; }
.cabin-overall-list { margin: 10px 0 0; padding-left: 20px; }
.cabin-overall-list li { font-size: 13.5px; color: var(--text-soft); line-height: 1.7; margin-bottom: 4px; }
.cabin-overall-worth { font-size: 13px; color: var(--accent); margin: 12px 0 0; font-weight: 500; }
.cabin-overall-incomplete { font-size: 13px; color: var(--warn, #a15c00); margin: 10px 0 0; font-weight: 500; }
.cabin-empty-all { font-size: 14.5px; color: var(--text-soft); padding: 24px 0; line-height: 1.7; }

/* Tabs — a segmented control, not a native <select>. */
.cabin-tabs {
  display: flex;
  gap: 4px;
  background: var(--surface-sunk);
  border-radius: var(--radius-sm);
  padding: 4px;
  margin-bottom: 22px;
}
.cabin-tab {
  flex: 1;
  background: transparent;
  border: none;
  border-radius: 7px;
  color: var(--text-soft);
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 500;
  padding: 12px 10px;
  cursor: pointer;
  transition: background var(--dur-micro) ease, color var(--dur-micro) ease, box-shadow var(--dur-micro) ease;
}
.cabin-tab:hover { color: var(--text); }
.cabin-tab.active { background: var(--surface); color: var(--text); font-weight: 600; box-shadow: var(--shadow-sm); }
.cabin-tab-unavailable:not(.active) { color: var(--text-muted); opacity: 0.65; }

.cabin-panels { position: relative; margin-bottom: 8px; }
.cabin-panel { display: none; animation: cardIn 0.4s var(--ease) both; }
.cabin-panel.active { display: block; padding-bottom: 12px; }

.cabin-unavailable {
  background: var(--surface-sunk);
  border-radius: var(--radius);
  padding: 32px 30px;
  text-align: left;
}
.cabin-unavailable-title { font-family: var(--font-display); font-size: 17px; font-weight: 500; color: var(--text); margin-bottom: 8px; }
.cabin-unavailable p { font-size: 13.5px; color: var(--text-soft); line-height: 1.7; margin: 0; }

/* The primary recommendation card — richer than a standard flight-card,
   built from structured rows rather than compact tags. */
/* Restrained corner radius (var(--radius), not --radius-lg) -- per the
   redesign's "avoid extremely large radii that make every section
   resemble a floating bubble" note, individual cards stay clearly card-like
   without reading as an oversized bubble the way the previous --radius-lg
   (28px) did at this size. */
.cabin-primary-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 26px 28px;
  box-shadow: var(--shadow-sm);
  position: relative;
}
.cabin-primary-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; }
.cabin-primary-airline { font-family: var(--font-display); font-size: 20px; font-weight: 500; color: var(--text); letter-spacing: -0.01em; }
.cabin-primary-route { font-size: 14px; color: var(--text-soft); margin-top: 6px; }

/* Denser two-column layout on wide screens: outbound/return times on the
   left, cabin+aircraft+baggage on the right, instead of one long vertical
   stack -- the same information, using the width the redesign asks for
   instead of leaving it as blank space either side of a narrow column. */
.cabin-primary-details {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  gap: 6px 32px;
}
.cabin-primary-legs { min-width: 0; }
.cabin-primary-times { font-size: 13.5px; color: var(--text-soft); margin-bottom: 8px; line-height: 1.6; }
.cabin-primary-times-label {
  display: inline-block;
  min-width: 60px;
  color: var(--text-muted);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-right: 8px;
}
.cabin-primary-meta { min-width: 0; }
.cabin-primary-meta-line { font-size: 13.5px; color: var(--text); font-weight: 500; margin-bottom: 8px; }
.cabin-primary-row { display: flex; gap: 10px; font-size: 13px; color: var(--text-soft); margin-top: 6px; }
.cabin-primary-row-label { color: var(--text-muted); min-width: 100px; font-weight: 500; }
@media (max-width: 700px) {
  .cabin-primary-details { grid-template-columns: 1fr; }
}

.cabin-primary-block { margin-top: 22px; }
.cabin-primary-block h4 { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-muted); margin: 0 0 10px; }
.cabin-primary-block .flight-reason { margin: 0; }
.cabin-primary-block .flag { margin-bottom: 7px; }
.cabin-primary-block .flag:last-child { margin-bottom: 0; }

.cabin-alternatives { margin-top: 16px; }
.cabin-alternatives summary {
  cursor: pointer; font-size: 13px; color: var(--text-soft); list-style: none; user-select: none;
  padding: 4px 2px; transition: color 0.15s ease;
}
.cabin-alternatives summary::-webkit-details-marker { display: none; }
.cabin-alternatives summary::before { content: "› "; color: var(--accent); }
.cabin-alternatives[open] summary::before { content: "⌄ "; }
.cabin-alternatives summary:hover { color: var(--text); }
.cabin-alternatives-list { margin-top: 14px; }
.cabin-alternatives-list .flight-card { box-shadow: var(--shadow-sm); }

/* Feedback controls under every primary recommendation. */
.feedback-row { margin-top: 26px; padding-top: 20px; border-top: 1px solid var(--border); }
.feedback-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); margin-bottom: 10px; }
.feedback-buttons { display: flex; flex-wrap: wrap; gap: 8px; }
.feedback-btn {
  background: var(--surface-sunk);
  border: 1px solid var(--border-strong);
  color: var(--text-soft);
  font-size: 12px; font-weight: 500;
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: border-color var(--dur-micro) ease, color var(--dur-micro) ease, background var(--dur-micro) ease, transform var(--dur-micro) ease;
}
.feedback-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); transform: translateY(-1px); }
.feedback-btn-positive { border-color: var(--ok); color: var(--ok); }
.feedback-btn-positive:hover:not(:disabled) { background: var(--ok-soft); border-color: var(--ok); color: var(--ok); }
.feedback-btn.selected { background: var(--accent-bright); border-color: var(--accent-bright); color: var(--text-on-accent); }
.feedback-btn-positive.selected { background: var(--ok); border-color: var(--ok); color: #F6FBF4; }
.feedback-btn:disabled { cursor: default; opacity: 0.7; }
.feedback-status { font-size: 12px; color: var(--ok); margin-top: 10px; height: 0; opacity: 0; transition: opacity 0.3s ease; }
.feedback-status.show { opacity: 1; height: auto; }
.feedback-status.error { color: var(--danger); }

/* ============================================================
   Seat card -- deliberately a SEPARATE card below the itinerary card
   (.cabin-primary-card), never merged into it. Matches the same surface/
   radius/shadow language as the itinerary card so it reads as part of the
   same premium result, while staying visually distinct as its own unit.
   ============================================================ */
.seat-card {
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: 26px 32px;
  box-shadow: var(--shadow-card);
  margin-top: 16px;
  border: 1px solid var(--border);
}
.seat-card-loading { display: flex; align-items: center; }
.seat-card-loading-text { font-size: 13px; color: var(--text-muted); font-style: italic; }
.seat-card-eyebrow { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-muted); margin-bottom: 14px; }
.seat-card-unavailable-text { font-size: 13.5px; color: var(--text-soft); line-height: 1.7; margin: 0; }

.seat-card-block + .seat-card-block { margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--border); }
.seat-card-subheading { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--accent); margin-bottom: 8px; }
.seat-card-designator-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.seat-card-seat-label { font-size: 12px; color: var(--text-muted); font-weight: 500; }
.seat-card-direction { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--accent); margin-bottom: 8px; }
.seat-card-designator { font-family: var(--font-display); font-size: 26px; font-weight: 500; color: var(--text); letter-spacing: -0.01em; }
.seat-confidence-badge {
  font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--accent); background: var(--accent-soft); padding: 4px 10px; border-radius: var(--radius-pill);
}
.seat-card-explanation { font-size: 13.5px; color: var(--text-soft); line-height: 1.7; margin: 12px 0 0; }

.seat-card-reasons { margin-top: 14px; }
.seat-card-reasons h5 { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); margin: 0 0 8px; }
.seat-card-reasons ul { margin: 0; padding-left: 18px; }
.seat-card-reasons li { font-size: 13px; color: var(--text-soft); line-height: 1.7; }
.seat-card-positive li::marker { color: var(--ok); }
.seat-card-negative li::marker { color: var(--warning); }

.seat-card-price { font-size: 13px; color: var(--text); font-weight: 500; margin-top: 12px; }

.seat-card-sources { margin-top: 14px; }
.seat-card-sources summary {
  cursor: pointer; font-size: 12px; color: var(--text-muted); list-style: none; user-select: none;
  padding: 2px 0; transition: color 0.15s ease;
}
.seat-card-sources summary::-webkit-details-marker { display: none; }
.seat-card-sources summary::before { content: "› "; color: var(--accent); }
.seat-card-sources[open] summary::before { content: "⌄ "; }
.seat-card-sources summary:hover { color: var(--text); }
.seat-card-sources > div { font-size: 12px; color: var(--text-soft); line-height: 1.9; margin-top: 8px; }
.seat-card-sources a { color: var(--accent); }
.seat-card-sources a:hover { color: var(--accent-hover); }

.seat-card-alternatives { margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--border); }
.seat-card-alternatives summary {
  cursor: pointer; font-size: 13px; color: var(--text-soft); list-style: none; user-select: none;
}
.seat-card-alternatives summary::-webkit-details-marker { display: none; }
.seat-card-alternatives summary::before { content: "› "; color: var(--accent); }
.seat-card-alternatives[open] summary::before { content: "⌄ "; }

.seat-card-map-btn { margin-top: 20px; font-size: 12.5px; padding: 9px 16px; }
.seat-card-map-btn:disabled { cursor: default; opacity: 0.55; }

@media (max-width: 700px) {
  .seat-card { padding: 22px 20px; }
  .seat-card-designator { font-size: 22px; }
}

/* ============================================================
   SEAT INTELLIGENCE PANEL — the seat_intel foundation's own surface
   (static/seat_panel.js). Same paper-lift language as .seat-card, but a
   distinct unit: this panel is built entirely from curated facts with
   explicit provenance, so its job visually is to keep four separate
   certainties legible — layout, seat, availability, price — and never
   let an exact seat number look more certain than the layout it rests
   on. The warning banner therefore sits ABOVE the seat number, and the
   airline-confirmation notice is in normal flow at every width (never a
   tooltip, never inside a <details>, never display:none).
   ============================================================ */
.seat-intel-panel {
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: 26px 32px;
  box-shadow: var(--shadow-card);
  margin-top: 16px;
  border: 1px solid var(--border);
}
.seat-intel-title {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--text-muted); margin-bottom: 14px;
}
.seat-intel-synthetic {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--danger); background: var(--danger-soft); border: 1px solid var(--danger);
  border-radius: var(--radius-sm); padding: 8px 12px; margin-bottom: 14px; line-height: 1.5;
}

/* Layout uncertainty, rendered above the recommendation so it is read first. */
.seat-intel-layout-banner {
  display: block; border-radius: var(--radius-sm); padding: 12px 14px; margin-bottom: 16px;
  background: var(--warning-soft); border-left: 3px solid var(--warning);
}
.seat-intel-layout-banner strong {
  display: block; font-size: 12.5px; font-weight: 700; color: var(--text); margin-bottom: 4px;
}
.seat-intel-layout-banner span { display: block; font-size: 12.5px; color: var(--text-soft); line-height: 1.6; }
.seat-intel-layout-unsupported { background: var(--surface-sunk); border-left-color: var(--text-muted); }

.seat-intel-headline { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.seat-intel-eyebrow {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--accent);
}
.seat-intel-seat {
  font-family: var(--font-display); font-size: 26px; font-weight: 500; color: var(--text);
  letter-spacing: -0.01em; overflow-wrap: anywhere;
}
.seat-intel-group-note {
  font-size: 11px; font-weight: 600; color: var(--accent); background: var(--accent-soft);
  padding: 4px 10px; border-radius: var(--radius-pill);
}
.seat-intel-config { font-size: 12.5px; color: var(--text-muted); margin: 6px 0 0; line-height: 1.6; }
.seat-intel-uncertain-lede { font-size: 13.5px; color: var(--text-soft); line-height: 1.7; margin: 0; }

.seat-intel-section { margin-top: 18px; }
.seat-intel-section h5 {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-muted); margin: 0 0 8px;
}
.seat-intel-section ul { margin: 0; padding-left: 18px; }
.seat-intel-section li { font-size: 13px; color: var(--text-soft); line-height: 1.7; }
.seat-intel-why-list li::marker { color: var(--ok); }
.seat-intel-compromise-list li::marker { color: var(--warning); }
.seat-intel-priorities { font-size: 13px; color: var(--text-soft); line-height: 1.7; margin: 0; }

.seat-intel-alternatives ul { list-style: none; padding-left: 0; }
.seat-intel-alt { border-top: 1px solid var(--border); padding-top: 12px; margin-top: 12px; }
.seat-intel-alt:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
.seat-intel-alt-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.seat-intel-alt-seat { font-size: 15px; font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
.seat-intel-alt-kind {
  font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--accent); background: var(--accent-soft); padding: 3px 9px; border-radius: var(--radius-pill);
}
.seat-intel-alt-why { font-size: 12.5px; color: var(--text-soft); line-height: 1.6; margin: 6px 0 0; }
.seat-intel-alt-status { font-size: 12px; color: var(--text-muted); line-height: 1.6; margin: 4px 0 0; }

/* Layout / availability / price, each labelled separately so an unknown in one
   can never be read as a claim about another. */
.seat-intel-facts { margin: 18px 0 0; padding: 16px 0 0; border-top: 1px solid var(--border); }
.seat-intel-fact { display: grid; grid-template-columns: 130px 1fr; gap: 6px 16px; padding: 7px 0; }
.seat-intel-fact dt {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-muted); padding-top: 2px;
}
.seat-intel-fact dd { margin: 0; min-width: 0; }
.seat-intel-fact-value { display: block; font-size: 13px; font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
.seat-intel-fact-detail { display: block; font-size: 12px; color: var(--text-soft); line-height: 1.6; margin-top: 2px; }
.seat-intel-fact-known_available .seat-intel-fact-value { color: var(--ok); }
.seat-intel-fact-known .seat-intel-fact-value,
.seat-intel-fact-range .seat-intel-fact-value { color: var(--text); }
.seat-intel-fact-unknown .seat-intel-fact-value,
.seat-intel-fact-partially_known .seat-intel-fact-value,
.seat-intel-fact-chargeable_amount_unknown .seat-intel-fact-value { color: var(--warning); }

.seat-intel-notice {
  font-size: 12.5px; color: var(--text); line-height: 1.65; margin: 18px 0 0;
  padding: 12px 14px; background: var(--surface-sunk); border-radius: var(--radius-sm);
}

@media (max-width: 700px) {
  .seat-intel-panel { padding: 22px 20px; }
  .seat-intel-seat { font-size: 22px; }
  /* Single column so neither the label nor the value is squeezed/clipped; the
     notice keeps its own full-width block and is never hidden. */
  .seat-intel-fact { grid-template-columns: 1fr; gap: 2px; }
}

/* ============================================================
   Seat-advice progressive disclosure (static/seat_panel.js)

   The compact row that keeps the panel above one deliberate click away. It is
   collapsed by default at every width, so the flight-results experience stays
   clean and the detail is opt-in.

   Three visual jobs:
     * make the row unmistakably tappable when there IS something to open
       (min-height 48px -- past the 44px touch target at every width, not just
       on mobile, because a mouse target this shallow is uncomfortable too);
     * make the unsupported row visibly quiet: no chevron, no hover, no border
       emphasis, no error colour -- it must not look like something failed;
     * never clip. Every text run wraps; the summary may be a long seat-group
       label ("12A, 12B and 12C looks like your best fit") and still must not
       overflow a narrow card.
   ============================================================ */
.seat-advice { margin-top: 16px; }

.seat-advice-toggle {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 6px 12px;
  width: 100%;
  min-height: 48px;
  padding: 12px 16px;
  text-align: left;
  font: inherit;
  color: inherit;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.seat-advice-toggle:hover { border-color: var(--accent); background: var(--accent-soft); }
/* Keyboard focus is never invisible: the browser's own ring is replaced, not
   removed, and it is the same treatment the rest of Aster's controls use. */
.seat-advice-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.seat-advice-label {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-muted); white-space: nowrap;
}
.seat-advice-summary {
  font-size: 13.5px; color: var(--text); line-height: 1.55; min-width: 0; overflow-wrap: anywhere;
}
/* The written state indicator ("View why" -> "Hide why"). The chevron below is
   a second, redundant cue -- never the only one. */
.seat-advice-action { font-size: 12.5px; font-weight: 600; color: var(--accent); white-space: nowrap; }
.seat-advice-chevron {
  font-size: 18px; line-height: 1; color: var(--text-muted);
  transform: rotate(90deg); transition: transform 0.15s ease;
}
.seat-advice-open .seat-advice-chevron { transform: rotate(-90deg); }

/* The panel keeps its own card styling; the row above it is the affordance. */
.seat-advice-panel .seat-intel-panel { margin-top: 10px; }

/* Unsupported: same shape, no affordance. Sunk surface, muted text, no chevron,
   no hover, no border highlight, and no red/amber anywhere -- a flight Aster has
   no curated layout for is not a broken flight. */
.seat-advice-static {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 6px 12px;
  padding: 12px 16px;
  background: var(--surface-sunk);
  border-radius: var(--radius-sm);
}
.seat-advice-static .seat-advice-summary { font-size: 12.5px; color: var(--text-muted); }

@media (max-width: 700px) {
  /* The label moves onto its own line so the summary keeps full width and the
     action word is never squeezed against it; the row grows taller rather than
     clipping, keeping the touch target comfortable. */
  .seat-advice-toggle {
    grid-template-columns: minmax(0, 1fr) auto auto;
    padding: 14px 14px;
  }
  .seat-advice-label { grid-column: 1 / -1; }
  .seat-advice-static { grid-template-columns: minmax(0, 1fr); }
}

/* ---- /dev/seat-intel review page only (templates/seat_intel_demo.html) ----
   Puts the preference state that produced each panel side by side with the panel
   itself, so a reviewer can see WHY a seat won. Stacks below 900px; nothing here
   is used by any public surface. */
.seat-intel-demo-case { padding: 28px 32px; margin-bottom: 22px; }
.seat-intel-demo-head h3 { font-family: var(--font-display); font-size: 19px; font-weight: 500; margin: 0; }
.seat-intel-demo-flight {
  font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-muted); margin: 6px 0 0;
}
.seat-intel-demo-blurb { font-size: 13.5px; color: var(--text-soft); line-height: 1.7; margin: 10px 0 0; max-width: 70ch; }
.seat-intel-demo-body { display: grid; grid-template-columns: minmax(0, 260px) minmax(0, 1fr); gap: 24px; margin-top: 18px; align-items: start; }
.seat-intel-demo-prefs { background: var(--surface-sunk); border-radius: var(--radius-sm); padding: 16px 18px; }
.seat-intel-demo-prefs h4 {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-muted); margin: 0 0 4px;
}
.seat-intel-demo-source { font-size: 11.5px; color: var(--text-muted); line-height: 1.5; margin: 0 0 10px; }
.seat-intel-demo-disclosure { min-width: 0; }
.seat-intel-demo-note { font-size: 11.5px; color: var(--text-muted); line-height: 1.6; margin: 10px 0 0; }
.seat-intel-demo-prefs dl { margin: 0; }
.seat-intel-demo-prefs dl > div { display: flex; justify-content: space-between; gap: 12px; padding: 4px 0; }
.seat-intel-demo-prefs dt { font-size: 12px; color: var(--text-soft); flex: 0 0 auto; }
.seat-intel-demo-prefs dd { font-size: 12px; font-weight: 600; color: var(--text); margin: 0; text-align: right; min-width: 0; overflow-wrap: anywhere; }
/* The panel is the point of the page, so it keeps its own card look but loses the
   extra top margin it would carry inside a flight result. */
.seat-intel-demo-panel .seat-intel-panel { margin-top: 0; }

@media (max-width: 900px) {
  .seat-intel-demo-body { grid-template-columns: minmax(0, 1fr); }
  .seat-intel-demo-case { padding: 22px 20px; }
}

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 700px) {
  .cabin-tabs { flex-wrap: wrap; }
  .cabin-tab { min-width: 45%; }
  .cabin-primary-card { padding: 24px 22px; }
  .cabin-overall { padding: 24px 22px; }
  .cabin-primary-top { flex-direction: column; }
  .feedback-buttons { gap: 6px; }
  .feedback-btn { font-size: 11.5px; padding: 7px 12px; }
  .steps { grid-template-columns: 1fr; gap: 28px; }
  .search-row { grid-template-columns: 1fr; }
  .field-narrow { max-width: none; }
  .hero { padding: 56px 0 44px; }
  .hero h1 { font-size: 38px; }
  .hero-lede { font-size: 19px; }
  .plan-row { flex-direction: column; }
  .plan-row .btn { width: 100%; }
  .consultant-price { font-size: 19px; }
  .consultant-summary { flex-direction: column; align-items: flex-start; }
  .segmented button { min-width: 60px; font-size: 12px; padding: 9px 6px; }
  .chat-bubble { max-width: 92%; }
  /* Mobile keeps the same one-page-scrolling rule as desktop -- no nested
     max-height/overflow override here (acceptance criterion 7: "Mobile
     retains one-page scrolling"). */
  /* Mobile responsiveness (item 13): both the conversation thread and the
     composer drop back to the full available width instead of the
     90%/1300px desktop sizing, and stay aligned with each other. The Send
     button and hint stay anchored inside the textarea's own bottom padding
     (same overlay structure as desktop, just smaller offsets) so there's
     still exactly one composer surface, not a stacked layout with extra
     wrapper height. */
  .conversation-thread { width: 100%; }
  .composer { width: 100%; margin-top: 30px; }
  .composer-input { min-height: 140px; padding: 18px 16px 78px 16px; font-size: 15.5px; }
  .composer-hint { left: 14px; bottom: 16px; font-size: 11.5px; max-width: calc(100% - 110px); }
  .composer-send { right: 14px; bottom: 14px; padding: 12px 22px; font-size: 13px; }
  .panel { padding: 26px 22px; }
  .consultant-pick { padding: 26px 24px; }
  /* Same reasoning as .conversation-thread/.composer above -- on a narrow
     viewport, main's own gutter is already the only inset these need;
     stacking the desktop `min(100% - 48px, 1600px)` formula on top of it
     would over-narrow an already-tight screen. */
  .journeys, .search-summary-bar, #editSearchMount, #askAsterMount { width: 100%; }
}
