/* ===========================================================================
   booking-card.css — the controls booking-card.js adds to the hero card.
   ===========================================================================
   Loaded AFTER main.css on every page that renders the card, and it only adds:
   .search-card, .field and .search-fields are still main.css's, so the
   card keeps the design language it already had and this file cannot quietly
   restyle it.

   HEIGHT IS THE CONSTRAINT THIS FILE IS BUILT AROUND. The card is as tall as
   the one panel it holds and nothing more — the trip-type row is a 30px
   segmented control for that reason, and it is the card's first control now
   that the product tab strip above it is gone.

   The one place the card does grow is Round Trip, which has a second route to
   show and cannot show it in a row that does not exist. It grows by exactly
   one field row and animates, rather than jumping.
   =========================================================================== */

/* A class selector beats the UA stylesheet's `[hidden] { display: none }`, so
   .trip-upcoming{display:flex} and .search-fields{display:grid} both stayed on
   screen while the attribute said otherwise — the card carried the Multi City
   panel AND the field row at once and was 140px too tall. Scoped to the card
   rather than declared globally. */
.search-card [hidden] { display: none !important; }

/* THE PANEL STACK HAD TO GO.

   main.css used to stack all four product panels in one grid cell
   (grid-area:1/1, inactive ones visibility:hidden) so the tallest set the
   height once. That was right when every panel was a single row of fields and
   wrong once a five-leg Multi City itinerary reached ~800px, because a hidden
   panel still taking part in layout made every other product 800px of mostly
   empty card.

   Only the ACTIVE panel is laid out, and a card now builds only one panel in
   the first place — so this pair is what keeps the built panel visible and
   what keeps a re-seeded card from showing two at once. */
.search-card .search-panel { display: none; }
.search-card .search-panel.active { display: block; visibility: visible; }

/* --------------------------------------------------------------------------
   The collapsed summary strip — phones, on a results page only
   --------------------------------------------------------------------------
   A results page on a 375px phone gave the search card ~920px of screen before
   the first fare, because the fields stack. The card is not what someone who
   has already searched is there to read; it is what they occasionally need to
   CHANGE. So on a narrow screen it folds down to one line of what they asked
   for, and opens again on a tap.

   SCOPED TO .hero.is-compact, so the landing page is untouched: there the card
   IS the content and folding it would leave a page with nothing to do. The
   markup is rendered on every page and simply never shown on the others, which
   keeps one card rather than a card and a mobile card.
   -------------------------------------------------------------------------- */
.search-strip { display: none; }

@media (max-width: 760px) {
  .hero.is-compact .search-card > .search-strip {
    display: flex; align-items: center; gap: 12px; width: 100%;
    padding: 13px 15px; border: none; background: none;
    font-family: inherit; text-align: left; cursor: pointer;
    color: var(--navy); border-radius: inherit;
  }
  /* Everything except the handle. The strip stays put when the card opens —
     a disclosure whose only close control disappears on open is a trap. */
  .hero.is-compact .search-card.is-collapsed > :not(.search-strip) { display: none; }
  /* Open: the strip becomes a header, so it needs a line under it. */
  .hero.is-compact .search-card:not(.is-collapsed) > .search-strip {
    border-bottom: 1px solid rgba(10, 37, 64, .09);
  }

  .search-strip-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
  /* Both lines truncate rather than wrap: a two-line route pushes the whole
     strip taller than the row it is replacing. */
  .search-strip-main,
  .search-strip-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .search-strip-main { font-size: 14.5px; font-weight: 800; letter-spacing: -.01em; }
  .search-strip-sub { font-size: 12px; font-weight: 600; color: var(--muted); }

  .search-strip-edit {
    display: inline-flex; align-items: center; gap: 3px; flex: none;
    font-size: 12.5px; font-weight: 700; color: var(--coral);
  }
  .search-strip-edit .jpi { width: 15px; height: 15px; transition: transform .22s ease; }
  .search-card:not(.is-collapsed) .search-strip-edit .jpi { transform: rotate(180deg); }
  .search-strip:focus-visible { outline: 3px solid var(--coral); outline-offset: -3px; }

  /* The band exists only to hold the card now, so it stops being a hero. */
  .hero.is-compact:has(.search-card.is-collapsed) { padding-bottom: 14px; }
}

/* --------------------------------------------------------------------------
   Product tabs — the first control in the card
   --------------------------------------------------------------------------
   What you are booking, asked before anything else, because it decides what
   every field under it means. Deliberately a DIFFERENT shape from the trip
   pills below it: underlined tabs against a rounded pill group, so the two
   rows never read as one strip of eight equal choices. They answer different
   questions and they should not look interchangeable.
   -------------------------------------------------------------------------- */
