/* JF Luxe - site.css */

/* ---------- Fonts ---------- */
@font-face{
  font-family:"Cormorant";
  src:url("/assets/fonts/cormorant-var-latin.woff2?v=17") format("woff2");
  font-weight:400 700;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"Cormorant";
  src:url("/assets/fonts/cormorant-italic-var-latin.woff2?v=17") format("woff2");
  font-weight:400 700;font-style:italic;font-display:swap;
}
@font-face{
  font-family:"Montserrat";
  src:url("/assets/fonts/montserrat-var-latin.woff2?v=17") format("woff2");
  font-weight:300 700;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"Montserrat";
  src:url("/assets/fonts/montserrat-italic-var-latin.woff2?v=17") format("woff2");
  font-weight:300 700;font-style:italic;font-display:swap;
}

/* ---------- Tokens ---------- */
:root{
  --bg:#0B0A08;
  --bg-2:#12100D;
  --bg-3:#181512;
  --ink:#F4EFE6;
  --ink-soft:#CFC8BC;
  --muted:#A79F92;
  --gold:#C9A227;
  --gold-bright:#E4C65B;
  --gold-deep:#8C6E15;
  --line:rgba(201,162,39,.22);
  --line-soft:rgba(244,239,230,.10);
  --serif:"Cormorant",Georgia,"Times New Roman",serif;
  --sans:"Montserrat","Helvetica Neue",Arial,sans-serif;
  --radius:20px;
  --radius-sm:14px;
  --shadow:0 24px 60px -24px rgba(0,0,0,.7);
  --la-accent:#C9A227;
  --nav-h:124px;
}

