/* ==========================================================================
   Travelfront API — search console
   Plain CSS. No build step. Light and dark from one set of tokens via
   light-dark(), following the system unless the topbar toggle pins a theme.

   Laid out the way a travel site is laid out, and for the same reason: the
   SEARCH (from / to / when / who) is one band at the top and only runs when
   asked, while the FILTERS sit beside the results and apply on the spot. Those
   are two different kinds of action and the old single sidebar made them look
   like one, so every filter tweak read as a brand-new search.

   The visual language is deliberately quiet — neutral surfaces, one ink colour
   for primary actions, one accent for focus and selection — so that the colours
   that DO appear carry meaning: provider hues, and the green / amber / red that
   separate a bookable price from a browse price and a failure from an answer.
   ========================================================================== */

@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(./fonts/geist-latin-wght-normal.woff2) format("woff2-variations"),
       url(./fonts/geist-latin-wght-normal.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(./fonts/geist-latin-ext-wght-normal.woff2) format("woff2-variations"),
       url(./fonts/geist-latin-ext-wght-normal.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(./fonts/geist-mono-latin-wght-normal.woff2) format("woff2-variations"),
       url(./fonts/geist-mono-latin-wght-normal.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(./fonts/geist-mono-latin-ext-wght-normal.woff2) format("woff2-variations"),
       url(./fonts/geist-mono-latin-ext-wght-normal.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  color-scheme: light dark;

  --font: "Geist", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
          Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: "Geist Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
          "Liberation Mono", monospace;

  --bg:          light-dark(#f6f6f4, #09090b);
  --surface:     light-dark(#ffffff, #111113);
  --surface-2:   light-dark(#f3f3f1, #18181b);
  --surface-3:   light-dark(#e9e9e6, #232327);
  --line:        light-dark(rgb(17 17 20 / 0.08), rgb(255 255 255 / 0.08));
  --line-2:      light-dark(rgb(17 17 20 / 0.14), rgb(255 255 255 / 0.14));
  --text:        light-dark(#111114, #f4f4f5);
  --text-2:      light-dark(#5b5c63, #a1a1aa);
  /* Tertiary text still carries hints and counts people read, so it holds 4.5:1 on
     every surface it lands on, accent-soft included. */
  --text-3:      light-dark(#696a71, #909099);

  /* Primary actions are ink, not a hue: black on light, white on dark. */
  --ink:         light-dark(#111114, #f4f4f5);
  --ink-fg:      light-dark(#ffffff, #09090b);

  --accent:      light-dark(#3354ff, #8095ff);
  --accent-soft: light-dark(#edf0ff, #1a2042);
  --brand-1:     #4f6bff;
  --brand-2:     #00b3c7;

  --ok:          light-dark(#0f7a3d, #4ade80);
  --ok-soft:     light-dark(#e6f6ec, #0f2a1b);
  --ok-line:     light-dark(#b9e3c8, #1d4a30);
  --warn:        light-dark(#9a5800, #fbbf24);
  --warn-soft:   light-dark(#fdf3e0, #2a2110);
  --warn-line:   light-dark(#f1d39d, #4f3b14);
  --err:         light-dark(#c4281c, #ff7b72);
  --err-soft:    light-dark(#fdeceb, #2c1412);
  --err-line:    light-dark(#f3c4bf, #5c2622);

  /* One hue per provider, so a mixed result list is separable at a glance. Same
     soft-background / strong-ink shape as the semantic pairs above. */
  --prov-tripx:    light-dark(#2747a8, #93b0ff);  --prov-tripx-soft:    light-dark(#e6ecfc, #18233f);
  --prov-sembo:    light-dark(#0d6e59, #5fd6b6);  --prov-sembo-soft:    light-dark(#dcf2eb, #10302a);
  --prov-sunweb:   light-dark(#8a5a09, #e9b867);  --prov-sunweb-soft:   light-dark(#fbefd6, #33270f);
  --prov-nazar:    light-dark(#5b3aa6, #bba0f3);  --prov-nazar-soft:    light-dark(#eee6fb, #261d40);
  --prov-solresor: light-dark(#a32a4a, #f397ad);  --prov-solresor-soft: light-dark(#fbe3e9, #3a1823);
  --prov-ving:     light-dark(#b34700, #ffb27a);  --prov-ving-soft:     light-dark(#ffead9, #3a2212);
  --prov-tui:      light-dark(#0b6a94, #6ccbf2);  --prov-tui-soft:      light-dark(#d8eef8, #10303e);

  --shadow-1: 0 1px 2px light-dark(rgb(16 18 30 / 0.05), rgb(0 0 0 / 0.5)),
              0 1px 1px light-dark(rgb(16 18 30 / 0.03), rgb(0 0 0 / 0.3));
  --shadow-2: 0 10px 30px -12px light-dark(rgb(16 18 30 / 0.16), rgb(0 0 0 / 0.7)),
              0 2px 6px light-dark(rgb(16 18 30 / 0.05), rgb(0 0 0 / 0.4));
  --shadow-pop: 0 28px 70px -16px light-dark(rgb(16 18 30 / 0.28), rgb(0 0 0 / 0.8)),
                0 4px 16px light-dark(rgb(16 18 30 / 0.08), rgb(0 0 0 / 0.5));

  --r-xs: 7px;
  --r-sm: 10px;
  --r:    14px;
  --r-lg: 18px;
  --r-xl: 22px;

  --ease: cubic-bezier(.2, .8, .2, 1);
  /* viewport-fit=cover lets the page run under a landscape notch; the gutter grows to
     clear it. */
  --page-pad: max(24px, env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
  --header-h: 60px;
}

:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }

* { box-sizing: border-box; }

/* The UA's `[hidden] { display: none }` loses to any author `display:` rule, and
   several blocks below are laid out with flex/grid while also being toggled by the
   `hidden` attribute. Without this they render as empty bars on first paint. */
[hidden] { display: none !important; }

/* The horizontal-overflow guard belongs on <body> ALONE. On <html> it makes the
   document element the scrollport, and every `position: sticky` on the page then stops
   pinning and scrolls away instead — measured: the topbar sat at y=-600 after a 600px
   scroll. Nothing errors and nothing overflows, so the symptom reads as "the design
   just isn't sticky", which is why it survived. */
html { max-width: 100%; background: var(--bg); }
body { max-width: 100%; overflow-x: hidden; }

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font);
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--text);
  background: transparent;
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: "ss01" 0;
}

/* A faint wash of the brand colours at the top of the page. Fixed and behind
   everything, so it costs nothing on scroll and never sits on top of content. */
body::before {
  content: "";
  position: fixed;
  inset: 0 0 auto 0;
  height: 560px;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(900px 420px at 8% -12%, color-mix(in srgb, var(--brand-1) 11%, transparent), transparent 70%),
    radial-gradient(760px 380px at 96% -8%, color-mix(in srgb, var(--brand-2) 9%, transparent), transparent 70%);
}

code, kbd, pre { font-family: var(--mono); }
code { font-size: .92em; }
a { color: var(--accent); }
button, input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3 { text-wrap: balance; }
p { text-wrap: pretty; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 6px;
}

::selection { background: color-mix(in srgb, var(--accent) 22%, transparent); }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.ic {
  width: 18px;
  height: 18px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ic-sm { width: 16px; height: 16px; }
.ic-xs { width: 13px; height: 13px; stroke-width: 2; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.hint {
  margin: 6px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-3);
}
.hint.pad { padding: 18px 6px; margin: 0; display: flex; align-items: center; gap: 8px; }
.hint code { color: var(--text-2); }
.err-text { color: var(--err); }

kbd {
  display: inline-block;
  min-width: 20px;
  padding: 0 6px;
  font-size: 11.5px;
  line-height: 18px;
  text-align: center;
  color: var(--text-2);
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-bottom-width: 2px;
  border-radius: 6px;
}

.spin {
  display: inline-block;
  width: 13px;
  height: 13px;
  flex: none;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  opacity: .75;
  vertical-align: -2px;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ================================================================ buttons == */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 38px;
  padding: 0 14px;
  font-size: 13.5px;
  font-weight: 550;
  line-height: 1;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background-color .15s var(--ease), border-color .15s var(--ease),
              color .15s var(--ease), transform .15s var(--ease), opacity .15s var(--ease);
}
.btn:hover { background: var(--surface-2); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; transform: none; }

.btn-sm { height: 32px; padding: 0 11px; font-size: 12.5px; border-radius: 9px; gap: 6px; }
.btn-quiet { background: transparent; border-color: transparent; color: var(--text-2); }
.btn-quiet:hover { background: var(--surface-2); color: var(--text); }
.btn-ink { background: var(--ink); color: var(--ink-fg); border-color: var(--ink); }
.btn-ink:hover { background: var(--ink); opacity: .88; }
.btn-block { width: 100%; height: 46px; font-size: 14.5px; border-radius: 12px; }

.btn.copied { color: var(--ok); }
.btn.copy-failed { color: var(--warn); }

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 36px;
  height: 36px;
  padding: 0 9px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-2);
  text-decoration: none;
  background: transparent;
  border: 0;
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background-color .15s var(--ease), color .15s var(--ease);
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); }

.badge-count {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  font-size: 11px;
  font-weight: 650;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--ink-fg);
  background: var(--accent);
  border-radius: 999px;
}

/* ================================================================= topbar == */

.topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  -webkit-backdrop-filter: saturate(1.6) blur(16px);
  backdrop-filter: saturate(1.6) blur(16px);
  border-bottom: 1px solid var(--line);
}

.topbar-in {
  max-width: 1480px;
  margin: 0 auto;
  height: 60px;
  padding: 0 var(--page-pad);
  display: flex;
  align-items: center;
  gap: 14px;
}

.brand { display: flex; align-items: center; gap: 11px; min-width: 0; flex: none; }

.brand-mark {
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  flex: none;
  color: #fff;
  border-radius: 10px;
  background: linear-gradient(135deg, var(--brand-1), var(--brand-2));
  box-shadow: 0 6px 16px -6px color-mix(in srgb, var(--brand-1) 70%, transparent),
              inset 0 1px 0 rgb(255 255 255 / .25);
}
.brand-mark .ic { width: 17px; height: 17px; fill: #fff; stroke: none; }

.brand-text { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.brand-text strong { font-size: 14.5px; font-weight: 650; letter-spacing: -.015em; }
.brand-sub { font-size: 12px; color: var(--text-3); }

/* Shown once the search bar has scrolled away. */
.top-summary {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  max-width: 560px;
  height: 38px;
  margin: 0 auto;
  padding: 0 16px 0 12px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: var(--shadow-1);
  cursor: pointer;
  animation: rise .22s var(--ease);
}
.top-summary .ic { color: var(--text-3); }
.top-summary:hover { box-shadow: var(--shadow-2); }
.top-summary-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 4px; min-width: 0; }

.api-wrap { position: relative; min-width: 0; margin-right: 4px; }

.api-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 300px;
  height: 34px;
  padding: 0 11px 0 12px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-2);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  transition: background-color .15s var(--ease), border-color .15s var(--ease);
}
.api-chip:hover, .api-chip[aria-expanded="true"] { border-color: var(--line-2); color: var(--text); }
.api-chip .ic { color: var(--text-3); }
.api-chip-url { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

.dot {
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--text-3);
}
.dot[data-state="ok"] {
  background: var(--ok);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok) 22%, transparent);
}
.dot[data-state="down"] {
  background: var(--err);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--err) 22%, transparent);
}
.dot[data-state="locked"] {
  background: var(--warn);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--warn) 22%, transparent);
}
.dot[data-state="checking"] { background: var(--warn); animation: blink 1s ease-in-out infinite; }
@keyframes blink { 50% { opacity: .35; } }

.api-editor {
  position: absolute;
  right: 0;
  top: calc(100% + 10px);
  z-index: 80;
  width: 400px;
  max-width: calc(100vw - 24px);
  display: grid;
  gap: 10px;
  padding: 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-pop);
  animation: pop-in .18s var(--ease);
  font-family: var(--font);
}
.api-field { display: grid; gap: 8px; }
.api-field .pop-label { margin: 0; }
.api-field + .api-field { margin-top: 4px; }
.api-row { display: flex; gap: 8px; }
.api-row input { flex: 1; min-width: 0; font-family: var(--mono); font-size: 12.5px; }
.api-key { font-family: var(--mono); font-size: 12.5px; }
.api-editor .hint { margin: 0; }
.api-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.api-foot .hint { flex: 1; }
.api-foot code { white-space: nowrap; }

/* ============================================================ the search bar == */

.searchbar { position: relative; }

.sb-in {
  max-width: 1480px;
  margin: 0 auto;
  padding: 22px var(--page-pad) 10px;
}

/* NOTE: nothing from .searchbar down to a .pop may set transform, filter,
   backdrop-filter or contain. Any of them makes that ancestor the containing block
   for `position: fixed`, and on a phone every popover is a fixed bottom sheet. */
.sb {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1.3fr) minmax(0, 1.2fr) minmax(0, .95fr) auto;
  align-items: stretch;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-2);
  transition: background-color .2s var(--ease);
}
.sb.has-open { background: var(--surface-2); }

.sb-cell {
  position: relative;
  min-width: 0;
  border-radius: 16px;
  transition: background-color .15s var(--ease), box-shadow .15s var(--ease);
}
.sb-cell:not(.sb-actions):hover { background: var(--surface-2); }
.sb.has-open .sb-cell:not(.sb-actions):hover { background: color-mix(in srgb, var(--surface-3) 70%, transparent); }
.sb-cell.open, .sb.has-open .sb-cell.open:hover { background: var(--surface); box-shadow: var(--shadow-2); }

/* Hairline dividers that step aside for a hovered or open cell, so the highlight reads
   as one shape rather than a box with a line through its edge. */
.sb-cell + .sb-cell:not(.sb-actions)::before {
  content: "";
  position: absolute;
  left: 0;
  top: 16px;
  bottom: 16px;
  width: 1px;
  background: var(--line-2);
  transition: opacity .15s var(--ease);
}
.sb-cell:hover::before, .sb-cell:hover + .sb-cell::before,
.sb-cell.open::before, .sb-cell.open + .sb-cell::before { opacity: 0; }

.sb-btn {
  display: grid;
  align-content: center;
  gap: 2px;
  width: 100%;
  height: 100%;
  min-height: 60px;
  padding: 10px 20px;
  text-align: left;
  background: transparent;
  border: 0;
  border-radius: 16px;
  cursor: pointer;
}

.sb-label {
  display: block;
  font-size: 12px;
  font-weight: 650;
  letter-spacing: .01em;
  color: var(--text);
}
.sb-value {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 14.5px;
  color: var(--text-2);
}
.sb-value.empty { color: var(--text-3); }

/* The native select covers the whole cell, so a tap anywhere on it opens the picker,
   while the label sits on top of it purely as decoration. */
.sb-origin { min-height: 60px; }
.sb-origin .sb-label {
  position: absolute;
  top: 13px;
  left: 20px;
  pointer-events: none;
  z-index: 1;
}
.sb-select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 31px 40px 11px 20px;
  font-size: 14.5px;
  color: var(--text-2);
  text-overflow: ellipsis;
  background: transparent;
  border: 0;
  border-radius: 16px;
  outline: none;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.sb-select:focus-visible { box-shadow: inset 0 0 0 2px var(--accent); }
.sb-btn:focus-visible { outline-offset: -2px; }
.sb-caret { position: absolute; right: 16px; top: 50%; margin-top: -8px; color: var(--text-3); pointer-events: none; }

.sb-actions { display: flex; align-items: center; padding-left: 6px; }

.btn-go, .btn-stop {
  height: 56px;
  padding: 0 24px 0 20px;
  gap: 9px;
  font-size: 15px;
  font-weight: 600;
  border-radius: 16px;
}
.btn-go {
  color: var(--ink-fg);
  background: var(--ink);
  border: 0;
  box-shadow: 0 10px 22px -10px light-dark(rgb(17 17 20 / .55), rgb(255 255 255 / .25));
}
.btn-go:hover { background: var(--ink); opacity: .9; }
.btn-stop {
  color: var(--err);
  background: var(--err-soft);
  border: 1px solid var(--err-line);
}
.btn-stop:hover { background: var(--err-soft); filter: saturate(1.2); }
.btn-stop .ic { fill: currentColor; animation: blink 1.2s ease-in-out infinite; }

/* Phones: the folded question. Hidden everywhere else. */
.sb-summary { display: none; }

/* ============================================================== popovers == */

.pop {
  position: absolute;
  top: calc(100% + 12px);
  left: 0;
  /* Under the sticky topbar (50): a popover scrolled up slides beneath it rather than
     over the API chip. Phones raise it again, where it is a sheet above a scrim. */
  z-index: 45;
  width: 400px;
  max-width: calc(100vw - 32px);
  padding: 8px 18px 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-pop);
  cursor: default;
  animation: pop-in .18s var(--ease);
}
.pop-wide { width: 540px; }
.pop-right { left: auto; right: 0; }

@keyframes pop-in {
  from { opacity: 0; transform: translateY(-6px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

.sheet-head { display: none; }

.pop-head { display: flex; gap: 8px; align-items: center; padding-top: 8px; }
.pop-sub { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.pop-note { margin-left: auto; font-size: 12.5px; color: var(--text-3); white-space: nowrap; }

.pop-section { padding: 14px 0; }
.pop-section + .pop-section { border-top: 1px solid var(--line); }

.pop-label {
  display: block;
  margin: 0 0 10px;
  font-size: 12.5px;
  font-weight: 650;
  color: var(--text);
}

.pop-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.pop-foot .hint { flex: 1; margin: 0; }

.pop-scrim {
  position: fixed;
  inset: 0;
  z-index: 55;
  background: rgb(0 0 0 / .32);
  animation: fade .2s var(--ease);
}
@keyframes fade { from { opacity: 0; } }

/* ============================================================ form atoms == */

.field { display: grid; gap: 6px; min-width: 0; }
.field > span { font-size: 12.5px; font-weight: 500; color: var(--text-2); }

input[type="text"], input[type="url"], input[type="number"], input[type="date"],
input[type="search"], input[type="password"], select {
  width: 100%;
  min-width: 0;
  height: 40px;
  padding: 0 12px;
  font-size: 14px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  outline: none;
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
select:not(.sb-select) {
  padding-right: 32px;
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238b8c93' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  cursor: pointer;
}
input:focus-visible, select:not(.sb-select):focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
  outline: none;
}
input::placeholder { color: var(--text-3); }

/* Safari renders a date input at its own intrinsic width and ignores `width:100%`
   unless the field is told it may shrink. Two of these sit in a 1fr 1fr grid. */
input[type="date"] { min-width: 0; -webkit-appearance: none; appearance: none; }
input[type="date"]::-webkit-date-and-time-value { text-align: left; }

.row.two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px; }
.row + .hint, .row + .row { margin-top: 10px; }
.nights-custom { margin-top: 12px; }

.select-sm { height: 34px; font-size: 13px; width: auto; max-width: 60%; }

.search-field {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  min-width: 0;
  height: 42px;
  padding: 0 12px;
  color: var(--text-3);
  background: var(--surface-2);
  border: 1px solid transparent;
  border-radius: 12px;
  transition: background-color .15s var(--ease), border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.search-field:focus-within {
  background: var(--surface);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.search-field input {
  flex: 1;
  height: 100%;
  padding: 0;
  background: transparent;
  border: 0;
  box-shadow: none !important;
}
.search-field input::-webkit-search-cancel-button { cursor: pointer; }

/* ------------------------------------------------------- segmented ctrl -- */

.seg {
  display: inline-flex;
  flex: none;
  padding: 3px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 12px;
}
.seg button {
  height: 30px;
  padding: 0 13px;
  font-size: 13px;
  font-weight: 550;
  color: var(--text-2);
  background: transparent;
  border: 0;
  border-radius: 9px;
  cursor: pointer;
  transition: background-color .15s var(--ease), color .15s var(--ease), box-shadow .15s var(--ease);
}
.seg button:hover { color: var(--text); }
.seg button.on { color: var(--text); background: var(--surface); box-shadow: var(--shadow-1), 0 0 0 1px var(--line); }

/* ------------------------------------------------------------------ chips -- */

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chips-quick { margin-bottom: 12px; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 32px;
  padding: 0 12px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: 999px;
  cursor: pointer;
  transition: background-color .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.chip:hover { background: var(--surface-2); }
.chip .n {
  font-size: 12px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--text-3);
}
.chip.on { color: var(--ink-fg); background: var(--ink); border-color: var(--ink); }
.chip.on .n { color: color-mix(in srgb, var(--ink-fg) 65%, transparent); }
/* A count of zero is a real answer ("we looked, there are none"), so the option stays
   clickable and legible rather than being hidden — hiding it is indistinguishable
   from never having offered it. */
.chip.zero { color: var(--text-3); border-style: dashed; }

/* ----------------------------------------------------- destination picker -- */

.dest-list {
  max-height: 340px;
  margin: 10px -10px 0;
  padding: 0 10px 4px;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--line-2) transparent;
}

.dest-group {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 12px 8px 6px;
  font-size: 11.5px;
  font-weight: 650;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--text-3);
  background: var(--surface);
}

.dest-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px;
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background-color .12s var(--ease);
}
.dest-row:hover { background: var(--surface-2); }
.dest-row input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.dest-row .box { flex: none; }
.dest-row .nm { flex: 0 1 auto; min-width: 0; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dest-row .code {
  flex: none;
  padding: 2px 6px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-2);
  background: var(--surface-2);
  border-radius: 6px;
}
.dest-row:hover .code { background: var(--surface-3); }
.dest-row .ct { flex: none; margin-left: auto; font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Shared custom checkbox: the real input stays in the DOM for keyboard and state. */
.box {
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--ink-fg);
  background: var(--surface);
  /* 3:1 against the surface: an unchecked box has to be visible as a control. */
  border: 1.5px solid color-mix(in srgb, var(--text-3) 80%, var(--surface));
  border-radius: 6px;
  transition: background-color .12s var(--ease), border-color .12s var(--ease);
}
.box .ic { width: 12px; height: 12px; stroke-width: 3; opacity: 0; transform: scale(.6); transition: opacity .12s var(--ease), transform .12s var(--ease); }
input:checked + .box { background: var(--ink); border-color: var(--ink); }
input:checked + .box .ic { opacity: 1; transform: none; }
input:focus-visible + .box { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ------------------------------------------------------------------ party -- */

.party { display: grid; gap: 4px; }

.stepper {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 36px 40px 36px;
  align-items: center;
  padding: 8px 0;
}
.stepper + .stepper { border-top: 1px solid var(--line); }
.stepper-label { font-size: 14.5px; font-weight: 550; }
.stepper-label small { display: block; font-size: 12.5px; font-weight: 400; color: var(--text-3); }
.stepper output {
  text-align: center;
  font-size: 15px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.stepper button {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: 50%;
  cursor: pointer;
  transition: border-color .15s var(--ease), background-color .15s var(--ease);
}
.stepper button:hover { border-color: var(--text-2); }

.child-ages {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  gap: 8px;
  margin-top: 6px;
}
.child-ages:empty { display: none; }
.child-age { display: grid; gap: 4px; }
.child-age span { font-size: 12px; color: var(--text-2); }
.child-age input { height: 38px; }

/* ================================================================ layout == */

.layout {
  max-width: 1480px;
  margin: 0 auto;
  padding: 18px var(--page-pad) 96px;
  display: grid;
  grid-template-columns: 272px minmax(0, 1fr);
  gap: 36px;
  align-items: start;
}

/* ================================================================== rail == */

.rail {
  position: sticky;
  top: calc(var(--header-h) + 16px);
  max-height: calc(100vh - var(--header-h) - 32px);
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.rail-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0 10px;
}
.rail-head h2 { margin: 0 auto 0 0; font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
.rail-close { display: none; }

.rail-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  margin-right: -10px;
  padding-right: 10px;
  scrollbar-width: thin;
  scrollbar-color: var(--line-2) transparent;
}
.rail-foot { display: none; }

.fgroup { padding: 18px 0; border-top: 1px solid var(--line); }
.fgroup:first-child { border-top: 0; padding-top: 8px; }
.fgroup h3 {
  margin: 0 0 12px;
  font-size: 13px;
  font-weight: 650;
}
.fnote { font-weight: 400; color: var(--text-3); margin-left: 4px; }
.fnote-filtered { font-style: italic; }

.price-row {
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 12px;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.price-row:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent); }
.price-row input { flex: 1; height: 100%; padding: 0; border: 0; background: transparent; box-shadow: none !important; }
.price-row .cur { font-size: 12px; font-weight: 650; color: var(--text-3); }

.checks { display: grid; gap: 1px; margin: 0 -8px; }
.checks label {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 11px;
  padding: 7px 8px;
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background-color .12s var(--ease);
}
.checks label:hover { background: var(--surface-2); }
.checks input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.checks .bl { font-size: 14px; }
.checks .bl small {
  margin-left: 7px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-3);
}
.checks .fc { font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }

.score-row { margin-top: 14px; }

.switch {
  display: flex;
  align-items: center;
  gap: 11px;
  font-size: 14px;
  cursor: pointer;
  user-select: none;
}
.switch input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.switch .track {
  position: relative;
  width: 36px;
  height: 21px;
  flex: none;
  background: color-mix(in srgb, var(--text-3) 70%, var(--surface));
  border-radius: 999px;
  transition: background-color .2s var(--ease);
}
.switch .track::after {
  content: "";
  position: absolute;
  top: 2.5px;
  left: 2.5px;
  width: 16px;
  height: 16px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgb(0 0 0 / .25);
  transition: transform .2s var(--ease);
}
.switch input:checked + .track { background: var(--accent); }
.switch input:checked + .track::after { transform: translateX(15px); }
.switch input:focus-visible + .track { outline: 2px solid var(--accent); outline-offset: 2px; }

.dev {
  margin: 8px 0 4px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
}
.dev summary {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 12px 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
  list-style: none;
  cursor: pointer;
}
.dev summary::-webkit-details-marker { display: none; }
.dev summary:hover { color: var(--text); }
.dev-caret { margin-left: auto; transition: transform .2s var(--ease); }
.dev[open] .dev-caret { transform: rotate(180deg); }
.dev-body { display: grid; gap: 12px; padding: 2px 14px 14px; }
.dev-body .hint { margin-top: -6px; }
.dev-body .row + .row { margin-top: 0; }
.dev-body .btn { justify-self: start; }

/* =============================================================== results == */

.results { display: flex; flex-direction: column; gap: 14px; min-width: 0; }

/* --------------------------------------------------------------- hero ---- */

.hero { padding: 40px 4px 24px; animation: rise .4s var(--ease); }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 0;
  padding: 5px 13px 5px 10px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-2);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: var(--shadow-1);
}
.eyebrow-dot {
  position: relative;
  width: 8px;
  height: 8px;
  background: var(--ok);
  border-radius: 50%;
}
.eyebrow-dot::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 2px solid var(--ok);
  opacity: 0;
  animation: ping 2.4s var(--ease) infinite;
}
@keyframes ping {
  0% { transform: scale(.5); opacity: .6; }
  80%, 100% { transform: scale(1.4); opacity: 0; }
}

.hero h1 {
  margin: 20px 0 16px;
  font-size: clamp(38px, 5.2vw, 64px);
  font-weight: 650;
  line-height: 1.02;
  letter-spacing: -.045em;
}
.grad {
  background: linear-gradient(100deg, var(--brand-1) 10%, var(--brand-2) 90%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.lede { max-width: 620px; margin: 0; font-size: 17px; line-height: 1.6; color: var(--text-2); }
.lede strong { color: var(--text); font-weight: 600; }

.hero-try { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-top: 28px; }
.hero-try-label { font-size: 13px; font-weight: 600; color: var(--text-3); margin-right: 2px; }
.chip-example { height: 36px; padding: 0 14px; background: var(--surface); box-shadow: var(--shadow-1); border-color: var(--line); }
.chip-example .ic { color: var(--text-3); transition: transform .2s var(--ease), color .2s var(--ease); }
.chip-example:hover { background: var(--surface); border-color: var(--line-2); box-shadow: var(--shadow-2); }
.chip-example:hover .ic { transform: translateX(2px); color: var(--text); }

.hero-provs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-top: 40px;
}
.hero-provs .hint { grid-column: 1 / -1; }
.hp {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: "dot name tag" "dot id tag";
  align-items: center;
  column-gap: 11px;
  padding: 13px 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow-1);
}
.hp-dot {
  grid-area: dot;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--pc);
  box-shadow: 0 0 0 4px var(--pc-soft);
}
.hp-name { grid-area: name; font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hp-id { grid-area: id; font-family: var(--mono); font-size: 11.5px; color: var(--text-3); }
.hp-tag {
  grid-area: tag;
  padding: 3px 8px;
  font-size: 11px;
  font-weight: 550;
  color: var(--text-2);
  white-space: nowrap;
  background: var(--surface-2);
  border-radius: 999px;
}
.hero-foot { margin-top: 26px; }

/* ------------------------------------------------------- results header -- */

.res-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 20px;
  padding-top: 4px;
}
.res-count { min-width: 0; }
.big {
  margin: 0;
  font-size: 28px;
  font-weight: 650;
  line-height: 1.1;
  letter-spacing: -.03em;
}
.big-n { font-variant-numeric: tabular-nums; }
.sub { margin: 5px 0 0; font-size: 13.5px; color: var(--text-2); }

.res-tools { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }

.sortsel {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 38px;
  padding: 0 0 0 12px;
  color: var(--text-2);
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.sortsel:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent); }
.sortsel select {
  height: 100%;
  width: auto;
  padding: 0 32px 0 0;
  font-size: 13.5px;
  font-weight: 550;
  color: var(--text);
  background: none;
  border: 0;
  box-shadow: none !important;
}
.sortsel-caret { position: absolute; right: 11px; pointer-events: none; color: var(--text-3); }

/* Below the width where the rail turns into a sheet. */
.rail-toggle { display: none; }
.rail-toggle .badge-count { margin-left: 2px; }

/* -------------------------------------------------- active filter chips -- */

.active-filters { display: flex; flex-wrap: wrap; gap: 6px; }
.active-filters:empty { display: none; }
.chip-active {
  height: 30px;
  padding: 0 6px 0 11px;
  font-size: 12.5px;
  background: var(--accent-soft);
  border-color: transparent;
}
.chip-active:hover { background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
.chip-active .k { color: var(--text-3); font-weight: 450; }
.chip-active .txt { font-weight: 550; }
.chip-active .x {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  color: var(--text-2);
  border-radius: 50%;
  transition: background-color .15s var(--ease);
}
.chip-active:hover .x { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--text); }
.chip-clear { height: 30px; font-size: 12.5px; color: var(--text-2); background: transparent; border-color: transparent; }
.chip-clear:hover { background: var(--surface-2); color: var(--text); }

/* ------------------------------------------------------------- run panel -- */

.run {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}

.progress-bar { height: 3px; background: var(--surface-2); overflow: hidden; transition: height .3s var(--ease); }
.progress:not(.running) .progress-bar { height: 0; }
.progress-fill {
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--brand-1), var(--brand-2));
  transition: width .35s var(--ease);
}
.progress-fill.indet { width: 35% !important; animation: indet 1.2s var(--ease) infinite; }
@keyframes indet { from { transform: translateX(-100%); } to { transform: translateX(300%); } }

.progress-text {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 18px;
  padding: 12px 16px;
  font-size: 13px;
  color: var(--text-2);
}
.progress-row { display: flex; align-items: center; gap: 10px; }
.progress-row .progress-text { flex: 1; min-width: 0; }
.run-stop {
  display: none;
  flex: none;
  align-items: center;
  gap: 6px;
  height: 34px;
  margin-right: 12px;
  padding: 0 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--err);
  background: var(--err-soft);
  border: 1px solid var(--err-line);
  border-radius: 999px;
  cursor: pointer;
}
.run-stop .ic { fill: currentColor; }
.run-status { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; color: var(--text); }
.run-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-3); }
.run-ok .run-dot { background: var(--ok); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok) 20%, transparent); }
.run-warn { color: var(--warn); }
.run-warn .run-dot { background: var(--warn); }
.run-err { color: var(--err); }
.run-err .run-dot { background: var(--err); }
.pm { display: inline-flex; align-items: baseline; gap: 5px; }
.pm-k { color: var(--text-3); }
.pm b { font-weight: 550; color: var(--text); font-variant-numeric: tabular-nums; }

/* The run's own vital signs. Not decoration: `ranked by browse prices` and a short
   `bookable prices` count say the page may not be what it looks like, so they sit with
   the result count rather than in a drawer. Hairlines come from each tile's own right
   and bottom border, clipped at the panel's edge, so a wrapped row still lines up. */
.res-diag {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -1px -1px 0;
  border-top: 1px solid var(--line);
}
.stat {
  display: grid;
  align-content: start;
  gap: 3px;
  flex: 1 1 150px;
  min-width: 0;
  padding: 12px 16px;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.stat-k { font-size: 12px; color: var(--text-3); line-height: 1.35; }
.stat-v { font-size: 14.5px; font-weight: 600; font-variant-numeric: tabular-nums; }
.stat.warn { background: var(--warn-soft); }
.stat.warn .stat-k { color: color-mix(in srgb, var(--warn) 80%, var(--text-3)); }
.stat.warn .stat-v { color: var(--warn); }
.stat-x { display: grid; gap: 5px; margin-top: 4px; }
.stagebar { display: flex; gap: 2px; width: 100%; max-width: 200px; height: 5px; border-radius: 999px; overflow: hidden; background: var(--surface-2); }
.stagebar .sg { display: block; min-width: 3px; }
.sg-search  { background: var(--brand-1); }
.sg-pricing { background: #a06cf6; }
.sg-flights { background: var(--brand-2); }
.stagekey { font-size: 11.5px; color: var(--text-3); }

.prov-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 12px 16px;
  border-top: 1px solid var(--line);
}
.prov-wait { display: inline-flex; align-items: center; gap: 9px; font-size: 13px; color: var(--text-2); }

.pchip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 30px;
  padding: 0 11px;
  font-size: 12.5px;
  color: var(--text-2);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  transition: background-color .15s var(--ease), border-color .15s var(--ease);
}
.pchip:hover { border-color: var(--line-2); background: var(--surface-2); }
.pchip-dot { width: 7px; height: 7px; flex: none; border-radius: 50%; background: var(--text-3); }
.pchip-id { font-family: var(--mono); font-size: 12px; font-weight: 600; color: var(--text); }
.pchip-meta { font-variant-numeric: tabular-nums; }
.pchip-ok .pchip-dot { background: var(--ok); }
.pchip-warn { background: var(--warn-soft); border-color: var(--warn-line); color: var(--warn); }
.pchip-warn .pchip-dot { background: var(--warn); }
.pchip-err { background: var(--err-soft); border-color: var(--err-line); color: var(--err); }
.pchip-err .pchip-dot { background: var(--err); }
.pchip-err .pchip-id { color: var(--err); }
.pchip-skip { border-style: dashed; }
.pchip-skip .pchip-dot { background: transparent; border: 1.5px solid var(--text-3); }
.pchip-run .spin { width: 10px; height: 10px; border-width: 1.5px; }
.pchip-link { margin-left: auto; border-color: transparent; background: transparent; color: var(--text-2); font-weight: 550; }
.pchip-link:hover { color: var(--text); }

/* ----------------------------------------------------------------- alerts -- */

.alerts { display: grid; gap: 10px; }
.alerts:empty { display: none; }

.alert {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 12px;
  padding: 14px 16px;
  font-size: 13.5px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r);
  animation: rise .25s var(--ease);
}
.alert.err  { background: var(--err-soft);  border-color: var(--err-line); }
.alert.warn { background: var(--warn-soft); border-color: var(--warn-line); }
.a-icon { display: grid; place-items: start; padding-top: 1px; color: var(--text-2); }
.alert.err .a-icon { color: var(--err); }
.alert.warn .a-icon { color: var(--warn); }
.a-title { font-size: 14px; font-weight: 600; line-height: 1.4; }
.alert.err .a-title { color: var(--err); }
.a-detail { margin-top: 2px; color: var(--text-2); }
.a-foot { margin-top: 10px; }

.a-rows { display: grid; gap: 4px; margin: 10px 0 0; padding: 0; list-style: none; }
.a-row {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  align-items: center;
  gap: 9px;
  padding: 6px 8px;
  background: color-mix(in srgb, var(--surface) 60%, transparent);
  border-radius: var(--r-sm);
}
.a-row-kind { font-family: var(--mono); font-size: 11.5px; font-weight: 600; color: var(--err); }
.alert.warn .a-row-kind { color: var(--warn); }
.a-row-msg {
  min-width: 0;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-2);
  overflow-wrap: anywhere;
}
.a-suggest { margin-top: 8px; }
.a-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  padding: 0;
  font-size: 13px;
  font-weight: 600;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}
