/**
 * Components. KEEP-on-clone — every value comes from brand tokens.
 *
 * Two rules hold the design together:
 *   1. Gold marks what you can act on and what you have chosen. Nothing else.
 *   2. Nothing a customer must read is smaller than 16px.
 */

/* ── Panels ─────────────────────────────────────────────────────────────── */

.panel {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--sp-5);
  box-shadow: var(--shadow-sm);
}

.panel-tight { padding: var(--sp-4); }

.panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
  flex-wrap: wrap;
}

/* ── Buttons ────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--tap-min);
  padding: 0 var(--sp-5);
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: var(--paper);
  color: var(--ink);
  font-size: var(--text-base);
  font-weight: 600;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, transform 60ms ease;
}
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* Gold fill with navy text — 6.1:1, so the most important control on the page
   is also the most readable. Gold as TEXT would not pass, which is why it never
   appears that way. */
.btn-primary { background: var(--gold); border-color: var(--gold); color: var(--ink); }
.btn-primary:hover:not(:disabled) { background: var(--gold-hover); }

.btn-secondary { border-color: var(--line-strong); color: var(--ink); }
.btn-secondary:hover:not(:disabled) { background: var(--paper-tint); border-color: var(--ink-muted); }

.btn-ghost {
  min-height: auto;
  padding: var(--sp-2) var(--sp-3);
  background: transparent;
  color: var(--ink-soft);
  font-weight: 500;
}
.btn-ghost:hover { background: var(--paper-tint); color: var(--ink); }

.btn-block { width: 100%; }

/* ── Form fields ────────────────────────────────────────────────────────── */

.field { display: flex; flex-direction: column; gap: var(--sp-2); }

.label { font-size: var(--text-sm); font-weight: 600; color: var(--ink-soft); }
.hint  { font-size: var(--text-sm); color: var(--ink-muted); }

.input {
  min-height: var(--tap-min);
  padding: var(--sp-2) var(--sp-3);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  color: var(--ink);
}
.input::placeholder { color: var(--ink-faint); }
.input:hover { border-color: var(--ink-muted); }

/**
 * A field the assistant has just filled or changed.
 *
 * Safety rule 1: every assistant edit is visible. The customer must never find
 * a value they did not type without being shown that it appeared.
 */
.input[data-touched='agent'],
.field[data-touched='agent'] .input {
  border-color: var(--gold);
  background: var(--gold-wash);
  animation: touched 1.2s ease;
}
@keyframes touched {
  0%   { box-shadow: 0 0 0 0 rgba(var(--gold-rgb), 0.5); }
  100% { box-shadow: 0 0 0 10px rgba(var(--gold-rgb), 0); }
}

/* A value proposed but not yet confirmed — held, not committed. */
.pending {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  padding: var(--sp-3);
  background: var(--gold-wash);
  border: 1px dashed var(--gold);
  border-radius: var(--radius);
  font-size: var(--text-sm);
}

/* Passenger count and similar: tap, don't type. */
.stepper-input {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  overflow: hidden;
}
.stepper-input button {
  width: var(--tap-min); height: var(--tap-min);
  border: 0; background: var(--paper);
  font-size: var(--text-lg); color: var(--ink-soft); cursor: pointer;
}
.stepper-input button:hover:not(:disabled) { background: var(--gold-wash); color: var(--ink); }
.stepper-input button:disabled { color: var(--ink-faint); cursor: not-allowed; }
.stepper-input .value {
  min-width: 3.5rem; text-align: center;
  font-variant-numeric: tabular-nums; font-weight: 600;
}

/* ── Chips ──────────────────────────────────────────────────────────────── */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 40px;
  padding: var(--sp-2) var(--sp-4);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  color: var(--ink-soft);
  cursor: pointer;
  text-align: left;
}
.chip:hover { border-color: var(--gold); background: var(--gold-wash); color: var(--ink); }
.chip[aria-pressed='true'] {
  background: var(--gold-soft);
  border-color: var(--gold);
  color: var(--ink);
  font-weight: 600;
}