/* ---------- Reset / base ---------- */
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
html:focus-within{scroll-behavior:smooth}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--sans);font-size:16px;line-height:1.65;font-weight:400;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  overflow-x:clip;
}
img,video{max-width:100%;display:block}
a{color:inherit}
h1,h2,h3{font-family:var(--serif);font-weight:500;line-height:1.12;margin:0;text-wrap:balance}
p{margin:0 0 1em}
button{font:inherit;cursor:pointer}
:focus-visible{outline:2px solid var(--gold-bright);outline-offset:3px;border-radius:4px}
::selection{background:rgba(201,162,39,.35);color:#fff}

/* The header is fixed, so anchored targets must stop clear of it instead of
   scrolling up underneath. Applies to section, service-card and main targets. */
/* Land a section's HEADING just under the fixed header, not its top padding.
   The old value cleared the header only, so the section's own padding-block
   (up to 140px, and up to 190px on a band) then pushed the content a further
   screenful down and a nav click appeared to land on empty space. Subtracting
   that padding puts the heading ~24px below the header instead. The calc stays
   positive at every breakpoint (124+24-140=8 at desktop, 88+24-84=28 at 360px). */
section[id],article[id],main[id]{scroll-margin-top:calc(var(--nav-h) + 24px - clamp(84px,10vw,140px))}

.wrap{width:min(1180px,92vw);margin-inline:auto}
.section{padding-block:clamp(84px,10vw,140px)}
.section-head{max-width:720px;margin-bottom:clamp(40px,5vw,64px)}
.center{margin-inline:auto;text-align:center}

/* Typography scale */
.eyebrow{
  font-family:var(--sans);font-size:12px;font-weight:600;
  letter-spacing:.32em;text-transform:uppercase;color:var(--gold);
  display:flex;align-items:flex-start;gap:14px;margin-bottom:22px;
}
.eyebrow::before,.eyebrow::after{margin-top:.55em}
.center .eyebrow{justify-content:center}
.eyebrow::before{content:"";width:34px;height:1px;background:var(--gold);flex:none}
.center .eyebrow::after{content:"";width:34px;height:1px;background:var(--gold);flex:none}
.h1{font-size:clamp(38px,7.2vw,92px);letter-spacing:.01em}
.h2{font-size:clamp(34px,4.6vw,58px)}
.h3{font-size:clamp(22px,2.4vw,28px)}
.lead{font-size:clamp(16px,1.6vw,19px);color:var(--ink-soft);font-weight:300}
/* Gold headline accent. The solid colour stays as the base so the text is never
   invisible; the metallic sweep is layered on only where background-clip:text is
   supported, since that technique needs transparent fill to show through. */
.gold-i{font-style:italic;color:var(--gold-bright)}
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .gold-i{
    background:linear-gradient(100deg,
      var(--gold-deep) 0%,var(--gold) 18%,var(--gold-bright) 33%,
      #FFF4CF 44%,var(--gold-bright) 55%,var(--gold) 72%,var(--gold-deep) 100%);
    background-size:250% 100%;
    -webkit-background-clip:text;background-clip:text;
    -webkit-text-fill-color:transparent;color:transparent;
    animation:goldShine 6.5s ease-in-out infinite;
  }
}
@keyframes goldShine{
  0%,100%{background-position:140% 0}
  50%{background-position:-40% 0}
}

/* ---------- Buttons ---------- */
.btn{
  position:relative;display:inline-flex;align-items:center;justify-content:center;gap:10px;
  min-height:54px;padding:14px 34px;border-radius:999px;
  font-family:var(--sans);font-size:13px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;
  text-decoration:none;transition:transform .25s ease,box-shadow .25s ease,background .25s ease,color .25s ease;
  cursor:pointer;overflow:hidden;white-space:nowrap;
}
.btn-gold{
  background:linear-gradient(120deg,var(--gold-deep),var(--gold) 45%,var(--gold-bright));
  color:#151002;border:0;
  box-shadow:0 12px 34px -12px rgba(201,162,39,.55);
}
.btn-gold:hover{transform:translateY(-2px);box-shadow:0 18px 44px -14px rgba(201,162,39,.75)}
.btn-gold::after{ /* sheen sweep */
  content:"";position:absolute;inset:0;
  background:linear-gradient(115deg,transparent 30%,rgba(255,255,255,.5) 50%,transparent 70%);
  transform:translateX(-120%);
}
.btn-gold:hover::after{transition:transform .8s ease;transform:translateX(120%)}
.btn-ghost{
  background:rgba(11,10,8,.25);color:var(--ink);
  border:1px solid rgba(244,239,230,.35);backdrop-filter:blur(6px);
}
.btn-ghost:hover{border-color:var(--gold);color:var(--gold-bright);transform:translateY(-2px)}
.btn svg{width:16px;height:16px;flex:none}

/* ---------- Scroll progress ---------- */
.progress{
  position:fixed;top:0;left:0;height:2px;width:100%;z-index:90;
  background:transparent;pointer-events:none;
}
.progress span{
  display:block;height:100%;width:100%;
  background:linear-gradient(90deg,var(--gold-deep),var(--gold-bright));
  transform-origin:0 50%;transform:scaleX(0);
}

/* ---------- Header ---------- */
.site-header{
  position:fixed;inset:0 0 auto 0;z-index:80;height:var(--nav-h);
  display:flex;align-items:center;
  transition:background .35s ease,border-color .35s ease,backdrop-filter .35s ease;
  border-bottom:1px solid transparent;
}
.site-header.scrolled{
  background:rgba(11,10,8,.82);backdrop-filter:blur(14px);
  border-bottom-color:var(--line-soft);
}
.nav{display:flex;align-items:center;gap:32px;width:min(1280px,94vw);margin-inline:auto}
.brand{display:flex;align-items:center;text-decoration:none;flex:none}
.brand-logo{width:min(100%,309px);height:auto;display:block}
.nav-links{display:flex;gap:30px;list-style:none;margin:0 0 0 auto;padding:0}
.nav-links a{
  font-size:12px;font-weight:600;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink-soft);text-decoration:none;padding:11px 2px;position:relative;
  transition:color .25s ease;
}
.nav-links a::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:var(--gold);transform:scaleX(0);transform-origin:0 50%;transition:transform .3s ease;
}
.nav-links a:hover{color:var(--gold-bright)}
.nav-links a:hover::after{transform:scaleX(1)}
.nav-phone{
  display:flex;align-items:center;gap:9px;text-decoration:none;flex:none;
  font-size:13.5px;font-weight:600;letter-spacing:.06em;color:var(--ink);
  transition:color .25s ease;
}
.nav-phone svg{width:15px;height:15px;color:var(--gold)}
.nav-phone:hover{color:var(--gold-bright)}
.nav-cta{min-height:44px;padding:11px 24px;font-size:11px;flex:none}
.nav-toggle{
  display:none;margin-left:auto;background:none;border:0;padding:14px 10px;
  flex-direction:column;gap:5px;
}
.nav-toggle span{width:24px;height:2px;background:var(--ink);transition:transform .3s ease,opacity .3s ease}
.nav-toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.nav-toggle[aria-expanded="true"] span:nth-child(2){opacity:0}
.nav-toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* Mobile menu */
.mobile-menu{
  position:fixed;inset:0;z-index:75;background:rgba(11,10,8,.97);backdrop-filter:blur(18px);
  display:flex;flex-direction:column;align-items:center;gap:8px;
  /* A landscape phone is only ~300px tall and this list is ~470px. Centring with
     justify-content would push the top items to negative offsets that no gesture
     can reach, so start at the top, clear the fixed header, and allow scrolling.
     Auto margins on the children still centre it when there IS spare room. */
  justify-content:safe center;
  padding:calc(var(--nav-h) + 12px) 16px calc(28px + env(safe-area-inset-bottom));
  overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
  opacity:0;visibility:hidden;transition:opacity .35s ease,visibility .35s ease;
}
/* The header deliberately stays above the overlay so the logo and close button
   remain reachable, but its full-width 124px box must not swallow taps on the
   menu rows sitting beneath it on a short landscape screen. */
.menu-open .site-header,.menu-open .nav{pointer-events:none}
.menu-open .brand,.menu-open .nav-toggle,.menu-open .nav-cta{pointer-events:auto}
.mobile-menu.open{opacity:1;visibility:visible}
.mobile-menu .menu-logo{width:min(100%,288px);height:auto;margin-bottom:26px}
.mobile-menu a{
  font-family:var(--serif);font-size:34px;color:var(--ink);text-decoration:none;padding:10px 20px;
  transition:color .25s ease;
}
.mobile-menu a:hover{color:var(--gold-bright)}
.mobile-menu .menu-contact{font-family:var(--sans);font-size:14px;letter-spacing:.14em;color:var(--gold);margin-top:26px;padding:14px 20px}

/* ---------- Hero ---------- */
.hero{
  position:relative;min-height:100svh;display:flex;align-items:center;
  overflow:hidden;isolation:isolate;
}
.hero-media{position:absolute;inset:0;z-index:-2}
.hero-media video{width:100%;height:100%;object-fit:cover}
/* Two-axis scrim. The horizontal pass shields the left-hand text column so the
   headline stays legible over the bright sunset sky; the vertical pass keeps the
   header readable and grounds the hero into the section below. Tuned against
   measured pixel luminance behind the text, not by eye. */
.hero-scrim{
  position:absolute;inset:0;z-index:-1;
  background:
    linear-gradient(100deg,rgba(11,10,8,.93) 0%,rgba(11,10,8,.86) 30%,rgba(11,10,8,.45) 62%,rgba(11,10,8,.14) 100%),
    linear-gradient(to bottom,rgba(11,10,8,.60) 0%,rgba(11,10,8,.34) 42%,rgba(11,10,8,.90) 94%);
}
/* Mobile stacks the copy full-width, so it needs an even veil rather than a
   left-weighted one. */