.alert.err .a-link { color: var(--err); }
.a-link:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ----------------------------------------------------------------- offers -- */

/* Provider hue, set once per element and read by whatever shows it. */
.prov-tripx,    .prov-edge-tripx    { --pc: var(--prov-tripx);    --pc-soft: var(--prov-tripx-soft); }
.prov-sembo,    .prov-edge-sembo    { --pc: var(--prov-sembo);    --pc-soft: var(--prov-sembo-soft); }
.prov-sunweb,   .prov-edge-sunweb   { --pc: var(--prov-sunweb);   --pc-soft: var(--prov-sunweb-soft); }
.prov-nazar,    .prov-edge-nazar    { --pc: var(--prov-nazar);    --pc-soft: var(--prov-nazar-soft); }
.prov-solresor, .prov-edge-solresor { --pc: var(--prov-solresor); --pc-soft: var(--prov-solresor-soft); }
.prov-ving,     .prov-edge-ving     { --pc: var(--prov-ving);     --pc-soft: var(--prov-ving-soft); }
.prov-tui,      .prov-edge-tui      { --pc: var(--prov-tui);      --pc-soft: var(--prov-tui-soft); }
.prov-unknown,  .prov-edge-unknown  { --pc: var(--text-2);        --pc-soft: var(--surface-2); }

