/*
 * RideXpress Design System — Journey patterns (Wave 42 Track A)
 * ============================================================
 *
 * The component layer for a page about a SPECIFIC JOURNEY or SERVICE:
 * "Bangalore Airport -> Mysore", "Local Taxi in Bangalore",
 * "Bangalore to Coorg Tour Package". This is the shared vocabulary
 * Tracks B (airportbase/outstationbase, ~8,804 pages), C
 * (destination/package pages), D (blog) and F (global shell) build
 * their redesigns against.
 *
 * WHY A NEW NAMESPACE (.rx-journey-*)
 * -----------------------------------
 * `.rx-route-card` / `.rx-route-summary` already exist in patterns.css
 * and are in live use inside the STAFF PORTALS (a dispatcher's booking
 * row, an editable pickup/drop summary). Reusing those names for a
 * public marketing surface would have made one class mean two
 * unrelated things and put a portal regression one careless selector
 * away from a public page. `journey` is also the more accurate word:
 * a public page is about a journey a customer is considering, not a
 * route record a dispatcher is editing.
 *
 * WHAT IS REUSED RATHER THAN REBUILT (this design system's own
 * "check before you add" convention, per wave41-trackI's §5):
 *   - .rx-btn / .rx-badge / .rx-input / .rx-field  (components.css)
 *   - .rx-breadcrumb + templates/design_system/patterns/_breadcrumbs.html
 *     (components.css) — extended here with an on-dark variant and a
 *     route-family trail, NOT reimplemented.
 *   - .rx-pill-group / .rx-pill-option  (patterns.css) — the trip-type
 *     selector is these, not a new segmented control.
 *   - .rx-location-field / .rx-location-field__icon (patterns.css) —
 *     the pickup/drop inputs are these.
 *   - .rx-marketing__section / __section-head
 *     (marketing-patterns.css) — section chrome around these components.
 *     NOTE (Wave 42 Track G): __section-eyebrow used to be on this list and
 *     was genuinely used by _journey_trust.html, but marketing-patterns.css
 *     is NOT one of the four stylesheets contract §1 requires — so on Track
 *     B's ~8,804 pages that eyebrow matched no rule and fell back to legacy
 *     style.css's body colour (1.35:1, measured). It is now
 *     .rx-journey-trust__eyebrow, defined below. Anything this file's own
 *     markup renders must be styleable from the four required sheets.
 * Only what genuinely did not exist is defined below.
 *
 * DESIGN RESEARCH THIS IMPLEMENTS
 * -------------------------------
 * See docs/program/wave42-trackA-report.md §2 for the full write-up.
 * The load-bearing findings, from real reference products:
 *
 *  - Blacklane (blacklane.com, per-city airport-transfer pages) leads
 *    with the specific city ("Airport Transfer in New York"), states an
 *    all-inclusive fixed price as the core promise, and carries vehicle
 *    class cards with real capacity/luggage specs. Its weakness: the
 *    booking form sits BELOW the hero image, so a visitor scrolls past
 *    a photo before reaching either a route fact or the action.
 *  - Gozo Cabs (gozocabs.com/book-taxi/bangalore-mysore — the closest
 *    real analogue to these pages, same market, same city-pair page
 *    type) states distance (~145 km), travel time (3-4 h), the via-route
 *    and a per-km rate as PROMINENT NUMERIC FACTS, plus vehicle rows
 *    with category/capacity/AC/price. Its weakness: the form is at the
 *    top but the route facts that justify this page existing are buried
 *    in prose beneath it.
 *  - Rome2Rio renders a route as a compact, scannable set of labelled
 *    facts (duration / distance / price / legs) rather than prose.
 *
 * The synthesis, and the actual IA move here: FUSE the journey identity,
 * the at-a-glance facts, the trust proof and the booking action into ONE
 * hero unit (.rx-journey-hero), instead of legacy's
 * generic-banner-then-separate-widget-slab. Neither reference product
 * does this; both are beaten by it on the specific failure each has.
 *
 * WHAT THIS REPLACES (legacy, live on ~8,804 pages today)
 * -------------------------------------------------------
 * A full-bleed photo with the heading "WELCOME TO RIDEXPRESS!" — the
 * identical string on every one of those pages — above a grey tab bar
 * and a white "Book Your Ride" slab, followed by two competing
 * equal-weight CTAs ("About Us" / "Learn More"). The page's real H1
 * (e.g. "Bangalore to Mysore Cab") appears roughly 800px further down.
 * Zero route facts, zero price, zero trust signal, and no breadcrumb
 * appear above the fold anywhere in that family.
 *
 * BREAKPOINTS: 480/768/1024px, hardcoded per tokens.css's own documented
 * note that custom properties cannot be used inside an @media condition.
 */

/* ==================================================================== */
/* 1. JOURNEY HERO — the fused identity + facts + trust + booking unit   */
/* ==================================================================== */

.rx-journey-hero {
  position: relative;
  background: var(--rx-color-dark-surface);
  color: var(--rx-color-text-on-dark);
  overflow: hidden;
}

/* Optional photographic backdrop. Set as an inline background-image on
   the element (the image is page-specific, so it cannot live in CSS).
   The scrim below is NOT decoration: hero copy and the fact strip must
   stay legible over an arbitrary photo, and the legacy hero's gold-on-
   photo heading is the exact failure mode being designed out. */
.rx-journey-hero--media::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    rgba(19, 36, 53, 0.94) 0%,
    rgba(19, 36, 53, 0.86) 45%,
    rgba(19, 36, 53, 0.62) 100%
  );
  z-index: 1;
}