@media (max-width:920px){
  .hero-scrim{
    /* Weighted to the upper third, where the eyebrow and headline sit. The mid
       band stays lighter so the fleet reads through behind the body copy. */
    background:linear-gradient(to bottom,rgba(11,10,8,.86) 0%,rgba(11,10,8,.80) 32%,rgba(11,10,8,.66) 58%,rgba(11,10,8,.72) 80%,rgba(11,10,8,.93) 96%);
  }
}
.hero-inner{width:min(1180px,92vw);margin-inline:auto;padding-top:calc(var(--nav-h) + 30px);padding-bottom:110px}
/* Eyebrows sitting over video need the brighter gold to clear 4.5:1 at 12px.
   Applies at every width: the desktop plates are the bright ones. */
.hero .eyebrow,.band .eyebrow{color:var(--gold-bright)}
.hero .eyebrow::before,.hero .eyebrow::after,
.band .eyebrow::before,.band .eyebrow::after{background:var(--gold-bright)}
.hero .eyebrow{margin-bottom:26px}
.hero-title{max-width:none}
/* The mask that hides each line before it rises must still leave room for
   Cormorant's descenders (g, y, p), which sit below the 1.12 line box. The
   negative margin cancels the padding so the layout is unchanged. */
.hero-title .line{display:block;overflow:hidden;padding-bottom:.18em;margin-bottom:-.18em}
/* The hero intro must never hide something already painted. The inline head
   script adds .hero-anim before first paint (and only when motion is allowed),
   so these start hidden rather than flashing in and back out. A failsafe in that
   same script removes the class if the intro never runs. */
.hero-anim .hero .eyebrow,.hero-anim .hero-sub,.hero-anim .hero-ctas{opacity:0}
.hero-anim .hero-title .line>span{transform:translateY(110%)}
.hero-title .line>span{display:inline-block}
.hero-sub{max-width:560px;margin-top:26px;font-size:clamp(16px,1.7vw,19px);color:var(--ink-soft);font-weight:300}
.hero-ctas{display:flex;flex-wrap:wrap;gap:16px;margin-top:40px}

/* ---------- Marquee ---------- */
.marquee{
  border-block:1px solid var(--line);background:var(--bg-2);
  overflow:hidden;padding-block:22px;position:relative;
}
.marquee-track{display:flex;gap:0;width:max-content;animation:marquee 36s linear infinite}
.marquee:hover .marquee-track{animation-play-state:paused}
.marquee-seq{display:flex;align-items:center;flex:none}
.marquee-seq span{
  font-family:var(--serif);font-size:19px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--ink-soft);white-space:nowrap;padding-inline:26px;
}
.marquee-seq svg{width:9px;height:9px;color:var(--gold);flex:none}
@keyframes marquee{to{transform:translateX(-50%)}}

/* ---------- Intro / stats ---------- */
.intro-grid{display:grid;grid-template-columns:1.1fr .9fr;gap:clamp(44px,6vw,96px);align-items:center}
.intro-figure{position:relative;border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow)}
.intro-figure img{display:block;width:100%;height:auto}
.intro-figure::after{
  content:"";position:absolute;inset:0;border-radius:var(--radius);
  border:1px solid rgba(244,239,230,.14);pointer-events:none;
}
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line-soft);border:1px solid var(--line-soft);border-radius:var(--radius-sm);overflow:hidden;margin-top:44px}
.stat{background:var(--bg-2);padding:22px 14px;text-align:center}
.stat b{display:block;font-family:var(--serif);font-size:clamp(28px,3vw,38px);font-weight:600;color:var(--gold-bright);line-height:1}
.stat small{display:block;min-height:2lh;margin-top:8px;font-size:10.5px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}

/* ---------- Services ---------- */
.svc-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
.svc{
  position:relative;isolation:isolate;background:var(--bg-2);border:1px solid var(--line-soft);
  border-radius:var(--radius);padding:34px 28px 30px;overflow:hidden;
  transition:transform .35s ease,border-color .35s ease,box-shadow .35s ease;
}
.svc::before{ /* top gold hairline that grows on hover */
  content:"";position:absolute;top:0;left:28px;right:28px;height:1px;
  background:linear-gradient(90deg,transparent,var(--gold),transparent);
  opacity:0;transition:opacity .35s ease;
}
.svc:hover{transform:translateY(-8px);border-color:rgba(201,162,39,.42);box-shadow:var(--shadow),0 0 34px rgba(201,162,39,.14)}
.svc:hover::before{opacity:1}
/* Particle video sits behind the card content. It is the same file in all eight
   cards, so it is one fetch and one decode pipeline; the clip is near-black
   (mean luminance ~0.0015) which is why the copy needs no scrim over it. */
.svc-video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  z-index:0;opacity:.5;pointer-events:none;
  transition:opacity .5s ease,transform 1.2s cubic-bezier(.2,.7,.2,1);
}
.svc:hover .svc-video{opacity:.95;transform:scale(1.06)}
/* Content must clear the video layer. */
.svc-icon,.svc h3,.svc p{position:relative;z-index:2}

/* Sheen: a soft diagonal highlight that crosses the card once on hover. */
.svc::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(115deg,transparent 36%,rgba(244,239,230,.07) 48%,transparent 60%);
  transform:translateX(-125%);
  transition:transform 1s cubic-bezier(.2,.7,.2,1);
}
.svc:hover::after{transform:translateX(125%)}