.chip-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

/* ── Badges ─────────────────────────────────────────────────────────────── */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 2px var(--sp-2);
  border-radius: var(--radius-sm);
  background: var(--paper-tint);
  border: 1px solid var(--line);
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--ink-soft);
}
.badge-gold { background: var(--gold-soft); border-color: var(--gold); color: var(--ink); }
.badge-warn { background: var(--warn-wash); border-color: var(--warn-line); color: var(--warn); }

/* The airline's own name for the fare — "Eco Flex", "IndiGo UpFront".
   A step quieter than the facts beside it: it is the label being explained, not
   one of the things that explain it, so it must not out-shout the cabin. */
.badge-quiet {
  background: transparent;
  border-style: dashed;
  color: var(--ink-muted);
  font-weight: 500;
}

/* ── Flight card ────────────────────────────────────────────────────────── */

.flight {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--sp-4);
  align-items: center;
  padding: var(--sp-4);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.flight:hover { border-color: var(--line-strong); box-shadow: var(--shadow); }
.flight[data-chosen='true'] {
  border-color: var(--gold);
  box-shadow: 0 0 0 1px var(--gold);
  background: var(--gold-wash);
}

.flight-carrier {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--text-sm); color: var(--ink-muted);
  margin-bottom: var(--sp-3);
}

/* departure — middle — arrival */
.journey {
  display: grid;
  grid-template-columns: auto minmax(90px, 1fr) auto;
  gap: var(--sp-4);
  align-items: center;
}

.endpoint .time {
  font-size: var(--text-xl);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.endpoint .place { font-size: var(--text-sm); color: var(--ink-soft); font-weight: 600; }
.endpoint .date  { font-size: var(--text-sm); color: var(--ink-muted); }

/* The +1 that says you land tomorrow. Small, but it must not be missable. */
.plus-days {
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--warn);
  vertical-align: super;
  margin-left: 2px;
}

.leg-middle { text-align: center; }
.leg-middle .dur { font-size: var(--text-sm); font-weight: 600; color: var(--ink-soft); }
.leg-middle .rule {
  height: 1px; background: var(--line-strong);
  margin: var(--sp-2) 0; position: relative;
}
.leg-middle .rule::after {
  content: '✈'; position: absolute; right: -2px; top: -9px;
  font-size: 12px; color: var(--gold); background: var(--paper); padding-left: 3px;
}
.leg-middle .stops { font-size: var(--text-sm); color: var(--ink-muted); }

.flight-price { text-align: right; }
.flight-price .amount {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 600;
  line-height: 1.1;
  /* Prices in a vertical list are compared digit by digit, and proportional
     figures make "64,03" and "119,90" sit at different widths so the eye cannot
     scan the column. The slider readout already does this; the cards, which are
     the thing actually being compared, did not. */
  font-variant-numeric: tabular-nums;
}

/* Same reasoning, for the two facts read most often after the price. Times
   already align; the duration between them did not. */
.leg-middle .dur, .endpoint .time { font-variant-numeric: tabular-nums; }
.flight-price .per { font-size: var(--text-xs); color: var(--ink-muted); }

.flight-facts {
  display: flex; flex-wrap: wrap; gap: var(--sp-2);
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
}

/* What distinguishes this fare from the others on the same flight. Set in gold
   because it is the reason this card is not a duplicate — it has to be read
   before the badges below it, not after. */
.fare-diff {
  margin-top: var(--sp-3);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--gold-deep);
}

.return-leg {
  margin-top: var(--sp-3); padding-top: var(--sp-3);
  border-top: 1px dashed var(--line-strong);
  font-size: var(--text-sm); color: var(--ink-soft);
}

@media (max-width: 720px) {
  .flight { grid-template-columns: 1fr; }
  .flight-price { text-align: left; display: flex; align-items: baseline; gap: var(--sp-3); }
  .journey { grid-template-columns: auto 1fr auto; gap: var(--sp-2); }
  .endpoint .time { font-size: var(--text-lg); }
}