.offer-list, .group-list { display: grid; gap: 14px; }

.offer {
  position: relative;
  display: grid;
  overflow: hidden;
  grid-template-columns: 264px minmax(0, 1fr) 216px;
  gap: 20px;
  padding: 10px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-1);
  transition: box-shadow .2s var(--ease), border-color .2s var(--ease);
  animation: rise .3s var(--ease) both;
}
.offer:hover { box-shadow: var(--shadow-2); border-color: var(--line-2); }

/* ---- image ---- */

.offer-img {
  position: relative;
  min-height: 208px;
  overflow: hidden;
  background: var(--surface-2);
  border-radius: var(--r);
  isolation: isolate;
}
.offer-img img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity .35s var(--ease), transform .6s var(--ease);
}
.offer-img.loaded img { opacity: 1; }
.offer:hover .offer-img.loaded img { transform: scale(1.03); }
.offer-img:not(.loaded):not(.empty)::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 20%, color-mix(in srgb, var(--surface) 55%, transparent) 50%, transparent 80%);
  background-size: 200% 100%;
  animation: shimmer 1.4s linear infinite;
}
.offer-img-none {
  position: absolute;
  inset: 0;
  display: none;
  place-content: center;
  justify-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--text-3);
}
.offer-img.empty .offer-img-none { display: grid; }
.offer-img.empty .offer-img-none .ic { width: 22px; height: 22px; stroke-width: 1.5; }