.svc-icon{
  position:relative;width:56px;height:56px;border-radius:16px;
  display:grid;place-items:center;margin-bottom:22px;
  background:linear-gradient(145deg,rgba(201,162,39,.22),rgba(201,162,39,.05));
  border:1px solid rgba(201,162,39,.34);
  box-shadow:inset 0 1px 0 rgba(244,239,230,.10),0 6px 18px rgba(0,0,0,.45);
  color:var(--gold-bright);
  transition:transform .5s cubic-bezier(.2,.7,.2,1),box-shadow .5s ease,border-color .5s ease;
}
.svc:hover .svc-icon{
  transform:translateY(-4px) scale(1.07);
  border-color:rgba(201,162,39,.66);
  box-shadow:inset 0 1px 0 rgba(244,239,230,.16),0 12px 28px rgba(0,0,0,.55),0 0 24px rgba(201,162,39,.30);
}
.svc-icon svg{
  width:26px;height:26px;
  filter:drop-shadow(0 0 6px rgba(201,162,39,.35));
  transition:filter .5s ease;
}
.svc:hover .svc-icon svg{filter:drop-shadow(0 0 10px rgba(201,162,39,.65))}
.svc h3{font-size:23px;margin-bottom:10px}
.svc p{font-size:14.5px;color:var(--muted);margin:0}

/* ---------- Video band sections ---------- */
.band{
  position:relative;isolation:isolate;overflow:hidden;
  padding-block:clamp(110px,14vw,190px);
}
.band-media{position:absolute;inset:0;z-index:-2}
.band-media video,.band-media img{width:100%;height:100%;object-fit:cover}
.band-scrim{position:absolute;inset:0;z-index:-1;background:linear-gradient(to bottom,rgba(11,10,8,.92),rgba(11,10,8,.74) 45%,rgba(11,10,8,.92))}
/* Phones show the band copy full-width, so the desktop veil over-darkens the
   footage. Lightened so the vehicles read clearly while the copy stays above
   4.5:1. Must sit AFTER the base rule: same specificity, so source order wins. */
@media (max-width:920px){
  .band-scrim{background:linear-gradient(to bottom,rgba(11,10,8,.90),rgba(11,10,8,.67) 45%,rgba(11,10,8,.90))}
}
.band .h2{max-width:16ch}
.band .lead{max-width:540px}

/* ---------- Fleet ---------- */
/* Full-view fleet: images render at their natural aspect ratio, never cropped.
   Row 1 = three ~3:2 cards. Row 2 widths are proportioned to each image's aspect
   (1.024 vs 1.498) so both cards land at the same height. */
/* Stacked showroom rows rather than a wrapped grid.
   The grid version put unequal cards side by side: copy lengths differ per
   vehicle, so card bodies never lined up and each row ended with ragged empty
   space under the shorter card. Stacking removes the comparison entirely --
   every vehicle gets the full width, the photograph gets real size, and the
   image side alternates so the eye zig-zags down the section. */
.fleet-grid{display:flex;flex-direction:column;gap:22px}
.fleet-card{
  position:relative;border-radius:var(--radius);overflow:hidden;
  border:1px solid var(--line-soft);background:var(--bg-2);
  display:grid;grid-template-columns:1.08fr .92fr;align-items:stretch;min-width:0;
  transition:transform .4s cubic-bezier(.2,.7,.2,1),border-color .4s ease,box-shadow .4s ease;
}
/* Mirror every second row. Both children are placed explicitly rather than
   relying on order, so the DOM stays image-then-copy for screen readers. */
.fleet-card:nth-child(even){grid-template-columns:.92fr 1.08fr}
.fleet-card:nth-child(even) > img{grid-column:2;grid-row:1}
.fleet-card:nth-child(even) > .fleet-body{grid-column:1;grid-row:1}
/* Per-vehicle CTA: deep-links to the form with that vehicle preselected. The
   arrow slides on hover; the whole row is a 44px+ target on touch. */
.fleet-cta{
  display:inline-flex;align-items:center;gap:9px;margin-top:24px;align-self:flex-start;
  padding:10px 16px;border-radius:999px;
  background:linear-gradient(145deg,rgba(201,162,39,.20),rgba(201,162,39,.06));
  border:1px solid rgba(201,162,39,.38);
  font-size:12.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  color:var(--gold-bright);text-decoration:none;
  transition:border-color .35s ease,box-shadow .35s ease,transform .35s ease,background .35s ease;
}
.fleet-cta svg{width:16px;height:16px;transition:transform .35s cubic-bezier(.2,.7,.2,1)}
.fleet-cta:hover,.fleet-cta:focus-visible{
  border-color:rgba(201,162,39,.75);
  background:linear-gradient(145deg,rgba(201,162,39,.30),rgba(201,162,39,.10));
  box-shadow:0 0 20px rgba(201,162,39,.22);
}
.fleet-cta:hover svg,.fleet-cta:focus-visible svg{transform:translateX(4px)}
@media (prefers-reduced-motion:reduce){.fleet-cta:hover svg{transform:none}}
/* Per-vehicle description under the passenger count. */
.fleet-blurb{margin:16px 0 0;font-size:15px;line-height:1.7;color:var(--muted);max-width:46ch}
.fleet-card > img{display:block;width:100%;height:100%;object-fit:cover;aspect-ratio:3/2;transition:filter .5s ease}
.fleet-card:hover > img{filter:brightness(1.1)}
.fleet-card:hover{transform:translateY(-6px);border-color:rgba(201,162,39,.42);box-shadow:var(--shadow),0 0 34px rgba(201,162,39,.12)}
.fleet-body{display:flex;flex-direction:column;justify-content:center;padding:clamp(26px,3.2vw,46px);width:100%}
.fleet-body h3{font-size:clamp(24px,2.5vw,32px);line-height:1.15}
.fleet-meta{display:flex;align-items:center;gap:10px;margin-top:8px;font-size:11.5px;font-weight:600;letter-spacing:.2em;text-transform:uppercase;color:var(--gold-bright)}
.fleet-meta svg{width:14px;height:14px}
.fleet-note{margin-top:22px;font-size:13px;color:var(--muted)}

