/* ============================================================================
   LUX4RIDES — HOMEPAGE v2  (2026-07-24)
   Homepage-only stylesheet. Every selector is namespaced under `.l4h`
   (set on <main>) or prefixed `l4h-`, so nothing here can collide with
   global.css, the shared header (.lux-hd-*) or the shared footer (.lux-footer-*).

   EXCEPTIONS — intentionally NOT namespaced, and why:
     .hp-booker-*  the frozen hero booking-form contract (class names are style
                   AND logic hooks; they must keep these exact names)
     .pac-container / .pac-item   Google Places injects these at <body> level,
                   outside .l4h, so they cannot be scoped

   Typography uses the two families the shared header already loads
   (Playfair Display + Montserrat). No additional font family is requested.
   ========================================================================== */

/* ── Design tokens ───────────────────────────────────────────────────────── */
.l4h {
  --l4h-black:        #080808;
  --l4h-charcoal:     #141414;
  --l4h-ink:          #0e0e0e;
  --l4h-ivory:        #F7F4EE;
  --l4h-ivory-deep:   #EFEAE1;
  --l4h-light-text:   #171717;
  --l4h-light-muted:  #5E5951;
  --l4h-gold:         #E8A020;
  --l4h-gold-lt:      #F5BE5A;
  /* Gold for use on the ivory sections. The brief suggested #936B1E, but that
     measures only 4.39:1 on #F7F4EE and 4.02:1 on #EFEAE1 — below the WCAG AA
     4.5:1 minimum for text at these sizes (11–12px). Darkened to #7A5714,
     which measures 5.98:1 / 5.48:1 / 6.56:1 and keeps the same gold character.
     The accessibility gate takes precedence over the suggested hex. */
  --l4h-gold-on-light:#7A5714;
  --l4h-hairline-dark: rgba(232,160,32,.16);
  --l4h-hairline-light: rgba(20,18,14,.12);
  --l4h-on-dark:      rgba(255,255,255,.72);
  --l4h-on-dark-soft: rgba(255,255,255,.55);

  --l4h-motion-fast:      220ms;
  --l4h-motion-reveal:    650ms;
  --l4h-motion-cinematic: 900ms;
  --l4h-ease-out:  cubic-bezier(.22, 1, .36, 1);
  --l4h-ease-soft: cubic-bezier(.2, .7, .2, 1);
  --l4h-stagger:   70ms;

  --l4h-maxw:      1280px;
  --l4h-pad-y:     clamp(80px, 8vw, 116px);
  --l4h-pad-y-sm:  clamp(52px, 14vw, 72px);
  --l4h-radius:    16px;
  --l4h-radius-sm: 12px;
  --l4h-radius-lg: 20px;
  --l4h-tap:       44px;

  --l4h-serif: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --l4h-body:  'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  font-family: var(--l4h-body);
  background: var(--l4h-black);
  color: #fff;
  display: block;
  overflow-x: clip;
}

.l4h *, .l4h *::before, .l4h *::after { box-sizing: border-box; }
.l4h img { max-width: 100%; height: auto; display: block; }

/* NOTE on specificity: global.css styles bare elements —
   `h1..h6 { color: var(--fg) }` and `p { color: var(--fg-muted) }`, both light.
   A bare element rule always beats an INHERITED value, so headings inside the
   ivory sections would render near-white unless we set colour explicitly here.
   `color: inherit` below (specificity 0,1,1) restores inheritance so each
   heading takes its section's colour — white on dark, ink on ivory.

   Conversely we must NOT set `color` on `.l4h a`: that would be (0,1,1) and
   would beat component classes like `.l4h-btn--gold` (0,1,0), turning gold
   button labels white-on-gold. global.css already gives anchors
   `color: inherit` at (0,0,1), which every component class safely overrides. */
.l4h a { text-decoration: none; }
.l4h h1, .l4h h2, .l4h h3, .l4h h4, .l4h h5, .l4h h6 {
  font-family: var(--l4h-serif);
  font-weight: 500;
  line-height: 1.14;
  letter-spacing: -0.01em;
  margin: 0;
  color: inherit;
}
.l4h p { margin: 0; }
.l4h ul { margin: 0; padding: 0; list-style: none; }

/* ── Layout primitives ───────────────────────────────────────────────────── */
.l4h-wrap {
  width: 100%;
  max-width: var(--l4h-maxw);
  margin-inline: auto;
  padding-inline: clamp(20px, 5vw, 44px);
}
.l4h-section { padding-block: var(--l4h-pad-y); position: relative; }
@media (max-width: 768px) { .l4h-section { padding-block: var(--l4h-pad-y-sm); } }

.l4h-section--dark  { background: var(--l4h-black); color: #fff; }
.l4h-section--ink   { background: var(--l4h-ink); color: #fff; }
.l4h-section--light { background: var(--l4h-ivory); color: var(--l4h-light-text); }
.l4h-section--light-deep { background: var(--l4h-ivory-deep); color: var(--l4h-light-text); }

/* Section heading block */
.l4h-head { max-width: 720px; margin-bottom: clamp(38px, 4.5vw, 60px); }
.l4h-head--center { margin-inline: auto; text-align: center; }
.l4h-eyebrow {
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--l4h-gold);
  margin-bottom: 14px;
}
.l4h-section--light .l4h-eyebrow,
.l4h-section--light-deep .l4h-eyebrow { color: var(--l4h-gold-on-light); }
.l4h-h2 { font-size: clamp(1.85rem, 3.6vw, 2.9rem); margin-bottom: 14px; }
.l4h-lead {
  font-size: clamp(0.98rem, 1.2vw, 1.08rem);
  line-height: 1.75;
  color: var(--l4h-on-dark);
  max-width: 62ch;
}
.l4h-section--light .l4h-lead,
.l4h-section--light-deep .l4h-lead { color: var(--l4h-light-muted); }

/* Hairline rule */
.l4h-rule {
  height: 1px;
  background: linear-gradient(90deg, var(--l4h-gold), rgba(232,160,32,0));
  width: 56px;
  margin-top: 18px;
}

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.l4h-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: var(--l4h-tap);
  padding: 14px 28px;
  border-radius: var(--l4h-radius-sm);
  font-family: var(--l4h-body);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform var(--l4h-motion-fast) var(--l4h-ease-out),
              background var(--l4h-motion-fast) var(--l4h-ease-out),
              border-color var(--l4h-motion-fast) var(--l4h-ease-out),
              color var(--l4h-motion-fast) var(--l4h-ease-out);
}
.l4h-btn svg { width: 15px; height: 15px; flex-shrink: 0; }
.l4h-btn--gold { background: linear-gradient(135deg, var(--l4h-gold-lt), var(--l4h-gold)); color: #0a0a0a; }
.l4h-btn--ghost { background: rgba(255,255,255,.04); border-color: rgba(255,255,255,.22); color: #fff; }
.l4h-btn--dark { background: transparent; border-color: rgba(20,18,14,.28); color: var(--l4h-light-text); }
@media (hover: hover) {
  .l4h-btn:hover { transform: translateY(-2px); }
  .l4h-btn--ghost:hover { background: rgba(232,160,32,.10); border-color: var(--l4h-gold); color: var(--l4h-gold-lt); }
  .l4h-btn--dark:hover { border-color: var(--l4h-gold-on-light); color: var(--l4h-gold-on-light); }
}
.l4h-btn:active { transform: translateY(0) scale(.985); }

/* Text link with arrow */
.l4h-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: var(--l4h-tap);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--l4h-gold);
}
.l4h-section--light .l4h-link,
.l4h-section--light-deep .l4h-link { color: var(--l4h-gold-on-light); }
.l4h-link svg { width: 14px; height: 14px; transition: transform var(--l4h-motion-fast) var(--l4h-ease-out); }
@media (hover: hover) { .l4h-link:hover svg { transform: translateX(5px); } }