.offer-gallery-controls {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 8px;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  pointer-events: none;
}
.offer-gallery-button {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  color: #111;
  background: rgb(255 255 255 / .92);
  border: 0;
  border-radius: 50%;
  box-shadow: 0 2px 8px rgb(0 0 0 / .2);
  cursor: pointer;
  pointer-events: auto;
  opacity: 0;
  transform: scale(.9);
  transition: opacity .2s var(--ease), transform .2s var(--ease);
}
.offer-gallery-button .ic { width: 16px; height: 16px; stroke-width: 2.2; }
.offer:hover .offer-gallery-button, .offer-gallery-button:focus-visible { opacity: 1; transform: none; }
.offer-image-count {
  padding: 2px 8px;
  font-size: 11.5px;
  font-weight: 550;
  font-variant-numeric: tabular-nums;
  color: #fff;
  background: rgb(0 0 0 / .5);
  border-radius: 999px;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
/* Touch screens have no hover, so the arrows are simply always there. */
@media (hover: none) {
  .offer-gallery-button { opacity: 1; transform: none; }
}

/* ---- body ---- */

.offer-main {
  display: flex;
  flex-direction: column;
  gap: 9px;
  min-width: 0;
  padding: 8px 0;
}

.offer-kicker { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; }

/* Which provider a row came from. Monospaced because the text is the literal
   ProviderId an operator greps for; the colour is a second channel, never the only one. */
.prov {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 22px;
  padding: 0 9px 0 8px;
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--pc);
  background: var(--pc-soft);
  border-radius: 999px;
}
.prov::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
/* An id this console has no colour for must look unrecognised, not like a sixth brand. */
.prov-unknown { border: 1px dashed var(--line-2); }