/* ---------- Experience ---------- */
.exp-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(44px,6vw,90px);align-items:center}
.exp-panel{
  /* Fallback for engines without backdrop-filter: stays the old near-opaque panel
     so the copy is never left floating over raw footage. */
  background:rgba(17,15,12,.78);
  border:1px solid var(--line-soft);border-radius:var(--radius);
  padding:clamp(32px,4vw,52px);
}
/* Where backdrop-filter IS supported the panel is glass: a 12% tint and a light
   10px blur, with NO brightness knock-down, so the band footage genuinely reads
   through it rather than being darkened back into a slab.
   The blur radius is the contrast mechanism here, not the tint. This clip peaks
   at pure white (camera flashes) while averaging only ~0.14; at 10px those hot
   spots flatten to ~0.70, which is what holds --muted body copy at 4.95:1 on the
   worst frame (headings 11.3:1, gold 5.4:1). Cutting the blur re-sharpens the
   flashes and drops body copy toward failing - measure before changing it. */
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .exp-panel{
    background:rgba(17,15,12,.12);
    -webkit-backdrop-filter:blur(10px) saturate(1.1);
    backdrop-filter:blur(10px) saturate(1.1);
    border-color:rgba(244,239,230,.20);
  }
}
.exp-list{list-style:none;margin:34px 0 0;padding:0;display:grid;gap:0}
.exp-list li{
  display:flex;gap:18px;align-items:flex-start;padding-block:20px;
  border-top:1px solid var(--line-soft);
}
.exp-list li:first-child{border-top:0;padding-top:0}
.exp-num{
  font-family:var(--serif);font-size:20px;font-style:italic;color:var(--gold);flex:none;
  width:34px;padding-top:2px;
}
.exp-list h3{font-size:21px;margin-bottom:6px}
.exp-list p{font-size:14.5px;color:var(--muted);margin:0}

/* ---------- Steps ---------- */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;counter-reset:step}
.step{
  position:relative;isolation:isolate;overflow:hidden;border:1px solid var(--line-soft);border-radius:var(--radius);
  padding:36px 30px;
  /* Two layers: a 1px hairline across the top that lights up on hover, over a
     soft gradient ground. Done as backgrounds because ::before is the numeral
     and ::after is the flow connector -- there is no third pseudo-element. */
  background:
    linear-gradient(90deg,transparent,rgba(201,162,39,0),transparent) top/100% 1px no-repeat,
    linear-gradient(160deg,rgba(38,32,24,.55),rgba(23,20,16,.32));
  transition:transform .4s cubic-bezier(.2,.7,.2,1),border-color .4s ease,box-shadow .4s ease,background .4s ease;
}
.step:hover{
  transform:translateY(-6px);
  border-color:rgba(201,162,39,.42);
  box-shadow:0 18px 40px rgba(0,0,0,.45),0 0 30px rgba(201,162,39,.13);
  background:
    linear-gradient(90deg,transparent,var(--gold),transparent) top/100% 1px no-repeat,
    linear-gradient(160deg,rgba(46,38,28,.7),rgba(23,20,16,.42));
}
/* Particle clip behind each step card. Same url as the service and contact
   cards, so it is still one fetch for the whole page. */
.step-video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  z-index:0;opacity:.42;pointer-events:none;
  transition:opacity .5s ease,transform 1.2s cubic-bezier(.2,.7,.2,1);
}
.step:hover .step-video{opacity:.9;transform:scale(1.06)}
/* ::before is the numeral, so it has to clear the video too. */
.step > :not(.step-video),.step::before{position:relative;z-index:1}

/* Flow connector: drawn in the grid gap so the cards read as a sequence, with a
   highlight travelling along it. Delays are staggered per card so the pulse
   moves across the row rather than firing on every gap at once. */
.steps .step:not(:last-child)::after{
  content:"";position:absolute;top:54px;right:-18px;width:18px;height:1px;
  background:linear-gradient(90deg,
    rgba(201,162,39,.18) 0%,rgba(201,162,39,.18) 38%,
    #F6E7A8 50%,
    rgba(201,162,39,.18) 62%,rgba(201,162,39,.18) 100%);
  background-size:320% 100%;
  animation:flowPulse 2.8s linear infinite;
}
.steps .step:nth-child(2)::after{animation-delay:.55s}
.steps .step:nth-child(3)::after{animation-delay:1.1s}
@keyframes flowPulse{
  0%{background-position:210% 0}
  100%{background-position:-110% 0}
}
/* The numeral is the sequence marker, so it carries the emphasis: outlined at
   rest, filled with the gold gradient once the card is hovered. */