/* ── Assistant messages ─────────────────────────────────────────────────── */

.msg {
  padding: var(--sp-3);
  border-radius: var(--radius);
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
}
.msg-agent { background: var(--paper-tint); color: var(--ink); }
.msg-user  { background: var(--ink); color: var(--paper); margin-left: var(--sp-6); }

/* A question the assistant could not answer and has written down for a human.
   Deliberately not styled as an error — it is the system working correctly. */
.msg-note {
  background: var(--gold-wash);
  border-left: 3px solid var(--gold);
  color: var(--ink-soft);
}

/* ── Empty and loading ──────────────────────────────────────────────────── */

.empty {
  text-align: center;
  padding: var(--sp-8) var(--sp-4);
  color: var(--ink-muted);
}

.skeleton {
  background: linear-gradient(90deg, var(--line) 25%, var(--paper-tint) 50%, var(--line) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s infinite;
  border-radius: var(--radius);
}
@keyframes shimmer { to { background-position: -200% 0; } }

/* ── Range sliders on the filter bar ─────────────────────────────────────── */

/* Price and flight time are set here, against the real spread of what came
   back, rather than guessed on the search form before a fare has been seen. */
/* No rule of its own any more: it sits inside `.filter-more`, which already
   draws one, and two lines a few pixels apart read as a mistake. */
.slider-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--sp-2) var(--sp-6);
}

.slider { display: flex; flex-direction: column; gap: var(--sp-1) }
.slider-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3) }
.slider-label { font-size: var(--text-sm); font-weight: 600; color: var(--ink-soft) }
.slider-value { font-size: var(--text-sm); font-weight: 600; font-variant-numeric: tabular-nums }
.slider-ends {
  display: flex;
  justify-content: space-between;
  font-size: var(--text-xs);
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

/* A tap target that clears the 44px minimum without a 44px-tall grey bar:
   the input is tall and transparent, the visible track is drawn inside it. */
.slider-track {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  min-height: var(--tap-min);
  margin: 0;
  background: transparent;
  cursor: pointer;
}
.slider-track::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--line-strong);
}
.slider-track::-moz-range-track {
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--line-strong);
}
.slider-track::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 22px;
  height: 22px;
  margin-top: -9px;
  border-radius: 50%;
  background: var(--gold-deep);
  border: 2px solid var(--paper);
  box-shadow: var(--shadow-sm);
}
.slider-track::-moz-range-thumb {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--gold-deep);
  border: 2px solid var(--paper);
  box-shadow: var(--shadow-sm);
}
.slider-track:focus-visible { outline: 2px solid var(--gold); outline-offset: 4px }

/* A multi-city trip against its cap while it is still being built. Never
   labelled as the price — the text always says how many legs are in it. */
.budget-strip {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
}
.budget-strip[data-over='true'] {
  border-color: var(--warn);
  background: var(--warn-wash);
}
.budget-of  { font-size: var(--text-sm); color: var(--ink-muted) }
.budget-sum { font-family: var(--font-display); font-size: var(--text-xl); font-weight: 600 }
.budget-cap { font-size: var(--text-sm); color: var(--ink-muted) }
.budget-left { margin-left: auto; font-size: var(--text-sm); font-weight: 600 }
.budget-strip[data-over='true'] .budget-left { color: var(--warn) }

/* ── Search form layout ─────────────────────────────────────────────────── */

.search-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--sp-4);
}

.search-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  margin-top: var(--sp-5);
}

/* ── Travellers, as a field that opens ──────────────────────────────────── */

/*
 * Closed it reads as a sentence — "2 adults, 1 child" — and open it is three
 * rows on one grid, so the names, the age bands and the steppers each line up
 * down a column instead of drifting with the length of the word beside them.
 * Same shape as the autocomplete below it: the form has one idea of what an
 * opening field looks like.
 */
.pax-wrap { position: relative; }