.rx-journey-hero__inner {
  position: relative;
  z-index: 2;
  max-width: 1200px;
  margin: 0 auto;
  padding: var(--rx-space-6) var(--rx-space-6) var(--rx-space-12);
}

/* Identity column and booking panel are ONE grid, not a hero with a
   widget beneath it. 1fr/minmax keeps the booking panel at a usable
   form width while the identity column takes the remainder. */
.rx-journey-hero__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--rx-space-8);
  align-items: start;
  margin-top: var(--rx-space-6);
}

@media (min-width: 1024px) {
  .rx-journey-hero__grid {
    grid-template-columns: minmax(0, 1fr) minmax(420px, 480px);
    gap: var(--rx-space-12);
  }
  .rx-journey-hero__inner {
    padding-top: var(--rx-space-8);
    padding-bottom: var(--rx-space-16);
  }
}

.rx-journey-hero__identity {
  min-width: 0;
}

.rx-journey-hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--rx-space-2);
  font-family: var(--rx-font-mono);
  font-size: var(--rx-text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--rx-color-brand);
  margin: 0 0 var(--rx-space-3);
}

/* THE headline. Legacy's is a generic greeting; this is the journey
   itself, marked up as real parts (origin / connector / destination)
   rather than one baked string, so a route page and a service page can
   share the component and so the connector can be hidden from
   assistive tech without hiding the place names. */
.rx-journey-hero__title {
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-3xl);
  font-weight: var(--rx-weight-bold);
  line-height: var(--rx-leading-tight);
  letter-spacing: -0.01em;
  margin: 0;
  color: var(--rx-color-white);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--rx-space-3);
}

@media (min-width: 768px) {
  .rx-journey-hero__title { font-size: var(--rx-text-4xl); }
}

.rx-journey-hero__endpoint {
  display: inline-block;
}

/* The arrow between origin and destination. aria-hidden in markup —
   a screen reader should hear "Bangalore Airport to Mysore" from the
   visually-hidden connector text, not "right arrow". */
.rx-journey-hero__connector {
  display: inline-flex;
  align-items: center;
  color: var(--rx-color-brand);
  flex-shrink: 0;
}

.rx-journey-hero__sub {
  font-size: var(--rx-text-lg);
  line-height: var(--rx-leading-normal);
  color: var(--rx-color-text-on-dark-muted);
  margin: var(--rx-space-4) 0 0;
  max-width: 54ch;
}

/* ---------- Fact strip: distance / duration / from-price ----------
   The single most important addition versus legacy, and the reason a
   visitor can tell this page apart from the other 8,803: the numbers
   that answer "how far, how long, how much" without a scroll.
   Grounded in Gozo's numeric-facts-early pattern and Rome2Rio's
   labelled-fact rendering. */
.rx-journey-hero__facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--rx-space-6);
  margin: var(--rx-space-6) 0 0;
  padding: var(--rx-space-4) 0 0;
  border-top: 1px solid rgba(245, 250, 255, 0.16);
  list-style: none;
}

.rx-journey-hero__fact { min-width: 0; }

.rx-journey-hero__fact-label {
  display: block;
  font-size: var(--rx-text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--rx-color-text-on-dark-muted);
  margin-bottom: var(--rx-space-1);
}

.rx-journey-hero__fact-value {
  display: block;
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-numeric-lg);
  font-weight: var(--rx-weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--rx-color-white);
  line-height: 1.1;
}

/* The price fact is the one number allowed to carry brand gold —
   tokens.css's own rule: brand is "reserved for exactly one use per
   screen (primary CTA or the single most important numeral)". Here the
   CTA lives on a light surface inside the booking panel, so the gold
   on this dark column is not competing with it. */
.rx-journey-hero__fact--price .rx-journey-hero__fact-value {
  color: var(--rx-color-brand);
}

.rx-journey-hero__fact-note {
  display: block;
  font-size: var(--rx-text-xs);
  color: var(--rx-color-text-on-dark-muted);
  margin-top: var(--rx-space-1);
}

/* ---------- Trust checklist in the identity column ----------
   Placed adjacent to the price, deliberately: the trust research
   (see report §2) is consistent that credibility markers do their work
   at the decision moment, not in a footer. Legacy has nothing of this
   kind above the fold. */
.rx-journey-hero__trust {
  display: flex;
  flex-wrap: wrap;
  gap: var(--rx-space-3) var(--rx-space-6);
  margin: var(--rx-space-6) 0 0;
  padding: 0;
  list-style: none;
}

.rx-journey-hero__trust-item {
  display: flex;
  align-items: center;
  gap: var(--rx-space-2);
  font-size: var(--rx-text-sm);
  color: var(--rx-color-text-on-dark);
}

.rx-journey-hero__trust-item svg {
  flex-shrink: 0;
  color: var(--rx-color-brand);
}

/* ==================================================================== */
/* 2. BOOKING PANEL — the redesigned 4-tab booking widget                */
/* ==================================================================== */
/*
 * !!! FUNCTIONAL CONTRACT — READ BEFORE ADOPTING !!!
 * Every input id/name, the .autocomeple_g / .date-picker /
 * .pickup-time classes, the .tabcontent / .tablink classes, the
 * .drop-fields wrapper, #swapIcon, the onclick="openPage(...)"
 * attributes and the form action/ridetype hidden inputs are LOAD-
 * BEARING. Google Places autocomplete, the jQuery-UI datepicker,
 * the round-trip drop-field toggle, the now/time prefill loop and
 * the backend search view all key off them. This stylesheet changes
 * how the widget LOOKS and how its fields are ORDERED AND GROUPED.
 * It changes nothing about what the form submits.
 * Full field inventory: docs/program/wave42-trackA-component-contracts.md §3.
 */