.search-tabs {
  display: flex; gap: 2px; align-items: stretch;
  padding: 6px 10px 0;
  border-bottom: 1px solid rgba(10, 37, 64, .09);
  /* Scrolls INSIDE the card on a narrow screen rather than widening it. The
     card is the scroll container, so the page itself never gains a horizontal
     scrollbar — which is the failure this replaces, not a nicety. */
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.search-tabs::-webkit-scrollbar { display: none; }

.search-tab {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 11px 15px 10px; border: none; background: none;
  border-bottom: 2.5px solid transparent; margin-bottom: -1px;
  font-family: inherit; font-size: 13px; font-weight: 700; letter-spacing: .01em;
  color: var(--navy); opacity: .55; cursor: pointer; white-space: nowrap;
  transition: opacity .2s ease, color .2s ease, border-color .2s ease;
}
/* Matches on .jpi, not svg. Every icon here is a jp-icons drawing now, so what
   needs sizing is the hydrated host; the <svg> inside already fills it. */
/* Sized by .jpi-btn at 18px; this only has to keep it out of the flex sizing. */
.search-tab .jpi { flex: none; }
.search-tab:hover:not(.is-on) { opacity: .85; }
.search-tab.is-on { opacity: 1; color: var(--coral); border-bottom-color: var(--coral); }
/* Inset, because the outline of a tab flush against the card's rounded top
   edge is otherwise clipped by the card's own overflow. */
.search-tab:focus-visible { outline: 3px solid var(--coral); outline-offset: -3px; border-radius: 6px; }

@media (max-width: 700px) {
  .search-tabs { padding: 4px 6px 0; }
  .search-tab { padding: 10px 11px 9px; font-size: 12.5px; gap: 5px; }
  .search-tab .jpi { width: 16px; height: 16px; }
}

/* --------------------------------------------------------------------------
   Trip type — the flights panel's first control
   -------------------------------------------------------------------------- */
/* Sits under the product tabs, inside the Flights panel only: it says what
   KIND of flight search this is, which is a different question from which
   product is being searched. Its own top margin (below) is the whole gap
   between the two rows. */

.trip-types {
  display: flex; gap: 3px; width: max-content; max-width: 100%;
  margin: 6px 6px 5px; padding: 2px; border-radius: 100px;
  background: rgba(10, 37, 64, 0.055);
}
.trip-type {
  padding: 5px 14px; border-radius: 100px; border: none; background: none;
  font-family: inherit; font-size: 12px; font-weight: 700; letter-spacing: .01em;
  color: var(--navy); opacity: .6; cursor: pointer; white-space: nowrap;
  transition: background .22s ease, opacity .22s ease, box-shadow .22s ease, color .22s ease;
}
.trip-type:hover:not(.is-on) { opacity: .88; background: rgba(255, 255, 255, .55); }
.trip-type.is-on {
  background: var(--navy); color: #fff; opacity: 1; box-shadow: var(--shadow-sm);
}
.trip-type:focus-visible { outline: 3px solid var(--coral); outline-offset: 2px; }

/* --------------------------------------------------------------------------
   The flights row

   Named areas rather than source order, because the same eight columns carry
   two different layouts: one way puts the return DATE in the fifth column,
   round trip gives the whole return LEG a second row underneath the outbound
   one. DOM order is outbound, return leg, party, so the tab order and the
   small-screen stack both read top to bottom without a single `order`.
   -------------------------------------------------------------------------- */
/* SEVEN COLUMNS NOW, NOT EIGHT. Moving Search into the card footer gave the
   row back its widest column, and the 114px went to the fields that measured
   short of what they hold. The shares are set from MEASURED text, not guessed:

       "Hyderabad (HYD)"     140px text + 36 padding             = 176
       "Thu, 10 Sep"         114px (incl. the calendar icon
                             gutter) + 36                        = 150
       "Premium Economy"     156px + 36 + 22 for the select arrow = 214
       "2 Adults, 2 Children,
        1 Infant"            211px at 14.5px + 36 + 21 caret     = 268

   1099px to divide at 1280px, and 176+176+150+150+268+214 is 1134 — still 35
   over, so Cabin keeps the 197 it can live with (it was clipping at 150 before
   any of this) and Passengers takes 250, which holds every party up to
   "2 Adults, 1 Child, 1 Infant" whole. */
.flight-grid {
  grid-template-columns: 1.06fr auto 1.06fr .9fr .9fr 1.5fr 1.18fr;
  grid-template-areas: "from swap to dep ret pax cabin";
  transition: none;
}
.flight-grid.is-round {
  grid-template-areas:
    "from  swap   to  dep dep pax cabin"
    "rfrom mirror rto ret ret pax cabin";
}

.flight-grid > [data-fg="from"]   { grid-area: from; }
.flight-grid > [data-fg="swap"]   { grid-area: swap; }
.flight-grid > [data-fg="to"]     { grid-area: to; }
.flight-grid > [data-fg="dep"]    { grid-area: dep; }
.flight-grid > [data-fg="ret"]    { grid-area: ret; }
.flight-grid > [data-fg="rfrom"]  { grid-area: rfrom; }
.flight-grid > [data-fg="mirror"] { grid-area: mirror; }
.flight-grid > [data-fg="rto"]    { grid-area: rto; }
.flight-grid > [data-fg="pax"]    { grid-area: pax; }
.flight-grid > [data-fg="cabin"]  { grid-area: cabin; }

/* The return leg exists in the DOM for every trip type so the mirror can be
   kept up to date without re-rendering; only Round Trip shows it. */
.flight-grid > [data-fg="rfrom"],
.flight-grid > [data-fg="mirror"],
.flight-grid > [data-fg="rto"] { display: none; }
.flight-grid.is-round > [data-fg="rfrom"],
.flight-grid.is-round > [data-fg="rto"] { display: block; }
.flight-grid.is-round > [data-fg="mirror"] { display: flex; }

/* Passengers and Cabin sit beside a one-row or a two-row route, so their
   contents centre in whatever height the row turns out to be. */
.flight-grid > [data-fg="pax"],
.flight-grid > [data-fg="cabin"] { display: flex; flex-direction: column; justify-content: center; }

/* A grid track is never narrower than its content unless it is told it may be.
   The party summary is one nowrap line, so "3 Adults, 2 Children, 1 Infant"
   pushed the Passengers column from 150px to 282px and took the width out of
   the airport boxes beside it — the column changed size as the party did.
   min-width:0 lets the track keep its share and the label ellipsis instead. */
.flight-grid > [data-fg="pax"] { min-width: 0; }

/* --------------------------------------------------------------------------
   Airport picker

   The MARKUP is SearchWidgets.mountAutocomplete's, shared with the hotels and
   packages panels — hence the tx-ap-* names. Only the SKIN is particular: those
   panels are flat white surfaces using --sp-* tokens, and this one has to sit
   over a video against a glass card.

   SELECTED BY [data-ap-owner], not by .search-card, because the list is not
   inside the card any more: anchorDropdown() moves it to <body> so the card's
   backdrop-filter cannot capture its fixed positioning. The attribute is set
   only on the lists this file portals, so travel-explore.css's plain
   .tx-ap-list still dresses the hotels and packages panels and neither file has
   to know about the other.
   -------------------------------------------------------------------------- */
.field-airport { position: relative; }

.tx-ap-list[data-ap-owner] {
  position: fixed; z-index: 130;
  /* min-width is set from the field by anchorDropdown; max-content lets a long
     city name size the list past it rather than wrap or truncate. */
  width: max-content; max-width: min(380px, calc(100vw - 16px));
  max-height: min(320px, 50vh); overflow-y: auto; overscroll-behavior: contain;
  padding: 6px; border-radius: 16px;
  background: #fff; border: 1px solid var(--line); box-shadow: var(--shadow-lg);
}
[data-ap-owner] .tx-ap-group {
  padding: 9px 10px 5px; font-size: 10.5px; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
[data-ap-owner] .tx-ap-opt {
  padding: 9px 10px; border-radius: 10px; cursor: pointer;
  transition: background .14s ease;
}
[data-ap-owner] .tx-ap-opt b { display: block; font-size: 14px; font-weight: 700; color: var(--navy); }
[data-ap-owner] .tx-ap-opt span { display: block; font-size: 12px; font-weight: 600; color: var(--muted); }
/* is-active is the keyboard cursor; hover is the mouse. They look the same on
   purpose — there is only ever one of them on screen. */
[data-ap-owner] .tx-ap-opt:hover,
[data-ap-owner] .tx-ap-opt.is-active { background: rgba(10, 37, 64, 0.06); }
[data-ap-owner] .tx-ap-empty { padding: 14px 10px; font-size: 13px; font-weight: 600; color: var(--muted); }

/* --------------------------------------------------------------------------
   One way — the return date stays in place and is visibly out of service
   -------------------------------------------------------------------------- */
.field-date.is-disabled {
  opacity: .42; pointer-events: none; background: rgba(10, 37, 64, 0.03);
}
.field-date.is-disabled .date-display { cursor: not-allowed; }
.field-date.is-disabled .date-display::placeholder { opacity: .85; font-weight: 600; }

/* --------------------------------------------------------------------------
   Round trip — the mirrored return route
   -------------------------------------------------------------------------- */
.field-mirrored { background: rgba(10, 37, 64, 0.028); }
.field-mirrored:hover { background: rgba(10, 37, 64, 0.05); }
.field-mirrored input {
  cursor: default; color: var(--navy); opacity: .82;
}
.field-mirrored input:focus-visible { outline: 3px solid var(--coral); outline-offset: 4px; }

/* Points at the pair it links, and turns with the swap it reflects. */
.mirror-mark {
  align-self: center; justify-content: center; align-items: center;
  width: 42px; height: 42px; color: var(--muted); opacity: .55;
}
.mirror-mark .jpi { width: 19px; height: 19px; }

/* --------------------------------------------------------------------------
   Card footer — the one Search button, bottom right

   It used to be the last cell of the field row, which pinned it to the outer
   edge, stretched it to whatever height the row happened to be, and gave every
   product panel its own copy. Down here there is ONE, it sits at the bottom
   right of the card whatever the panel above is showing, and Multi City can
   grow to five route rows without it having to be the end of anything.
   -------------------------------------------------------------------------- */
.search-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 10px 6px 0; margin-top: 2px;
}
.search-foot-note { margin: 0; font-size: 11.5px; font-weight: 600; color: var(--muted); }
.search-foot-note:empty { display: none; }
/* One message, beside the button that produced it. See booking-card.js's
   clearError/complain for why it lives here and not under each field. */
.search-foot-error { margin: 0; font-size: 12.5px; font-weight: 700; color: var(--coral-dark, #C0392B); }
.search-foot-error:empty { display: none; }
/* A note and an error never both apply, and the error is the one that matters. */
.search-foot-error:not(:empty) ~ .search-foot-note,
.search-foot-note:has(~ .search-foot-error:not(:empty)) { display: none; }

/* The field the message is about. */
.search-card .field.is-invalid {
  background: rgba(192, 57, 43, .07);
  box-shadow: inset 0 0 0 1.5px var(--coral-dark, #C0392B);
}
/* Hotels, Cruises and Packages each ended their column template with an `auto`
   track for the Search button they used to carry. The button is in the footer
   now, so that track would sit empty at the end of the row and pull the fields
   left of centre. main.css is left alone; the trailing track is simply dropped
   here, where the rest of this feature already lives. */
.search-fields.cols-6 { grid-template-columns: 1.2fr .95fr .95fr .9fr .9fr; }
.search-fields.cols-5 { grid-template-columns: 1.15fr .9fr .9fr .9fr; }
.search-fields.cols-3 { grid-template-columns: 1.3fr 1fr; }
/* Gaming Tour Packages: Destination, Date, Time — three fields on one row. */
.search-fields.cols-gaming { grid-template-columns: 1.3fr 1fr 1fr; }

.search-foot .search-go {
  /* margin-left:auto, not just justify-content — the note is hidden when empty
     and the button must stay right whether or not it has a neighbour. */
  margin-left: auto; flex: none;
  min-height: 48px; padding: 0 34px; border-radius: 14px; font-size: 15px;
}

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

   Route rows reuse .field, .swap-btn and .field-date exactly as the one-way row
   does — they are the same controls, so they get the same classes and inherit
   every later change to them for free. What is particular to a leg is only the
   number badge, the remove button and the column template.
   -------------------------------------------------------------------------- */
.mc { padding: 6px; }
.mc-routes { display: flex; flex-direction: column; gap: 6px; }

.mc-route {
  display: grid; align-items: center; gap: 3px;
  /* A leg carries three fields where the one-way row carries five, so it gets
     its own proportions rather than the row's — matching them exactly would
     force Departure to 683px to keep From and To at their 176px, which is a
     date box four times wider than the date it holds. The cap is what stops
     Departure absorbing everything the missing fields left behind. */
  grid-template-columns: 26px minmax(0, 1fr) auto minmax(0, 1fr) minmax(0, 260px) 40px;
  /* max-height rather than height, because the row has no fixed height to
     animate between; 200px clears the tallest it gets (84px) without the
     easing visibly overshooting. */
  max-height: 200px; overflow: hidden;
  transition: max-height .28s cubic-bezier(.22, 1, .36, 1),
              opacity .22s ease, transform .28s cubic-bezier(.22, 1, .36, 1);
}

/* ENTRY IS A KEYFRAME ANIMATION, REMOVAL IS A TRANSITION, AND THAT ASYMMETRY
   IS DELIBERATE.

   A transition needs its start value committed before the end value is set, and
   it only lands on the end value if the animation actually runs. A row that is
   added while the tab is not compositing therefore stayed at max-height:0 —
   present, focusable, and invisible. An animation with no fill-mode cannot fail
   that way: it decorates the row's natural state rather than defining it, so if
   it never runs the row is simply there at full height.

   Removal is the opposite case — the node is deleted at the end either way, and
   removeRoute has a timeout that fires whether or not transitionend does. */
@keyframes mcRouteIn {
  from { max-height: 0; opacity: 0; transform: translateY(-6px); }
  to   { max-height: 200px; opacity: 1; transform: none; }
}
.mc-route.is-entering { animation: mcRouteIn .28s cubic-bezier(.22, 1, .36, 1); }
.mc-route.is-leaving { max-height: 0; opacity: 0; transform: translateY(-6px); }

/* Which leg this is. A number rather than "Flight 1 — From Airport" on every
   label: the labels stay as short as the one-way row's, and the leg number is
   on each input's accessible name instead (booking-card.js, paintRouteChrome). */
.mc-num {
  display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%;
  background: rgba(10, 37, 64, 0.07); color: var(--muted);
  font-size: 11.5px; font-weight: 800; font-variant-numeric: tabular-nums;
}

.mc-remove {
  display: grid; place-items: center; width: 34px; height: 34px; justify-self: center;
  border: none; border-radius: 10px; background: none; color: var(--muted);
  cursor: pointer; transition: background .18s ease, color .18s ease;
}
.mc-remove:hover { background: rgba(233,185,73,.16); color: var(--coral); }
.mc-remove:focus-visible { outline: 3px solid var(--coral); outline-offset: 2px; }
.mc-remove .jpi { width: 17px; height: 17px; }
/* The first leg IS the itinerary and has nothing to be removed back to. Hidden
   rather than absent so every row keeps the same six columns — and
   visibility:hidden also takes it out of the tab order. */
.mc-remove.is-hidden { visibility: hidden; }

.mc-actions { display: flex; align-items: center; gap: 14px; padding: 10px 6px 2px; }
.mc-add {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 16px; border-radius: 100px;
  border: 1.5px dashed rgba(10, 37, 64, .22); background: none;
  font-family: inherit; font-size: 13px; font-weight: 700; color: var(--navy);
  cursor: pointer; transition: border-color .2s ease, color .2s ease, background .2s ease;
}
.mc-add:hover:not(:disabled) {
  border-color: var(--coral); color: var(--coral); background: rgba(255, 77, 77, .06);
}
.mc-add:disabled { opacity: .45; cursor: not-allowed; }
.mc-add:focus-visible { outline: 3px solid var(--coral); outline-offset: 2px; }
.mc-add .jpi { width: 16px; height: 16px; }
.mc-limit { margin: 0; font-size: 11.5px; font-weight: 600; color: var(--muted); }
.mc-limit:empty { display: none; }

/* Passengers and Cabin, once, for the whole itinerary. These are the SAME two
   elements as the one-way row — paintTrip moves them here — so they only need
   somewhere to sit, and they sit under the columns they occupy up there. */
.mc-party {
  display: grid; gap: 3px; margin-top: 4px;
  /* The 26px gutter lines this band's left edge up with the route rows' From
     boxes, past their number badges. Passengers and Cabin then take the exact
     widths they have in the one-way row, so switching trip type does not resize
     the two controls that are shared between them. */
  grid-template-columns: 26px minmax(0, 250px) minmax(0, 197px) 1fr;
}
.mc-party > [data-fg="pax"] { grid-column: 2; }
.mc-party > [data-fg="cabin"] { grid-column: 3; }
/* Overrides the .flight-grid rule, which no longer applies out here. */
.mc-party > .field { display: flex; flex-direction: column; justify-content: center; }

@media (prefers-reduced-motion: reduce) {
  .mc-route { transition: none; }
  .mc-route.is-entering { animation: none; }
}

/* --------------------------------------------------------------------------
   Hotels

   Destination, Check-in, Check-out and Nights are the same four cells in both
   modes and never move — that is what "shared data survives the switch" looks
   like in the layout, not just in the state. Only the fifth and sixth cells
   change, and the contact block below appears.
   -------------------------------------------------------------------------- */
.hotel-grid {
  grid-template-columns: 1.9fr 1.05fr 1.05fr .5fr 1.5fr;
  grid-template-areas: "dest in out nights rooms";
}
.hotel-grid.is-group {
  grid-template-columns: 1.9fr 1.05fr 1.05fr .5fr .8fr 1.1fr;
  grid-template-areas: "dest in out nights grooms gguests";
}
.hotel-grid > [data-hf="dest"]     { grid-area: dest; min-width: 0; }
.hotel-grid > [data-hf="in"]       { grid-area: in; }
.hotel-grid > [data-hf="out"]      { grid-area: out; }
.hotel-grid > [data-hf="nights"]   { grid-area: nights; }
.hotel-grid > [data-hf="rooms"]    { grid-area: rooms; min-width: 0; }
.hotel-grid > [data-hf="grooms"]   { grid-area: grooms; }
.hotel-grid > [data-hf="gguests"]  { grid-area: gguests; }

/* Each mode hides the other's cells. Hidden, not removed: the elements keep
   their values, so switching back and forth does not reset a room count. */
.hotel-grid > [data-hf="grooms"],
.hotel-grid > [data-hf="gguests"] { display: none; }
.hotel-grid.is-group > [data-hf="rooms"] { display: none; }
.hotel-grid.is-group > [data-hf="grooms"],
.hotel-grid.is-group > [data-hf="gguests"] { display: flex; flex-direction: column; justify-content: center; }

.hotel-grid > [data-hf="rooms"] { display: flex; flex-direction: column; justify-content: center; }

/* Derived from the two dates, so it is an output rather than a control — no
   hover lift, no pointer, nothing that suggests it can be changed directly. */
.field-nights { background: rgba(10, 37, 64, 0.025); }
.field-nights:hover { background: rgba(10, 37, 64, 0.025); }
.nights-out {
  display: block; font-size: 15.5px; font-weight: 700; color: var(--navy);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* Number inputs for the group's room and guest counts. The spinner is left on
   — this is a quantity, and the arrows are the fastest way to nudge one. */
.hotel-grid input[type="number"] {
  border: none; background: none; width: 100%; outline: none;
  font-family: inherit; font-weight: 700; font-size: 15.5px; color: var(--navy);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Group Deals — the contact block

   Appears below the common row rather than replacing it, so the dates and
   destination stay exactly where they were when the mode changed.
   -------------------------------------------------------------------------- */
.hotel-group {
  padding: 4px 6px 0;
  animation: hotelGroupIn .26s cubic-bezier(.22, 1, .36, 1);
}
/* An animation rather than a height transition, for the reason set out over
   .mc-route: with no fill-mode it decorates the block's natural state, so a
   frame that never runs leaves the form visible rather than collapsed. */
@keyframes hotelGroupIn {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}
.hotel-group-lead {
  margin: 6px 0 10px; font-size: 12.5px; font-weight: 600; color: var(--muted);
  line-height: 1.5;
}
.hotel-contact {
  grid-template-columns: 1fr 1.2fr 1fr;
  grid-template-areas:
    "name  email   phone"
    "company notes notes";
}
.hotel-contact > [data-hf="name"]    { grid-area: name; }
.hotel-contact > [data-hf="email"]   { grid-area: email; }
.hotel-contact > [data-hf="phone"]   { grid-area: phone; }
.hotel-contact > [data-hf="company"] { grid-area: company; }
.hotel-contact > [data-hf="notes"]   { grid-area: notes; }

.hotel-contact textarea {
  border: none; background: none; width: 100%; outline: none; resize: vertical;
  font-family: inherit; font-weight: 600; font-size: 14.5px; color: var(--navy);
  line-height: 1.45; min-height: 42px;
}
.hotel-contact textarea::placeholder { color: var(--navy); opacity: .45; font-weight: 600; }

/* --------------------------------------------------------------------------
   Group enquiry: sending, and sent
   --------------------------------------------------------------------------
   The acknowledgement REPLACES the form rather than sitting above it. A form
   still on screen after a successful submit reads as one that did not go, and
   is the shortest path to the same enquiry arriving twice. */
.search-panel.is-sent > *:not(.hotel-sent) { display: none; }

.hotel-sent {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 6px; padding: 26px 18px 22px;
  animation: hotelSentIn .3s cubic-bezier(.22, 1, .36, 1);
}
@keyframes hotelSentIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.hotel-sent-tick {
  width: 42px; height: 42px; border-radius: 50%;
  color: var(--emerald, #1E9E6A); margin-bottom: 4px;
}
.hotel-sent h3 { margin: 0; font-size: 18px; font-weight: 800; color: var(--navy); }
.hotel-sent p {
  margin: 0; max-width: 46ch; font-size: 13.5px; font-weight: 600;
  color: var(--muted); line-height: 1.55;
}
.hotel-sent-again { margin-top: 12px; }

/* Mid-send. The label already says "Sending…"; this stops the press landing
   twice and takes the hover affordance away while it is in flight. */
.search-go.is-busy { opacity: .72; cursor: progress; }
.search-go[disabled] { pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .hotel-sent { animation: none; }
}

/* Says a field can be skipped without making it look disabled. */
.field-optional {
  font-size: 9.5px; font-weight: 700; letter-spacing: .04em;
  color: var(--muted); opacity: .8; text-transform: none;
}

/* --------------------------------------------------------------------------
   Rooms & guests popover
   -------------------------------------------------------------------------- */
.rooms-pop { width: min(420px, calc(100vw - 20px)); }
.rooms-list { display: flex; flex-direction: column; gap: 14px; }
.rooms-room + .rooms-room { padding-top: 14px; border-top: 1px solid var(--line); }
.rooms-room-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.rooms-room-head b { font-size: 13.5px; font-weight: 800; color: var(--navy); }
.rooms-remove {
  border: none; background: none; padding: 2px 6px; border-radius: 8px;
  font-family: inherit; font-size: 12px; font-weight: 700; color: var(--muted);
  cursor: pointer; transition: color .18s ease, background .18s ease;
}
.rooms-remove:hover { color: var(--coral); background: rgba(233,185,73,.16); }
.rooms-remove:focus-visible { outline: 3px solid var(--coral); outline-offset: 2px; }

/* SearchWidgets.stepperRow's markup, in the card's clothes. The panels on the
   hotels and packages pages dress the same classes from travel-explore.css;
   scoping here keeps the two skins apart without either file knowing. */
.rooms-pop .tx-pax-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 5px 0; }
.rooms-pop .tx-pax-row b { display: block; font-size: 13.5px; font-weight: 700; color: var(--navy); }
.rooms-pop .tx-pax-row span { display: block; font-size: 11.5px; font-weight: 600; color: var(--muted); }
.rooms-pop .tx-pax-step { display: flex; align-items: center; gap: 10px; flex: none; }
.rooms-pop .tx-pax-btn {
  width: 30px; height: 30px; border-radius: 9px; border: 1.5px solid var(--line);
  background: #fff; color: var(--navy); font-family: inherit; font-size: 15px;
  font-weight: 700; line-height: 1; cursor: pointer;
  transition: border-color .16s ease, color .16s ease;
}
.rooms-pop .tx-pax-btn:hover:not(:disabled) { border-color: var(--coral); color: var(--coral); }
.rooms-pop .tx-pax-btn:disabled { opacity: .35; cursor: not-allowed; }
.rooms-pop .tx-pax-btn:focus-visible { outline: 3px solid var(--coral); outline-offset: 2px; }
.rooms-pop .tx-pax-step output {
  min-width: 20px; text-align: center; font-weight: 800; font-size: 15px;
  color: var(--navy); font-variant-numeric: tabular-nums;
}

.rooms-ages { margin-top: 8px; padding-top: 10px; border-top: 1px dashed var(--line); }
.rooms-ages b { display: block; font-size: 11px; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 7px; }
.rooms-agegrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); gap: 8px; }
.rooms-age span { display: block; font-size: 11px; font-weight: 600; color: var(--muted); margin-bottom: 3px; }
.rooms-age select {
  width: 100%; padding: 7px 8px; border-radius: 9px; border: 1.5px solid var(--line);
  background: #fff; color: var(--navy); font-family: inherit; font-size: 13.5px; font-weight: 700;
  cursor: pointer; outline: none;
}
.rooms-age select:focus-visible { outline: 3px solid var(--coral); outline-offset: 1px; }
/* An age nobody has chosen yet. Outlined rather than filled: it is a gap in the
   form, not an error the guest has made. */
.rooms-age.is-unset select { border-color: var(--coral); color: var(--muted); }
.rooms-add { width: 100%; justify-content: center; margin-top: 14px; }

/* --------------------------------------------------------------------------
   Passengers — trigger
   -------------------------------------------------------------------------- */
.field-pax .pax-trigger {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  width: 100%; padding: 0; border: none; background: none; cursor: pointer;
  font-family: inherit; font-size: 15.5px; font-weight: 700; color: var(--navy);
  text-align: left; line-height: 1.35;
}
/* ONE line, and the column was widened to hold it — see the grid rebalance
   above. A second line was tried and rejected: it made the pax field 84px tall
   where every other field is 72, which pushed the whole row and the card 12px
   taller, and card height is the constraint this feature was given. At 14.5px
   in the widened column the parties people actually book — up to "3 Adults, 2
   Children" — fit whole; the rare longest one ellipsises, with the full text on
   the button's title and accessible name (pax-selector.js, paintTrigger). */
.pax-trigger-text {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 14.5px;
}
.pax-caret { width: 15px; height: 15px; flex: none; color: var(--muted); transition: transform .22s ease; }
.pax-trigger[aria-expanded="true"] .pax-caret { transform: rotate(180deg); }

/* --------------------------------------------------------------------------
   Passengers — the popover

   position:fixed and a child of <body>: the hero is overflow:hidden and clipped
   an absolutely positioned panel. pax-selector.js measures the trigger and
   flips this above it when the space below is short.
   -------------------------------------------------------------------------- */
.pax-pop {
  position: fixed; z-index: 140;
  width: min(370px, calc(100vw - 20px));
  /* A phone in landscape has less height than this panel needs. It scrolls
     inside itself rather than running off the bottom of the screen, which is
     where a fixed element has nowhere to go. */
  max-height: calc(100vh - 16px); overflow-y: auto; overscroll-behavior: contain;
  padding: 16px; border-radius: 20px;
  background: #fff; border: 1px solid var(--line); box-shadow: var(--shadow-lg);
  opacity: 0; transform: translateY(-6px) scale(.985); transform-origin: top center;
  transition: opacity .18s ease, transform .18s ease;
}
.pax-pop.is-above { transform-origin: bottom center; transform: translateY(6px) scale(.985); }
.pax-pop.is-open { opacity: 1; transform: none; }

.pax-group + .pax-group { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.pax-group-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 9px; }
.pax-group-head b { font-size: 13.5px; font-weight: 800; color: var(--navy); }
.pax-group-head span { font-size: 11.5px; font-weight: 600; color: var(--muted); }

/* Nine columns for every group, not just Adults: the seven-block rows then
   line up under the nine-block one instead of stretching to fill the width. */
.pax-blocks { display: grid; grid-template-columns: repeat(9, 1fr); gap: 5px; }
.pax-block {
  height: 34px; padding: 0; border-radius: 10px;
  border: 1.5px solid var(--line); background: #fff;
  font-family: inherit; font-size: 13.5px; font-weight: 700; color: var(--navy);
  cursor: pointer; font-variant-numeric: tabular-nums;
  transition: background .16s ease, border-color .16s ease, color .16s ease, transform .12s ease;
}
.pax-block:hover:not(:disabled):not(.is-on) { border-color: var(--coral); color: var(--coral); }
.pax-block:active:not(:disabled) { transform: translateY(1px); }
.pax-block.is-on { background: var(--navy); border-color: var(--navy); color: #fff; }
.pax-block:disabled { opacity: .3; cursor: not-allowed; }
.pax-block:focus-visible { outline: 3px solid var(--coral); outline-offset: 2px; }

.pax-pop-foot { display: flex; align-items: center; gap: 12px; margin-top: 15px; padding-top: 13px; border-top: 1px solid var(--line); }
.pax-hint { flex: 1; margin: 0; font-size: 11.5px; font-weight: 600; color: var(--muted); line-height: 1.45; }
/* An auto-reduction is the one thing in this panel the traveller did not ask
   for, so it is the one thing that is not grey. */
.pax-hint .is-adjusted { color: var(--coral-dark); font-weight: 700; }
.pax-done {
  flex: none; padding: 9px 20px; border-radius: 11px; border: none;
  background: var(--navy); color: #fff; font-family: inherit;
  font-size: 13px; font-weight: 800; cursor: pointer; transition: background .2s ease;
}
.pax-done:hover { background: var(--navy-3, #1B4577); }
.pax-done:focus-visible { outline: 3px solid var(--coral); outline-offset: 2px; }

/* --------------------------------------------------------------------------
   Responsive

   main.css already collapses .search-fields to one column below 900px. The
   named areas have to be dropped there or they would keep forcing eight
   columns onto a phone; source order takes over, which is why the DOM is
   ordered the way it is.
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
  /* THE COLUMN TEMPLATES HAVE TO BE UNDONE HERE, NOT JUST THE AREAS.
     main.css collapses .search-fields to a single column below 900px, and it
     used to be the only rule setting columns on these grids. This file now sets
     its own — same specificity, later stylesheet — so main.css's mobile rule
     lost and a 375px phone rendered the seven-column desktop row inside a 553px
     card that the hero then clipped. Every template this file introduces is
     listed below; adding another one means adding it here too. */
  .flight-grid, .flight-grid.is-round,
  .hotel-grid, .hotel-grid.is-group, .hotel-contact,
  .search-fields.cols-6, .search-fields.cols-5, .search-fields.cols-3,
  .search-fields.cols-gaming {
    grid-template-columns: 1fr;
  }
  .flight-grid, .flight-grid.is-round { grid-template-areas: none; }
  .hotel-grid, .hotel-grid.is-group, .hotel-contact { grid-template-areas: none; }
  .hotel-grid > [data-hf], .hotel-contact > [data-hf] { grid-area: auto; }
  .rooms-agegrid { grid-template-columns: repeat(2, 1fr); }
  /* A leg stacks the same way the one-way row does. The number badge and the
     remove button share a line above the fields rather than each taking a full
     row of their own. */
  .mc-route {
    grid-template-columns: 1fr auto;
    max-height: 520px;
  }
  /* grid-row:1 on BOTH, or auto-placement puts the remove button after the
     three full-width fields and it lands at the bottom of the row instead of
     on its header line. The fields then flow from row 2 on their own. */
  .mc-num { grid-column: 1; grid-row: 1; justify-self: start; }
  .mc-remove { grid-column: 2; grid-row: 1; justify-self: end; }
  .mc-route > .field, .mc-route > .field-date { grid-column: 1 / -1; }
  .mc-routes { gap: 14px; }
  .mc-party { grid-template-columns: 1fr; gap: 6px; }
  .mc-party > [data-fg="pax"], .mc-party > [data-fg="cabin"] { grid-column: 1; }
  .search-foot { flex-wrap: wrap; }
  .search-foot .search-go { width: 100%; }
  /* `grid-area: from` MUST be reset with the areas, not just left behind.
     Dropping grid-template-areas does not turn those names back into auto
     placement — an unmatched name is resolved against IMPLICIT lines, so every
     field claimed a line of its own and the ten of them ended up in one row on
     a 375px screen, in a grid 425px wide that the hero then clipped. */
  .flight-grid > [data-fg] { grid-area: auto; }
  .mirror-note { grid-column: auto; }
  .mirror-mark { display: none !important; }
  .trip-types { width: 100%; justify-content: space-between; }
  .trip-type { flex: 1; text-align: center; padding: 8px 6px; }
  .pax-blocks { gap: 4px; }
  .pax-block { height: 32px; font-size: 13px; }
}
@media (max-width: 420px) {
  .pax-pop { padding: 14px; }
  .pax-pop-foot { flex-direction: column; align-items: stretch; gap: 9px; }
  .pax-done { width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .pax-pop { transition: none; }
  .hotel-group { animation: none; }
}

/* ===========================================================================
   Flights page — the landing page continued, not a second layout
   ===========================================================================
   Set by flights.html on <body>. The page wears the landing page's header,
   hero video and search card; these rules are only about the seam between that
   hero and the results underneath it.
   =========================================================================== */

/* booking.css speaks --sp-*, the token names service-page.css declares. This
   page does not load service-page.css (it would bring a second header design
   and a second palette), so the names are bridged onto main.css's palette here.
   Aliases, not new values: the booking flow looks the same on every page it
   opens on, which is the point of it having tokens at all. */
body.sp-continuation {
  --sp-bg:          var(--bg);
  --sp-surface:     var(--white);
  --sp-surface-2:   #F1F5F9;
  --sp-ink:         var(--navy);
  --sp-muted:       var(--muted);
  --sp-line:        var(--line);
  --sp-accent:      var(--coral);
  --sp-accent-dk:   var(--coral-dark);
  --sp-coral-dark:  #C0392B;
  --sp-accent-soft: rgba(233,185,73,.18);
  --sp-gold:        var(--gold);
  --sp-emerald:     var(--emerald);
  --sp-header:      var(--navy);
  --sp-header-ink:  #fff;
  --sp-radius:      16px;
}

/* THE HERO IS NOT RESIZED HERE, AND THAT IS THE POINT.

   An earlier version shrank it — smaller heading, shorter hero — so the flight
   list would start nearer the fold. Measured against the landing page at
   1280px that moved the heading from x=205 to x=352, the h1 from 78px to 50px
   and the card 88px up the page: the exact "noticeable layout shift" the whole
   continuation is meant to avoid. So there is no hero rule here at all. The
   hero renders identically, and travel-explore.js scrolls to the results once
   they are rendered — the content beneath the hero changing, which is what the
   navigation is supposed to feel like.

   THE AUTH SLOT USED TO BE BRIDGED HERE and is not any more. `#shellAuth` was
   a <span> wrapping the Login link and the Sign Up button, flattened with
   display:contents so the two would pick up .nav-actions' 14px gap. It worked,
   and it made the row 9px wider than the landing page's plain .pm-slot div,
   which under `justify-content:space-between` slid the whole nav 5px sideways
   between Home and every other page — the one measurable difference left
   between the two headers. hero-shell.js emits the SAME .pm-slot div now, so
   there is nothing to bridge and this rule would flatten the wrong element. */

/* .tx-section is 1200px/20px and .wrap is 1280px/32px — the same content edge
   in both, so the results line up under the card rather than a few pixels
   inside it. */
body.sp-continuation .tx-section { max-width: var(--max, 1280px); padding: 44px 32px 56px; }

@media (max-width: 900px) {
  body.sp-continuation .tx-section { padding: 32px 20px 44px; }
}

/* ===========================================================================
   THE RESULTS-PAGE SEARCH BAR
   ===========================================================================
   Same component, same fields, same handlers — laid out as one editable row
   instead of the landing page's card. It is not a summary of the search that
   ran: every field is live, and pressing Search re-runs the results on the
   page you are already on. That is the whole reason there is no separate
   "Modify Search" screen.

   The product tabs and the trust row are not drawn at all in this mode (see
   cardHtml), so there is nothing here hiding them.
   =========================================================================== */
.search-card.is-bar {
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(10, 37, 64, .05), 0 6px 18px rgba(10, 37, 64, .06);
}
.search-card.is-bar .search-body { padding: 0; }

/* One row, and the fields size themselves to their content rather than to an
   equal share: "Hyderabad (HYD)" and "1 Adult" do not want the same width. */
.search-card.is-bar .search-fields {
  display: flex; flex-wrap: wrap; align-items: stretch; gap: 1px;
  padding: 0; margin: 0; background: transparent;
}
.search-card.is-bar .search-fields > .field { flex: 1 1 150px; min-width: 0; border-radius: 0; }
.search-card.is-bar .search-fields > .field:first-child { border-top-left-radius: 14px; }
.search-card.is-bar .field-date,
.search-card.is-bar .field-pax { flex: 0 1 168px; }

/* The trip pills sit above the row, flush left, with the row's own padding. */
.search-card.is-bar .trip-types { margin: 10px 12px 8px; }

/* Search joins the row rather than sitting under it on a line of its own. */
.search-card.is-bar .search-foot {
  padding: 10px 12px; gap: 10px; align-items: center;
}
.search-card.is-bar .search-go { min-width: 132px; }

/* The mirrored return leg and the multi-city rows keep their own grids; the
   bar only changes the single-row case. */
.search-card.is-bar [data-trip-multi] .search-fields { padding: 0 12px 10px; }

@media (max-width: 900px) {
  .search-card.is-bar .search-fields > .field { flex: 1 1 46%; }
}
@media (max-width: 560px) {
  .search-card.is-bar .search-fields > .field { flex: 1 1 100%; }
}