/* Focus visibility on BOTH dark and light sections (WCAG AA) */
.l4h a:focus-visible,
.l4h button:focus-visible,
.l4h input:focus-visible,
.l4h select:focus-visible,
.l4h [tabindex]:focus-visible {
  outline: 3px solid var(--l4h-gold);
  outline-offset: 3px;
  border-radius: 4px;
}
.l4h-section--light a:focus-visible,
.l4h-section--light button:focus-visible,
.l4h-section--light-deep a:focus-visible,
.l4h-section--light-deep button:focus-visible { outline-color: #7A5714; }

/* ============================================================================
   MOTION SYSTEM — progressive enhancement
   Content is VISIBLE BY DEFAULT. Only after home-v2.js initialises does it add
   `.l4h-motion-ready` to <html>, which arms not-yet-revealed elements. If JS
   fails, the observer errors, or the browser lacks IntersectionObserver, the
   class is never added (or is removed), so everything simply stays visible.
   ========================================================================== */
.l4h [data-reveal] { opacity: 1; transform: none; }

.l4h-motion-ready .l4h [data-reveal]:not(.is-visible) {
  opacity: 0;
  transform: translate3d(0, 22px, 0);
}
.l4h [data-reveal] {
  transition: opacity var(--l4h-motion-reveal) var(--l4h-ease-out),
              transform var(--l4h-motion-reveal) var(--l4h-ease-out);
}
.l4h [data-reveal].is-visible { opacity: 1; transform: none; }

/* Card assembly: slight lateral offset + <1.5deg rotation, desktop only */
@media (min-width: 769px) {
  .l4h-motion-ready .l4h [data-reveal="card"]:not(.is-visible) {
    transform: translate3d(0, 58px, 0) rotate(1.1deg);
  }
  .l4h-motion-ready .l4h [data-reveal="card-alt"]:not(.is-visible) {
    transform: translate3d(0, 62px, 0) rotate(-1.05deg);
  }
}
/* Mobile: <=22px displacement, never any rotation */
@media (max-width: 768px) {
  .l4h-motion-ready .l4h [data-reveal]:not(.is-visible) {
    transform: translate3d(0, 20px, 0);
  }
}

/* ============================================================================
   LOWER-PAGE MOTION (added 2026-07-25)

   Extends the SAME single IntersectionObserver — no second observer, no library,
   no scroll-jacking, no pinning, nothing that loops forever. Every family below
   animates only transform/opacity, reveals once, and is fully neutralised by the
   reduced-motion block further down.

   PROTECTED COMPONENT: none of these selectors can reach the approved
   "Cadillac Escalade ESV" section (#l4hVehicle). Specifically:
     • `.l4h-head` — #l4hVehicle's eyebrow/h2/lead are direct children of a plain
       <div>, not of a .l4h-head, so these rules structurally cannot match it.
     • `.l4h-rule` is deliberately NOT used: its only instance on the page is
       inside #l4hVehicle. A brand-new `.l4h-head::after` hairline is used instead.
     • `.l4h-final`, `.l4h-svc*`, `.l4h-fleet-card*`, `.l4h-faq__item`,
       `#l4hExpFrame` do not exist inside #l4hVehicle.
     • The shared classes it DOES carry (.l4h-section, .l4h-section--dark,
       .l4h-wrap, .l4h-eyebrow, .l4h-h2, .l4h-lead) are never targeted bare.
   ========================================================================== */

/* ── Section heading + supporting copy, with an internal cascade ─────────── */
.l4h .l4h-head > * {
  transition: opacity 560ms var(--l4h-ease-out), transform 560ms var(--l4h-ease-out);
}
.l4h-motion-ready .l4h .l4h-head:not(.is-visible) > * {
  opacity: 0;
  transform: translate3d(0, 16px, 0);
}
.l4h .l4h-head.is-visible > * { opacity: 1; transform: none; }
.l4h .l4h-head.is-visible > .l4h-eyebrow { transition-delay: 0ms; }
.l4h .l4h-head.is-visible > .l4h-h2      { transition-delay: 90ms; }
.l4h .l4h-head.is-visible > .l4h-lead    { transition-delay: 180ms; }
@media (max-width: 768px) {
  .l4h-motion-ready .l4h .l4h-head:not(.is-visible) > * { transform: translate3d(0, 12px, 0); }
}

/* ── Gold hairline that draws itself under each heading ──────────────────── */
.l4h .l4h-head { position: relative; }
.l4h .l4h-head::after {
  content: '';
  position: absolute;
  left: 0; bottom: -20px;
  width: 64px; height: 1px;
  background: linear-gradient(90deg, var(--l4h-gold), rgba(232, 160, 32, 0));
  transform: scaleX(1);
  transform-origin: left center;
  transition: transform 760ms var(--l4h-ease-soft) 260ms;
}
.l4h-section--light .l4h-head::after,
.l4h-section--light-deep .l4h-head::after {
  background: linear-gradient(90deg, var(--l4h-gold-on-light), rgba(122, 87, 20, 0));
}
.l4h-motion-ready .l4h .l4h-head:not(.is-visible)::after { transform: scaleX(0); }
.l4h .l4h-head--center::after { left: 50%; margin-left: -32px; transform-origin: center center; }

/* ── Journey tiles assembling into the grid ──────────────────────────────── */
.l4h [data-reveal="tile"] {
  transition: opacity 520ms var(--l4h-ease-out), transform 520ms var(--l4h-ease-out);
}
.l4h-motion-ready .l4h [data-reveal="tile"]:not(.is-visible) {
  opacity: 0;
  transform: translate3d(0, 26px, 0) scale(.986);
}
@media (max-width: 768px) {
  .l4h-motion-ready .l4h [data-reveal="tile"]:not(.is-visible) { transform: translate3d(0, 18px, 0) scale(.99); }
}

/* ── Trust/credential facts entering in sequence ─────────────────────────── */
.l4h [data-reveal="fact"] {
  transition: opacity 520ms var(--l4h-ease-out), transform 520ms var(--l4h-ease-out);
}
.l4h-motion-ready .l4h [data-reveal="fact"]:not(.is-visible) {
  opacity: 0;
  transform: translate3d(0, 14px, 0);
}
/* the small pills inside the two feature cards follow their card in */
.l4h .l4h-svc__fact {
  transition: opacity 380ms var(--l4h-ease-out), transform 380ms var(--l4h-ease-out);
}
.l4h-motion-ready .l4h .l4h-svc[data-reveal]:not(.is-visible) .l4h-svc__fact {
  opacity: 0;
  transform: translate3d(0, 6px, 0);
}
.l4h .l4h-svc[data-reveal].is-visible .l4h-svc__fact:nth-child(1) { transition-delay: 300ms; }
.l4h .l4h-svc[data-reveal].is-visible .l4h-svc__fact:nth-child(2) { transition-delay: 360ms; }
.l4h .l4h-svc[data-reveal].is-visible .l4h-svc__fact:nth-child(3) { transition-delay: 420ms; }

/* ── Card imagery settling out of a slight scale ─────────────────────────── */
.l4h-motion-ready .l4h [data-reveal]:not(.is-visible) .l4h-svc__media img,
.l4h-motion-ready .l4h [data-reveal]:not(.is-visible) .l4h-fleet-card__media img {
  transform: scale(1.06);
}
.l4h [data-reveal].is-visible .l4h-svc__media img,
.l4h [data-reveal].is-visible .l4h-fleet-card__media img {
  transform: scale(1);
  transition: transform 1100ms var(--l4h-ease-soft);
}
/* Re-assert the hover zoom: the rule above is (0,4,1) and would otherwise
   outrank the existing (0,3,1) hover rule and kill it. */
@media (hover: hover) {
  .l4h [data-reveal].is-visible:hover .l4h-svc__media img { transform: scale(1.045); }
}

/* ── Feature pair converging from opposite sides (desktop only) ──────────── */
@media (min-width: 1025px) {
  .l4h-motion-ready .l4h .l4h-svc--feature[data-reveal="card"]:not(.is-visible) {
    transform: translate3d(-20px, 46px, 0) rotate(.7deg);
  }
  .l4h-motion-ready .l4h .l4h-svc--feature[data-reveal="card-alt"]:not(.is-visible) {
    transform: translate3d(20px, 46px, 0) rotate(-.7deg);
  }
}

/* ── FAQ rows entering one at a time ────────────────────────────────────── */
.l4h .l4h-faq__item {
  transition: opacity 460ms var(--l4h-ease-out), transform 460ms var(--l4h-ease-out);
}
.l4h-motion-ready .l4h .l4h-faq__item:not(.is-visible) {
  opacity: 0;
  transform: translate3d(0, 10px, 0);
}
.l4h .l4h-faq__item.is-visible { opacity: 1; transform: none; }

/* ── Experience frame entrance + its controls ────────────────────────────── */
.l4h #l4hExpFrame {
  transition: opacity 780ms var(--l4h-ease-soft), transform 780ms var(--l4h-ease-soft);
}
.l4h-motion-ready .l4h #l4hExpFrame:not(.is-visible) { opacity: 0; transform: scale(.985); }
.l4h-motion-ready .l4h #l4hExpFrame:not(.is-visible) + .l4h-exp__controls {
  opacity: 0;
  transform: translate3d(0, 8px, 0);
}
.l4h #l4hExpFrame.is-visible + .l4h-exp__controls {
  opacity: 1; transform: none;
  transition: opacity 460ms var(--l4h-ease-out) 260ms, transform 460ms var(--l4h-ease-out) 260ms;
}

/* ── Final CTA, the one place the slower cinematic register is used ──────── */
.l4h .l4h-final > .l4h-wrap > * {
  transition: opacity 820ms var(--l4h-ease-soft), transform 820ms var(--l4h-ease-soft);
}
.l4h-motion-ready .l4h .l4h-final:not(.is-visible) > .l4h-wrap > * {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
}
.l4h-motion-ready .l4h .l4h-final:not(.is-visible) > .l4h-wrap > .l4h-final__ctas {
  transform: translate3d(0, 12px, 0);
}
.l4h .l4h-final.is-visible > .l4h-wrap > * { opacity: 1; transform: none; }
.l4h .l4h-final.is-visible > .l4h-wrap > .l4h-eyebrow     { transition-delay: 0ms; }
.l4h .l4h-final.is-visible > .l4h-wrap > .l4h-h2          { transition-delay: 110ms; }
.l4h .l4h-final.is-visible > .l4h-wrap > .l4h-lead        { transition-delay: 210ms; }
.l4h .l4h-final.is-visible > .l4h-wrap > .l4h-final__ctas { transition-duration: 560ms; transition-delay: 320ms; }
.l4h .l4h-final.is-visible > .l4h-wrap > .l4h-final__note { transition-delay: 420ms; }

/* ── While armed, don't let an invisible control take a click ────────────── */
.l4h-motion-ready .l4h [data-reveal="tile"]:not(.is-visible),
.l4h-motion-ready .l4h .l4h-faq__item:not(.is-visible),
.l4h-motion-ready .l4h .l4h-final:not(.is-visible) > .l4h-wrap > .l4h-final__ctas {
  pointer-events: none;
}

/* ── Mobile fleet rail: scale instead of translate, so a reveal can never
      create scroll distance inside the horizontal rail ─────────────────── */
@media (max-width: 900px) {
  .l4h-motion-ready .l4h .l4h-fleet-card[data-reveal]:not(.is-visible) { transform: scale(.97); }
}

/* ============================================================================
   SCROLL-PROGRESS CHOREOGRAPHY — "scatter · settle · release"
   Used by the Credentials grid and the Fleet rail.

   Each card carries a deterministic direction (--sx / --sy / --sr, authored below
   per position — never random). home-v2.js writes a single 0→1 progress value per
   card as its section crosses the viewport, and the transform is derived from it,
   so the motion is inherently REVERSIBLE when scrolling back up — no observer
   re-trigger, no flicker.

   Progress map (see js): 0–0.34 scatter→settle · 0.34–0.72 held perfectly still
   and readable · 0.72–1 gentle release. Opacity is only animated on the way IN;
   on release the cards stay fully opaque, so content never disappears while the
   section is still being read.
   ========================================================================== */
.l4h-scatter {
  --p: 1;              /* transform progress: 0 = scattered, 1 = settled */
  --o: 1;              /* opacity progress — SEPARATE from --p on purpose */
  --sx: 0px;           /* authored scatter direction, per card */
  --sy: 0px;
  --sr: 0deg;
  transform:
    translate3d(calc(var(--sx) * (1 - var(--p))), calc(var(--sy) * (1 - var(--p))), 0)
    rotate(calc(var(--sr) * (1 - var(--p))))
    scale(calc(0.92 + (0.08 * var(--p))));
  /* Opacity is driven by --o, which only ever rises (on the way in) and then stays
     at 1. The release phase moves --p but NOT --o, so a card can drift outward
     without ever fading — essential content cannot disappear while it is readable. */
  /* Floor of 0.35 rather than 0, and --o completes early (see js), so a card is
     always legible — it never arrives as an invisible block of text. */
  opacity: calc(0.35 + (0.65 * var(--o)));
  will-change: transform;
}
/* Settled state: nothing animating, no will-change left behind. */
.l4h-scatter.is-settled {
  transform: none;
  opacity: 1;
  will-change: auto;
}
/* Before JS arms the page — and forever, if JS never runs — cards sit finished. */
.l4h:not(.l4h-armed) .l4h-scatter,
html:not(.l4h-motion-ready) .l4h-scatter {
  transform: none !important;
  opacity: 1 !important;
  will-change: auto !important;
}