.rx-journey-booking {
  background: var(--rx-color-surface);
  border: 1px solid var(--rx-color-border);
  border-radius: var(--rx-radius-lg);
  box-shadow: var(--rx-shadow-md);
  overflow: hidden;
  color: var(--rx-color-text);
}

/* ---------- Tab strip ----------
   Legacy renders four Bootstrap .btn elements floating in a grey bar,
   with no shared container and no visual relationship to the panel
   they control. This is a single segmented strip sitting ON the panel. */
.rx-journey-booking__tabs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  background: var(--rx-color-surface-sunken);
  border-bottom: 1px solid var(--rx-color-border);
}

/*
 * Wave 42 Track G — legacy tab-bar CSS leaking into the redesigned strip.
 *
 * The widget keeps `id="servicecontainer"` and `class="tablink"` because
 * both are part of the preserved JS-hook contract (Track A contracts §3.2,
 * §3.3). static/css/style.css still carries the rules it wrote for the OLD
 * grey Bootstrap tab bar against those exact hooks:
 *
 *   #servicecontainer{background:#f5f5f5;border-radius:10px;padding:1px}
 *   #servicecontainer{margin-right:9px;margin-left:9px;width:100%;max-width:362px}
 *   .tablink{...;border-radius:8px 8px 0 0;margin:4px 2px 0;...}
 *
 * An id selector (1,0,0) outranks `.rx-journey-booking__tabs` (0,1,0), so
 * those declarations won outright; `.tablink` ties `.rx-journey-booking__tab`
 * on specificity and leaks every property this file does not itself declare.
 * Every page that loads style.css is affected — i.e. the whole ~8,804-page
 * Track B family.
 *
 * Measured live on /airport-taxi at a genuine 390px viewport:
 *   - margin:0 9px + width:100% made the strip 321px wide inside a 321px
 *     content box that it also sat 9px into, so it overhung the panel's
 *     right edge by 8px. `.rx-journey-booking` is overflow:hidden, so the
 *     fourth tab was clipped mid-word — "Outstation" rendered "Outstatio"
 *     (clientWidth 76 vs scrollWidth 77). This is the overflow Track B
 *     disclosed in its report §9.5 and explicitly handed off to be fixed
 *     once in the component rather than patched per-track.
 *   - background:#f5f5f5 beat --rx-color-surface-sunken, so the strip stayed
 *     light grey in dark mode inside a panel that correctly inverted to
 *     #14212C. tokens.css applies its dark palette from
 *     `@media (prefers-color-scheme: dark)`, so this reached any visitor
 *     whose OS is set to dark, not just an explicit toggle.
 *   - border-radius (10px on the strip, 8px 8px 0 0 on each tab) and the
 *     4px 2px tab margins broke the "single segmented strip" this file's
 *     own comment above describes.
 *
 * Both overrides are qualified by the component class so they can only ever
 * match the redesigned widget. main.html, meta_main.html,
 * main_google_airport.html and main_google_outstation.html still render the
 * legacy #servicecontainer / .tablink markup and must keep the style.css
 * rules exactly as they are — same containment approach Track B used for the
 * legacy #swapIcon rule (its report §8.1).
 */
#servicecontainer.rx-journey-booking__tabs {
  margin-left: 0;
  margin-right: 0;
  width: auto;
  max-width: none;
  padding: 0;
  background: var(--rx-color-surface-sunken);
  border-radius: 0;
}

.rx-journey-booking__tabs .rx-journey-booking__tab {
  margin: 0;
  border-radius: 0;
}

/*
 * `!important` here is deliberate and load-bearing, not laziness.
 * The legacy openPage() function — which Tracks B/C keep unchanged,
 * because it is what actually shows/hides the tab panels — writes
 * INLINE `style.backgroundColor` and `style.color` onto every .tablink
 * on every tab switch. Inline styles beat any normal stylesheet rule,
 * so without !important the new tab design would be overwritten by
 * legacy's gold-fill/black-text the moment a tab is clicked.
 * Marking only these two properties keeps the design intact while
 * leaving openPage()'s real job (panel display) untouched.
 */
.rx-journey-booking__tab {
  appearance: none;
  border: 0;
  border-bottom: 3px solid transparent;
  background: transparent !important;
  color: var(--rx-color-text-muted) !important;
  font-family: var(--rx-font-body);
  font-size: var(--rx-text-sm);
  font-weight: var(--rx-weight-medium);
  min-height: 52px;
  padding: 0 var(--rx-space-2);
  cursor: pointer;
  transition:
    color var(--rx-motion-fast) var(--rx-ease-standard),
    background-color var(--rx-motion-fast) var(--rx-ease-standard),
    border-color var(--rx-motion-fast) var(--rx-ease-standard);
}

.rx-journey-booking__tab:hover {
  color: var(--rx-color-text) !important;
  background: rgba(201, 162, 39, 0.08) !important;
}

.rx-journey-booking__tab:focus-visible {
  outline: 2px solid var(--rx-color-focus-ring);
  outline-offset: -3px;
  border-radius: var(--rx-radius-sm);
}

/* Active state is driven by .is-active / aria-selected, set by the
   additive journey-booking.js enhancement (which does NOT replace or
   modify openPage()). Without that script the widget still works and
   still looks like Design 2.0 — every tab simply renders in the
   inactive treatment. */