.step::before{
  counter-increment:step;content:"0" counter(step);
  font-family:var(--serif);font-size:58px;font-style:italic;line-height:1;
  color:transparent;-webkit-text-stroke:1px rgba(201,162,39,.6);
  display:block;margin-bottom:16px;
  transition:text-shadow .4s ease,filter .4s ease;
}
/* Polished gold: the same metallic sweep the headline accents use, running on
   the numeral permanently rather than only on hover. Behind an @supports guard
   because it needs a transparent fill -- without the guard an unsupporting
   browser would show nothing at all where the number should be, so the outlined
   version above stays as the base. */
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .step::before{
    -webkit-text-stroke:0;
    background:linear-gradient(120deg,
      var(--gold-deep) 0%,var(--gold) 22%,var(--gold-bright) 38%,
      #FFF6D8 48%,var(--gold-bright) 58%,var(--gold) 76%,var(--gold-deep) 100%);
    background-size:250% 100%;
    -webkit-background-clip:text;background-clip:text;
    -webkit-text-fill-color:transparent;
    animation:goldShine 6.5s ease-in-out infinite;
    filter:drop-shadow(0 2px 10px rgba(201,162,39,.22));
  }
}
.step:hover::before{filter:drop-shadow(0 2px 18px rgba(201,162,39,.5))}
.step h3{font-size:22px;margin-bottom:8px}
.step p{font-size:14.5px;color:var(--muted);margin:0}

/* ---------- FAQ ---------- */
.faq{max-width:800px;margin-inline:auto}
.faq details{
  border-bottom:1px solid var(--line-soft);
}
.faq details:first-of-type{border-top:1px solid var(--line-soft)}
.faq summary{
  display:flex;align-items:center;justify-content:space-between;gap:20px;
  padding:26px 4px;cursor:pointer;list-style:none;
  font-family:var(--serif);font-size:clamp(19px,2vw,23px);font-weight:500;color:var(--ink);
  transition:color .25s ease;
}
.faq summary::-webkit-details-marker{display:none}
/* The question is a real h3 for answer engines; it must not look like one. */
.faq summary h3{display:inline;margin:0;font:inherit;color:inherit;letter-spacing:inherit}
.faq summary:hover{color:var(--gold-bright)}
.faq summary .faq-x{
  flex:none;width:30px;height:30px;border-radius:50%;
  border:1px solid var(--line);display:grid;place-items:center;color:var(--gold);
  transition:transform .3s ease,background .3s ease;
}
.faq summary .faq-x svg{width:12px;height:12px}
.faq details[open] summary .faq-x{transform:rotate(45deg);background:rgba(201,162,39,.12)}
.faq .faq-a{padding:0 44px 26px 4px;color:var(--muted);font-size:15px}
.faq .faq-a p{margin:0}

/* ---------- Final CTA ---------- */
.cta-final{text-align:center}
.cta-final .h2{max-width:none}
.cta-final .lead{margin-inline:auto}
.cta-contacts{display:flex;flex-wrap:wrap;gap:16px;justify-content:center;margin-top:42px}

/* ---------- Contact cards ---------- */
.contact-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.contact-card{
  position:relative;isolation:isolate;overflow:hidden;
  background:var(--bg-2);border:1px solid var(--line-soft);border-radius:var(--radius);
  padding:38px 30px;text-align:center;text-decoration:none;
  display:flex;flex-direction:column;align-items:center;
  transition:transform .4s cubic-bezier(.2,.7,.2,1),border-color .4s ease,box-shadow .4s ease;
}
/* Same particle clip as the service cards and the request-a-ride ground: one
   shared url, so this adds no fetch. Near-black, so the copy needs no scrim. */
.cc-video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  z-index:0;opacity:.45;pointer-events:none;
  transition:opacity .5s ease,transform 1.2s cubic-bezier(.2,.7,.2,1);
}
.contact-card:hover .cc-video{opacity:.9;transform:scale(1.06)}
.contact-card > :not(.cc-video){position:relative;z-index:1}
.contact-card:hover{
  transform:translateY(-8px);
  border-color:rgba(201,162,39,.42);
  box-shadow:var(--shadow),0 0 32px rgba(201,162,39,.14);
}
.contact-card .svc-icon{margin-inline:auto}
/* The icon tile animates on hover here exactly as it does on a service card --
   .svc:hover .svc-icon is scoped to .svc, so the contact grid needs its own. */
.contact-card:hover .svc-icon{
  transform:translateY(-4px) scale(1.07);
  border-color:rgba(201,162,39,.66);
  box-shadow:inset 0 1px 0 rgba(244,239,230,.16),0 12px 28px rgba(0,0,0,.55),0 0 24px rgba(201,162,39,.30);
}
.contact-card:hover .svc-icon svg{filter:drop-shadow(0 0 10px rgba(201,162,39,.65))}
.contact-card b{display:block;font-family:var(--serif);font-size:24px;font-weight:500;color:var(--ink);margin-bottom:6px}
.contact-card span{font-size:14px;color:var(--muted)}
/* The action reads as a real button. The card itself is the <a>, so this stays a
   span -- a nested link would be invalid, and the whole card is already the
   target, so the pill is clickable either way. margin-top:auto pins it to the
   bottom so all four line up despite different copy lengths. */
.contact-card .val{
  display:inline-flex;align-items:center;justify-content:center;
  margin-top:auto;padding:11px 24px;border-radius:999px;
  background:linear-gradient(145deg,rgba(201,162,39,.22),rgba(201,162,39,.06));
  border:1px solid rgba(201,162,39,.40);
  font-size:12.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--gold-bright);
  transition:background .35s ease,border-color .35s ease,box-shadow .35s ease;
}
.contact-card span.val{font-size:12.5px}
.contact-card .val + *{margin-top:0}
.contact-card span:not(.val){margin-bottom:18px}
.contact-card:hover .val{
  background:linear-gradient(145deg,rgba(201,162,39,.34),rgba(201,162,39,.12));
  border-color:rgba(201,162,39,.75);
  box-shadow:0 0 22px rgba(201,162,39,.26);
}
@media (prefers-reduced-motion:reduce){
  .contact-card:hover{transform:none}
  .contact-card:hover .svc-icon,.contact-card:hover .cc-video{transform:none}
}