.pax-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  width: 100%;
  text-align: left;
  cursor: pointer;
  font: inherit;
}
.pax-summary { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pax-trigger[aria-expanded='true'] { border-color: var(--gold); }
.pax-trigger[aria-expanded='true'] .filter-caret { transform: rotate(180deg); }

.pax-pop {
  position: absolute;
  top: 100%; left: 0;
  z-index: 40;
  min-width: 100%;
  width: max-content;
  max-width: min(22rem, calc(100vw - 2 * var(--sp-4)));
  margin-top: var(--sp-1);
  padding: var(--sp-3);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
}

/* The alignment: one column for the words, one for the control. */
.stepper-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--line);
}
.stepper-row:last-of-type { border-bottom: 0; }

.stepper-label { display: flex; flex-direction: column; gap: 2px; }
.stepper-name { font-weight: 600; }
.stepper-age { font-size: var(--text-sm); color: var(--ink-muted); }

.stepper-note { margin: var(--sp-2) 0 0; }

.pax-done { display: flex; justify-content: flex-end; margin-top: var(--sp-2); }

/* ── Airport autocomplete ───────────────────────────────────────────────── */

.ac-wrap { position: relative; }

.ac-list {
  position: absolute;
  top: 100%; left: 0; right: 0;
  z-index: 40;
  margin-top: var(--sp-1);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  max-height: 320px;
  overflow-y: auto;
}

.ac-item {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0 var(--sp-3);
  width: 100%;
  padding: var(--sp-3);
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
  border-bottom: 1px solid var(--line);
}
.ac-item:last-child { border-bottom: 0; }
.ac-item:hover { background: var(--gold-wash); }

/**
 * The arrow-key highlight.
 *
 * Focus never leaves the text box — moving it into the list would take the
 * customer's typing with it — so this is the ONLY thing that shows where the
 * keyboard is. It therefore has to be at least as loud as :hover, not a subtle
 * tint: the gold edge is the same mark the rest of the product uses for "this
 * is the one", and Enter acts on whatever is wearing it.
 */
.ac-item.is-active {
  background: var(--gold-wash);
  box-shadow: inset 3px 0 0 var(--gold);
}