.stars { font-size: 12.5px; letter-spacing: 1.5px; color: #f2a516; }
.stars .half { opacity: .4; }

.score { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--text-3); }
.score b {
  display: inline-grid;
  place-items: center;
  min-width: 30px;
  height: 22px;
  padding: 0 6px;
  font-size: 12px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  background: var(--surface-3);
  border-radius: 7px 7px 7px 2px;
}
.score.good b { color: #fff; background: #0f7a3d; }
.score.mid b { color: var(--warn); background: var(--warn-soft); }

.offer-name {
  margin: 0;
  font-size: 19px;
  font-weight: 620;
  line-height: 1.25;
  letter-spacing: -.02em;
}

.offer-where, .offer-dates {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  font-size: 13.5px;
  color: var(--text-2);
}
.offer-where span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.offer-where .ic, .offer-dates .ic { color: var(--text-3); }
.offer-dates { color: var(--text); font-weight: 500; }

.tags { display: flex; flex-wrap: wrap; gap: 6px; }
.tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 24px;
  max-width: 100%;
  padding: 0 9px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-2);
  white-space: nowrap;
  background: var(--surface-2);
  border-radius: 7px;
}
.tag b { font-family: var(--mono); font-size: 11px; font-weight: 650; color: var(--text); }
.tag.strong { color: var(--text); }
.tag.direct, .tag.ok { color: var(--ok); background: var(--ok-soft); }
.tag.warn { color: var(--warn); background: var(--warn-soft); }
.tag.stops { color: var(--text); }
.tag.unknown { color: var(--text-3); background: transparent; border: 1px dashed var(--line-2); }
.tag-room { max-width: 280px; overflow: hidden; text-overflow: ellipsis; display: inline-block; line-height: 24px; }

/* ---- flight legs: a small timeline, departure and arrival either side of the line ---- */

.legs {
  display: grid;
  gap: 6px;
  margin-top: 2px;
  padding: 10px 12px;
  background: var(--surface-2);
  border-radius: 12px;
}
.leg {
  display: grid;
  grid-template-columns: 50px auto minmax(36px, 110px) auto minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  font-size: 13px;
}
.dir {
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-3);
}
.leg-end { display: inline-flex; align-items: baseline; gap: 6px; white-space: nowrap; }
.leg-end b { font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums; }
.leg-end span { font-family: var(--mono); font-size: 11.5px; color: var(--text-2); }
.leg-line { position: relative; height: 1.5px; background: var(--line-2); border-radius: 2px; }
.leg-line::before, .leg-line::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 5px;
  height: 5px;
  margin-top: -2.5px;
  border-radius: 50%;
  background: var(--text-3);
}
.leg-line::before { left: -2px; }
.leg-line::after { right: -2px; }
.leg-line.has-stops { background: repeating-linear-gradient(90deg, var(--line-2) 0 4px, transparent 4px 7px); }
.leg-line .ic {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 14px;
  height: 14px;
  padding: 0 2px;
  box-sizing: content-box;
  color: var(--text-2);
  fill: var(--text-2);
  stroke: none;
  background: var(--surface-2);
  transform: translate(-50%, -50%) rotate(45deg);
}
.leg-meta {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  min-width: 0;
  overflow: hidden;
  font-size: 12px;
  color: var(--text-3);
  white-space: nowrap;
}
.leg-meta .fno { font-family: var(--mono); font-size: 11.5px; }
.legs-none { display: flex; padding: 0; background: none; }
.legs-none .carrier { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-3); }