.rx-journey-booking__tab.is-active,
.rx-journey-booking__tab[aria-selected='true'] {
  color: var(--rx-color-text) !important;
  background: var(--rx-color-surface) !important;
  border-bottom-color: var(--rx-color-brand);
  font-weight: var(--rx-weight-semibold);
}

.rx-journey-booking__body {
  padding: var(--rx-space-5);
}

@media (min-width: 480px) {
  .rx-journey-booking__body { padding: var(--rx-space-6); }
}

.rx-journey-booking__title {
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-lg);
  font-weight: var(--rx-weight-semibold);
  margin: 0 0 var(--rx-space-4);
  color: var(--rx-color-text);
}

/* ---------- Field layout ----------
   Mobile-first single column; the date/time pair becomes a 2-up row
   at 480px because those two fields are genuinely half-width content
   and stacking them wastes the most valuable vertical space on the
   page. Legacy uses Bootstrap col-lg-11/col-lg-4/col-lg-3, which
   collapses to a full-width stack below 992px and leaves the submit
   button orphaned at the bottom of a very tall form on mobile. */
.rx-journey-booking__fields {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--rx-space-4);
}

.rx-journey-booking__row-2up {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--rx-space-4);
}

@media (min-width: 480px) {
  .rx-journey-booking__row-2up {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/*
 * Dark-theme contrast fix for the trip-type pills, scoped to this
 * component.
 *
 * .rx-pill-option's checked state (patterns.css) sets
 * `background: var(--rx-color-brand-soft)` -- a pale gold that does NOT
 * invert per theme -- while `color: var(--rx-color-text)` DOES invert.
 * In dark mode the selected pill therefore renders near-white on pale
 * gold: measured live at 1.15:1, against WCAG AA's 4.5:1 floor. This is
 * the same class of defect tokens.css already documents for the status
 * colours ("the dark theme below only inverted the -bg halves"), and
 * the same class Wave 41 Track F fixed on the legacy booking widget's
 * active tab.
 *
 * --rx-color-cta-text is the token that means exactly "the required
 * text colour on a gold fill", and it resolves to the same dark navy in
 * BOTH themes -- which is precisely right against a background that
 * does not invert.
 *
 * Deliberately scoped to .rx-journey-booking rather than fixed in
 * patterns.css: .rx-pill-option is shared with the staff portals, and
 * changing a shared component's appearance is a wider blast radius than
 * this track owns. The underlying shared-component bug is real and is
 * flagged for its own scoped pass in
 * docs/program/wave42-trackA-report.md.
 */
.rx-journey-booking .rx-pill-option input:checked + label {
  color: var(--rx-color-cta-text);
}

/* ---------- The route field pair ----------
   Pickup and drop are one connected control, not two unrelated inputs
   with an easily-missed 16px icon between them. The rail + swap button
   make the from/to relationship visible, and turn legacy's 16px <i>
   tap target into a real 44px button. #swapIcon's id is preserved so
   the existing swap handler keeps working. */
.rx-journey-booking__route {
  position: relative;
  display: grid;
  gap: var(--rx-space-3);
}

.rx-journey-booking__route::before {
  content: '';
  position: absolute;
  left: 15px;
  top: 38px;
  bottom: 38px;
  width: 2px;
  background: repeating-linear-gradient(
    to bottom,
    var(--rx-color-border-strong) 0 4px,
    transparent 4px 8px
  );
  pointer-events: none;
}

/*
 * Wave 42 Track G — the connector above ran straight through the second
 * field's label.
 *
 * The rail is drawn on the .rx-journey-booking__route wrapper and spans
 * both location fields, but the drop-off field carries its own
 * "Drop off location" label between the two inputs, and the rail's x
 * position (left:15px) lands inside that label's first character.
 * Measured live on /airport-taxi at 1440px and at a genuine 390px, on
 * ALL FOUR tabs (Airport / Local / Packages / Outstation): the 2px rail
 * overlapped the label's text ink box by 2x17px, rendering as a line
 * struck through the word "Drop".
 *
 * Painting the labels in the panel's own surface token makes the rail
 * read as passing behind them, which is what a pin-to-pin route line is
 * meant to look like. The token is exact rather than approximate: the
 * .rx-journey-booking panel resolves to this same token in both themes
 * (verified live -- #FFFFFF light, #14212C dark), so the label paints no
 * visible band, it only masks the rail. `position: relative` is what puts
 * the label after the parent's ::before in paint order.
 *
 * Scoped to the route wrapper so no other .rx-field__label on the site
 * gains a background.
 */
.rx-journey-booking__route .rx-field__label {
  position: relative;
  background: var(--rx-color-surface);
}

/* Only the Airport tab carries a swap control (matching legacy, where
   #swapIcon exists on that form alone). Reserve room for it on that
   variant only, so a long pickup value like "Kempegowda International
   Airport Bengaluru (BLR), Karnataka, India" scrolls behind the field
   edge rather than under the button. */
.rx-journey-booking__route--swappable .rx-input {
  padding-right: 52px;
}

.rx-journey-booking__swap {
  position: absolute;
  right: var(--rx-space-2);
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--rx-radius-full);
  border: 1px solid var(--rx-color-border);
  background: var(--rx-color-surface);
  color: var(--rx-color-text-muted);
  cursor: pointer;
  z-index: 1;
  transition:
    color var(--rx-motion-fast) var(--rx-ease-standard),
    border-color var(--rx-motion-fast) var(--rx-ease-standard),
    transform var(--rx-motion-base) var(--rx-ease-standard);
}

.rx-journey-booking__swap:hover {
  color: var(--rx-color-brand-strong);
  border-color: var(--rx-color-brand);
}

.rx-journey-booking__swap:focus-visible {
  outline: 2px solid var(--rx-color-focus-ring);
  outline-offset: 2px;
}

/* ---------- Submit ---------- */
.rx-journey-booking__submit {
  margin-top: var(--rx-space-2);
}

/* A short reassurance line directly under the CTA. The price-
   transparency research (report §2) is unambiguous that what is and
   is not included belongs next to the action, not in a FAQ. Text is
   supplied by the adopting template — this component never hardcodes
   a claim. */
.rx-journey-booking__reassurance {
  display: flex;
  align-items: flex-start;
  gap: var(--rx-space-2);
  margin: var(--rx-space-4) 0 0;
  font-size: var(--rx-text-xs);
  color: var(--rx-color-text-muted);
  line-height: var(--rx-leading-normal);
}

.rx-journey-booking__reassurance svg {
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--rx-color-success);
}