/* Said out loud rather than shown as an empty box — see search.js. */
.ac-empty {
  padding: var(--sp-3);
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

.ac-city { font-weight: 600; color: var(--ink); }
.ac-code {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--gold-deep);
  font-weight: 700;
}
.ac-name {
  grid-column: 1 / -1;
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

/* ── Notices ────────────────────────────────────────────────────────────── */

.notice {
  margin-top: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  background: var(--paper-tint);
  border-left: 3px solid var(--line-strong);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  color: var(--ink-soft);
}
.notice-warn { background: var(--warn-wash); border-left-color: var(--warn); color: var(--warn); }

/* Marks a change the assistant made rather than the customer — safety rule 1.
   Gold, because that is already this product's "the assistant did this" colour. */
.notice-agent {
  margin-top: var(--sp-3);
  background: var(--gold-wash);
  border-left-color: var(--gold);
  color: var(--ink-soft);
}

/* "You are staff, and these prices are not what the customer sees."

   Deliberately NOT the gold of .notice-agent: gold in this product already
   means "the assistant did this", and this is not the assistant. It sits above
   the whole column rather than beside a field because it qualifies the entire
   screen, not one value on it. */
.notice-staff {
  margin: 0 0 var(--sp-4);
  background: var(--paper-tint);
  border-left-color: var(--line-strong);
  color: var(--ink-soft);
}

/* "preferred" beside a field label — a nudge, never a requirement marker. It is
   deliberately not an asterisk: an asterisk would say the field is compulsory,
   and either channel on its own is enough (D-033). */
.label-note {
  margin-left: var(--sp-2);
  padding: 1px var(--sp-2);
  border-radius: var(--radius-pill);
  background: var(--gold-wash);
  color: var(--gold-deep);
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
}

/* ── The other fares on one flight ──────────────────────────────────────── */

/* A row is now the card plus anything hanging off it, so `.results`' own gap
   still separates FLIGHTS rather than separating a card from its own fares. */
.result-row { display: flex; flex-direction: column; }

.fares { margin-top: calc(-1 * var(--sp-1)); }

/* Reads as an extension of the card above, not a control of its own: no border,
   sitting just inside the card's left edge. */
.fare-toggle {
  font-size: var(--text-sm);
  padding-left: var(--sp-4);
}

.fare-list {
  margin: var(--sp-2) 0 0 var(--sp-5);
  padding-left: var(--sp-4);
  /* One line tying the alternatives back to the flight they belong to. Without
     it a second card at full width reads as a second flight. */
  border-left: 2px solid var(--gold-soft);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}

.fare-intro { margin-bottom: var(--sp-1); }
.fare-row { display: flex; flex-direction: column; gap: var(--sp-1); }

/* What the upgrade costs, against the cheapest fare on this flight. The number
   the customer is actually weighing, so it sits above the card it applies to. */
.fare-extra { align-self: flex-start; }

@media (max-width: 640px) {
  /* The rule costs 24px of a narrow screen and the indent says the same thing. */
  .fare-list { margin-left: var(--sp-2); padding-left: var(--sp-3); }
}

/* ── Connection ─────────────────────────────────────────────────────────── */

/**
 * The socket, when it is not well.
 *
 * Deliberately NOT gold. Gold in this product means "you can act on this" or
 * "this is the one you chose", and a network fault is neither — borrowing the
 * accent here would blunt it everywhere else. Amber for a wait, a stronger
 * amber edge for the one that asks the customer to do something.
 *
 * Sits at the very top of the main column and pushes the page down rather than
 * floating over it: it applies to everything below, and a toast that fades would
 * be gone by the time someone looked up from their phone.
 */
.connbar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius);
  font-size: var(--text-sm);
  background: var(--warn-wash);
  border: 1px solid var(--warn-line);
  color: var(--warn);
}

.connbar strong { color: var(--warn); }
.connbar .btn { margin-left: auto; flex: none; }

.connbar-dot {
  width: 10px; height: 10px;
  flex: none;
  border-radius: 50%;
  background: var(--warn);
}

/* Still trying — the pulse is the only thing on the page that says "wait".
   Stilled by the reduced-motion rule in base.css. */
.connbar-offline .connbar-dot { animation: conn-pulse 1.2s ease-in-out infinite; }

@keyframes conn-pulse {
  50% { opacity: 0.25; }
}

/* It came back and the work did not. Solid, and it stays until dismissed. */
.connbar-lost { border-width: 2px; }

/* ── Filter bar ─────────────────────────────────────────────────────────── */

/* Deliberately more compact than a content panel, and separated from the list.
   It is a control strip the customer passes THROUGH on the way to the flights,
   not something to read — so it gives up its height to the cards, and the
   margin below stops it sitting flush against the first one. */
/**
 * Sticky under the header.
 *
 * With 32 rows the customer scrolls the controls off screen within a second and
 * then scrolls back up to change a sort — which is most of what this strip is
 * for. It follows them instead.
 *
 * `--header-h` because the masthead is itself sticky and would otherwise sit on
 * top of this. Given a background and a z-index deliberately: without both, the
 * cards scroll THROUGH a transparent bar, which looks like a rendering fault
 * rather than a fixed control.
 */
.filterbar {
  position: sticky;
  top: var(--header-h);
  z-index: 10;
  margin-top: var(--sp-4);
  margin-bottom: var(--sp-5);
  padding: var(--sp-3) var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  background: var(--paper);
}

/**
 * Except when its own panel is open.
 *
 * Expanded, the bar carries two chip rows, an airline list and two sliders —
 * on a phone that is most of the viewport, and pinning it would leave a sliver
 * of results underneath. It sticks while it is a strip and scrolls while it is
 * a panel.
 */
.filterbar:has(.filter-more:not([hidden])) { position: static; }

.filter-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}
.filter-row > strong { min-width: 3.2rem; color: var(--ink-muted); }