/* ---------- Footer ---------- */
.site-footer{background:#080706;border-top:1px solid var(--line-soft);padding:72px 0 96px}
.footer-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr 1.2fr;gap:44px}
.footer-logo{width:min(100%,354px);height:auto}
/* Social. 44px targets, gold hairline ring, same hover language as the cards.
   Scoped under .site-footer so it outranks the generic `.site-footer ul{display:grid}`
   and `.site-footer ul a{display:block}` rules above, which would otherwise stack
   the icons vertically and kill the centring. */
.site-footer .social{display:flex;flex-direction:row;gap:12px;margin:22px 0 0;padding:0;list-style:none}
.site-footer .social li{margin:0}
.site-footer .social a{
  display:grid;place-items:center;width:44px;height:44px;padding:0;border-radius:50%;
  border:1px solid var(--line);color:var(--gold);background:rgba(201,162,39,.07);
  transition:transform .25s ease,color .25s ease,border-color .25s ease,background .25s ease;
}
.site-footer .social a svg{width:18px;height:18px}
.site-footer .social a:hover,.site-footer .social a:focus-visible{
  transform:translateY(-3px);color:var(--gold-bright);
  border-color:var(--gold-bright);background:rgba(201,162,39,.16);
}
@media (prefers-reduced-motion:reduce){
  .site-footer .social a{transition:none}
  .site-footer .social a:hover{transform:none}
}
.footer-brand p{margin-top:18px;font-size:14px;color:var(--muted);max-width:34ch}
.site-footer .footer-h{
  font-size:11px;font-weight:700;letter-spacing:.26em;text-transform:uppercase;
  color:var(--gold);margin:0 0 18px;
}
.site-footer ul{list-style:none;margin:0;padding:0;display:grid;gap:0}
/* Block-level so the whole row is tappable, not just the word. */
.site-footer ul a{display:block;padding-block:11px;font-size:14px;color:var(--ink-soft);text-decoration:none;transition:color .25s ease}

/* Footer menu icons. The Services column reuses the exact glyphs from the service
   cards it links to, so the footer echoes the page rather than inventing a second
   icon language. Scoped under .site-footer to outrank the display:block rule above. */
.site-footer nav ul a,
.site-footer .footer-services a{display:flex;align-items:center;gap:10px}
.site-footer nav ul a svg,
.site-footer .footer-services a svg{
  width:15px;height:15px;flex:none;color:var(--gold);opacity:.72;
  transition:opacity .25s ease,color .25s ease,transform .25s ease;
}
.site-footer nav ul a:hover svg,
.site-footer .footer-services a:hover svg,
.site-footer nav ul a:focus-visible svg,
.site-footer .footer-services a:focus-visible svg{
  opacity:1;color:var(--gold-bright);transform:translateX(1px);
}
@media (prefers-reduced-motion:reduce){
  .site-footer nav ul a svg,.site-footer .footer-services a svg{transition:none}
  .site-footer nav ul a:hover svg,.site-footer .footer-services a:hover svg{transform:none}
}
.site-footer ul a:hover{color:var(--gold-bright)}
.footer-contact li{display:flex;gap:10px;align-items:center;font-size:14px;color:var(--ink-soft)}
.footer-contact li svg{width:16px;height:16px;flex:none}
/* Pad the CONTENT of every row, link or not, so all four share one rhythm and
   the two real links still clear a 44px touch target. Scoped with .site-footer
   so it outranks `.site-footer ul a{padding-block:11px}` above, which otherwise
   padded only the link rows and left the list visibly lopsided (63px vs 41px). */
.site-footer .footer-contact a,
.site-footer .footer-contact li > span{display:block;flex:1;padding-block:11px}
.site-footer .footer-contact a{color:var(--ink-soft);text-decoration:none;transition:color .25s ease}
.footer-contact a:hover{color:var(--gold-bright)}
.footer-contact svg{width:15px;height:15px;color:var(--gold);flex:none;margin-top:3px}
.footer-assoc{margin-top:56px;padding-top:40px;border-top:1px solid var(--line-soft);display:flex;flex-direction:column;align-items:center;gap:20px}
.footer-assoc-label{font-size:11.5px;font-weight:600;letter-spacing:.2em;text-transform:uppercase;color:var(--muted);margin:0}
/* Scoped under .site-footer to outrank the generic `.site-footer ul{display:grid}`. */
.site-footer .footer-assoc-logos{display:flex;gap:18px;flex-wrap:wrap;justify-content:center;list-style:none;margin:0;padding:0}
/* No white tile any more: both marks are supplied as transparent artwork, and
   the NLA one is WHITE -- a #fff tile would have rendered it invisible. They
   now sit straight on the footer ground. The box keeps its dimensions so the
   two stay optically aligned despite different aspect ratios (3:1 vs 16:9);
   the tile background, its radius and its drop shadow go with the tile. */
.site-footer .footer-assoc-logos li{width:210px;height:110px;display:flex;align-items:center;justify-content:center;padding:12px 16px}
.site-footer .footer-assoc-logos img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain}
.footer-bottom{margin-top:40px;border-top:1px solid var(--line-soft);padding-top:26px;text-align:center}
.footer-bottom p{font-size:13px;color:rgba(244,239,230,.5);margin:0}
.footer-bottom p + p{margin-top:8px}
.la-attr{
  display:inline-block;padding-block:12px;
  color:var(--la-accent);text-decoration:none;
  text-shadow:0 0 8px color-mix(in srgb,var(--la-accent) 55%,transparent);
  transition:text-shadow .3s ease,filter .3s ease;
}
.la-attr:hover,.la-attr:focus-visible{
  text-shadow:0 0 16px color-mix(in srgb,var(--la-accent) 85%,transparent);
  filter:brightness(1.15);
}