/* ==================================================================== */
/* 3. BREADCRUMB — route-family variant of the existing .rx-breadcrumb   */
/* ==================================================================== */
/* Not a new breadcrumb. This is the existing components.css component
   plus the one thing it could not do: sit legibly on the hero's dark
   surface. Everything else (markup, separator, aria-current) comes from
   templates/design_system/patterns/_breadcrumbs.html unchanged. */

.rx-journey-breadcrumb {
  position: relative;
  z-index: 2;
}

.rx-journey-breadcrumb--on-dark .rx-breadcrumb__item {
  color: var(--rx-color-text-on-dark-muted);
}

.rx-journey-breadcrumb--on-dark .rx-breadcrumb__link {
  color: var(--rx-color-text-on-dark-muted);
}

.rx-journey-breadcrumb--on-dark .rx-breadcrumb__link:hover {
  color: var(--rx-color-brand);
}

.rx-journey-breadcrumb--on-dark .rx-breadcrumb__item.is-current {
  color: var(--rx-color-white);
}

.rx-journey-breadcrumb--on-dark .rx-breadcrumb__separator {
  color: rgba(245, 250, 255, 0.35);
}

/* On a narrow screen a 4-level route trail wraps to three lines and
   pushes the H1 down. Scroll it instead — the trail stays complete
   (it is a real internal-linking and SEO surface) without costing
   vertical space above the fold. */
@media (max-width: 767px) {
  .rx-journey-breadcrumb .rx-breadcrumb {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: var(--rx-space-1);
  }
  .rx-journey-breadcrumb .rx-breadcrumb::-webkit-scrollbar { display: none; }
  .rx-journey-breadcrumb .rx-breadcrumb__item { white-space: nowrap; }
}

/*
 * Wave 42 Track G — keep the focus ring theme-aware inside these components.
 *
 * static/css/legacy-design2-bridge.css (Wave 41 Track C) forces
 *   a:focus-visible, button:focus-visible, … { outline: 2px solid #7A5F09 !important }
 * on the whole legacy family. Its !important is correct and must stay: it
 * exists to beat style.css's blanket `a{outline:0}` reset, which would
 * otherwise win a non-deterministic preload race and leave keyboard users
 * with no ring at all. That reasoning is pinned by a test, and the literal
 * declaration is asserted there — so this is fixed here, not there.
 *
 * The problem is that #7A5F09 is a fixed light-surface value, and Track B
 * put these theme-aware components on those same pages. tokens.css applies
 * its dark palette from @media (prefers-color-scheme: dark), so a visitor
 * with a dark OS preference gets dark component surfaces under a ring
 * picked for light ones. Measured live on /airport-taxi in genuine OS dark
 * mode (not a data-theme simulation):
 *
 *     #7A5F09 ring on the tab strip #0F1922 ....... 2.93:1
 *     #7A5F09 ring on the panel     #14212C ....... 2.70:1
 *     --rx-color-focus-ring (#C9A227) on those .... 7.34:1 / 6.76:1
 *
 * WCAG 1.4.11 requires 3:1 for a focus indicator, so both fail.
 *
 * Only outline-COLOR is re-asserted, and only inside these components —
 * width, offset and radius stay exactly as the bridge sets them, and the
 * legacy chrome keeps #7A5F09, which is right for it because the legacy
 * shell deliberately has no theme system and stays light (Track F §4.1).
 * A single global swap would be wrong for precisely that reason: it would
 * put a #C9A227 ring on the still-white legacy header (2.06:1).
 *
 * In light mode --rx-color-focus-ring IS #7A5F09, so this is a no-op there:
 * only the dark-mode rendering changes.
 */
.rx-journey-hero :focus-visible,
.rx-journey-booking :focus-visible,
.rx-journey-summary :focus-visible,
.rx-journey-card-grid :focus-visible,
.rx-journey-trust :focus-visible,
.rx-journey-faq :focus-visible,
.rx-journey-related :focus-visible,
.rx-journey-cta :focus-visible {
  outline-color: var(--rx-color-focus-ring) !important;
}

/* ==================================================================== */
/* 4. ROUTE SUMMARY — structured, schema-friendly journey facts          */
/* ==================================================================== */
/* Genuinely net-new: nothing equivalent exists in the legacy design at
   all. Where the hero fact strip is the 3-fact above-the-fold teaser,
   this is the full breakdown — distance, duration, via/stops, and the
   vehicle types actually available on the journey. */