/* Deterministic directions. Credentials: four cards sweep in from the four
   corners of the composition and rotate into alignment. */
.l4h-proof__grid > .l4h-scatter:nth-child(1) { --sx: -128px; --sy:  62px; --sr: -5deg; }
.l4h-proof__grid > .l4h-scatter:nth-child(2) { --sx:  -54px; --sy: -88px; --sr:  4deg; }
.l4h-proof__grid > .l4h-scatter:nth-child(3) { --sx:   58px; --sy:  92px; --sr: -4deg; }
.l4h-proof__grid > .l4h-scatter:nth-child(4) { --sx:  132px; --sy: -58px; --sr:  5.5deg; }

/* Fleet: alternating sides with a little depth, cards assembling into the row. */
.l4h-fleet__rail > .l4h-scatter:nth-child(1) { --sx: -122px; --sy:  54px; --sr: -4deg; }
.l4h-fleet__rail > .l4h-scatter:nth-child(2) { --sx:  -46px; --sy: -96px; --sr:  3.4deg; }
.l4h-fleet__rail > .l4h-scatter:nth-child(3) { --sx:   50px; --sy:  98px; --sr: -3.4deg; }
.l4h-fleet__rail > .l4h-scatter:nth-child(4) { --sx:  124px; --sy: -52px; --sr:  4.6deg; }

/* Vehicle images get their own small independent settle. */
.l4h-fleet-card.l4h-scatter .l4h-fleet-card__media img {
  transform: translate3d(0, calc(14px * (1 - var(--p))), 0);
}
.l4h-fleet-card.l4h-scatter.is-settled .l4h-fleet-card__media img { transform: none; }

/* Mobile: small upward entrance only — no rotation, no lateral travel, so a reveal
   can never create horizontal overflow or fight the scroll-snap rail.
   NOTE the `:nth-child(n)`: the per-card rules above are (0,2,1) because of their
   own :nth-child, so a plain child selector here would be (0,2,0) and LOSE — the
   desktop 132px displacement then leaked onto mobile. Matching their specificity
   and coming later in the file is what makes these values win. */
@media (max-width: 900px) {
  .l4h-proof__grid > .l4h-scatter:nth-child(n),
  .l4h-fleet__rail > .l4h-scatter:nth-child(n) { --sx: 0px; --sy: 24px; --sr: 0deg; }
  .l4h-scatter {
    transform: translate3d(0, calc(var(--sy) * (1 - var(--p))), 0) scale(calc(0.97 + (0.03 * var(--p))));
  }
}

@media (prefers-reduced-motion: reduce) {
  /* Completed static grid, always. */
  .l4h-scatter, .l4h-scatter.is-settled {
    transform: none !important;
    opacity: 1 !important;
    transition: none !important;
    will-change: auto !important;
  }
  .l4h-fleet-card.l4h-scatter .l4h-fleet-card__media img { transform: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .l4h [data-reveal],
  .l4h-motion-ready .l4h [data-reveal]:not(.is-visible),
  /* every family added above must be neutralised explicitly: the blanket
     `.l4h *` rule below only forces durations, never opacity or transform */
  .l4h-motion-ready .l4h .l4h-head:not(.is-visible) > *,
  .l4h-motion-ready .l4h .l4h-faq__item:not(.is-visible),
  .l4h-motion-ready .l4h .l4h-final:not(.is-visible) > .l4h-wrap > *,
  .l4h-motion-ready .l4h #l4hExpFrame:not(.is-visible),
  .l4h-motion-ready .l4h #l4hExpFrame:not(.is-visible) + .l4h-exp__controls,
  .l4h-motion-ready .l4h [data-reveal]:not(.is-visible) .l4h-svc__media img,
  .l4h-motion-ready .l4h [data-reveal]:not(.is-visible) .l4h-fleet-card__media img,
  .l4h-motion-ready .l4h .l4h-svc[data-reveal]:not(.is-visible) .l4h-svc__fact {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .l4h .l4h-head::after { transform: scaleX(1) !important; }
  .l4h *, .l4h *::before, .l4h *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================================
   A. HERO — dark
   ========================================================================== */
.l4h-hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: var(--l4h-black);
  padding-top: clamp(96px, 12vh, 140px);
  padding-bottom: clamp(40px, 6vw, 72px);
}
.l4h-hero__media { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.l4h-hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* `center 58%` was inert: at every real viewport ratio the hero box is taller
     relative to its width than the 16:9 source, so `cover` fits the height and
     overflows only horizontally — the vertical value never applied. The
     breakpoint blocks further down set the axis that actually does something. */
  object-position: 50% 50%;
  transform: scale(1.035);
  transform-origin: center center;
}
/* Hero settle: 1.035 -> 1 over ~1.4s, once, on first paint */
.l4h-hero__media img.is-settled { transform: scale(1); transition: transform 1400ms var(--l4h-ease-soft); }

.l4h-hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(180deg, rgba(8,8,8,.78) 0%, rgba(8,8,8,.30) 26%, rgba(8,8,8,.55) 62%, rgba(8,8,8,.95) 100%),
    linear-gradient(90deg, rgba(8,8,8,.86) 0%, rgba(8,8,8,.46) 46%, rgba(8,8,8,.12) 100%);
}
.l4h-hero__inner { position: relative; z-index: 2; width: 100%; }
.l4h-hero__content { max-width: 780px; }

.l4h-hero__eyebrow {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--l4h-gold-lt);
  padding: 8px 16px;
  border: 1px solid rgba(232,160,32,.32);
  border-radius: 100px;
  background: rgba(8,8,8,.5);
  margin-bottom: 20px;
}
.l4h-hero h1 {
  font-size: clamp(2.15rem, 5.4vw, 4.05rem);
  line-height: 1.06;
  margin-bottom: 18px;
  text-wrap: balance;
}
.l4h-hero h1 em { font-style: normal; color: var(--l4h-gold-lt); }
.l4h-hero__sub {
  font-size: clamp(0.95rem, 1.25vw, 1.08rem);
  line-height: 1.75;
  color: rgba(255,255,255,.78);
  max-width: 60ch;
  margin-bottom: 26px;
}
/* margin-top permanently reserves the slot the absolutely-positioned
   `.l4h-booker-fallback` occupies when Places is unavailable, so that hint can
   appear without shifting anything or overlapping these buttons. Below 1200px the
   form and these buttons share one column, so the reserve is required there; at
   >=1200px the form moves to its own grid column and the reserve is dropped. */
.l4h-hero__ctas { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 46px; }
@media (max-width: 640px) { .l4h-hero__ctas { margin-top: 56px; } }

/* ============================================================================
   HERO COMPOSITION (revised 2026-07-25)

   The booking panel used to sit directly on top of the car. Measured against the
   car's silhouette, the panel hid 76.9% of it at 1440, 75.1% at 1920, 92.8% at
   768 and 91.0% at 390 — and the part it hid was the whole FACE (grille, star,
   number plate, both headlights, bonnet, windscreen, front wheel), leaving only
   the rear visible. Nothing is layered over the form to fix this; instead the
   panel is moved into genuinely empty parts of the frame:

     >=1200px  copy left / panel top-right, over the empty sky above the roofline.
               The car keeps the entire lower band.
               Measured occlusion after: 5.85% at 1200 (a corner of the rear roof
               only), 1.21% at 1440, 0.09% at 1920, 0.00% at 2560.
               Side effect, deliberate: the hero collapses to exactly 100svh, so at
               1920 the whole frame is visible with no crop at all.
     <=1199px  the media becomes a deliberate top band and the panel sits on solid
               black beneath it — a real mobile crop rather than a shrunk desktop
               composition. Measured occlusion: exactly 0% at every width tested.
   ========================================================================== */
/* Breakpoint is 1024, not 1200. With the band layout running up to 1199px the whole
   booking panel fell below the fold on 1024-class laptops and iPad landscape —
   measured: submit button 283px below the fold at 1024x768 and 369px at 1180x820.
   The grid puts it back on screen (submit at ~426px) at the cost of a little more
   rear-roofline overlap, which is the right trade for a revenue-critical control. */
@media (min-width: 1024px) {
  .l4h-hero { align-items: flex-start; }
  .l4h-hero__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 440px;
    column-gap: clamp(32px, 4vw, 72px);
    align-items: start;
  }
  /* Promotes the five children into the grid with no HTML change. Safe here
     because .l4h-hero__content carries no box of its own (only a max-width). */
  .l4h-hero__content { display: contents; }
  .l4h-hero__eyebrow { grid-column: 1; grid-row: 1; }
  .l4h-hero h1       { grid-column: 1; grid-row: 2; }
  .l4h-hero__sub     { grid-column: 1; grid-row: 3; max-width: 44ch; }
  .l4h-hero__ctas    { grid-column: 1; grid-row: 4; margin-top: 24px; }
  /* Targeted by ID so the frozen .hp-booker-inline class rule is not edited. */
  #hpBookerForm {
    grid-column: 2;
    grid-row: 1 / span 4;
    align-self: start;
    margin-top: 0;
    max-width: 440px;
  }
  /* Re-balanced so the darkest part of the scrim falls on the empty edges rather
     than on the car's nose and the LAX pylon sign. */
  .l4h-hero__scrim {
    background:
      linear-gradient(180deg, rgba(8,8,8,.84) 0%, rgba(8,8,8,.40) 30%, rgba(8,8,8,.26) 58%, rgba(8,8,8,.90) 100%),
      linear-gradient(90deg, rgba(8,8,8,.74) 0%, rgba(8,8,8,.30) 38%, rgba(8,8,8,.08) 60%, rgba(8,8,8,.55) 100%);
  }
}

/* Narrow-desktop step: a slimmer panel and a smaller headline so the two columns
   both breathe at 1024-1199px. */