/* ---------- Sticky mobile bar ---------- */
.mobile-bar{
  position:fixed;left:0;right:0;bottom:0;z-index:70;display:none;
  grid-template-columns:1fr 1fr 1.4fr;gap:1px;background:var(--line-soft);
  border-top:1px solid var(--line-soft);
  padding-bottom:env(safe-area-inset-bottom);
  backdrop-filter:blur(14px);
}
/* Two-up variant: used on the reservation page, where a Reserve CTA would point
   at the page you are already on. */
.mobile-bar-2{grid-template-columns:1fr 1fr}
.mobile-bar a{
  display:flex;align-items:center;justify-content:center;gap:8px;
  min-height:56px;background:rgba(11,10,8,.92);color:var(--ink);
  font-size:12px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;text-decoration:none;
}
.mobile-bar a svg{width:15px;height:15px;color:var(--gold)}
.mobile-bar a.bar-cta{background:linear-gradient(120deg,var(--gold-deep),var(--gold) 45%,var(--gold-bright));color:#151002}
.mobile-bar a.bar-cta svg{color:#151002}

/* Puts a sentence on its own line without a hard <br>, so it still wraps
   naturally inside each line on narrow screens. */
.lead-line{display:block}

/* ---------- Reveal (JS adds .is-in) ---------- */
.reveal{opacity:0;transform:translateY(34px);transition:opacity .9s cubic-bezier(.2,.6,.2,1),transform .9s cubic-bezier(.2,.6,.2,1)}
.reveal.is-in{opacity:1;transform:none}
.no-js .reveal,html.no-observer .reveal{opacity:1;transform:none}

/* ---------- 404 ---------- */
.err-page{min-height:100svh;display:grid;place-items:center;text-align:center;padding:40px 20px}
.err-page .h1{font-style:italic}

/* ---------- Responsive ---------- */
@media (max-width:1080px){
  .svc-grid{grid-template-columns:repeat(2,1fr)}
  .fleet-card,.fleet-card:nth-child(even){grid-template-columns:1fr}
  /* Reset the mirror: with one column the explicit placement would put the
     copy above the photograph on every second row. */
  .fleet-card:nth-child(even) > img,
  .fleet-card:nth-child(even) > .fleet-body{grid-column:1;grid-row:auto}
  .footer-grid{grid-template-columns:1fr 1fr}
}
/* The full nav (logo + 5 links + phone + CTA) needs ~1280px once the logo is at
   full size. Below that the links collapse into the menu, but the primary CTA
   stays visible so it is never lost on tablets and small laptops. */
@media (max-width:1299px){
  .nav-links,.nav-phone{display:none}
  .nav-toggle{display:flex;margin-left:0}
  .nav-cta{margin-left:auto}
}
@media (max-width:920px){
  .intro-grid,.exp-grid{grid-template-columns:1fr}
  .steps{grid-template-columns:1fr}
  .contact-grid{grid-template-columns:1fr}
}
@media (max-width:640px){
  :root{--nav-h:104px}
  .brand-logo{width:min(100%,243px)}
  .nav{gap:14px}
  /* Below 640 the sticky bottom bar carries the primary action, so the header
     CTA steps aside and leaves the logo room to stay large. */
  .nav-cta{display:none}
  .nav-toggle{margin-left:auto}
  .svc-grid{grid-template-columns:1fr}

  .footer-grid{grid-template-columns:1fr;gap:36px}
  .mobile-bar{display:grid}
  .site-footer{padding-bottom:140px}
  .hero-ctas .btn{width:100%}
  .stats{grid-template-columns:repeat(3,1fr)}
  }

/* Smallest phones: the logo must yield enough room for the menu button. */
@media (max-width:360px){
  :root{--nav-h:88px}
  .brand-logo{width:min(100%,192px)}
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}
  .reveal{opacity:1;transform:none}
  /* Service cards: kill the sheen sweep, the icon lift and the video zoom.
     The particle clip itself still plays -- video is unconditional by owner
     directive -- but nothing else in the section moves. */
  .svc::after{transform:none;opacity:0}
  /* Metallic sweep and the flow pulse are decorative loops -- park them on a
     pleasant static frame rather than letting the global .01ms override run
     them at speed. */
  .gold-i{animation:none;background-position:50% 0}
  .steps .step:not(:last-child)::after{animation:none;background-position:50% 0}
  .step::before{animation:none;background-position:50% 0}
  .step:hover .step-video{transform:none}
  .step:hover{transform:none}
  .svc:hover .svc-icon,.svc:hover .svc-video{transform:none}
  /* The trust bar keeps scrolling. Owner directive (2026-08-27), same call as
     the video override: this strip is the only thing carrying the licensing
     and dispatch claims, and frozen it reads as a broken component rather
     than a static one. Everything else in this block still stops. */
    .la-attr{transition:none}
}

/* ---------- Short screens (landscape phones) ----------
   MUST be the final block in this file. Equal-specificity rules above
   (.mobile-menu a, and the max-width:640px/:360px --nav-h overrides) would
   otherwise win on source order and silently void everything here.
   A 124px header eats 40% of a 320px-tall viewport, so the chrome shrinks. */
@media (max-height:520px) and (max-width:1299px){
  :root{--nav-h:76px}
  .brand-logo{width:min(100%,190px)}
  .mobile-menu{padding-top:calc(var(--nav-h) + 8px);gap:0}
  .mobile-menu .menu-logo{display:none}
  .mobile-menu a{font-size:23px;padding:6px 20px}
  .mobile-menu .menu-contact{font-size:13px;margin-top:8px;padding:9px 20px}
}