.rx-journey-summary {
  background: var(--rx-color-surface);
  border: 1px solid var(--rx-color-border);
  border-radius: var(--rx-radius-lg);
  padding: var(--rx-space-6);
}

.rx-journey-summary__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--rx-space-3);
  margin-bottom: var(--rx-space-5);
}

.rx-journey-summary__title {
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-xl);
  font-weight: var(--rx-weight-semibold);
  margin: 0;
  color: var(--rx-color-text);
}

.rx-journey-summary__metrics {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--rx-space-5);
  margin: 0;
}

@media (min-width: 768px) {
  .rx-journey-summary__metrics {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* <dt>/<dd> pair — a metric is a term and its value, and marking it as
   a description list is what makes this block genuinely
   structured-data-friendly rather than a row of styled divs. */
.rx-journey-summary__metric-label {
  font-size: var(--rx-text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--rx-color-text-muted);
  margin: 0 0 var(--rx-space-1);
}

.rx-journey-summary__metric-value {
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-xl);
  font-weight: var(--rx-weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--rx-color-text);
  margin: 0;
  line-height: 1.15;
}

.rx-journey-summary__metric-note {
  display: block;
  font-family: var(--rx-font-body);
  font-size: var(--rx-text-xs);
  font-weight: var(--rx-weight-regular);
  color: var(--rx-color-text-muted);
  margin-top: var(--rx-space-1);
}

/* Via / stops rail — the waypoint sequence, rendered as a real ordered
   path rather than a comma-joined sentence. */
.rx-journey-summary__via {
  margin: var(--rx-space-6) 0 0;
  padding: var(--rx-space-5) 0 0;
  border-top: 1px solid var(--rx-color-border);
}

.rx-journey-summary__via-label {
  font-size: var(--rx-text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--rx-color-text-muted);
  margin: 0 0 var(--rx-space-3);
}

.rx-journey-summary__stops {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--rx-space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.rx-journey-summary__stop {
  display: inline-flex;
  align-items: center;
  gap: var(--rx-space-2);
  font-size: var(--rx-text-sm);
  color: var(--rx-color-text);
}

.rx-journey-summary__stop::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: var(--rx-radius-full);
  background: var(--rx-color-border-strong);
  flex-shrink: 0;
}

.rx-journey-summary__stop--terminus { font-weight: var(--rx-weight-semibold); }
.rx-journey-summary__stop--terminus::before { background: var(--rx-color-brand); }

.rx-journey-summary__stop-sep {
  color: var(--rx-color-border-strong);
  flex-shrink: 0;
}

/* Vehicle types available, as compact chips. Reuses .rx-badge for the
   chip itself in markup — this only lays them out. */
.rx-journey-summary__vehicles {
  display: flex;
  flex-wrap: wrap;
  gap: var(--rx-space-2);
  margin: var(--rx-space-3) 0 0;
  padding: 0;
  list-style: none;
}

/* ==================================================================== */
/* 5. DESTINATION / SERVICE CARDS — discovery grid                       */
/* ==================================================================== */
/* .rx-marketing__destination-card exists but is a photo tile with only
   a label overlay — no room for the distance/duration/from-price a
   route card needs to be useful. This is the fact-carrying sibling. */

.rx-journey-card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--rx-space-4);
}

@media (min-width: 640px) {
  .rx-journey-card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1024px) {
  .rx-journey-card-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .rx-journey-card-grid--4up { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.rx-journey-card {
  display: flex;
  flex-direction: column;
  gap: var(--rx-space-2);
  padding: var(--rx-space-5);
  background: var(--rx-color-surface);
  border: 1px solid var(--rx-color-border);
  border-radius: var(--rx-radius-lg);
  text-decoration: none;
  color: inherit;
  transition:
    border-color var(--rx-motion-fast) var(--rx-ease-standard),
    box-shadow var(--rx-motion-base) var(--rx-ease-decelerate),
    transform var(--rx-motion-base) var(--rx-ease-decelerate);
}

.rx-journey-card:hover {
  border-color: var(--rx-color-brand);
  box-shadow: var(--rx-shadow-md);
  transform: translateY(-2px);
}

.rx-journey-card:focus-visible {
  outline: 2px solid var(--rx-color-focus-ring);
  outline-offset: 2px;
}

.rx-journey-card__route {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--rx-space-2);
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-base);
  font-weight: var(--rx-weight-semibold);
  color: var(--rx-color-text);
  margin: 0;
}

.rx-journey-card__connector {
  color: var(--rx-color-brand);
  display: inline-flex;
  flex-shrink: 0;
}

.rx-journey-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--rx-space-1) var(--rx-space-3);
  font-size: var(--rx-text-sm);
  color: var(--rx-color-text-muted);
  margin: 0;
}

.rx-journey-card__meta-item {
  display: inline-flex;
  align-items: center;
  gap: var(--rx-space-1);
}

.rx-journey-card__price {
  margin: auto 0 0;
  padding-top: var(--rx-space-3);
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-lg);
  font-weight: var(--rx-weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--rx-color-text);
}

.rx-journey-card__price-prefix {
  font-family: var(--rx-font-body);
  font-size: var(--rx-text-xs);
  font-weight: var(--rx-weight-regular);
  color: var(--rx-color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  display: block;
}

/* Service (non-route) variant: an icon-led card for "Airport Taxi",
   "Local Rentals", "Corporate" rather than a city pair. */
.rx-journey-card--service .rx-journey-card__icon {
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--rx-radius-md);
  background: var(--rx-color-brand-soft);
  color: var(--rx-color-brand-strong);
  margin-bottom: var(--rx-space-1);
}