/* Scoped to the strip: a filter chip is a toggle in a row of twelve, not a
   primary action, so it does not need a primary action's tap target. Chips
   elsewhere keep their 40px. */
.filterbar .chip { min-height: 32px; padding: var(--sp-1) var(--sp-3); }

/* ── The fold ────────────────────────────────────────────────────────────── */

/* Reads as a control, not as a filter: no pill, no pressed state, and it sits
   after the chips it opens rather than among them. */
.filter-toggle {
  min-height: 32px;
  padding: var(--sp-1) var(--sp-3);
  gap: var(--sp-2);
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}

/* How many filters are switched on out of sight. The one thing that stops the
   fold from being somewhere a filter can hide. */
.filter-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.35rem;
  border-radius: var(--radius-pill);
  /* The same pairing `.badge-gold` uses, and the only one in the palette that
     is safe to read: ink on the soft gold, never text on the solid gold. */
  background: var(--gold-soft);
  border: 1px solid var(--gold);
  color: var(--ink);
  font-size: var(--text-xs);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.filter-caret { transition: transform 140ms ease; line-height: 1; }
.filter-toggle[aria-expanded='true'] .filter-caret { transform: rotate(180deg); }

.filter-more {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
}
.filter-more[hidden] { display: none; }

/* Label and chips on one line, the label a fixed column so the rows line up
   with the Sort and Filter rows above rather than starting at three widths. */
.filter-group {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}
.filter-group > strong { min-width: 3.2rem; color: var(--ink-muted); }

/* ── Results ────────────────────────────────────────────────────────────── */

.results { display: flex; flex-direction: column; gap: var(--sp-3); }
.results-h { margin: var(--sp-6) 0 var(--sp-2); }

.backbar { margin: var(--sp-5) 0 var(--sp-3); }

/* ── Pager (D-078) ─────────────────────────────────────────────────────────
   The numbers wrap rather than scroll: five pages fit anywhere, and a route
   that somehow produced twenty should push the list down, not hide pages off
   the right-hand edge of a phone. */
.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  margin: var(--sp-5) 0 var(--sp-2);
}
.pager-numbers { display: flex; flex-wrap: wrap; gap: var(--sp-1); justify-content: center; }
.pager-n {
  min-width: 2.25rem;
  padding: var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm, 6px);
  background: var(--surface);
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.pager-n:hover:not([disabled]) { border-color: var(--gold, currentColor); }
/* The current page is the disabled one — it is where you already are, so it
   reads as a label rather than something to press. */
.pager-n[aria-current='page'] {
  font-weight: 600;
  border-color: var(--gold, currentColor);
  cursor: default;
}
.pager-step[disabled] { opacity: .45; cursor: default; }
.pager-status {
  flex-basis: 100%;
  margin: 0;
  text-align: center;
  font-size: var(--fs-sm, .875rem);
  color: var(--muted);
}


.chosen-summary {
  margin-bottom: var(--sp-4);
  border-color: var(--gold);
  background: var(--gold-wash);
  font-size: var(--text-sm);
}

.next-steps {
  margin: 0 0 var(--sp-4);
  padding-left: var(--sp-5);
  color: var(--ink-soft);
}
.next-steps li { margin-bottom: var(--sp-2); }

/* ── Assistant rail extras ──────────────────────────────────────────────── */

.rail-suggestions { margin-bottom: var(--sp-3); }

/* "Thinking" — three dots, so a pause reads as work rather than a hang. */
.msg-thinking { display: flex; gap: 6px; align-items: center; }
.msg-thinking .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--ink-faint);
  animation: blink 1.2s infinite;
}
.msg-thinking .dot:nth-child(2) { animation-delay: 0.2s; }
.msg-thinking .dot:nth-child(3) { animation-delay: 0.4s; }
@keyframes blink { 0%, 80%, 100% { opacity: 0.3; } 40% { opacity: 1; } }

.pending { flex-direction: column; align-items: stretch; }
.pending .btn { min-height: 40px; }