@media (min-width: 1024px) and (max-width: 1199px) {
  .l4h-hero__inner { grid-template-columns: minmax(0, 1fr) 400px; column-gap: 28px; }
  #hpBookerForm { max-width: 400px; }
  .l4h-hero h1 { font-size: clamp(1.9rem, 3.5vw, 2.5rem); }
  .l4h-hero__sub { max-width: 38ch; }
}

@media (max-width: 1023px) {
  .l4h-hero { padding-top: 0; align-items: flex-start; }
  .l4h-hero__media { inset: 0 0 auto 0; }
  .l4h-hero__scrim {
    background: linear-gradient(180deg,
      rgba(8,8,8,.55) 0%, rgba(8,8,8,.10) 22%,
      rgba(8,8,8,.08) 56%, rgba(8,8,8,.97) 93%, #080808 100%);
  }
  .l4h-hero__sub {
    display: -webkit-box; -webkit-line-clamp: 3;
    -webkit-box-orient: vertical; overflow: hidden;
    margin-bottom: 18px;
  }
}
@media (max-width: 767px) {
  .l4h-hero__media { height: clamp(232px, 32svh, 340px); }
  .l4h-hero__media img { object-position: 40% 72%; }
  .l4h-hero__inner { padding-top: calc(clamp(232px, 32svh, 340px) + 16px); }
}
@media (min-width: 768px) and (max-width: 1023px) {
  .l4h-hero__media { aspect-ratio: 100 / 40; height: auto; }
  .l4h-hero__media img { object-position: 50% 56%; }
  .l4h-hero__inner { padding-top: calc(40vw + 20px); }
}

/* Hero entrance stagger — CSS-only, runs once, never gates interactivity.
   The booking form is deliberately NOT in this list: it is visible and usable
   from the very first frame. */
@keyframes l4hRise {
  from { opacity: 0; transform: translate3d(0, 18px, 0); }
  to   { opacity: 1; transform: none; }
}
/* Duration is deliberately short (520ms, not the 900ms cinematic token) and the
   stagger is 70ms. These elements start at opacity:0, so a long entrance would
   push Largest Contentful Paint out by exactly its delay + duration — measured
   at 1856ms with a 220ms delay + 900ms duration, which failed the LCP budget.
   The hero booking form is intentionally excluded from this animation and is
   interactive from the first frame. */
.l4h-hero__eyebrow,
.l4h-hero h1,
.l4h-hero__sub,
.l4h-hero__ctas {
  animation: l4hRise 520ms var(--l4h-ease-out) both;
}
.l4h-hero__eyebrow { animation-delay: 40ms; }
.l4h-hero h1       { animation-delay: 110ms; }
.l4h-hero__sub     { animation-delay: 180ms; }
.l4h-hero__ctas    { animation-delay: 250ms; }
@media (prefers-reduced-motion: reduce) {
  .l4h-hero__eyebrow, .l4h-hero h1, .l4h-hero__sub, .l4h-hero__ctas { animation: none; }
  .l4h-hero__media img, .l4h-hero__media img.is-settled { transform: none; transition: none; }
}

/* ============================================================================
   FROZEN BOOKING CONTRACT — .hp-booker-* (class names must not change).
   Carried over from the previous inline homepage styles, with the two endless
   animations (gold shimmer + scanline) removed per the motion brief.
   ========================================================================== */
.hp-booker-inline{--hp-ease:cubic-bezier(.16,1,.3,1);max-width:780px;margin:26px 0 0;display:flex;flex-direction:column;align-items:stretch;width:100%;position:relative;font-family:inherit;text-align:left}
.hp-booker-inline *{box-sizing:border-box}
.hp-booker-inline::before{content:'';position:absolute;top:-30px;left:50%;transform:translateX(-50%);width:85%;height:130%;background:radial-gradient(ellipse at center,rgba(232,160,32,.10) 0%,transparent 65%);pointer-events:none;z-index:0}

.hp-booker-tabs{position:relative;z-index:1;display:inline-flex;align-self:flex-start;gap:2px;padding:4px;background:rgba(5,8,16,.8);border:1px solid rgba(232,160,32,.15);border-radius:100px;margin-bottom:12px;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);box-shadow:0 6px 20px rgba(0,0,0,.35)}
.hp-booker-tab{padding:10px 18px;background:transparent;border:none;color:rgba(255,255,255,.72);font-size:11px;font-weight:700;letter-spacing:.12em;cursor:pointer;border-radius:100px;transition:all .28s var(--hp-ease);font-family:inherit;text-transform:uppercase;white-space:nowrap;-webkit-tap-highlight-color:transparent;min-height:44px}
.hp-booker-tab:hover:not(.active){color:#fff;background:rgba(255,255,255,.04)}
.hp-booker-tab.active{background:linear-gradient(135deg,#F5BE5A,#E8A020);color:#0a0a0a;box-shadow:0 4px 16px rgba(232,160,32,.4)}

.hp-booker-bar{position:relative;z-index:1;display:grid;grid-template-columns:1fr 1fr;gap:6px;padding:8px;background:rgba(5,8,16,.85);border:1px solid rgba(232,160,32,.22);border-radius:16px;box-shadow:0 0 0 1px rgba(232,160,32,.06),0 32px 80px rgba(0,0,0,.7),inset 0 1px 0 rgba(255,255,255,.04);-webkit-backdrop-filter:blur(32px) saturate(1.8);backdrop-filter:blur(32px) saturate(1.8)}
.hp-booker-field{position:relative;padding:12px 16px;border-radius:10px;background:rgba(255,255,255,.028);border:1px solid rgba(232,160,32,.12);min-width:0;display:flex;flex-direction:column;justify-content:center;transition:border-color .25s var(--hp-ease),background .25s var(--hp-ease)}
.hp-booker-field:focus-within{border-color:rgba(232,160,32,.55);background:rgba(232,160,32,.04);box-shadow:0 0 0 3px rgba(232,160,32,.08)}
.hp-booker-field-lg{grid-column:1 / -1}
.hp-booker-field-hours{grid-column:1 / -1}
.hp-booker-field.is-hidden{display:none}

.hp-booker-field label{display:block;font-size:9px;font-weight:700;letter-spacing:.28em;text-transform:uppercase;color:rgba(232,160,32,.78);margin-bottom:4px;cursor:pointer}
.hp-booker-input-wrap{display:flex;align-items:center;gap:8px}
.hp-booker-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.hp-booker-dot--pu{background:#22c55e;box-shadow:0 0 0 3px rgba(34,197,94,.22)}
.hp-booker-dot--do{background:#f43f5e;box-shadow:0 0 0 3px rgba(244,63,94,.22)}
/* NOTE — `background-color`, deliberately NOT the `background` shorthand.
   When the Google Maps JS API fails to authenticate (bad key, referrer
   restriction, exhausted quota, lapsed billing, rotated key) Google adds the
   class `gm-err-autocomplete` to these inputs and sets an error icon as an
   INLINE background-image, relying on its own rule
       .gm-err-autocomplete{background-repeat:no-repeat;background-size:15px 15px}
   to draw it once. That rule is specificity (0,1,0); this one is (0,1,1), so a
   `background` shorthand here would win and reset background-repeat to `repeat`
   and background-size to `auto` — tiling Google's 15px error icon ~47× across
   the field. That was the "repeated grey warning icons" defect. Setting only
   background-color leaves Google's repeat/size intact. See also the
   .gm-err-autocomplete override further down, which removes the icon entirely. */
.hp-booker-field input,
.hp-booker-field select.hp-booker-select{width:100%;border:none;background-color:transparent;color:#fff;font-size:16px;font-weight:500;padding:0;outline:none;font-family:inherit;-webkit-appearance:none;appearance:none;cursor:pointer;line-height:1.3;min-height:0}
.hp-booker-field input::placeholder{color:rgba(255,255,255,.4);font-weight:400}
.hp-booker-field input[type="date"],.hp-booker-field input[type="time"]{color-scheme:dark;cursor:pointer}
.hp-booker-field select.hp-booker-select{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23F5BE5A' stroke-width='2.5'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 0 center;padding-right:22px}

.hp-booker-submit{grid-column:1 / -1;margin-top:2px;padding:16px 28px;background:linear-gradient(135deg,#F5BE5A,#E8A020);color:#080808;border:none;border-radius:10px;font-size:13px;font-weight:800;letter-spacing:.18em;text-transform:uppercase;cursor:pointer;transition:transform .25s var(--hp-ease),box-shadow .25s var(--hp-ease);display:inline-flex;align-items:center;justify-content:center;gap:10px;white-space:nowrap;font-family:inherit;min-height:56px;box-shadow:0 8px 32px rgba(232,160,32,.45);-webkit-tap-highlight-color:transparent}
.hp-booker-submit:hover{transform:translateY(-2px);box-shadow:0 14px 38px rgba(232,160,32,.58)}
.hp-booker-submit svg{width:15px;height:15px}

.hp-booker-trust{position:relative;z-index:1;display:flex;align-items:center;justify-content:flex-start;gap:8px;flex-wrap:wrap;margin:12px 0 0;font-size:11px;font-weight:500;color:rgba(255,255,255,.58);letter-spacing:.03em}
.hp-booker-trust svg{width:12px;height:12px;color:#F5BE5A;flex-shrink:0;opacity:.95}

/* Google Places dropdown — injected at <body> level, so NOT namespaced.
   z-index must clear every fixed layer (.lux-hd 1000, .l4h-quotebar 900,
   .l4h-fab 800) so suggestion taps always land on the dropdown. */
.pac-container{background:#100b04 !important;border:1px solid rgba(232,160,32,.30) !important;border-radius:14px !important;box-shadow:0 24px 68px rgba(0,0,0,.7) !important;overflow:hidden;font-family:'Montserrat',-apple-system,sans-serif !important;padding:6px 0;margin-top:8px !important;z-index:100001 !important}
.pac-item{padding:13px 18px !important;border:none !important;color:rgba(255,255,255,.82) !important;font-size:14px !important;cursor:pointer;line-height:1.45;min-height:44px;box-sizing:border-box}
.pac-item:hover,.pac-item-selected{background:rgba(232,160,32,.12) !important}
.pac-item-query{color:#fff !important;font-weight:600 !important;font-size:14px !important}
.pac-matched{color:#F5BE5A !important;font-weight:700 !important}
.pac-icon,.pac-icon-marker,.pac-logo::after{display:none !important}

/* ── Google Maps auth-failure hardening ──────────────────────────────────────
   If the Maps API cannot authenticate, Google decorates the autocomplete inputs
   with `gm-err-autocomplete` + an inline error-icon background. We never want a
   foreign error graphic drawn inside a Lux4Rides booking field, so the image is
   removed outright (inline styles need !important to beat) and the padding it
   reserved is reverted. The field then looks completely normal and stays fully
   usable for manual address entry; home-v2.js surfaces a proper text hint via
   the documented window.gm_authFailure hook. */
.hp-booker-field input.gm-err-autocomplete,
.hp-booker-field input.gm-err-autocomplete:focus {
  background-image: none !important;
  background-repeat: no-repeat !important;
  background-size: auto !important;
  padding-left: 0 !important;
}

/* Manual-entry fallback hint (shown only when Places is unavailable).
   ABSOLUTELY positioned on purpose. Google only flags the auth failure after the
   first Places request fails — which happens WHILE the customer is typing — so a
   hint in normal flow would grow the form and slide the fields out from under
   their cursor. Taking it out of flow means showing it can never move a control
   or contribute layout shift. The space it occupies is permanently reserved by
   `.l4h-hero__ctas { margin-top }` below, so nothing overlaps either. */
.l4h-booker-fallback {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 2;
  /* Deliberately compact: a single quiet line, not a warning panel. It must never
     dominate the hero — it only ever appears after a real API failure. */
  align-items: center;
  gap: 6px;
  margin: 6px 0 0;
  padding: 0;
  border: 0;
  background: none;
  font-size: 11.5px;
  line-height: 1.45;
  letter-spacing: .01em;
  color: rgba(255,255,255,.62);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.l4h-booker-fallback svg { width: 13px; height: 13px; flex: 0 0 auto; stroke: var(--l4h-gold-lt); opacity: .9; }
@media (max-width: 640px) { .l4h-booker-fallback { white-space: normal; } }
.l4h-booker--manual .l4h-booker-fallback { display: flex; }

@media(max-width:640px){
  .hp-booker-tabs{align-self:stretch;justify-content:space-between;gap:2px}
  .hp-booker-tab{flex:1;padding:10px 8px;font-size:10px;letter-spacing:.1em}
  .hp-booker-bar{grid-template-columns:1fr 1fr;padding:6px;gap:5px;border-radius:14px}
  .hp-booker-field{padding:10px 14px;border-radius:10px;min-height:56px}
  .hp-booker-field-sm{grid-column:span 1}
  .hp-booker-submit{padding:14px 20px;min-height:52px;border-radius:10px;font-size:12px}
}
@media(prefers-reduced-motion:reduce){
  .hp-booker-inline,.hp-booker-tab,.hp-booker-field,.hp-booker-submit{transition:none !important;animation:none !important}
}

/* Keyboard focus for the booking fields.
   The widget's original styling resets `outline:none` on these inputs, so every
   focus ring here has to be re-declared. Two Chrome behaviours matter:
     · date/time inputs delegate keyboard focus into their shadow DOM, so when a
       user tabs to #hpDate or #hpTime the host <input> is document.activeElement
       but matches NEITHER :focus NOR :focus-visible — the match is on the shadow
       child. Only :focus-within reaches the host, so it must be in this list;
       without it those two fields were the only tab stops on the page with no
       ring (clicking them looked fine, which is what hid the problem).
     · :focus is included alongside :focus-visible because these are text entry
       fields, where showing the ring to a pointer user is helpful, not noisy. */
.l4h .hp-booker-field input:focus,
.l4h .hp-booker-field input:focus-within,
.l4h .hp-booker-field input:focus-visible,
.l4h .hp-booker-field select:focus,
.l4h .hp-booker-field select:focus-visible,
.l4h .hp-booker-tab:focus-visible,
.l4h .hp-booker-submit:focus-visible {
  outline: 3px solid var(--l4h-gold);
  outline-offset: 2px;
}

/* Tap comfort: the inputs themselves were only ~21px tall inside a 56px field,
   so the input's own hit area was below the minimum target size. Growing the
   input to fill the field keeps the widget's proportions but makes the whole
   field practically tappable (the <label for> already forwards taps too). */
.l4h .hp-booker-field input,
.l4h .hp-booker-field select.hp-booker-select { min-height: 34px; }

/* ============================================================================
   B. PROOF & PRESS — warm white
   ========================================================================== */
/* The hairline rules here are painted BY EACH CARD, never by the container.
   The usual "tinted container showing through a 1px gap" trick only holds while
   every track is covered by a card. Two things break that contract on this page:
   a scattering card is transformed off its track, and `auto-fit` could leave a
   ragged final row. Either one exposes the tint as a grey slab. A 1px ring on the
   card itself renders the same 1px divider at rest — adjacent rings coincide
   inside the 1px gap — and keeps border and background attached to the card
   through every transform. */
.l4h-proof__grid {
  display: grid;
  /* Fixed counts, not auto-fit: four items must land 4x1 / 2x2 / 1x4 and never
     leave an empty track. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: transparent;
}
@media (min-width: 1000px) { .l4h-proof__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (max-width: 559px)  { .l4h-proof__grid { grid-template-columns: minmax(0, 1fr); } }
.l4h-proof__item {
  background: var(--l4h-ivory);
  box-shadow: 0 0 0 1px var(--l4h-hairline-light);
  padding: 26px 22px;
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
.l4h-proof__item svg { width: 20px; height: 20px; stroke: var(--l4h-gold-on-light); flex-shrink: 0; margin-top: 2px; }
.l4h-proof__label { font-size: 13.5px; font-weight: 700; color: var(--l4h-light-text); letter-spacing: .01em; line-height: 1.4; }
.l4h-proof__note { display: block; font-size: 12px; font-weight: 500; color: var(--l4h-light-muted); margin-top: 4px; line-height: 1.5; }

/* ── Press coverage: centred authority wall ─────────────────────────────────
   Three equal cards on one centred row. The publisher name and the disclosure are
   always visible text — never image-only — so they stay indexable and audible. */
.l4h-press { margin-top: clamp(46px, 5.5vw, 74px); }
.l4h-press__head { text-align: center; max-width: 720px; margin: 0 auto clamp(26px, 3vw, 40px); position: relative; }
.l4h-press__h {
  font-family: var(--l4h-serif);
  font-size: clamp(1.35rem, 2.5vw, 1.95rem);
  font-weight: 500;
  color: var(--l4h-light-text);
  margin: 10px 0 0;
}
/* Gold divider that draws outward from the centre as the block arrives. */
.l4h-press__rule {
  display: block;
  width: 120px; height: 1px;
  margin: 18px auto 0;
  background: linear-gradient(90deg, rgba(122,87,20,0), var(--l4h-gold-on-light), rgba(122,87,20,0));
  transform: scaleX(0);
  transform-origin: center center;
  transition: transform 760ms var(--l4h-ease-soft) 160ms;
}
.l4h-press.is-visible .l4h-press__rule { transform: scaleX(1); }
html:not(.l4h-motion-ready) .l4h-press__rule { transform: scaleX(1); }

.l4h-press__wall {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(14px, 1.8vw, 22px);
  max-width: 1000px;
  margin-inline: auto;
}

.l4h-press-card {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 172px;
  padding: 28px 20px 24px;
  text-align: center;
  background: #fff;
  border: 1px solid var(--l4h-hairline-light);
  border-radius: var(--l4h-radius);
  transition: transform 260ms var(--l4h-ease-out),
              border-color 260ms var(--l4h-ease-out),
              box-shadow 260ms var(--l4h-ease-out);
}
.l4h-press-card__wordmark {
  font-family: var(--l4h-serif);
  font-size: clamp(1.25rem, 2.1vw, 1.6rem);
  letter-spacing: .01em;
  color: var(--l4h-light-text);
  line-height: 1.1;
}
.l4h-press-card__logo { max-width: 180px; height: auto; filter: grayscale(1); opacity: .85; transition: filter 260ms, opacity 260ms; }
.l4h-press-card__name {
  font-size: 12px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--l4h-light-muted);
}
.l4h-press-card__disclosure {
  font-size: 11px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  color: var(--l4h-gold-on-light);
}
.l4h-press-card__link {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 4px; min-height: 24px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--l4h-light-muted);
  transition: color 220ms var(--l4h-ease-out), gap 220ms var(--l4h-ease-out);
}
.l4h-press-card__link svg { width: 13px; height: 13px; }

@media (hover: hover) {
  .l4h-press-card:hover {
    transform: translateY(-5px);
    border-color: rgba(122,87,20,.5);
    box-shadow: 0 16px 38px rgba(20,18,14,.13);
  }
  .l4h-press-card:hover .l4h-press-card__logo { filter: grayscale(0); opacity: 1; }
  .l4h-press-card:hover .l4h-press-card__link { color: var(--l4h-gold-on-light); gap: 10px; }
}
.l4h-press-card:focus-visible {
  transform: translateY(-5px);
  border-color: var(--l4h-gold-on-light);
  box-shadow: 0 0 0 3px rgba(122,87,20,.28);
}

/* Cool blue/silver sweep — once on arrival (staggered per card), once on intent. */
.l4h-press-card__sheen {
  position: absolute; inset: 0; z-index: 2; pointer-events: none; opacity: 0;
  border-radius: var(--l4h-radius);
  background: linear-gradient(115deg,
    rgba(198,222,245,0) 34%, rgba(219,236,255,.55) 47%,
    rgba(240,248,255,.8) 50%, rgba(219,236,255,.55) 53%, rgba(198,222,245,0) 66%);
  background-size: 260% 100%;
  background-position: 130% 0;
}
.l4h-press-card.is-sheen .l4h-press-card__sheen { animation: l4hSheen 1000ms var(--l4h-ease-soft) 1 both; }
@media (hover: hover) { .l4h-press-card:hover .l4h-press-card__sheen { animation: l4hSheen 1000ms var(--l4h-ease-soft) 1 both; } }
.l4h-press-card:focus-visible .l4h-press-card__sheen { animation: l4hSheen 1000ms var(--l4h-ease-soft) 1 both; }

/* Entrance: left card from the left, centre card rises, right card from the right. */
.l4h-press-card { transition-property: transform, border-color, box-shadow, opacity; }
.l4h-motion-ready .l4h-press:not(.is-visible) .l4h-press-card {
  opacity: 0;
  transition: opacity 620ms var(--l4h-ease-out), transform 620ms var(--l4h-ease-out);
}
.l4h-motion-ready .l4h-press:not(.is-visible) .l4h-press-card[data-enter="left"]   { transform: translate3d(-78px, 42px, 0) rotate(-2.4deg) scale(.95); }
.l4h-motion-ready .l4h-press:not(.is-visible) .l4h-press-card[data-enter="center"] { transform: translate3d(0, 56px, 0) scale(.95); }
.l4h-motion-ready .l4h-press:not(.is-visible) .l4h-press-card[data-enter="right"]  { transform: translate3d(78px, 42px, 0) rotate(2.4deg) scale(.95); }
.l4h-press.is-visible .l4h-press-card { opacity: 1; transform: none; }
.l4h-press.is-visible .l4h-press-card[data-enter="left"]   { transition-delay: 0ms; }
.l4h-press.is-visible .l4h-press-card[data-enter="center"] { transition-delay: 110ms; }
.l4h-press.is-visible .l4h-press-card[data-enter="right"]  { transition-delay: 220ms; }

@media (max-width: 780px) {
  .l4h-press__wall { grid-template-columns: 1fr; max-width: 420px; }
  .l4h-press-card { min-height: 148px; }
  /* No rotation and no lateral travel on mobile. */
  .l4h-motion-ready .l4h-press:not(.is-visible) .l4h-press-card[data-enter="left"],
  .l4h-motion-ready .l4h-press:not(.is-visible) .l4h-press-card[data-enter="center"],
  .l4h-motion-ready .l4h-press:not(.is-visible) .l4h-press-card[data-enter="right"] {
    transform: translate3d(0, 22px, 0) scale(.98);
  }
}

@media (prefers-reduced-motion: reduce) {
  .l4h-motion-ready .l4h-press:not(.is-visible) .l4h-press-card,
  .l4h-press-card { opacity: 1 !important; transform: none !important; transition: none !important; }
  .l4h-press__rule { transform: scaleX(1) !important; transition: none !important; }
  .l4h-press-card__sheen { animation: none !important; opacity: 0 !important; }
}

/* ============================================================================
   C. SIGNATURE SERVICES — warm white, LAX + Disneyland dominant
   ========================================================================== */
.l4h-svc-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 18px; }
.l4h-svc {
  position: relative;
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid var(--l4h-hairline-light);
  border-radius: var(--l4h-radius);
  overflow: hidden;
  transition: transform var(--l4h-motion-fast) var(--l4h-ease-out),
              box-shadow var(--l4h-motion-fast) var(--l4h-ease-out),
              border-color var(--l4h-motion-fast) var(--l4h-ease-out);
}
.l4h-svc--feature { grid-column: span 6; }
.l4h-svc--std { grid-column: span 4; }
@media (max-width: 1024px) {
  .l4h-svc--feature { grid-column: span 12; }
  .l4h-svc--std { grid-column: span 6; }
}
@media (max-width: 620px) {
  .l4h-svc--std { grid-column: span 12; }
  .l4h-svc-grid { gap: 14px; }
}
@media (hover: hover) {
  .l4h-svc:hover { transform: translateY(-4px); box-shadow: 0 22px 50px rgba(20,18,14,.13); border-color: rgba(147,107,30,.4); }
  .l4h-svc:hover .l4h-svc__media img { transform: scale(1.045); }
}
.l4h-svc__media { position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: var(--l4h-ivory-deep); }
.l4h-svc__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 600ms var(--l4h-ease-out); }
.l4h-svc__body { padding: 22px 22px 20px; display: flex; flex-direction: column; flex: 1; gap: 10px; }
.l4h-svc__tag {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--l4h-gold-on-light);
}
.l4h-svc h3 { font-size: clamp(1.15rem, 1.9vw, 1.5rem); color: var(--l4h-light-text); }
.l4h-svc--std h3 { font-size: 1.08rem; }
.l4h-svc p { font-size: 14px; line-height: 1.7; color: var(--l4h-light-muted); flex: 1; }
.l4h-svc__facts { display: flex; flex-wrap: wrap; gap: 6px 8px; margin-top: 2px; }
.l4h-svc__fact {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--l4h-light-muted);
  background: var(--l4h-ivory);
  border: 1px solid var(--l4h-hairline-light);
  border-radius: 100px;
  padding: 5px 11px;
}
/* One primary anchor per card, stretched over the whole card (no nested <a>). */
.l4h-svc__cta { align-self: flex-start; }
.l4h-svc__cta::after { content: ''; position: absolute; inset: 0; }

/* ============================================================================
   D. SIGNATURE VEHICLE STORY — dark, one restrained scroll-progress scene
   ========================================================================== */
.l4h-vehicle { overflow: hidden; }
.l4h-vehicle__layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(28px, 5vw, 64px);
  align-items: center;
}
@media (max-width: 900px) { .l4h-vehicle__layout { grid-template-columns: 1fr; } }
.l4h-vehicle__specs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1px; background: var(--l4h-hairline-dark); border: 1px solid var(--l4h-hairline-dark); border-radius: var(--l4h-radius); overflow: hidden; margin-top: 26px; }
.l4h-vehicle__spec { background: var(--l4h-charcoal); padding: 18px 20px; }
.l4h-vehicle__spec dt { font-size: 10.5px; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: var(--l4h-gold); margin-bottom: 6px; }
.l4h-vehicle__spec dd { margin: 0; font-size: 14px; color: rgba(255,255,255,.82); line-height: 1.55; }
.l4h-vehicle__stage { position: relative; }
.l4h-vehicle__stage img {
  width: 100%;
  border-radius: var(--l4h-radius-lg);
  /* Travels a restrained distance as the section scrolls (JS sets --l4h-travel) */
  transform: translate3d(calc(var(--l4h-travel, 0) * 18vw), 0, 0);
}
@media (prefers-reduced-motion: reduce) {
  .l4h-vehicle__stage img { transform: none !important; }
}

/* ============================================================================
   E. POPULAR JOURNEYS — warm white (replaces the retired World Cup promo)
   ========================================================================== */
.l4h-journeys__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; }
.l4h-journey {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 22px 22px 20px;
  background: #fff;
  border: 1px solid var(--l4h-hairline-light);
  border-radius: var(--l4h-radius-sm);
  min-height: 118px;
  justify-content: center;
  transition: transform var(--l4h-motion-fast) var(--l4h-ease-out),
              border-color var(--l4h-motion-fast) var(--l4h-ease-out),
              box-shadow var(--l4h-motion-fast) var(--l4h-ease-out);
}
.l4h-journey--primary { background: linear-gradient(150deg, #fff 0%, #FBF7F0 100%); border-color: rgba(147,107,30,.34); }
@media (hover: hover) {
  .l4h-journey:hover { transform: translateY(-3px); border-color: var(--l4h-gold-on-light); box-shadow: 0 16px 36px rgba(20,18,14,.10); }
}
.l4h-journey__route { font-family: var(--l4h-serif); font-size: 1.16rem; color: var(--l4h-light-text); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.l4h-journey__route span { color: var(--l4h-gold-on-light); }
.l4h-journey__note { font-size: 13px; color: var(--l4h-light-muted); line-height: 1.6; }

/* ============================================================================
   F. HOW SERVICE WORKS — dark, gold progress line fills once
   ========================================================================== */
.l4h-steps { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); gap: 22px; }
@media (max-width: 900px) { .l4h-steps { grid-template-columns: repeat(2, 1fr); gap: 28px 20px; } }
@media (max-width: 520px) { .l4h-steps { grid-template-columns: 1fr; } }
.l4h-steps__track {
  position: absolute;
  top: 21px;
  left: 12%;
  right: 12%;
  height: 1px;
  background: rgba(232,160,32,.16);
  overflow: hidden;
}
@media (max-width: 900px) { .l4h-steps__track { display: none; } }
/* The collapsed state exists only once motion is armed. Previously scaleX(0) was
   unconditional and only `.l4h-steps.is-visible` restored it, so with JavaScript
   disabled the gold line between the four step numbers stayed permanently invisible. */
.l4h-steps__fill {
  display: block;
  height: 100%;
  width: 100%;
  background: linear-gradient(90deg, var(--l4h-gold), var(--l4h-gold-lt));
  transform-origin: left center;
}
.l4h-motion-ready .l4h-steps:not(.is-visible) .l4h-steps__fill { transform: scaleX(0); }
.l4h-steps.is-visible .l4h-steps__fill { transform: scaleX(1); transition: transform 1500ms var(--l4h-ease-soft); }
@media (prefers-reduced-motion: reduce) { .l4h-steps__fill { transform: scaleX(1) !important; transition: none !important; } }
.l4h-step__num {
  width: 42px; height: 42px;
  border-radius: 50%;
  border: 1px solid rgba(232,160,32,.5);
  background: var(--l4h-black);
  color: var(--l4h-gold);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--l4h-serif); font-size: 1.02rem;
  margin-bottom: 18px;
  position: relative; z-index: 1;
}
.l4h-step h3 { font-size: 1.08rem; margin-bottom: 8px; }
.l4h-step p { font-size: 13.5px; line-height: 1.7; color: var(--l4h-on-dark-soft); }

/* ============================================================================
   G. FLEET — light, scroll-snap on mobile with visible manual controls
   ========================================================================== */
.l4h-fleet__rail { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.l4h-fleet-card {
  display: flex; flex-direction: column;
  background: #fff;
  border: 1px solid var(--l4h-hairline-light);
  border-radius: var(--l4h-radius);
  overflow: hidden;
}
/* The stage ratio matches the pre-composed source images exactly (1000x625 = 16:10),
   so `cover` scales without discarding anything — every vehicle renders complete.
   White stage because the three studio cut-outs are composited on white; it also
   matches the card background, so the image reads as one clean product stage.
   A min-height guarantees the box keeps its shape even if an image fails to load,
   so the card can never collapse. */
.l4h-fleet-card__media {
  aspect-ratio: 16 / 10;
  /* Matches the studio white the three cut-outs are composited onto, so stage and
     image read as one surface. The fixed aspect-ratio also means a failed image
     still holds the card's shape instead of collapsing it. */
  background: #fff;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.l4h-fleet-card__media picture { display: block; width: 100%; height: 100%; }
/* `contain`, not `cover`. The sources are pre-composed to exactly this stage ratio
   so the two are equivalent in the normal case, but `contain` cannot crop even if
   the rendered box lands a fraction off 16:10 through sub-pixel layout rounding —
   so a vehicle can never lose an edge. Any residual letterbox is the same white as
   the stage, so it is invisible. */
.l4h-fleet-card__media img { width: 100%; height: 100%; object-fit: contain; object-position: center center; }
.l4h-fleet-card__body { padding: 18px 18px 20px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.l4h-fleet-card h3 { font-size: 1.05rem; color: var(--l4h-light-text); }
.l4h-fleet-card__type { font-size: 10.5px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--l4h-gold-on-light); }
.l4h-fleet-card__spec { font-size: 13px; color: var(--l4h-light-muted); line-height: 1.6; }
@media (max-width: 900px) {
  .l4h-fleet__rail {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    gap: 14px;
    padding-bottom: 10px;
    scrollbar-width: thin;
  }
  .l4h-fleet-card { flex: 0 0 78%; scroll-snap-align: start; }
}
.l4h-fleet__controls { display: none; gap: 10px; margin-top: 16px; }
@media (max-width: 900px) { .l4h-fleet__controls { display: flex; } }
.l4h-fleet__btn {
  width: var(--l4h-tap); height: var(--l4h-tap);
  border-radius: 50%;
  border: 1px solid var(--l4h-hairline-light);
  background: #fff;
  color: var(--l4h-light-text);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.l4h-fleet__btn svg { width: 18px; height: 18px; }
.l4h-fleet__more { margin-top: 26px; }

/* ============================================================================
   H. THE EXPERIENCE — dark, restrained editorial crossfade
   ========================================================================== */
.l4h-exp__frame {
  position: relative;
  aspect-ratio: 21 / 9;
  border-radius: var(--l4h-radius-lg);
  overflow: hidden;
  background: var(--l4h-charcoal);
}
@media (max-width: 700px) { .l4h-exp__frame { aspect-ratio: 4 / 3; } }
.l4h-exp__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1200ms var(--l4h-ease-soft);
}
.l4h-exp__slide img { width: 100%; height: 100%; object-fit: cover; }

/* Per-slide framing. object-fit: cover always discards part of the source, so the
   crop is aimed deliberately per image rather than left at the 50%/50% default.
   Chauffeur slide (1500x844 in a 21:9 box → 643 of 844 rows visible): biasing to
   30% puts the visible slice at roughly y 60-703, so the head (y 110-236) clears
   the top edge with ~50px of headroom and the Escalade stays fully in frame.
   Under 700px the frame becomes 4:3, so the full height fits and the crop moves
   to the horizontal axis instead — biased right, because the chauffeur stands at
   about 79% of the frame width and centring would clip him. */
.l4h-exp__slide--chauffeur img { object-position: 50% 30%; }
@media (max-width: 700px) {
  .l4h-exp__slide--chauffeur img { object-position: 66% 32%; }
}
.l4h-exp__slide.is-active { opacity: 1; }
/* No-JS: show the first frame as a clean static composition. Scoped to the
   not-armed state — an unconditional `:first-child { opacity: 1 }` pinned slide 1
   visible forever, so the crossfade never actually appeared to change. */
html:not(.l4h-motion-ready) .l4h-exp__slide:first-child { opacity: 1; }
/* A slow drift that settles as each slide becomes active. */
.l4h-exp__slide { transform: scale(1.012); transition: opacity 1200ms var(--l4h-ease-soft), transform 2600ms var(--l4h-ease-soft); }
.l4h-exp__slide.is-active { transform: scale(1); }
@media (prefers-reduced-motion: reduce) {
  .l4h-exp__slide { transition: none; opacity: 0; }
  .l4h-exp__slide:first-child { opacity: 1; }
}
.l4h-exp__controls { display: flex; align-items: center; gap: 10px; margin-top: 16px; }
.l4h-exp__dot {
  width: var(--l4h-tap); height: var(--l4h-tap);
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; cursor: pointer; padding: 0;
}
.l4h-exp__dot::before {
  content: ''; width: 9px; height: 9px; border-radius: 50%;
  background: rgba(255,255,255,.28);
  transition: background var(--l4h-motion-fast) var(--l4h-ease-out), transform var(--l4h-motion-fast) var(--l4h-ease-out);
}
.l4h-exp__dot[aria-current="true"]::before { background: var(--l4h-gold); transform: scale(1.25); }

/* ============================================================================
   I. WHY LUX4RIDES — warm ivory
   ========================================================================== */
.l4h-why__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(272px, 1fr)); gap: 18px; }
.l4h-why-card {
  background: #fff;
  border: 1px solid var(--l4h-hairline-light);
  border-radius: var(--l4h-radius);
  padding: 26px 24px;
  display: flex; flex-direction: column; gap: 10px;
}
.l4h-why-card__icon {
  width: 40px; height: 40px; border-radius: 10px;
  background: rgba(147,107,30,.09);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 4px;
}
.l4h-why-card__icon svg { width: 19px; height: 19px; stroke: var(--l4h-gold-on-light); }
.l4h-why-card h3 { font-size: 1.06rem; color: var(--l4h-light-text); }
.l4h-why-card p { font-size: 13.5px; line-height: 1.7; color: var(--l4h-light-muted); }

/* ============================================================================
   K. DIRECT ANSWER + FAQ — light
   ========================================================================== */
.l4h-answer {
  background: #fff;
  border: 1px solid var(--l4h-hairline-light);
  border-left: 3px solid var(--l4h-gold-on-light);
  border-radius: var(--l4h-radius-sm);
  padding: clamp(24px, 3vw, 34px);
  max-width: 78ch;
}
.l4h-answer p { font-size: clamp(0.98rem, 1.15vw, 1.06rem); line-height: 1.8; color: var(--l4h-light-text); }
.l4h-answer p + p { margin-top: 12px; color: var(--l4h-light-muted); font-size: 14px; }

.l4h-faq { max-width: 900px; margin-top: clamp(34px, 4vw, 52px); }
.l4h-faq__item { border-bottom: 1px solid var(--l4h-hairline-light); }
.l4h-faq__q {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  padding: 22px 0;
  min-height: var(--l4h-tap);
  background: none; border: none; cursor: pointer;
  font-family: var(--l4h-serif);
  font-size: clamp(1.02rem, 1.5vw, 1.18rem);
  font-weight: 500;
  color: var(--l4h-light-text);
  text-align: left;
}
.l4h-faq__q svg { width: 18px; height: 18px; stroke: var(--l4h-gold-on-light); flex-shrink: 0; transition: transform var(--l4h-motion-fast) var(--l4h-ease-out); }
.l4h-faq__q[aria-expanded="true"] svg { transform: rotate(180deg); }
.l4h-faq__a { padding: 0 0 22px; font-size: 14.5px; line-height: 1.8; color: var(--l4h-light-muted); max-width: 72ch; }
/* No-JS: answers stay visible (details-free, JS only collapses them) */
.l4h-faq__a[hidden] { display: none; }

/* ============================================================================
   L. FINAL CTA — dark
   ========================================================================== */
.l4h-final { text-align: center; }
.l4h-final .l4h-h2 { margin-inline: auto; }
.l4h-final .l4h-lead { margin-inline: auto; }
.l4h-final__ctas { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 28px; }
.l4h-final__note { margin-top: 18px; font-size: 13px; color: var(--l4h-on-dark-soft); }

/* ============================================================================
   CONTACT FAB + MOBILE QUOTE ANCHOR
   ========================================================================== */
/* ── Single floating VIP email button ────────────────────────────────────────
   Replaces the former call + SMS + email stack (and the gold #scrollToTop circle
   that used to sit half-hidden behind it). One control, so it never competes with
   the booking CTA. It never pulses, and it is nudged aside while the mobile sticky
   CTA is on screen so the two can never overlap. */
.l4h-mailfab {
  position: fixed;
  right: clamp(12px, 2vw, 22px);
  bottom: calc(clamp(14px, 2vw, 24px) + env(safe-area-inset-bottom, 0px));
  z-index: 800;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 52px;
  padding: 0 18px 0 16px;
  border-radius: 26px;
  background: linear-gradient(135deg, #16161a 0%, #0b0b0d 100%);
  border: 1px solid rgba(232,160,32,.38);
  color: #fff;
  font-family: var(--l4h-body);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  box-shadow: 0 10px 28px rgba(0,0,0,.42);
  transition: transform var(--l4h-motion-fast) var(--l4h-ease-out),
              border-color var(--l4h-motion-fast) var(--l4h-ease-out),
              box-shadow var(--l4h-motion-fast) var(--l4h-ease-out);
}
.l4h-mailfab svg { width: 19px; height: 19px; stroke: var(--l4h-gold-lt); flex: 0 0 auto; }
@media (hover: hover) {
  .l4h-mailfab:hover {
    transform: translateY(-2px);
    border-color: var(--l4h-gold);
    box-shadow: 0 14px 34px rgba(232,160,32,.24);
  }
}
.l4h-mailfab:active { transform: translateY(0) scale(.98); }
/* Icon-only below 560px so it never crowds the page on small screens. */
@media (max-width: 560px) {
  .l4h-mailfab { width: 52px; height: 52px; padding: 0; justify-content: center; border-radius: 50%; }
  .l4h-mailfab__label { display: none; }
}

/* The shared footer's gold scroll-to-top circle is the button that appeared
   half-hidden behind the old phone button. Hidden on THIS page only — every other
   page keeps it, and global.js still runs against it harmlessly. */
body.l4h-page #scrollToTop { display: none !important; }

/* ── Mobile sticky booking CTA ───────────────────────────────────────────────
   One compact pill, mobile only. An ANCHOR to the existing hero form (never a
   second form), so values already typed are preserved. It is off-canvas rather
   than display:none while hidden, so showing it cannot cause layout shift, and it
   is inert (pointer-events + aria-hidden) while off screen. */
.l4h-quotebar {
  position: fixed;
  left: 50%;
  bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  z-index: 900;
  display: none;
  transform: translate(-50%, 160%);
  transition: transform 340ms var(--l4h-ease-out), opacity 240ms var(--l4h-ease-out);
  opacity: 0;
  pointer-events: none;
}
@media (max-width: 900px) { .l4h-quotebar { display: block; } }
.l4h-quotebar.is-shown { transform: translate(-50%, 0); opacity: 1; pointer-events: auto; }
.l4h-quotebar__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 50px;
  padding: 0 26px;
  border-radius: 25px;
  background: linear-gradient(135deg, var(--l4h-gold-lt), var(--l4h-gold));
  color: #0a0a0a;
  font-family: var(--l4h-body);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  box-shadow: 0 12px 30px rgba(0,0,0,.45), 0 0 0 1px rgba(232,160,32,.5);
  white-space: nowrap;
}
.l4h-quotebar__cta svg { width: 15px; height: 15px; }
/* Keep the email button clear of the sticky CTA while it is shown. */
.l4h-quotebar.is-shown ~ .l4h-mailfab {
  bottom: calc(78px + env(safe-area-inset-bottom, 0px));
}
@media (prefers-reduced-motion: reduce) {
  /* show/hide without sliding */
  .l4h-quotebar { transition: none; transform: translate(-50%, 0); opacity: 0; visibility: hidden; }
  .l4h-quotebar.is-shown { opacity: 1; visibility: visible; }
}

/* ============================================================================
   BEVERLY HILLS LUX RIDE — cross-brand section
   ========================================================================== */
.l4h-bhlr { overflow: hidden; }
/* Centred inside the 1280px wrap, with the two columns pulled closer together at
   a 48/52 split so the copy and photograph read as one composition rather than
   two objects pushed to opposite edges. */
.l4h-bhlr__layout {
  display: grid;
  grid-template-columns: 48fr 52fr;
  gap: clamp(24px, 3.5vw, 56px);
  align-items: center;
  max-width: 1180px;
  margin-inline: auto;
}
@media (max-width: 900px) {
  .l4h-bhlr__layout { grid-template-columns: 1fr; max-width: 560px; }
}
.l4h-bhlr__support {
  margin-top: 16px;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--l4h-gold-lt);
}
.l4h-bhlr__note {
  margin-top: 8px;
  font-size: 13.5px;
  line-height: 1.7;
  /* Lifted from the muted token for a little more contrast on black. */
  color: rgba(255,255,255,.74);
}
/* Body copy in this section reads slightly brighter than the page default. */
.l4h-bhlr .l4h-lead { color: rgba(255,255,255,.84); }
.l4h-bhlr__cta { margin-top: 26px; }
.l4h-bhlr__media { position: relative; }
.l4h-bhlr__media img {
  width: 100%;
  border-radius: var(--l4h-radius-lg);
  position: relative;
  z-index: 1;
}
/* A gold frame that draws itself in as the section arrives. */
.l4h-bhlr__frame {
  position: absolute;
  inset: -14px -14px 14px 14px;
  border: 1px solid var(--l4h-gold);
  border-radius: var(--l4h-radius-lg);
  opacity: .55;
  z-index: 0;
  transform-origin: left top;
}
/* Pull the offset in on narrow screens: at -14px the frame reached past the wrap
   padding and was visibly sliced by the section's overflow clip. */
@media (max-width: 900px) {
  .l4h-bhlr__frame { inset: -8px -8px 8px 8px; }
}
/* Below 420px even 8px can touch the edge, so tuck it fully inside the image. */
@media (max-width: 420px) {
  .l4h-bhlr__frame { inset: 6px 6px 6px 6px; }
}

/* ── Cool blue/silver reflection sweep ───────────────────────────────────────
   A single pass of ice-blue light across the photograph and its frame. It runs
   once when the section settles, repeats once ~2.5s later, then stops for good —
   it is not a loop. It also runs once on deliberate hover or keyboard focus.
   Peak opacity is 0.18, inside the 12–22% brief, so it reads as a reflection
   rather than a flash and never competes with the black-and-gold identity. */
.l4h-bhlr__media { position: relative; isolation: isolate; }
.l4h-bhlr__media::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: var(--l4h-radius-lg);
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(115deg,
    rgba(198, 222, 245, 0) 30%,
    rgba(214, 234, 255, .60) 46%,
    rgba(236, 246, 255, .85) 50%,
    rgba(214, 234, 255, .60) 54%,
    rgba(198, 222, 245, 0) 70%);
  background-size: 260% 100%;
  background-position: 130% 0;
}
.l4h-bhlr__media.is-sweeping::after { animation: l4hSheen 1100ms var(--l4h-ease-soft) 1 both; }
@keyframes l4hSheen {
  0%   { background-position: 130% 0; opacity: 0; }
  18%  { opacity: .18; }
  82%  { opacity: .18; }
  100% { background-position: -60% 0; opacity: 0; }
}
/* Hover / keyboard focus replays it exactly once. */
.l4h-bhlr__media.is-sweep-hover::after { animation: l4hSheen 1100ms var(--l4h-ease-soft) 1 both; }

@media (prefers-reduced-motion: reduce) {
  .l4h-bhlr__media::after { animation: none !important; opacity: 0 !important; }
}

/* ============================================================================
   BOOKING PANEL — premium three-dimensional entrance
   ONE state owner. The panel is fully present and interactive in the initial
   HTML; these classes only play a transition on it.

   WHY TWO SCOPED CLASSES INSTEAD OF A GENERIC `is-entered`
   -------------------------------------------------------
   The first attempt put the `transition` and the armed values on the SAME class.
   Adding that class therefore changed transform/opacity while a transition was
   already in effect, so the browser animated *into* the armed state over 860ms
   instead of snapping to it. The release fired 24ms later and reversed from ~3%
   of the way, which is why the measured transform never left identity and the
   entrance was invisible.

   The armed class now carries `transition: none`, so the start state SNAPS. It is
   committed with a single forced layout read, then removed, at which point the
   base transition applies and the panel animates once to its natural position.
   Scoped names (`l4h-booking-armed` / `l4h-booking-entered`) also guarantee the
   global reveal system can never take ownership of this element's transform.
   ========================================================================== */
.l4h-hero__inner { perspective: 1200px; }
@media (min-width: 1200px) { .l4h-hero__inner { perspective: 1400px; } }

/* Base: the transition only. No values, so nothing moves until we arm it. */
.l4h-booking-3d {
  transform-style: preserve-3d;
  transition: opacity 860ms var(--l4h-ease-out), transform 860ms var(--l4h-ease-out);
}

/* Armed start state — deliberately transition-free so it is applied instantly. */
.l4h-booking-armed {
  opacity: 0;
  transform: translate3d(55px, 28px, -70px) rotateY(-5deg) rotateX(2deg) scale(.97);
  transition: none !important;
  will-change: transform, opacity;
}
.l4h-booking-armed .hp-booker-tab   { opacity: 0; transform: translate3d(0, 10px, 0); transition: none !important; }
.l4h-booking-armed .hp-booker-field { opacity: 0; transform: translate3d(0, 12px, 0); transition: none !important; }

/* Released: natural position, animated by the base transition above. */
.l4h-booking-entered { opacity: 1; transform: none; }

/* Tabs follow the panel with a short stagger. */
.l4h-booking-3d .hp-booker-tab {
  opacity: 1; transform: none;
  transition: opacity 420ms var(--l4h-ease-out), transform 420ms var(--l4h-ease-out);
}
.l4h-booking-entered .hp-booker-tab:nth-child(1) { transition-delay: 300ms; }
.l4h-booking-entered .hp-booker-tab:nth-child(2) { transition-delay: 370ms; }
.l4h-booking-entered .hp-booker-tab:nth-child(3) { transition-delay: 440ms; }

/* Fields settle in after the outer panel has landed. */
.l4h-booking-3d .hp-booker-field {
  opacity: 1; transform: none;
  transition: opacity 460ms var(--l4h-ease-out), transform 460ms var(--l4h-ease-out);
}
.l4h-booking-entered .hp-booker-field:nth-of-type(1) { transition-delay: 420ms; }
.l4h-booking-entered .hp-booker-field:nth-of-type(2) { transition-delay: 490ms; }
.l4h-booking-entered .hp-booker-field:nth-of-type(3) { transition-delay: 560ms; }
.l4h-booking-entered .hp-booker-field:nth-of-type(4) { transition-delay: 560ms; }
.l4h-booking-entered .hp-booker-field:nth-of-type(5) { transition-delay: 630ms; }

/* Submit: a single restrained gold sweep, once — not a loop. */
.l4h-booking-3d .hp-booker-submit { position: relative; overflow: hidden; }
.l4h-booking-3d .hp-booker-submit::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0; left: -60%;
  width: 45%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.42), transparent);
  transform: translateX(0);
  opacity: 0;
  pointer-events: none;
}
.l4h-booking-entered .hp-booker-submit::after {
  animation: l4hSweep 900ms var(--l4h-ease-soft) 700ms 1 both;
}
@keyframes l4hSweep {
  from { transform: translateX(0); opacity: .9; }
  to   { transform: translateX(340%); opacity: 0; }
}

/* Mobile: gentler, no rotation, no depth translation — nothing that could push
   the layout sideways. */
@media (max-width: 900px) {
  .l4h-booking-armed { transform: translate3d(0, 26px, 0) scale(.985); }
}

@media (prefers-reduced-motion: reduce) {
  .l4h-booking-3d,
  .l4h-booking-armed,
  .l4h-booking-armed .hp-booker-tab,
  .l4h-booking-armed .hp-booker-field {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    will-change: auto !important;
  }
  .l4h-booking-entered .hp-booker-submit::after { animation: none !important; opacity: 0 !important; }
  .l4h-bhlr__frame { opacity: .55 !important; transform: none !important; }
}

/* ============================================================================
   PAGE-LEVEL RULES (body.l4h-page) — these target elements that live OUTSIDE
   <main class="l4h">: the skip link, and the shared footer's scroll-to-top
   button. Both are scoped to the homepage body class so no other page changes.
   ========================================================================== */
body.l4h-page .l4h-skip-link {
  position: absolute;
  top: -100%;
  left: 16px;
  z-index: 100002;
  background: var(--l4h-gold, #E8A020);
  color: #080808;
  padding: 12px 20px;
  font-family: 'Montserrat', -apple-system, sans-serif;
  font-size: 13px;
  font-weight: 700;
  border-radius: 0 0 10px 10px;
  transition: top .2s ease;
}
body.l4h-page .l4h-skip-link:focus { top: 0; }

/* The homepage shows both the contact FAB stack and the footer's scroll-to-top
   button; lift the latter clear of the FABs so they never overlap. */
body.l4h-page #scrollToTop { bottom: 12.5rem !important; right: 1rem !important; }
@media (max-width: 480px) { body.l4h-page #scrollToTop { right: .75rem !important; } }

/* ── Utility ─────────────────────────────────────────────────────────────── */
.l4h-visually-hidden {
  position: absolute !important;
  width: 1px !important; height: 1px !important;
  padding: 0 !important; margin: -1px !important;
  overflow: hidden !important; clip: rect(0,0,0,0) !important;
  white-space: nowrap !important; border: 0 !important;
}