.rx-journey-card__body {
  font-size: var(--rx-text-sm);
  color: var(--rx-color-text-muted);
  line-height: var(--rx-leading-normal);
  margin: 0;
}

/* ==================================================================== */
/* 6. TRUST SECTION                                                      */
/* ==================================================================== */
/* .rx-trust-card (patterns.css) is an icon+title+body card and is
   reused directly in markup. What did not exist is the surrounding
   band and the proof row — the place a real, sourced rating or
   verified count goes. Every value is supplied by the template; this
   component deliberately hardcodes no claim, matching .rx-review-card's
   own standing note that this codebase does not simulate confidence
   with invented content. */

.rx-journey-trust {
  background: var(--rx-color-surface-alt);
  border-radius: var(--rx-radius-lg);
  padding: var(--rx-space-8) var(--rx-space-6);
}

/*
 * Wave 42 Track G — the trust band's eyebrow had no stylesheet on the
 * biggest family that renders it.
 *
 * _journey_trust.html emitted this kicker as .rx-marketing__section-eyebrow,
 * which is defined ONLY in marketing-patterns.css. But contract §1 of
 * docs/program/wave42-trackA-component-contracts.md lists exactly four
 * required stylesheets — tokens, components, patterns, journey-patterns —
 * and marketing-patterns.css is not one of them. Track B followed that
 * contract literally, so on its ~8,804 pages the eyebrow matched no rule at
 * all and inherited legacy style.css's `body { color: var(--body-text-color) }`
 * (#D2D6E0, chosen for a black page). Measured live at 390px and 1440px on
 * /airport-taxi: "WHY RIDEXPRESS" rendered #D2D6E0 on the band's #F7F6F3,
 * i.e. 1.35:1 — far under AA's 4.5:1 and effectively invisible. It also lost
 * the uppercase, letter-spacing, weight and size treatment.
 *
 * Track C's 22 destination pages were unaffected because that track
 * independently added marketing-patterns.css to its own stack.
 *
 * Fixed by giving the component its own namespaced rule rather than by
 * adding a fifth stylesheet to 8,804 legacy pages: the journey set should
 * style its own markup from the sheet its contract already requires, and
 * pulling all of marketing-patterns.css onto the legacy family would be a
 * far wider change than this defect warrants. Declarations are copied
 * verbatim from .rx-marketing__section-eyebrow, so Track C renders
 * identically — including Track E's --rx-color-accent-strong fix, which is
 * the theme-aware token (#7A5F09 light / #C9A227 dark).
 */
.rx-journey-trust__eyebrow {
  display: block;
  color: var(--rx-color-accent-strong);
  font-weight: var(--rx-weight-semibold);
  font-size: var(--rx-text-sm);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin: 0 0 var(--rx-space-2);
}

.rx-journey-trust__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--rx-space-4);
  margin-top: var(--rx-space-6);
}

@media (min-width: 640px) {
  .rx-journey-trust__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1024px) {
  .rx-journey-trust__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Proof row — a rating, a count, a years-in-business figure. Rendered
   only when the adopting page has a real, attributable value for it. */
.rx-journey-trust__proof {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--rx-space-6);
  padding-top: var(--rx-space-6);
  margin-top: var(--rx-space-6);
  border-top: 1px solid var(--rx-color-border);
}

.rx-journey-trust__proof-item { min-width: 0; }

.rx-journey-trust__proof-value {
  display: flex;
  align-items: center;
  gap: var(--rx-space-2);
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-xl);
  font-weight: var(--rx-weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--rx-color-text);
}

.rx-journey-trust__proof-label {
  font-size: var(--rx-text-xs);
  color: var(--rx-color-text-muted);
  margin-top: var(--rx-space-1);
}

.rx-journey-trust__stars {
  display: inline-flex;
  gap: 2px;
  color: var(--rx-color-brand);
}

/* ==================================================================== */
/* 7. FAQ — reusable per-route / per-service accordion                   */
/* ==================================================================== */
/* Built on the same native <details>/<summary> mechanism as
   .rx-marketing__faq-item (which the homepage and /faq already use) so
   there is one accordion behaviour on the site, not two. The additions
   this family needs and that one does not have: a bordered card
   treatment that survives being placed on either surface token, a
   real open/close affordance, and a two-column layout at desktop for
   the 10-15 question sets these route pages actually carry. */

.rx-journey-faq {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--rx-space-3);
}

@media (min-width: 1024px) {
  .rx-journey-faq--2col { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.rx-journey-faq__item {
  background: var(--rx-color-surface);
  border: 1px solid var(--rx-color-border);
  border-radius: var(--rx-radius-md);
  transition: border-color var(--rx-motion-fast) var(--rx-ease-standard);
}

.rx-journey-faq__item[open] { border-color: var(--rx-color-brand); }

.rx-journey-faq__q {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--rx-space-4);
  padding: var(--rx-space-4) var(--rx-space-5);
  cursor: pointer;
  list-style: none;
  font-family: var(--rx-font-body);
  font-size: var(--rx-text-base);
  font-weight: var(--rx-weight-semibold);
  color: var(--rx-color-text);
}

.rx-journey-faq__q::-webkit-details-marker { display: none; }

.rx-journey-faq__q:focus-visible {
  outline: 2px solid var(--rx-color-focus-ring);
  outline-offset: -2px;
  border-radius: var(--rx-radius-md);
}

/* Chevron affordance. .rx-marketing__faq-item signals open/closed only
   by changing the summary's text colour, which is a colour-only state
   cue (WCAG 1.4.1). This rotates a real shape as well. */
.rx-journey-faq__chevron {
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--rx-color-text-muted);
  transition: transform var(--rx-motion-base) var(--rx-ease-standard);
}