/* ── Confirmation ───────────────────────────────────────────────────────── */

.confirmed { text-align: center; padding: var(--sp-8) var(--sp-5); }

.confirmed-mark {
  width: 56px; height: 56px;
  margin: 0 auto var(--sp-4);
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--gold-soft);
  border: 2px solid var(--gold);
  color: var(--ink);
  font-size: 26px; font-weight: 700;
}

.confirmed h2 { margin-bottom: var(--sp-4); }
.confirmed p { max-width: 46ch; margin-left: auto; margin-right: auto; }

/* The one thing on the page a customer might read down a phone line, so it is
   the largest and most spaced element on it. */
.reference {
  display: inline-flex; flex-direction: column; gap: var(--sp-1);
  margin: var(--sp-4) 0 var(--sp-5);
  padding: var(--sp-4) var(--sp-6);
  background: var(--gold-wash);
  border: 1px dashed var(--gold);
  border-radius: var(--radius-lg);
}
.reference-label {
  font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink-muted);
}
.reference-code {
  font-family: var(--font-mono);
  font-size: var(--text-2xl); font-weight: 700;
  letter-spacing: 0.12em; color: var(--ink);
  /* Double-click still selects the whole code for anyone who prefers to copy it
     by hand — the button is an addition, not a replacement. */
  user-select: all;
}

.reference-copy {
  margin-top: var(--sp-2);
  font-size: var(--text-sm);
  /* Fixed width so confirming does not resize the box under the cursor. */
  min-width: 9ch;
}
.reference-copy[data-done='true'] {
  background: var(--gold-soft);
  border-color: var(--gold);
}

.confirmed .notice { text-align: left; max-width: 46ch; margin: var(--sp-4) auto 0; }

/* ── Multi-city ─────────────────────────────────────────────────────────── */

.legs { display: flex; flex-direction: column; gap: var(--sp-4); margin-top: var(--sp-4); }

.leg {
  padding: var(--sp-4);
  background: var(--paper-tint);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
}
.leg-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: var(--sp-3);
}
.leg-n {
  font-size: var(--text-xs); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink-muted);
}
.leg-grid {
  display: grid; gap: var(--sp-3);
  grid-template-columns: 1fr 1fr minmax(9rem, 0.7fr);
}
@media (max-width: 700px) { .leg-grid { grid-template-columns: 1fr; } }

.legs-actions {
  display: flex; flex-direction: column; gap: var(--sp-2);
  align-items: flex-start; margin-top: var(--sp-2);
}

/* The shape of the whole trip, kept in view while choosing one flight of it. */
.trip-strip {
  display: flex; gap: var(--sp-2); flex-wrap: wrap;
  margin-bottom: var(--sp-5);
}
.trip-leg {
  flex: 1 1 10rem;
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--sp-3);
  text-align: left; cursor: pointer;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  font: inherit; color: var(--ink);
}
.trip-leg:hover { border-color: var(--gold); }
.trip-leg[aria-current="step"] {
  border-color: var(--gold); border-width: 2px; background: var(--gold-wash);
}
.trip-leg[data-done="true"] .trip-leg-n { color: var(--gold); }
.trip-leg-n { font-size: var(--text-xs); font-weight: 700; color: var(--ink-muted); }
.trip-leg-route { font-weight: 600; }
.trip-leg-detail { font-size: var(--text-sm); color: var(--ink-muted); }

.trip-row { display: flex; flex-direction: column; gap: var(--sp-2); }
.trip-row .badge { align-self: flex-start; }

.trip-total { margin-top: var(--sp-4); background: var(--gold-wash); }
.trip-total-amount { font-size: var(--text-xl); font-weight: 700; }

/* ── The guide: the assistant's voice, in the spine ─────────────────────── */