/* ---- price: a ticket stub, torn off along a dashed line ---- */

.offer-side {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-end;
  gap: 14px;
  min-width: 0;
  padding: 10px 8px 6px 22px;
  text-align: right;
  border-left: 1.5px dashed var(--line-2);
}
.offer-side::before, .offer-side::after {
  content: "";
  position: absolute;
  left: -10px;
  width: 18px;
  height: 18px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 50%;
}
.offer-side::before { top: -21px; }
.offer-side::after { bottom: -21px; }
.offer:hover .offer-side::before, .offer:hover .offer-side::after { border-color: var(--line-2); }

.price { display: grid; justify-items: end; gap: 2px; }
.price-from { font-size: 12px; color: var(--text-3); }
.price-pp {
  font-size: 25px;
  font-weight: 650;
  line-height: 1.1;
  letter-spacing: -.025em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.price-pp span { font-size: 13px; font-weight: 450; letter-spacing: 0; color: var(--text-3); }
.price-total { font-size: 13px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.price-total b { font-weight: 600; color: var(--text-2); }

/* A browse price and a bookable quote must never render identically: one is a dashed
   amber "this may not be the number", the other a solid green tick. */
.price-src {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 22px;
  margin-top: 8px;
  padding: 0 9px;
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--warn);
  background: var(--warn-soft);
  border: 1px dashed var(--warn-line);
  border-radius: 999px;
  cursor: help;
}
.price-src.quoted { color: var(--ok); background: var(--ok-soft); border: 1px solid transparent; }

.offer-actions { display: grid; grid-template-columns: minmax(0, 1fr); justify-items: end; gap: 6px; width: 100%; min-width: 0; }
.btn-cta {
  width: 100%;
  height: 42px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-fg);
  background: var(--ink);
  border: 0;
  border-radius: 12px;
}
.btn-cta:hover { background: var(--ink); opacity: .88; }
.btn-cta .ic { opacity: .7; }

.offer-id {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 100%;
  padding: 2px 0;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--text-3);
  background: none;
  border: 0;
  cursor: copy;
}
.offer-id .copy-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.offer-id .ic { opacity: 0; transition: opacity .15s var(--ease); }
.offer-id:hover { color: var(--text-2); }
.offer-id:hover .ic, .offer-id:focus-visible .ic { opacity: 1; }
.offer-id.copied { color: var(--ok); }

.no-link { font-size: 12.5px; font-style: italic; color: var(--text-3); }

/* ---- skeleton ---- */

.offer.skel { animation: none; box-shadow: none; }
.offer.skel .offer-side::before, .offer.skel .offer-side::after { display: none; }
.offer.skel .offer-side { border-left-style: solid; border-left-color: var(--line); }
.offer.skel .offer-main { justify-content: center; gap: 12px; }
.sk {
  display: block;
  background: var(--surface-2);
  background-image: linear-gradient(100deg, transparent 20%, color-mix(in srgb, var(--surface) 60%, transparent) 50%, transparent 80%);
  background-size: 200% 100%;
  animation: shimmer 1.4s linear infinite;
}
.sk-line { height: 12px; border-radius: 6px; }
.sk-lg { height: 22px; }
.sk-btn { width: 100%; height: 42px; border-radius: 12px; margin-top: auto; }
@keyframes shimmer { from { background-position: 150% 0; } to { background-position: -50% 0; } }

/* ----------------------------------------------------------------- groups -- */
/*
 * A grouped card reuses the offer card's three-column frame — image, body, price — so
 * the two views read as the same object arranged differently rather than as two
 * unrelated screens. What it adds is the evidence: what proved the rows are one hotel,
 * which prices the range was built from, and whether members were left out. That
 * evidence spans the full card width underneath.
 */

.group-detail {
  grid-column: 1 / -1;
  margin: 0 2px 2px;
  padding-top: 10px;
  border-top: 1.5px dashed var(--line-2);
}
.offer.group .offer-side::after { display: none; }
.group-detail .hint { margin: 8px 8px 0; }

.group-rows { display: grid; gap: 1px; }
.group-prow {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  min-height: 44px;
  padding: 6px 8px;
  font-size: 13px;
  border-radius: var(--r-sm);
  transition: background-color .12s var(--ease);
}
.group-prow:hover { background: var(--surface-2); }
.group-prow .price-src { margin-top: 0; }
.group-prow-date { min-width: 112px; font-weight: 550; }
.group-prow-price { min-width: 96px; font-weight: 650; font-variant-numeric: tabular-nums; }
.group-prow-pp { color: var(--text-3); font-variant-numeric: tabular-nums; }
.group-prow-go { margin-left: auto; }

.group-aka { margin-top: -4px; font-size: 12.5px; font-style: italic; color: var(--text-3); }

/*
 * The match badge. Never colour alone: a basis this stylesheet has no rule for still
 * renders its own raw value, the same discipline the provider badge follows, so a new
 * one cannot inherit a reassuring label it did not earn.
 */
.match {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 9px;
  font-size: 12px;
  font-weight: 550;
  border-radius: 7px;
  cursor: help;
}
.match-ok { color: var(--ok); background: var(--ok-soft); }
.match-warn { color: var(--warn); background: var(--warn-soft); }
.match-plain { color: var(--text-2); background: var(--surface-2); }
.match-unknown { color: var(--text-2); border: 1px dashed var(--line-2); }

.group-spread { margin-top: 6px; font-size: 13px; color: var(--ok); cursor: help; }
.group-spread b { font-weight: 650; }
/* No saving is a real answer, and it must not look like a smaller saving. */
.group-spread.muted { color: var(--text-3); font-style: italic; }

.group-note {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 0;
  padding: 11px 14px;
  font-size: 13px;
  color: var(--text-2);
  background: var(--surface-2);
  border-radius: var(--r);
}
.group-note .ic { margin-top: 1px; color: var(--text-3); }

/* ------------------------------------------------------- empty / pager --- */

.empty-state {
  display: grid;
  justify-items: center;
  padding: 52px 24px;
  text-align: center;
  background: var(--surface);
  border: 1.5px dashed var(--line-2);
  border-radius: var(--r-xl);
  animation: rise .3s var(--ease);
}
.empty-icon {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  margin-bottom: 14px;
  color: var(--text-2);
  background: var(--surface-2);
  border-radius: 50%;
}
.empty-icon .ic { width: 24px; height: 24px; }
.empty-err .empty-icon { color: var(--err); background: var(--err-soft); }
/* "Nothing was searched" is deliberately warn-coloured rather than neutral: an empty
   result caused by an input no provider can search is a different answer from an
   empty market, and it must not look like one. */
.empty-warn { border-color: var(--warn-line); }
.empty-warn .empty-icon { color: var(--warn); background: var(--warn-soft); }
.empty-state h2 { margin: 0 0 8px; font-size: 19px; font-weight: 620; letter-spacing: -.015em; }
.empty-state p { max-width: 560px; margin: 0; color: var(--text-2); }
.empty-state .hint { margin-top: 10px; }

.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 0 0;
}
.pager .btn { border-color: var(--line-2); background: var(--surface); color: var(--text); }
.pager .btn:disabled { background: transparent; }
#pager-text { min-width: 140px; text-align: center; font-size: 13px; color: var(--text-2); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ trace -- */

.trace {
  margin-top: 6px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  scroll-margin-top: calc(var(--header-h) + 16px);
}
.trace > summary {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 14px 16px;
  list-style: none;
  cursor: pointer;
}
.trace > summary::-webkit-details-marker { display: none; }
.trace > summary:hover { background: var(--surface-2); }
.trace-title { display: inline-flex; align-items: center; gap: 8px; margin-right: 4px; font-size: 14px; font-weight: 650; }
.trace-caret { margin-left: auto; color: var(--text-3); transition: transform .2s var(--ease); }
.trace[open] .trace-caret { transform: rotate(180deg); }

.pill {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 9px;
  font-size: 12px;
  font-weight: 550;
  font-variant-numeric: tabular-nums;
  color: var(--text-2);
  background: var(--surface-2);
  border-radius: 999px;
}
.pill.good { color: var(--ok); background: var(--ok-soft); }
.pill.bad  { color: var(--err); background: var(--err-soft); }
/* Neither clean nor failed: the calls we made succeeded, but part of the query was
   never searched at all. That deserves its own colour, not a green tick. */
.pill.warn { color: var(--warn); background: var(--warn-soft); }

.trace-body { display: grid; gap: 12px; padding: 14px 16px 16px; border-top: 1px solid var(--line); }