.rx-journey-faq__item[open] .rx-journey-faq__chevron {
  transform: rotate(180deg);
  color: var(--rx-color-brand-strong);
}

.rx-journey-faq__a {
  padding: 0 var(--rx-space-5) var(--rx-space-5);
  margin: 0;
  font-size: var(--rx-text-sm);
  color: var(--rx-color-text-muted);
  line-height: var(--rx-leading-normal);
}

@media (prefers-reduced-motion: reduce) {
  .rx-journey-faq__chevron,
  .rx-journey-card,
  .rx-journey-booking__swap { transition: none; }
}

/* ==================================================================== */
/* 8. RELATED ROUTES / DESTINATIONS — discovery                          */
/* ==================================================================== */
/* Upgrades the {% related_destinations %} tag's current output, which
   is an unstyled <ul> of bare <a> elements under a 6th-level-looking
   heading. The DATA is unchanged (superadmin/data/related_destinations.json,
   a real precomputed clustering of this site's own titles/URLs); only
   the rendering changes. Deliberately a link LIST rather than the
   fact-carrying .rx-journey-card, because that data source carries only
   {title, url} — no distance, duration or price exists for these
   entries, and a card shaped to show facts it does not have would
   invite someone to fill the gap with invented numbers. */

.rx-journey-related__list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--rx-space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 640px) {
  .rx-journey-related__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1024px) {
  .rx-journey-related__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.rx-journey-related__link {
  display: flex;
  align-items: center;
  gap: var(--rx-space-3);
  padding: var(--rx-space-3) var(--rx-space-4);
  border: 1px solid var(--rx-color-border);
  border-radius: var(--rx-radius-md);
  background: var(--rx-color-surface);
  color: var(--rx-color-text);
  text-decoration: none;
  font-size: var(--rx-text-sm);
  line-height: var(--rx-leading-normal);
  transition:
    border-color var(--rx-motion-fast) var(--rx-ease-standard),
    background-color var(--rx-motion-fast) var(--rx-ease-standard);
}

.rx-journey-related__link:hover {
  border-color: var(--rx-color-brand);
  background: var(--rx-color-surface-alt);
}

.rx-journey-related__link:focus-visible {
  outline: 2px solid var(--rx-color-focus-ring);
  outline-offset: 2px;
}

.rx-journey-related__icon {
  flex-shrink: 0;
  color: var(--rx-color-brand);
}

/* ==================================================================== */
/* 9. FOOTER CTA BAND — the final conversion push                        */
/* ==================================================================== */
/* Legacy's equivalent is two equal-weight buttons ("About Us" /
   "Learn More") sitting inside the hero, competing with the booking
   widget directly above them and pointing away from the booking flow.
   This is one band, at the end of the page, with one primary action
   and one genuinely secondary (phone) action. */

.rx-journey-cta {
  background: var(--rx-color-dark-surface);
  color: var(--rx-color-text-on-dark);
  border-radius: var(--rx-radius-lg);
  padding: var(--rx-space-10) var(--rx-space-6);
  text-align: center;
}

.rx-journey-cta--full {
  border-radius: 0;
  padding-left: var(--rx-space-6);
  padding-right: var(--rx-space-6);
}

.rx-journey-cta__inner {
  max-width: 640px;
  margin: 0 auto;
}

.rx-journey-cta__title {
  font-family: var(--rx-font-display);
  font-size: var(--rx-text-2xl);
  font-weight: var(--rx-weight-bold);
  line-height: var(--rx-leading-tight);
  margin: 0;
  color: var(--rx-color-white);
}

.rx-journey-cta__sub {
  font-size: var(--rx-text-base);
  color: var(--rx-color-text-on-dark-muted);
  margin: var(--rx-space-3) 0 0;
}

.rx-journey-cta__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--rx-space-3);
  margin-top: var(--rx-space-6);
}

/* The phone action. .rx-btn--outline's border/label resolve against the
   light theme's text token and drop to roughly 1.5:1 on this fixed dark
   navy, so this band needs its own on-dark secondary treatment rather
   than reusing that modifier. Fixed (not theme-aware) values, matching
   .rx-marketing__footer-inner's own documented reasoning for a
   permanently-dark surface. */
.rx-journey-cta__phone {
  display: inline-flex;
  align-items: center;
  gap: var(--rx-space-2);
  min-height: 44px;
  padding: 0 var(--rx-space-5);
  border-radius: var(--rx-radius-full);
  border: 1.5px solid rgba(245, 250, 255, 0.5);
  color: var(--rx-color-text-on-dark);
  background: transparent;
  font-family: var(--rx-font-body);
  font-size: var(--rx-text-sm);
  font-weight: var(--rx-weight-semibold);
  text-decoration: none;
  transition:
    border-color var(--rx-motion-fast) var(--rx-ease-standard),
    background-color var(--rx-motion-fast) var(--rx-ease-standard);
}

.rx-journey-cta__phone:hover {
  border-color: var(--rx-color-white);
  background: rgba(245, 250, 255, 0.08);
}

.rx-journey-cta__phone:focus-visible {
  outline: 2px solid var(--rx-color-brand);
  outline-offset: 2px;
}