/**
 * Pinned under the masthead, so the assistant's line stays with you while you
 * scroll a long list of flights instead of scrolling away at the top.
 *
 * Pinning only works if it is SHORT. It was three stacked rows — mark, name,
 * headline — plus detail, about 130px at the top of every step. Sticky at that
 * height would eat the screen it is meant to help you read. So the first three
 * are now one line, and the whole block is roughly 60px with detail and 40px
 * without.
 *
 * The ground must stay opaque: a translucent sticky element shows the results
 * sliding underneath it.
 */
.guide {
  position: sticky;
  top: var(--header-h);
  z-index: 5;

  margin-bottom: var(--sp-5);
  padding: var(--sp-3) var(--sp-4);
  background: var(--gold-wash);
  border: 1px solid var(--gold-soft);
  border-left: 3px solid var(--gold);
  border-radius: var(--radius-md);
}

.guide-body { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }

/* Mark, name and headline on one baseline. Wraps rather than truncating — a
   headline the customer cannot finish reading is worse than a taller box. */
.guide-top {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  flex-wrap: wrap;
  min-width: 0;
}

.guide-mark {
  flex: none;
  font-size: var(--text-lg);
  line-height: 1.2;
  color: var(--gold);
}

.guide-who {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  flex: none;
}

.guide-line   { font-size: var(--text-base); font-weight: 600; color: var(--ink); }
.guide-detail { color: var(--ink-soft); font-size: var(--text-sm); margin: 0; }

/* Something worth noticing about the screen as a whole. */
.guide-flag { font-size: var(--text-sm); }
.guide-note { color: var(--ink-soft); }
.guide-warn { color: var(--warn); font-weight: 600; }

/* Said by the model rather than computed. Same voice to the customer; kept
   distinguishable in the markup so a wrong one can be traced to its source. */
.guide-remark { color: var(--ink-soft); font-style: italic; }

/* ── Curated picks ──────────────────────────────────────────────────────── */

.picks { margin-top: var(--sp-2); }

.pick { display: flex; flex-direction: column; gap: var(--sp-2); }

.pick-head { display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap; }
.pick-reason { font-size: var(--text-sm); color: var(--ink-soft); }

/* The shortlist sits above the full list, never instead of it — so it needs a
   visible bottom edge rather than a button that hides what follows. */
.picks {
  padding-bottom: var(--sp-5);
  margin-bottom: var(--sp-5);
  border-bottom: 1px solid var(--line);
}
.picks .panel-head { align-items: baseline; }

/* ── Warnings pinned to one option ──────────────────────────────────────── */

.card-flags {
  display: flex; flex-wrap: wrap; gap: var(--sp-2);
  margin-top: var(--sp-3);
}

.card-flag {
  font-size: var(--text-sm);
  padding: 2px var(--sp-2);
  border-radius: var(--radius-sm);
  background: var(--paper-tint);
  color: var(--ink-soft);
}
.card-flag-warn {
  background: var(--warn-wash);
  color: var(--warn);
  font-weight: 600;
}

/* ── Theme toggle ───────────────────────────────────────────────────────── */
/* Chrome, not product. Shows the icon for the theme you would switch TO. */
.theme-toggle { padding: var(--sp-2); line-height: 0; }
.theme-toggle svg { width: 18px; height: 18px; fill: currentColor; display: block; }
.icon-moon { display: none; }
:root[data-theme='dark'] .icon-sun  { display: none; }
:root[data-theme='dark'] .icon-moon { display: block; }

/* ── Language toggle ────────────────────────────────────────────────────── */
/* Chrome, like the theme beside it, and shaped to match so the two read as one
   pair. It carries a word rather than an icon: there is no glyph for a language
   a reader can be expected to know, and a flag is a country — this German is
   read in Austria and Switzerland too. The word is the language you would
   switch TO, because someone who cannot read the current one cannot read
   "switch language" either. */
.lang-toggle {
  padding: 0 var(--sp-3);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
}


/* The optional note on the review screen. Resizes vertically only — a box the
   customer can drag wider than the column looks broken. */
.textarea {
  min-height: 4.5rem;
  resize: vertical;
  font-family: inherit;
  line-height: var(--leading-normal);
}