.req-url {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 5px 5px 5px 12px;
  background: var(--surface-2);
  border-radius: var(--r-sm);
}
.req-k { font-family: var(--mono); font-size: 10.5px; font-weight: 650; letter-spacing: .05em; text-transform: uppercase; color: var(--text-3); }
.req-url code {
  overflow-x: auto;
  white-space: nowrap;
  font-size: 12px;
  scrollbar-width: none;
}
.req-url code::-webkit-scrollbar { display: none; }

.tbl-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; }
table.t { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.t th {
  padding: 8px 12px;
  font-size: 11.5px;
  font-weight: 600;
  text-align: left;
  color: var(--text-3);
  white-space: nowrap;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
}
table.t td { padding: 8px 12px; border-bottom: 1px solid var(--line); vertical-align: top; }
table.t tr:last-child td { border-bottom: 0; }
table.t td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.t code { font-size: 12px; }
table.t tr.row-err td { background: color-mix(in srgb, var(--err-soft) 70%, transparent); }

.st { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 550; white-space: nowrap; }
.st::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.st.ok { color: var(--ok); }
.st.error { color: var(--err); }

.subtrace { border: 1px solid var(--line); border-radius: 12px; }
.subtrace > summary {
  padding: 10px 12px;
  font-size: 13px;
  font-weight: 550;
  cursor: pointer;
  border-radius: 12px;
}
.subtrace > summary:hover { background: var(--surface-2); }
.subtrace > .tbl-wrap { margin: 0 10px 10px; }
pre.json {
  max-height: 420px;
  margin: 0 10px 10px;
  padding: 12px 14px;
  overflow: auto;
  font-size: 12px;
  line-height: 1.55;
  background: var(--surface-2);
  border-radius: var(--r-sm);
}

/* ------------------------------------------------------------- scrims / fab -- */

.rail-scrim {
  position: fixed;
  inset: 0;
  z-index: 65;
  background: rgb(0 0 0 / .35);
  animation: fade .2s var(--ease);
}

.fab { display: none; }

/* ============================================================ responsive == */

@media (max-width: 1240px) {
  .offer { grid-template-columns: 220px minmax(0, 1fr) 196px; gap: 18px; }
  .leg { grid-template-columns: 46px auto minmax(28px, 80px) auto; }
  .leg-meta { grid-column: 2 / -1; justify-content: flex-start; margin-top: -2px; }
}

@media (max-width: 1080px) {
  .layout { grid-template-columns: 240px minmax(0, 1fr); gap: 28px; }
  .icon-btn-label { display: none; }
}

/* Below this the search bar becomes a 2 x 2 grid, and right-hand popovers anchor to
   their cell's right edge so they never run off the viewport. */
@media (max-width: 1000px) {
  .sb { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .sb-cell + .sb-cell::before { display: none; }
  .sb-cell:nth-child(n + 3):not(.sb-actions) { border-top: 1px solid var(--line); border-radius: 0 0 16px 16px; }
  .sb-cell:nth-child(even) .pop { left: auto; right: 0; }
  .sb-actions { grid-column: 1 / -1; padding: 6px 0 0; }
  .btn-go, .btn-stop { width: 100%; height: 50px; }

  /* Below this the rail becomes a drawer: a permanent column would leave the result
     cards unreadably narrow. */
  .layout { grid-template-columns: minmax(0, 1fr); }
  .rail {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: auto;
    z-index: 70;
    width: min(420px, 92vw);
    max-height: none;
    background: var(--surface);
    border-left: 1px solid var(--line);
    border-radius: var(--r-xl) 0 0 var(--r-xl);
    box-shadow: var(--shadow-pop);
    transform: translateX(105%);
    visibility: hidden;
    transition: transform .32s var(--ease), visibility 0s linear .32s;
  }
  .rail.open { transform: none; visibility: visible; transition: transform .32s var(--ease); }
  .rail-head { padding: 18px 18px 12px; border-bottom: 1px solid var(--line); }
  .rail-close { display: inline-flex; }
  .rail-body { padding: 0 18px; margin: 0; }
  .rail-foot {
    display: block;
    padding: 12px 18px calc(12px + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--line);
  }
  .rail-toggle { display: inline-flex; }
  body.rail-open { overflow: hidden; }
}

@media (max-width: 900px) {
  .offer { grid-template-columns: 200px minmax(0, 1fr); }
  .offer-side {
    grid-column: 1 / -1;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding: 12px 6px 4px;
    text-align: left;
    border-left: 0;
    border-top: 1.5px dashed var(--line-2);
  }
  .offer-side::before { top: -10px; left: -21px; }
  .offer-side::after { top: -10px; left: auto; right: -21px; bottom: auto; display: block; }
  .offer.group .offer-side::after { display: block; }
  .price { justify-items: start; }
  .price-src { margin-top: 6px; }
  .offer-actions { width: auto; min-width: 180px; justify-items: end; }
  .group-detail { border-top-style: solid; border-top-width: 1px; border-top-color: var(--line); }
}

/* ------------------------------------------------------------------- phones -- */

@media (max-width: 760px) {
  :root { --page-pad: max(16px, env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px)); --header-h: 56px; }

  .topbar-in { height: 56px; gap: 10px; }
  .brand-sub { display: none; }
  .brand-text strong { font-size: 14px; }
  .api-chip { max-width: 34vw; padding: 0 10px; }
  .api-chip > .ic { display: none; }
  .icon-btn { min-width: 34px; height: 34px; padding: 0 7px; }
  /* Once the question has scrolled away its summary takes the brand's place. */
  body.sb-away .brand-text, body.sb-away .api-chip-url { display: none; }
  body.sb-away .api-chip { padding: 0 12px; }
  .top-summary { flex: 1; margin: 0; max-width: none; height: 36px; padding: 0 12px; font-size: 13px; }

  .sb-in { padding: 14px var(--page-pad) 4px; }
  .sb { grid-template-columns: minmax(0, 1fr); border-radius: 20px; }
  .sb-cell:nth-child(n + 2):not(.sb-actions) { border-top: 1px solid var(--line); border-radius: 0; }
  .sb-cell:first-child { border-radius: 16px 16px 0 0; }
  .sb-btn, .sb-origin { min-height: 56px; }
  .sb-btn { padding: 8px 16px; grid-template-columns: 64px minmax(0, 1fr); align-items: center; }
  .sb-origin .sb-label { top: 50%; left: 16px; margin-top: -9px; }
  .sb-select { padding: 0 40px 0 80px; }
  .sb-cell.open { box-shadow: none; }

  /* The folded question. Stacked, the search bar is ~300px tall; once it has been
     asked, the answer gets the room and the question is one tap away. */
  .sb-summary {
    display: none;
    align-items: center;
    gap: 12px;
    width: 100%;
    height: 60px;
    padding: 0 8px;
    text-align: left;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 999px;
    box-shadow: var(--shadow-2);
    cursor: pointer;
  }
  body.searched .sb-summary { display: flex; }
  body.searched .searchbar:not(.expanded) .sb { display: none; }
  body.searched .searchbar.expanded .sb { margin-top: 10px; animation: rise .22s var(--ease); }
  .sb-summary-ic {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    flex: none;
    color: var(--ink-fg);
    background: var(--ink);
    border-radius: 50%;
  }
  .sb-summary-text { display: grid; min-width: 0; flex: 1; line-height: 1.3; }
  .sb-summary-text b, .sb-summary-text span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .sb-summary-text b { font-size: 14px; font-weight: 600; }
  .sb-summary-text span { font-size: 12.5px; color: var(--text-2); }
  .sb-summary-edit {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    flex: none;
    color: var(--text-2);
    border: 1px solid var(--line-2);
    border-radius: 50%;
  }
  .searchbar.expanded .sb-summary-edit { color: var(--ink-fg); background: var(--ink); border-color: var(--ink); }

  /* Popovers become bottom sheets. Anchored under their trigger they ran off the bottom
     of the screen with no way to scroll them; a sheet gets a real height budget and
     lands under the thumb. */
  .pop, .pop-wide, .pop-right, .sb-cell:nth-child(even) .pop {
    position: fixed;
    z-index: 60;
    top: auto;
    right: 0;
    bottom: 0;
    left: 0;
    width: auto;
    max-width: none;
    max-height: 88vh;
    padding: 0 18px;
    overflow-y: auto;
    overscroll-behavior: contain;
    border-width: 1px 0 0;
    border-radius: 24px 24px 0 0;
    animation: sheet-up .32s var(--ease);
  }
  @keyframes sheet-up { from { transform: translateY(40%); opacity: .4; } }
  .sheet-head {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: 0 -18px;
    padding: 18px 12px 10px 18px;
    background: var(--surface);
  }
  .sheet-head::before {
    content: "";
    position: absolute;
    top: 7px;
    left: 50%;
    width: 38px;
    height: 4px;
    margin-left: -19px;
    background: var(--line-2);
    border-radius: 999px;
  }
  .sheet-head h3 { margin: 0; font-size: 18px; font-weight: 650; letter-spacing: -.015em; }
  .pop-head { padding-top: 0; }
  /* Sticky, because the sheet scrolls: Done must not be able to scroll out of reach.
     The safe-area padding keeps it clear of the iOS home indicator. */
  .pop-foot {
    position: sticky;
    bottom: 0;
    z-index: 2;
    margin: 6px -18px 0;
    padding: 12px 18px calc(12px + env(safe-area-inset-bottom, 0px));
    background: var(--surface);
  }
  .pop-foot .btn-ink { height: 42px; padding: 0 22px; font-size: 14px; }
  .dest-list { max-height: none; }
  body.pop-open { overflow: hidden; }
  .seg button { height: 32px; }

  .layout { padding-top: 14px; gap: 0; }
  .results { gap: 12px; }

  /* The drawer becomes a bottom sheet, which is where a thumb already is. */
  .rail {
    top: auto;
    left: 0;
    width: auto;
    max-height: 90vh;
    border-left: 0;
    border-top: 1px solid var(--line);
    border-radius: 24px 24px 0 0;
    transform: translateY(105%);
  }
  .rail-head { position: relative; padding-top: 22px; }
  .rail-head::before {
    content: "";
    position: absolute;
    top: 8px;
    left: 50%;
    width: 38px;
    height: 4px;
    margin-left: -19px;
    background: var(--line-2);
    border-radius: 999px;
  }

  .hero { padding: 20px 2px 8px; }
  .hero h1 { margin: 16px 0 12px; }
  .lede { font-size: 15.5px; }
  .hero-try { margin-top: 22px; }
  .hero-try .chips { flex-direction: column; align-items: stretch; width: 100%; }
  .chip-example { justify-content: space-between; height: 44px; border-radius: 14px; }
  .hero-provs { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); margin-top: 28px; gap: 8px; }
  .hp { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "dot name" "dot id"; padding: 11px 12px; }
  .hp-tag { display: none; }

  .res-head { align-items: stretch; flex-direction: column; gap: 12px; }
  .big { font-size: 24px; }
  .res-tools { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; }
  .seg-view { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .seg-view button { height: 34px; }
  .sortsel { min-width: 0; }
  .sortsel select { width: 100%; }

  /* On a phone the run panel is read, not studied: the vital signs collapse to one
     wrapping line of "label value" pairs (warnings keep their colour), and the provider
     chips scroll sideways instead of stacking six rows deep above the first result. */
  .progress-text { gap: 4px 14px; padding: 11px 14px; font-size: 12.5px; }
  .res-diag { gap: 6px 14px; margin: 0; padding: 10px 14px; }
  .stat {
    display: inline-flex;
    align-items: baseline;
    flex: none;
    gap: 5px;
    padding: 0;
    border: 0;
  }
  .stat-k { font-size: 12px; }
  .stat-v { font-size: 12.5px; }
  .stat.warn { background: none; }
  .stat-x { display: none; }
  .prov-strip {
    flex-wrap: nowrap;
    overflow-x: auto;
    padding: 10px 14px;
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(90deg, #000 85%, transparent);
    mask-image: linear-gradient(90deg, #000 85%, transparent);
  }
  .prov-strip::-webkit-scrollbar { display: none; }
  .pchip { flex: none; }
  .pchip-link { margin-left: 0; padding-right: 28px; }
  .alert { padding: 13px 14px; gap: 10px; }
  .a-row { grid-template-columns: auto minmax(0, 1fr); }
  .a-row-msg { grid-column: 1 / -1; }

  /* The card stacks and the image becomes a banner. The image is never hidden on a
     phone: that is the one viewport where a hotel is actually chosen on its photo, and
     an operator checking what a provider really supplied must be able to check it here. */
  .offer {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    padding: 8px;
    border-radius: 20px;
  }
  /* `width: 100%` is load-bearing: with only `aspect-ratio` set, the box has an
     intrinsic ratio, so grid `stretch` stops applying and the CAPPED height drives
     the width instead — a 302px banner sitting in a 353px card. */
  .offer-img { width: 100%; min-height: 0; aspect-ratio: 16 / 10; max-height: 230px; border-radius: 14px; }
  /* "No image" is a real answer here, but it does not deserve a 230px grey band. */
  .offer-img.empty { aspect-ratio: auto; height: 44px; min-height: 44px; }
  .offer-img.empty .offer-img-none { grid-auto-flow: column; }
  .offer-main { padding: 14px 6px 4px; gap: 8px; }
  .offer-name { font-size: 18px; }
  .offer-side { padding: 14px 6px 6px; margin-top: 12px; }
  .offer-side::before { left: -19px; }
  .offer-side::after { right: -19px; }
  .offer-actions { min-width: 0; width: auto; }
  .btn-cta { width: auto; padding: 0 18px; }
  .offer-id { display: none; }
  .legs { padding: 10px; }
  .leg { grid-template-columns: 54px auto minmax(20px, 1fr) auto; gap: 8px; }
  .dir { font-size: 10px; }
  .leg-meta { grid-column: 2 / -1; justify-content: flex-start; }
  .tag-room { max-width: 100%; }

  .group-detail { margin-top: 12px; }
  .group-prow { padding: 8px 6px; }
  .group-prow-go { margin-left: auto; }

  .empty-state { padding: 40px 18px; }
  .trace > summary { padding: 13px 14px; }
  .trace-body { padding: 12px; }

  .fab {
    position: fixed;
    left: 50%;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    z-index: 40;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 46px;
    padding: 0 20px;
    font-size: 14px;
    font-weight: 600;
    color: var(--ink-fg);
    background: var(--ink);
    border: 0;
    border-radius: 999px;
    box-shadow: var(--shadow-pop);
    transform: translateX(-50%);
    cursor: pointer;
    animation: fab-in .3s var(--ease);
  }
  @keyframes fab-in { from { opacity: 0; transform: translate(-50%, 16px); } }
  .fab[hidden], body.rail-open .fab, body.pop-open .fab, body.filters-inview .fab { display: none !important; }
  .fab .badge-count { background: var(--accent); }
}

@media (max-width: 380px) {
  .api-chip-url { display: none; }
  .api-chip { padding: 0 11px; }
  .row.two { grid-template-columns: minmax(0, 1fr); }
  .hero-provs { grid-template-columns: minmax(0, 1fr); }
  .offer-side { flex-direction: column; align-items: stretch; }
  .offer-actions { justify-items: stretch; }
  .btn-cta { width: 100%; }
}

@media (min-width: 761px) {
  .pop-scrim { display: none !important; }
}

@media (max-width: 760px) {
  /* iOS Safari zooms the page on focus into any field under 16px, and stays zoomed after
     a sheet closes. Every class-level size above is overridden here on purpose. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), select, textarea {
    font-size: 16px !important;
  }

  /* Anchored to the chip, the editor's right edge sat ~96px in from the screen's and its
     400px ran off the left. The topbar is its containing block (backdrop-filter), so
     these insets are the screen's edges. */
  .api-editor {
    position: fixed;
    top: calc(var(--header-h) + 8px);
    left: var(--page-pad);
    right: var(--page-pad);
    width: auto;
    max-width: none;
  }

  /* The search bar folds away while a search runs, taking Stop with it; this one sits
     in the run panel instead. */
  body.is-running .run-stop { display: inline-flex; }
}

/* The rail is a static column here, so a scrim left over from the drawer (a tablet
   rotated to landscape) would sit over the whole page. app.js closes the drawer too. */
@media (min-width: 1001px) {
  .rail-scrim { display: none !important; }
}

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

/* ---------- console sign-in (console-auth.js) ----------
   A full-page door while the API asks for a Google sign-in. It only spares a signed-out
   visitor a console that would not work; the API refuses what matters by itself. */
.ca-pending body { visibility: hidden; }
.ca-locked body { overflow: hidden; }
.ca-gate {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-items: center;
  padding: 24px var(--page-pad);
  overflow-y: auto;
  background: var(--bg);
  visibility: visible;
}
.ca-card {
  width: 100%;
  max-width: 440px;
  padding: 36px 32px 30px;
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--shadow-2);
}
.ca-mark { width: 40px; height: 40px; margin-bottom: 22px; }
.ca-card h1 { margin: 0; font-size: 22px; line-height: 1.25; font-weight: 650; letter-spacing: -0.015em; }
.ca-lede { margin: 10px 0 0; color: var(--text-2); font-size: 14.5px; line-height: 1.55; }
.ca-note {
  margin: 18px 0 0;
  padding: 10px 12px;
  border: 1px solid var(--warn-line);
  border-radius: var(--r-sm);
  background: var(--warn-soft);
  color: var(--text);
  font-size: 13.5px;
  line-height: 1.5;
}
.ca-button { min-height: 44px; margin-top: 24px; }
.ca-hint { margin: 14px 0 0; color: var(--text-3); font-size: 12.5px; }
.ca-user {
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-2);
  font-size: 12.5px;
  margin-right: 2px;
}
.ca-signout { margin-right: 6px; }
@media (max-width: 720px) {
  .ca-user { display: none; }
  .ca-card { padding: 28px 20px 24px; }
}
