/* =========================================================================
   SWIFT EXOTICS — DESIGN SYSTEM
   One stylesheet, no framework. Tokens first, then layout, then components.
   Nothing here uses a magic number that is not defined as a token above it.
   ========================================================================= */

/* ---------- 1. TOKENS ---------------------------------------------------- */
:root {
  /* Brand. Purple is an accent, not a wash: buttons, rules, focus, one band.
     --purple is the deep tone from the brief and carries surfaces and buttons.
     --purple-lift is the exact purple sampled from the logo, used for accents
     on light surfaces (7.9:1 on paper). That same purple only reaches 2.4:1 on
     the dark sections, so --violet is a lighter tint of the identical hue for
     dark surfaces (7.4:1 on ink, 6.3:1 on the purple band). */
  /* --purple-lift is sampled directly from logo.png (hue 257.4, sat 77.3%).
     --violet is that exact same hue and saturation lifted to 70% lightness:
     the sampled purple only reaches 2.5:1 on charcoal, so it cannot carry
     accents on dark surfaces, but a tint of it can while staying the same
     colour family. --purple stays the deep tone for large surfaces. */
  --purple:       #24113F;
  --purple-mid:   #3B1C66;
  --purple-lift:  #561DE2;
  --violet:       #9A77EE;
  --violet-soft:  #EEE7FD;

  /* Neutrals. Never pure black, never pure white. */
  --ink:          #0B0710;
  --ink-raise:    #150E1E;
  --ink-line:     #2A2036;
  --paper:        #FAF9FB;
  --paper-raise:  #FFFFFF;
  --paper-sink:   #F2F0F5;
  --paper-line:   #E3DFE9;

  --text:         #17111E;
  --text-mute:    #655C72;
  --text-light:   #F6F3F9;
  --text-lmute:   #A79EB6;

  --ok:           #2C6E52;
  --ok-bg:        #E6F2EC;
  --busy:         #8A5A17;
  --busy-bg:      #F8EEDC;

  /* Type */
  --font-display: "Archivo", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-body:    "Archivo", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --fs-display: clamp(2.35rem, 5.4vw, 4.5rem);
  --fs-h1:      clamp(2.1rem, 5.2vw, 3.85rem);
  --fs-h2:      clamp(1.75rem, 3.6vw, 2.75rem);
  --fs-h3:      clamp(1.2rem, 1.9vw, 1.45rem);
  --fs-lead:    clamp(1.05rem, 1.5vw, 1.28rem);
  --fs-body:    1.0125rem;
  --fs-sm:      0.9rem;
  --fs-xs:      0.78rem;

  --lh-tight:   1.02;
  --lh-snug:    1.18;
  --lh-body:    1.62;

  /* Space — 4px base */
  --s1: 4px;   --s2: 8px;   --s3: 12px;  --s4: 16px;
  --s5: 24px;  --s6: 32px;  --s7: 48px;  --s8: 64px;
  --s9: 96px;  --s10: 128px;

  --section-y: clamp(72px, 9.5vw, 136px);
  --shell-x:   clamp(20px, 5vw, 56px);
  --shell-max: 1320px;

  /* Radius — restrained. Buttons are not pills. */
  --r-sm: 5px;
  --r:    10px;
  --r-lg: 16px;

  --line: 1px solid var(--paper-line);
  --line-dark: 1px solid var(--ink-line);

  --shadow-sm: 0 1px 2px rgba(18, 9, 30, .05);
  --shadow:    0 6px 28px -10px rgba(18, 9, 30, .16);
  --shadow-lg: 0 30px 70px -28px rgba(18, 9, 30, .34);

  /* Motion */
  --e-out: cubic-bezier(.22, 1, .36, 1);
  --e-io:  cubic-bezier(.65, 0, .35, 1);
  --t-fast: 160ms;
  --t:      280ms;
  --t-slow: 620ms;

  --header-h: 68px;
}

@media (min-width: 900px) { :root { --header-h: 80px; } }

/* ---------- 2. RESET ----------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + var(--s5));
}

body {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, picture, svg, video { display: block; max-width: 100%; }
img { height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }
h1, h2, h3, h4 { font-weight: 700; line-height: var(--lh-snug); letter-spacing: -0.02em; }

:focus-visible {
  outline: 2px solid var(--purple-lift);
  outline-offset: 3px;
  border-radius: 2px;
}
.on-dark :focus-visible, .site-footer :focus-visible, .hero :focus-visible {
  outline-color: var(--violet);
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: var(--s4); top: -100px; z-index: 200;
  background: var(--purple); color: #fff; padding: var(--s3) var(--s5);
  border-radius: var(--r-sm); font-weight: 600;
  transition: top var(--t-fast) var(--e-out);
}
.skip-link:focus { top: var(--s4); }

/* ---------- 3. LAYOUT ---------------------------------------------------- */
.shell {
  width: 100%;
  max-width: var(--shell-max);
  margin-inline: auto;
  padding-inline: var(--shell-x);
}

.section { padding-block: var(--section-y); }
.section--tight { padding-block: clamp(56px, 6vw, 88px); }

.section--dark {
  background: var(--ink);
  color: var(--text-light);
}
.section--sink { background: var(--paper-sink); }
.section--purple {
  background: var(--purple);
  color: var(--text-light);
  background-image:
    radial-gradient(120% 90% at 15% 0%, rgba(122, 68, 200, .34), transparent 60%);
}

.section--dark .section-sub,
.section--purple .section-sub { color: var(--text-lmute); }

/* ---------- 4. TYPE PRIMITIVES ------------------------------------------- */
.eyebrow {
  display: flex; align-items: center; gap: var(--s3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--purple-lift);
  margin-bottom: var(--s4);
}
.section--dark .eyebrow, .section--purple .eyebrow, .hero .eyebrow { color: var(--violet); }

.eyebrow-rule {
  width: 28px; height: 1px; flex: none;
  background: currentColor; opacity: .55;
}

.section-title {
  font-size: var(--fs-h2);
  letter-spacing: -0.032em;
  max-width: 20ch;
  text-wrap: balance;
}

.section-sub {
  margin-top: var(--s4);
  font-size: var(--fs-lead);
  color: var(--text-mute);
  max-width: 52ch;
}

.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s6);
  margin-bottom: clamp(36px, 4.5vw, 64px);
}
.section-head--center {
  flex-direction: column; align-items: center; text-align: center;
}
.section-head--center .section-title,
.section-head--center .section-sub { max-width: 30ch; margin-inline: auto; }
.section-head--center .eyebrow { justify-content: center; }

@media (max-width: 760px) {
  .section-head { flex-direction: column; align-items: flex-start; gap: var(--s5); }
}

/* Discrete links (not inline prose links) carry real tap area. Text at
   16px tall is a 16px target; padding lifts these past the 24px minimum
   without changing how they look. */
.link-arrow {
  display: inline-flex; align-items: center; gap: var(--s2);
  font-weight: 600; font-size: var(--fs-sm);
  color: var(--purple-lift);
  white-space: nowrap;
  padding-block: 7px;
  min-height: 34px;
}
.link-arrow .ico { width: 17px; height: 17px; transition: transform var(--t) var(--e-out); }
.link-arrow:hover .ico { transform: translateX(4px); }
.section--dark .link-arrow, .section--purple .link-arrow { color: var(--violet); }

.ico { width: 20px; height: 20px; flex: none; }

/* ---------- 5. BUTTONS --------------------------------------------------- */
.btn {
  --btn-bg: var(--purple);
  --btn-fg: #fff;
  --btn-bd: var(--purple);
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s2);
  padding: 15px var(--s5);
  min-height: 50px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-bd);
  border-radius: var(--r-sm);
  font-weight: 600;
  font-size: var(--fs-sm);
  letter-spacing: .005em;
  line-height: 1;
  cursor: pointer;
  transition: background var(--t) var(--e-out), color var(--t) var(--e-out),
              border-color var(--t) var(--e-out), transform var(--t-fast) var(--e-out);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn .btn-ico { display: inline-flex; }
.btn .ico { width: 17px; height: 17px; transition: transform var(--t) var(--e-out); }
.btn:hover .ico { transform: translateX(3px); }

.btn-primary:hover { --btn-bg: var(--purple-mid); --btn-bd: var(--purple-mid); }

.btn-ghost   { --btn-bg: transparent; --btn-fg: var(--text); --btn-bd: var(--paper-line); }
.btn-ghost:hover { --btn-bd: var(--purple); --btn-fg: var(--purple); }

.btn-outline { --btn-bg: transparent; --btn-fg: var(--purple); --btn-bd: var(--purple); }
.btn-outline:hover { --btn-bg: var(--purple); --btn-fg: #fff; }

.btn-light   { --btn-bg: #fff; --btn-fg: var(--purple); --btn-bd: #fff; }
.btn-light:hover { --btn-bg: var(--violet-soft); --btn-bd: var(--violet-soft); }

.btn-outline-light {
  --btn-bg: transparent; --btn-fg: #fff; --btn-bd: rgba(255,255,255,.42);
}
.btn-outline-light:hover { --btn-bd: #fff; --btn-bg: rgba(255,255,255,.1); }

/* Primary action on a dark or purple ground, built the same way as the scrolled
   header button: a translucent wash of the logo purple, a thin edge in the
   brighter brand purple, and white type. Hover stays inside the same purple
   family, lifting the tint and the edge a step and raising the button 2px. No
   solid fill, no glow, no gradient, no shadow. */
.btn-brand {
  --btn-bg: rgba(86, 29, 226, .32);
  --btn-fg: #fff;
  --btn-bd: #C0AAF6;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: background var(--t) var(--e-out),
              border-color var(--t) var(--e-out),
              transform var(--t) var(--e-out);
}
.btn-brand:hover {
  --btn-bg: rgba(86, 29, 226, .44);
  --btn-bd: #D3C6FA;
  transform: translateY(-2px);
}

/* Three specific buttons moved to --purple-mid. That token is the solid match
   for what the "Book now" and "Start a rental" buttons actually render as:
   both paint rgba(86,29,226,.38/.32) over a dark ground, compositing to
   ~#280F60 / #30136C. Their muted look comes from the transparency, not from a
   different hex, so the rgba cannot simply be copied here - over these light
   grounds it composites to ~#B7A0EE and white text becomes unreadable.

   Deliberately scoped, NOT applied to the variants themselves: .btn-primary is
   also the navbar "Book now" and the mobile-nav "Book a vehicle" on every page,
   and .btn-outline is also used on the homepage, investor and rent-to-own
   pages. .fleet-note holds exactly the two target buttons (fleet + about). */
.faq-aside .btn-primary { --btn-bg: var(--purple-mid); --btn-bd: var(--purple-mid); }

/* Hover fill only. --btn-fg: #fff already comes from .btn-outline:hover; the
   border is set too so a dark ring is not left around the fill. */
.fleet-note .btn-outline:hover { --btn-bg: var(--purple-mid); --btn-bd: var(--purple-mid); }

.btn-sm { min-height: 42px; padding: 11px var(--s4); font-size: var(--fs-xs); }
.btn-block { width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--s3); }

/* On a phone, side-by-side buttons wrap to ragged, unequal widths. Below the
   fold that is untidy; in the hero it is the primary action, so they go full
   width and become proper thumb targets. */
@media (max-width: 600px) {
  .btn-row { display: grid; grid-template-columns: 1fr; }
  .btn-row .btn { width: 100%; }
}

/* ---------- 6. CHIPS ----------------------------------------------------- */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px;
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .04em;
  background: var(--paper-sink);
  color: var(--text-mute);
  border: var(--line);
}
.chip::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; opacity: .8;
}
.chip--ok   { background: var(--ok-bg);   color: var(--ok);   border-color: transparent; }
.chip--busy { background: var(--busy-bg); color: var(--busy); border-color: transparent; }
.chip--soon { background: var(--violet-soft); color: var(--purple-lift); border-color: transparent; }
.chip--sm { padding: 4px 9px; }

.tag-soon {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; padding: 2px 6px; border-radius: 3px;
  background: var(--violet-soft); color: var(--purple-lift); margin-left: 6px;
}

/* ---------- 7. HEADER ---------------------------------------------------- */
/* ONE header for the whole site. Its solid state, the charcoal bar, is the
   source of truth and is what every page renders. It is declared here on the
   base class rather than under a body-class branch, so no page can drift.

   Previously the base was a LIGHT sticky bar and body.has-hero overrode it to
   a dark fixed one. That single fork was the root of the inconsistency: the
   homepage and every other page were two different colour environments, which
   forced the button, the logo and the nav underline to fork downstream too.

   The only remaining branch is the homepage's transparent-over-hero opening
   state, which is a genuine requirement rather than a second design. */
.site-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  background: rgba(11, 7, 16, .82);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  color: var(--text-light);
  border-bottom: 1px solid var(--ink-line);
  transition: background var(--t) var(--e-out), border-color var(--t) var(--e-out);
}

/* Homepage only, before scrolling: transparent over the hero photograph.
   Scrolling adds .is-stuck, which simply drops this exception and returns the
   header to the shared solid state above. */
body.has-hero .site-header:not(.is-stuck) {
  background: transparent;
  backdrop-filter: none; -webkit-backdrop-filter: none;
  border-bottom-color: transparent;
}

.header-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s5); height: var(--header-h);
}

/* The official logo. Two files ship per placement: the supplied artwork for
   light surfaces and a knockout for dark ones. Exactly one is ever displayed,
   and both are sized identically so swapping never shifts the layout. */
.logo { display: inline-flex; align-items: center; position: relative; }
.logo-img { display: block; width: auto; }
/* Header lockup: the SE brand mark with the "Swift Exotics" wordmark beside
   it, so the company name stays readable. The full stacked artwork is used
   only in the footer, where it has room. */
/* Mark and wordmark are balanced against each other: the monogram is held
   down and the name brought up so the two read as one lockup rather than the
   SE dominating. align-items:center keeps them optically centred. */
.logo--lockup { gap: 11px; align-items: center; }
.logo--lockup .logo-img { height: 26px; }
.logo--full .logo-img { height: 40px; }
@media (min-width: 900px) {
  .logo--lockup { gap: 12px; }
  .logo--lockup .logo-img { height: 30px; }
  .logo--full .logo-img { height: 48px; }
}

.logo-type {
  font-size: 1.1rem;
  letter-spacing: -0.015em;
  font-weight: 500;
  white-space: nowrap;
  line-height: 1;
}
.logo-type b { font-weight: 800; }

/* Default surface is light: show the supplied artwork. */
.logo-img--on-dark { display: none; }

/* Every dark surface takes the knockout. The header is on this list on all
   pages now, so the logo no longer swaps between the homepage and the rest. */
.site-header .logo-img--on-light,
.mobile-nav .logo-img--on-light,
.site-footer .logo-img--on-light { display: none; }
.site-header .logo-img--on-dark,
.mobile-nav .logo-img--on-dark,
.site-footer .logo-img--on-dark { display: block; }

/* 72px is the ceiling before the supplied file upscales on a 3x screen
   (artwork is 214px tall natively). The footer has room, and the stacked
   wordmark needs every pixel it can get to stay readable. */
.site-footer .logo--full .logo-img { height: 60px; }
@media (min-width: 900px) { .site-footer .logo--full .logo-img { height: 72px; } }
.brand {
  display: inline-flex; align-items: center;
  min-height: 44px;
  transition: opacity var(--t-fast) var(--e-out);
}
.brand:hover { opacity: .72; }

.nav-desktop { display: none; }
@media (min-width: 1000px) { .nav-desktop { display: block; } }

.nav-list { display: flex; align-items: center; gap: var(--s6); }

.nav-link {
  position: relative;
  font-size: var(--fs-sm); font-weight: 500;
  padding-block: 6px;
  opacity: .8;
  transition: opacity var(--t-fast) var(--e-out);
}
.nav-link::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--purple-lift);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--t) var(--e-out);
}
/* The header is a dark surface on every page, so its accent is --violet. */
.site-header .nav-link::after { background: var(--violet); }
.nav-link:hover { opacity: 1; }
.nav-link:hover::after, .nav-link.is-active::after { transform: scaleX(1); }
.nav-link.is-active { opacity: 1; font-weight: 600; }

.header-actions { display: flex; align-items: center; gap: var(--s3); }

/* ===== Header "Book now" button ==========================================
   Every state of this button lives in this one block so pages stay in sync.
   Size, padding, radius and transition all come from .btn and the desktop
   sizing rule further down; only the surface changes per header ground.

   There are three grounds:
     1. homepage, unscrolled - transparent header over the hero photograph
     2. homepage, scrolled   - charcoal header
     3. every other page     - light header

   Grounds 2 and 3 are the same design and are meant to look identical: deep
   brand purple, a brighter purple edge, white type. They cannot share one
   declaration, because ground 2 is a translucent wash that needs darkness
   behind it to read as purple. That same wash over the light header of ground
   3 composites to pale lavender, rgb(185,162,239), which leaves white type at
   2.21:1. Ground 3 therefore uses the solid colour that ground 2 composites
   to, so the two match on screen while both stay legible.
   ------------------------------------------------------------------------ */

/* --- the shared button: one declaration, every page ---
   This is the whole design. Because the header is now charcoal everywhere,
   the translucent wash of the logo purple reads correctly on all pages and
   nothing needs approximating per page. */
.site-header .btn-primary {
  --hdr-bd: var(--violet);
  --hdr-bd-hover: #B49CF4;
  --btn-bg: rgba(86, 29, 226, .38);
  --btn-bd: var(--hdr-bd);
  --btn-fg: #fff;
  background: rgba(86, 29, 226, .38);
  border-color: var(--hdr-bd);
  color: #fff;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: background var(--t) var(--e-out),
              border-color var(--t) var(--e-out),
              color var(--t) var(--e-out),
              transform var(--t-fast) var(--e-out);
}
.site-header .btn-primary:hover {
  --btn-bg: rgba(86, 29, 226, .58);
  --btn-bd: var(--hdr-bd-hover);
  background: rgba(86, 29, 226, .58);
  border-color: var(--hdr-bd-hover);
}

/* The single exception: over the hero photograph the header is transparent,
   so the button goes translucent white to sit on the image rather than on a
   surface. Scrolling removes this and the shared rule above takes over. */
body.has-hero .site-header:not(.is-stuck) .btn-primary {
  --btn-bg: rgba(255,255,255,.13);
  --btn-bd: rgba(255,255,255,.4);
  background: rgba(255,255,255,.13);
  border-color: rgba(255,255,255,.4);
}
body.has-hero .site-header:not(.is-stuck) .btn-primary:hover {
  --btn-bg: #fff; --btn-fg: var(--purple); --btn-bd: #fff;
  background: #fff; border-color: #fff; color: var(--purple);
}

.nav-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; margin-right: -8px;
  border-radius: var(--r-sm);
}
@media (min-width: 1000px) { .nav-toggle { display: none; } }
.nav-toggle .ico { width: 23px; height: 23px; }

/* Desktop header sizing refinement. Scoped to the width where the desktop nav
   actually appears, so the compact mobile header and the shared .btn-sm used
   by the sticky booking bar are both left alone. Header height is unchanged. */
@media (min-width: 1000px) {
  .nav-link { font-size: var(--fs-body); }
  .header-actions .btn-sm {
    font-size: var(--fs-sm);
    min-height: 46px;
    padding: 13px 22px;
  }
}

/* ---------- 8. MOBILE NAV ------------------------------------------------ */
.mobile-nav {
  position: fixed; inset: 0; z-index: 150;
  background: rgba(11, 7, 16, .55);
  opacity: 0; pointer-events: none;
  transition: opacity var(--t) var(--e-out);
}
.mobile-nav[hidden] { display: block; }
.mobile-nav.is-open { opacity: 1; pointer-events: auto; }

.mobile-nav-panel {
  position: absolute; inset: 0 0 0 auto;
  width: min(420px, 100%);
  background: var(--ink); color: var(--text-light);
  display: flex; flex-direction: column;
  padding: var(--s5) var(--s5) calc(var(--s5) + env(safe-area-inset-bottom));
  transform: translateX(100%);
  transition: transform var(--t-slow) var(--e-out);
  overflow-y: auto;
}
.mobile-nav.is-open .mobile-nav-panel { transform: none; }

.mobile-nav-head {
  display: flex; align-items: center; justify-content: space-between;
  height: var(--header-h); margin-bottom: var(--s6);
}
.nav-close {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; margin-right: -8px; color: inherit;
}

.mobile-nav-list { display: flex; flex-direction: column; }
.nav-link-lg {
  display: block;
  font-size: clamp(1.6rem, 6vw, 2.1rem);
  font-weight: 700; letter-spacing: -0.03em;
  padding-block: var(--s4);
  border-bottom: var(--line-dark);
  opacity: 1;
}
.nav-link-lg::after { display: none; }
.nav-link-lg.is-active { color: var(--violet); }

.mobile-nav-foot { margin-top: auto; padding-top: var(--s7); display: grid; gap: var(--s4); }
.mobile-call {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--text-lmute);
}

body.nav-open { overflow: hidden; }

/* ---------- 9. HERO ------------------------------------------------------ */
.hero {
  position: relative;
  min-height: min(92svh, 880px);
  display: flex; align-items: flex-end;
  padding-top: calc(var(--header-h) + var(--s7));
  /* Hero content is bottom-anchored, so this padding is the only thing under
     the buttons now that the trust line is gone. Raised to carry the weight
     that line used to, keeping the bottom edge deliberate rather than tight. */
  padding-bottom: clamp(var(--s9), 10vw, 140px);
  color: #fff;
  background: var(--ink);
}
/* Layered with positive indexes on purpose. A negative z-index here would
   paint the photograph behind the section's own background colour.
   The darkening gradient lives on this same layer as a pseudo-element rather
   than a separate positioned sibling: one composited layer instead of two,
   which also keeps the image and its scrim repainting together. */
.hero-media { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.hero-media picture { display: block; width: 100%; height: 100%; }
.hero-media img { width: 100%; height: 100%; object-fit: cover; object-position: 62% 50%; }

.hero-media::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(to top, rgba(11,7,16,.94) 0%, rgba(11,7,16,.55) 42%, rgba(11,7,16,.12) 78%),
    linear-gradient(to right, rgba(20,10,36,.82) 0%, rgba(20,10,36,.28) 46%, transparent 72%);
}
@media (min-width: 900px) {
  .hero-media img { object-position: 70% 50%; }
}

.hero-inner { position: relative; z-index: 2; width: 100%; }

.hero-title {
  font-size: var(--fs-display);
  line-height: 1.05;
  letter-spacing: -0.04em;
  max-width: 30ch;
}
/* Each authored line owns its own row above 700px so the two-line rhythm
   the copy was written for survives. Below that it wraps naturally. */
@media (min-width: 700px) { .hero-title span { display: block; } }

/* Sized 7.5% above --fs-lead, scoped to the hero only so every other lead
   paragraph on the site is unaffected. The ch measure drops from 46 to 43
   because ch scales with font size: this holds the rendered line width
   essentially where it was rather than letting it stretch. */
.hero-sub {
  margin-top: var(--s5);
  font-size: clamp(1.13rem, 1.61vw, 1.38rem);
  color: rgba(246, 243, 249, .84);
  max-width: 43ch;
}

.hero-actions { margin-top: clamp(var(--s6), 4vw, var(--s7)); }

/* Currently unrendered: the hero support line was removed pending new copy.
   Kept so restoring it is a one-line change in swift/pages/home.py.
   Icon and text are one row that never breaks apart: the icon is a fixed
   flex item and the sentence is a single wrapping child beside it. */
.hero-trust {
  margin-top: var(--s5);
  display: flex; align-items: flex-start; gap: var(--s2);
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .04em; color: rgba(246, 243, 249, .78);
  max-width: 42ch; line-height: 1.5;
}
.hero-trust .ico { width: 15px; height: 15px; margin-top: 2px; }

.hero-scroll {
  position: absolute; right: var(--shell-x); bottom: clamp(var(--s7), 8vw, var(--s9));
  display: none; align-items: center; gap: var(--s3);
  writing-mode: vertical-rl;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .22em;
  text-transform: uppercase; color: rgba(246,243,249,.55);
}
@media (min-width: 1100px) { .hero-scroll { display: flex; } }
.hero-scroll::after {
  content: ""; width: 1px; height: 54px; background: currentColor;
  animation: scrollHint 2.4s var(--e-io) infinite;
  transform-origin: top;
}
@keyframes scrollHint {
  0%, 100% { transform: scaleY(.28); opacity: .4; }
  50%      { transform: scaleY(1);   opacity: 1; }
}

/* Compact hero for interior pages.
   The header is fixed, so --header-h is the clearance it needs; the clamp on
   top of that is the actual breathing room. It used to add up to 176px before
   the first line of content, which read as a gap rather than as spacing and
   left the intro feeling detached from the header. Trimmed to 136px on
   desktop, still generous but connected. */
.page-head {
  padding-top: calc(var(--header-h) + clamp(28px, 4vw, 56px));
  padding-bottom: clamp(40px, 5vw, 72px);
  border-bottom: var(--line);
}
.page-head--dark { background: var(--ink); color: var(--text-light); border-bottom-color: var(--ink-line); }
.page-title {
  font-size: var(--fs-h1);
  letter-spacing: -0.038em;
  max-width: 18ch;
  text-wrap: balance;
}
.page-lead {
  margin-top: var(--s5); font-size: var(--fs-lead);
  color: var(--text-mute); max-width: 56ch;
}
.page-head--dark .page-lead { color: var(--text-lmute); }

/* ---------- 10. VEHICLE CARD --------------------------------------------- */
.v-grid {
  display: grid;
  gap: clamp(var(--s5), 2.4vw, var(--s6));
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
}
@media (min-width: 1100px) {
  .v-grid--few { grid-template-columns: repeat(auto-fill, minmax(min(100%, 420px), 1fr)); }
}

.v-card {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--paper-raise);
  border: var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  transition: border-color var(--t) var(--e-out), box-shadow var(--t) var(--e-out),
              transform var(--t) var(--e-out);
}
.v-card:hover { border-color: #d3cbdf; box-shadow: var(--shadow); transform: translateY(-3px); }
.v-card:has(.v-card-link:focus-visible) { border-color: var(--purple-lift); }

.v-card-link { position: absolute; inset: 0; z-index: 3; }

.v-media {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--paper-sink);
  overflow: hidden;
}
.v-media .pic, .v-media img { width: 100%; height: 100%; object-fit: cover; }
.v-media img { transition: transform var(--t-slow) var(--e-out); }
.v-card:hover .v-media img { transform: scale(1.045); }

.pic-note {
  position: absolute; left: var(--s3); bottom: var(--s3);
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em;
  background: rgba(11,7,16,.62); color: #fff;
  padding: 4px 8px; border-radius: 3px;
  backdrop-filter: blur(4px);
}

/* Designed empty state: a drawing, not a broken image icon.
   Each category carries its own tint so a fleet awaiting photography still
   reads as a considered set rather than a row of identical grey holes. */
.v-media--empty {
  display: flex; flex-direction: column; justify-content: space-between;
  padding: var(--s5);
  --tint: rgba(82, 42, 140, .09);
  background:
    radial-gradient(90% 70% at 50% 30%, var(--tint), transparent 70%),
    var(--paper-sink);
}
.v-media--empty[data-cat="everyday"] { --tint: rgba(82, 42, 140, .10); }
.v-media--empty[data-cat="suv"]      { --tint: rgba(28, 84, 96, .12); }
.v-media--empty[data-cat="premium"]  { --tint: rgba(120, 52, 92, .12); }
.v-media--empty[data-cat="luxury"]   { --tint: rgba(140, 96, 30, .12); }
.v-empty-art {
  flex: 1; display: grid; place-items: center;
  color: var(--purple);
  opacity: .34;
}
.v-empty-art .silhouette { width: min(78%, 250px); height: auto; }
.v-empty-meta {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .06em; color: var(--text-mute);
}
.v-empty-cat { text-transform: uppercase; }
.v-empty-note { display: inline-flex; align-items: center; gap: 6px; opacity: .74; }
.v-empty-note .ico { width: 14px; height: 14px; }

.v-body { padding: var(--s5); display: flex; flex-direction: column; gap: var(--s4); flex: 1; }
.v-status { order: -1; }

.v-title { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.v-year {
  font-family: var(--font-mono); font-size: var(--fs-sm);
  color: var(--text-mute); font-weight: 400;
}
.v-name { font-size: var(--fs-h3); letter-spacing: -0.025em; }
.v-trim {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--text-mute); letter-spacing: .06em; text-transform: uppercase;
}

/* Two fixed columns rather than a wrapping row. Wrapping left the fourth fact
   stranded alone on a second line, which read as an accident; a 2x2 block reads
   as a spec list and stays aligned from card to card. */
.v-facts {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: var(--s2) var(--s4);
  font-size: var(--fs-sm); color: var(--text-mute);
}
.v-fact { display: inline-flex; align-items: center; gap: 7px; }
.v-fact .ico { width: 17px; height: 17px; color: var(--purple-lift); opacity: .85; }

/* Daily rate is the headline number and gets its own line. Week and month sit
   beneath it as label-then-value pairs on one row. Previously they were pushed
   to the opposite side of the daily rate with 10px uppercase labels stacked
   above the figures, which made three prices compete at the same moment. */
.v-price {
  margin-top: auto;
  padding-top: var(--s4);
  border-top: var(--line);
  display: grid; gap: var(--s3);
}
.v-price-main { display: flex; align-items: baseline; gap: 5px; }
.v-price-num {
  font-family: var(--font-mono); font-size: 1.7rem; font-weight: 500;
  letter-spacing: -0.03em; color: var(--text);
}
.v-price-unit { font-size: var(--fs-sm); color: var(--text-mute); }

.v-price-alt { display: flex; flex-wrap: wrap; gap: 4px var(--s5); }
.v-price-alt div { display: flex; align-items: baseline; gap: 6px; }
.v-price-alt dt { font-size: var(--fs-xs); color: var(--text-mute); }
.v-price-alt dd {
  font-family: var(--font-mono); font-size: var(--fs-sm);
  font-weight: 500; color: var(--text);
}

.v-cta { margin-top: var(--s2); }

.v-card.is-busy .v-media { filter: saturate(.5); }
.v-card.is-busy .v-empty-art { opacity: .2; }

/* ---------- 11. EMPTY STATE ---------------------------------------------- */
.empty-state {
  border: 1px dashed var(--paper-line);
  border-radius: var(--r-lg);
  padding: clamp(var(--s7), 8vw, var(--s9)) var(--s5);
  text-align: center;
  background: var(--paper-raise);
}
.empty-state-msg { font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.02em; }
.empty-state-help { margin: var(--s3) auto var(--s5); color: var(--text-mute); max-width: 40ch; }

/* ---------- 12. USE CASES (editorial rows) -------------------------------- */
.usecases { display: grid; gap: clamp(var(--s6), 4.5vw, var(--s8)); }

.uc {
  display: grid;
  gap: clamp(var(--s5), 4vw, var(--s7));
  align-items: center;
}
@media (min-width: 880px) {
  .uc { grid-template-columns: 1fr 1fr; }
  .uc:nth-child(even) .uc-media { order: 2; }
}

.uc-media {
  position: relative;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--paper-sink);
}
.uc-media img { width: 100%; height: auto; aspect-ratio: 4/5; object-fit: cover; }
/* A 4:5 portrait at half of a wide screen becomes 800px tall and strands the
   copy in dead space. Capped so each row stays one comfortable eyeful. */
@media (min-width: 880px) {
  .uc-media img { aspect-ratio: 5/6; max-height: 600px; }
}

/* Vehicles break the grid edge on wide screens: an editorial move, not decoration. */
@media (min-width: 1180px) {
  .uc:nth-child(odd) .uc-media { margin-left: calc(var(--shell-x) * -1); }
  .uc:nth-child(even) .uc-media { margin-right: calc(var(--shell-x) * -1); }
}

.uc-kicker {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .16em; color: var(--purple-lift);
  display: flex; align-items: center; gap: var(--s3); margin-bottom: var(--s4);
}
.uc-kicker::after { content: ""; height: 1px; flex: 1; background: var(--paper-line); }
.section--dark .uc-kicker { color: var(--violet); }
.section--dark .uc-kicker::after { background: var(--ink-line); }

.uc-title { font-size: var(--fs-h2); letter-spacing: -0.032em; margin-bottom: var(--s4); }
.uc-body { color: var(--text-mute); max-width: 46ch; font-size: var(--fs-lead); }
.section--dark .uc-body { color: var(--text-lmute); }

/* ---------- 13. WHY (spec sheet list) ------------------------------------ */
.why-list {
  display: grid;
  gap: 0;
  border-top: var(--line-dark);
}
@media (min-width: 820px) { .why-list { grid-template-columns: 1fr 1fr; column-gap: clamp(var(--s6), 5vw, var(--s9)); } }

.why-item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s4);
  padding-block: var(--s5);
  border-bottom: var(--line-dark);
  align-items: start;
}
.why-n {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--violet); letter-spacing: .08em; padding-top: 4px;
}
.why-title { font-size: 1.06rem; letter-spacing: -0.018em; margin-bottom: 6px; }
.why-body { color: var(--text-lmute); font-size: var(--fs-sm); max-width: 44ch; }

/* ---------- 14. STEPS ---------------------------------------------------- */
.steps { display: grid; gap: var(--s6); counter-reset: step; }
@media (min-width: 900px) { .steps { grid-template-columns: repeat(3, 1fr); gap: var(--s7); } }

.step { position: relative; padding-top: var(--s6); border-top: 1px solid currentColor; }
.section--purple .step { border-top-color: rgba(255,255,255,.24); }

.step-n {
  position: absolute; top: var(--s4); right: 0;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .12em; opacity: .6;
}
/* Optional stage label above a step title. Only steps whose data carries a
   'label' render one, so the homepage band is untouched. */
.step-label {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--purple-lift); margin-bottom: var(--s3);
}
.section--purple .step-label { color: var(--violet); }

.step-title { font-size: clamp(1.5rem, 3vw, 2rem); letter-spacing: -0.03em; margin-bottom: var(--s3); }
.step-body { color: var(--text-lmute); max-width: 34ch; }
.section--purple .step-body { color: rgba(246,243,249,.76); }

/* ---------- 15. EDITORIAL BAND ------------------------------------------- */
/* The homepage header is position:fixed so it can sit transparently over the
   hero, which means it floats above every section below it too. Every other
   section clears it via --section-y padding; this one had none, so its content
   sat flush to the section edge and the header covered the top of the image and
   the eyebrow. Padding is derived from the header height rather than hardcoded,
   so it stays correct if the header is ever resized. */
.editorial {
  position: relative; background: var(--ink); color: var(--text-light);
  overflow: hidden;
  padding-block: calc(var(--header-h) + var(--s4));
}
.editorial-media { position: relative; }
.editorial-media img { width: 100%; height: auto; aspect-ratio: 16/9; object-fit: cover; }
@media (min-width: 980px) {
  .editorial-inner {
    display: grid; grid-template-columns: 1fr 1fr; align-items: center;
    gap: clamp(var(--s6), 5vw, var(--s8));
  }
  .editorial-media img { aspect-ratio: 4/3; }
}
/* Vertical rhythm now lives on the section itself, so the text block does not
   add a second helping of it. Stacked layouts still need the gap under the
   image, which the media query below restores. */
.editorial-text { padding-block: 0; }
@media (max-width: 979px) {
  .editorial-text { padding-top: clamp(var(--s5), 5vw, var(--s6)); }
}
.editorial-title { font-size: var(--fs-h2); letter-spacing: -0.034em; margin-bottom: var(--s5); }
.editorial-body { color: var(--text-lmute); font-size: var(--fs-lead); max-width: 44ch; margin-bottom: var(--s6); }

/* ---------- 16. ACCORDION ------------------------------------------------ */
.acc { border-top: var(--line); }
.acc-item { border-bottom: var(--line); }

.acc-q {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s5);
  padding-block: var(--s5);
  cursor: pointer;
  list-style: none;
  font-weight: 600;
  font-size: clamp(1rem, 1.6vw, 1.14rem);
  letter-spacing: -0.015em;
  transition: color var(--t-fast) var(--e-out);
}
.acc-q::-webkit-details-marker { display: none; }
.acc-q:hover { color: var(--purple-lift); }
.acc-q-text { flex: 1; }

.acc-icon {
  flex: none; width: 30px; height: 30px;
  display: grid; place-items: center;
  border: var(--line); border-radius: 50%;
  color: var(--purple-lift);
  transition: transform var(--t) var(--e-out), background var(--t) var(--e-out),
              color var(--t) var(--e-out);
}
.acc-icon .ico { width: 15px; height: 15px; }
.acc-item[open] .acc-icon {
  transform: rotate(45deg);
  background: var(--purple); color: #fff; border-color: var(--purple);
}

.acc-a { padding-bottom: var(--s5); padding-right: var(--s7); }
.acc-a p { color: var(--text-mute); max-width: 62ch; }
.acc-item[open] .acc-a { animation: accIn var(--t) var(--e-out); }
@keyframes accIn { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; transform: none; } }

.faq-group + .faq-group { margin-top: clamp(var(--s7), 6vw, var(--s8)); }
.faq-group-title {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--purple-lift); margin-bottom: var(--s4);
}

/* ---------- 17. CTA BAND ------------------------------------------------- */
.cta-band {
  position: relative;
  padding-block: clamp(var(--s8), 11vw, 168px);
  color: #fff; text-align: center;
  background: var(--purple);
  overflow: hidden;
}
.cta-media { position: absolute; inset: 0; z-index: 0; }
.cta-media .pic { width: 100%; height: 100%; }
.cta-media img { width: 100%; height: 100%; object-fit: cover; }
.cta-band::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to bottom, rgba(20,10,36,.9), rgba(36,17,63,.82));
}
.cta-inner { position: relative; z-index: 2; }
.cta-title {
  font-size: var(--fs-h1); letter-spacing: -0.04em;
  max-width: 16ch; margin-inline: auto; text-wrap: balance;
}
.cta-sub {
  margin: var(--s5) auto 0; max-width: 46ch;
  color: rgba(246,243,249,.82); font-size: var(--fs-lead);
}
.cta-actions {
  margin-top: var(--s7); display: flex; flex-wrap: wrap;
  gap: var(--s3); justify-content: center;
}
@media (max-width: 600px) {
  .cta-actions { display: grid; grid-template-columns: 1fr; }
  .cta-actions .btn { width: 100%; }
}
.cta-note {
  margin-top: var(--s6);
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .05em; color: rgba(246,243,249,.62);
}
.cta-note .ico { width: 15px; height: 15px; }

/* ---------- 18. REVIEWS -------------------------------------------------- */
.review-grid {
  display: grid; gap: var(--s5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
}
.review {
  padding: var(--s6); background: var(--paper-raise);
  border: var(--line); border-radius: var(--r-lg);
}
.review-stars { display: flex; gap: 2px; margin-bottom: var(--s4); }
.star { color: var(--paper-line); font-size: 1.05rem; }
.star.is-on { color: var(--purple-lift); }
.review-text p { font-size: 1.05rem; letter-spacing: -0.01em; }
.review-by {
  margin-top: var(--s4); font-family: var(--font-mono);
  font-size: var(--fs-xs); color: var(--text-mute); letter-spacing: .04em;
}
.review-src { opacity: .7; }

/* ---------- 19. VEHICLE DETAIL ------------------------------------------- */
.v-detail { padding-top: calc(var(--header-h) + var(--s5)); }

.crumbs {
  display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--text-mute); letter-spacing: .05em; margin-bottom: var(--s5);
}
.crumbs a { display: inline-flex; align-items: center; min-height: 30px; }
.crumbs a:hover { color: var(--purple-lift); }
.crumbs span { opacity: .5; }

/* Single column on a phone. Source order is media, title, booking, body, so
   the price and the CTA land immediately under the heading. On desktop named
   areas move the booking card into its own sticky column. */
.v-layout { display: grid; gap: var(--s5); align-items: start; }
.v-col-head { margin-top: var(--s2); }

@media (min-width: 1000px) {
  .v-layout {
    grid-template-columns: minmax(0, 1.32fr) minmax(340px, .68fr);
    column-gap: clamp(var(--s6), 5vw, var(--s8));
    row-gap: var(--s5);
    grid-template-areas:
      "media book"
      "head  book"
      "body  book";
  }
  .v-col-media { grid-area: media; }
  .v-col-head  { grid-area: head; }
  .v-col-book  { grid-area: book; }
  .v-col-body  { grid-area: body; }
  .v-col-head { margin-top: var(--s4); }
}

.gallery { display: grid; gap: var(--s3); }
.gallery-main {
  border-radius: var(--r-lg); overflow: hidden;
  background: var(--paper-sink); aspect-ratio: 4/3;
}
.gallery-main .v-media { aspect-ratio: 4/3; height: 100%; }
.gallery-main img { width: 100%; height: 100%; object-fit: cover; }
.gallery-thumbs {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(88px, 1fr);
  gap: var(--s3); overflow-x: auto; scroll-snap-type: x mandatory;
  padding-bottom: 4px; scrollbar-width: thin;
}
.gallery-thumb {
  border-radius: var(--r); overflow: hidden; aspect-ratio: 4/3;
  border: 2px solid transparent; scroll-snap-align: start; cursor: pointer;
  background: var(--paper-sink);
}
.gallery-thumb.is-active { border-color: var(--purple); }
.gallery-thumb img { width: 100%; height: 100%; object-fit: cover; }

.v-detail-title { font-size: var(--fs-h1); letter-spacing: -0.038em; margin-block: var(--s4) var(--s3); }
.v-detail-headline { font-size: var(--fs-lead); color: var(--text-mute); max-width: 48ch; }

.booking-card {
  background: var(--paper-raise);
  border: var(--line); border-radius: var(--r-lg);
  padding: clamp(var(--s5), 3vw, var(--s6));
  box-shadow: var(--shadow-sm);
}
@media (min-width: 1000px) { .booking-card { position: sticky; top: calc(var(--header-h) + var(--s5)); } }

.price-table { display: grid; gap: 0; margin-block: var(--s5); }
.price-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s4);
  padding-block: var(--s3); border-bottom: var(--line);
}
.price-row:last-child { border-bottom: 0; }
.price-row dt { color: var(--text-mute); font-size: var(--fs-sm); }
.price-row dd { font-family: var(--font-mono); font-weight: 500; font-size: 1.08rem; }
.price-row--lead dd { font-size: 1.5rem; letter-spacing: -0.03em; }
.price-row--lead dt { font-weight: 600; color: var(--text); }

.booking-note {
  margin-top: var(--s4); font-size: var(--fs-xs); color: var(--text-mute);
  line-height: 1.55;
}

.spec-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--s5) var(--s4);
  border-top: var(--line); padding-top: var(--s6); margin-top: var(--s6);
}
.spec dt {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-mute); margin-bottom: 5px;
}
.spec dd { font-weight: 600; font-size: 1.02rem; }

.feature-list { display: grid; gap: var(--s3); }
@media (min-width: 620px) { .feature-list { grid-template-columns: 1fr 1fr; } }
.feature-list li { display: flex; align-items: flex-start; gap: var(--s3); font-size: var(--fs-sm); }
.feature-list .ico { width: 18px; height: 18px; color: var(--purple-lift); margin-top: 2px; }

.req-list { display: grid; gap: var(--s4); }
.req-item { display: grid; grid-template-columns: auto 1fr; gap: var(--s3); align-items: start; }
.req-item .ico { width: 19px; height: 19px; color: var(--purple-lift); margin-top: 3px; }
.req-title { font-weight: 600; font-size: var(--fs-body); }
.req-body { color: var(--text-mute); font-size: var(--fs-sm); }

.v-block { margin-top: clamp(var(--s7), 6vw, var(--s8)); }
.v-block-title {
  font-size: var(--fs-h3); letter-spacing: -0.025em; margin-bottom: var(--s5);
  padding-bottom: var(--s3); border-bottom: var(--line);
}

/* Sticky mobile CTA */
.sticky-cta {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  padding: var(--s3) var(--s4) calc(var(--s3) + env(safe-area-inset-bottom));
  background: rgba(255,255,255,.94);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-top: var(--line);
  transform: translateY(110%);
  transition: transform var(--t) var(--e-out);
}
.sticky-cta.is-shown { transform: none; }
@media (min-width: 1000px) { .sticky-cta { display: none; } }
.sticky-cta-info { display: flex; flex-direction: column; gap: 1px; line-height: 1.25; }
.sticky-cta-price { font-family: var(--font-mono); font-size: 1.16rem; font-weight: 500; }
.sticky-cta-price span { font-size: var(--fs-xs); color: var(--text-mute); }
.sticky-cta-alt, .sticky-cta-status { font-size: var(--fs-xs); color: var(--text-mute); }
.sticky-cta-name { font-weight: 600; font-size: var(--fs-sm); }
.sticky-cta .btn { flex: none; }

/* ---------- 20. FORMS ---------------------------------------------------- */
.form { display: grid; gap: var(--s5); }
.form-grid { display: grid; gap: var(--s5); }
@media (min-width: 640px) { .form-grid--2 { grid-template-columns: 1fr 1fr; } }

.field { display: grid; gap: 7px; }
.field-label { font-weight: 600; font-size: var(--fs-sm); }
.field-hint { font-size: var(--fs-xs); color: var(--text-mute); }
.field-req { color: var(--purple-lift); }

.input, .select, .textarea {
  width: 100%;
  padding: 14px var(--s4);
  min-height: 52px;
  background: var(--paper-raise);
  border: 1px solid var(--paper-line);
  border-radius: var(--r-sm);
  font-size: 1rem; /* 16px minimum stops iOS zooming on focus */
  transition: border-color var(--t-fast) var(--e-out), box-shadow var(--t-fast) var(--e-out);
}
.input:hover, .select:hover, .textarea:hover { border-color: #cfc7db; }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--purple-lift);
  box-shadow: 0 0 0 3px rgba(82, 42, 140, .14);
}
.textarea { min-height: 132px; resize: vertical; line-height: 1.55; }
.select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9' fill='none'%3E%3Cpath d='M1 1l6 6 6-6' stroke='%23655C72' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--s4) center;
  padding-right: var(--s7);
}
/* :user-invalid, not :invalid. A required-but-empty field is invalid from the
   moment it renders, which would paint an error on a form nobody has touched. */
.input:user-invalid,
.select:user-invalid,
.textarea:user-invalid { border-color: #B04242; }
.input:user-invalid:focus,
.textarea:user-invalid:focus { box-shadow: 0 0 0 3px rgba(176, 66, 66, .16); }

.choice-grid { display: grid; gap: var(--s3); }
@media (min-width: 560px) { .choice-grid { grid-template-columns: repeat(3, 1fr); } }
.choice { position: relative; }
.choice input { position: absolute; opacity: 0; width: 0; height: 0; }
.choice-face {
  display: flex; flex-direction: column; gap: 3px;
  padding: var(--s4);
  border: 1px solid var(--paper-line); border-radius: var(--r-sm);
  background: var(--paper-raise);
  cursor: pointer; min-height: 76px; justify-content: center;
  transition: border-color var(--t-fast) var(--e-out), background var(--t-fast) var(--e-out);
}
.choice-face:hover { border-color: #cfc7db; }
.choice input:checked + .choice-face {
  border-color: var(--purple); background: var(--violet-soft);
  box-shadow: inset 0 0 0 1px var(--purple);
}
.choice input:focus-visible + .choice-face { outline: 2px solid var(--purple-lift); outline-offset: 2px; }
.choice-name { font-weight: 600; font-size: var(--fs-sm); }
.choice-meta { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-mute); }

.form-aside {
  background: var(--paper-sink);
  border-radius: var(--r-lg);
  padding: clamp(var(--s5), 3vw, var(--s6));
}
.reassure { display: grid; gap: var(--s3); }
.reassure li { display: flex; align-items: flex-start; gap: var(--s3); font-size: var(--fs-sm); }
.reassure .ico { width: 18px; height: 18px; color: var(--ok); margin-top: 2px; }

.form-status {
  padding: var(--s5); border-radius: var(--r); border: var(--line);
  background: var(--paper-raise);
}
.form-status[hidden] { display: none; }
.form-status--ok { border-color: var(--ok); background: var(--ok-bg); }
.form-status--err { border-color: #B04242; background: #FBECEC; }
.form-status-title { font-weight: 700; margin-bottom: 5px; }

.honeypot { position: absolute; left: -9999px; opacity: 0; height: 0; overflow: hidden; }

/* ---------- 21. CONTACT / INFO ------------------------------------------- */
.info-grid { display: grid; gap: clamp(var(--s6), 5vw, var(--s8)); align-items: start; }
@media (min-width: 940px) { .info-grid { grid-template-columns: 1.1fr .9fr; } }

.contact-list { display: grid; gap: var(--s5); }
.contact-item { display: grid; grid-template-columns: auto 1fr; gap: var(--s4); align-items: start; }
.contact-item .ico { width: 21px; height: 21px; color: var(--purple-lift); margin-top: 3px; }
.contact-label {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-mute); margin-bottom: 3px;
}
.contact-value { font-size: 1.08rem; font-weight: 600; letter-spacing: -0.015em; }
.contact-value a:hover { color: var(--purple-lift); }
.contact-sub { color: var(--text-mute); font-size: var(--fs-sm); margin-top: 2px; }

.hours-list { display: grid; gap: 6px; margin-top: 4px; }
.hours-row { display: flex; justify-content: space-between; gap: var(--s4); font-size: var(--fs-sm); max-width: 320px; }
.hours-row dt { color: var(--text-mute); }
.hours-row dd { font-variant-numeric: tabular-nums; }

.prose { max-width: 68ch; }
.prose h2 { font-size: var(--fs-h3); letter-spacing: -0.025em; margin-top: var(--s7); margin-bottom: var(--s3); }
.prose h2:first-child { margin-top: 0; }
.prose p { color: var(--text-mute); margin-bottom: var(--s4); }
.prose p strong { color: var(--text); }
.prose ul { display: grid; gap: var(--s2); margin-bottom: var(--s4); }
.prose ul li { display: flex; gap: var(--s3); color: var(--text-mute); }
.prose ul li::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--purple-lift); margin-top: 10px; flex: none; }

.notice {
  display: grid; grid-template-columns: auto 1fr; gap: var(--s4);
  padding: var(--s5); border-radius: var(--r);
  background: var(--violet-soft); border: 1px solid #DFD2F2;
  margin-block: var(--s6);
}
.notice .ico { width: 21px; height: 21px; color: var(--purple-lift); margin-top: 2px; }
.notice-title { font-weight: 700; margin-bottom: 4px; }
.notice p { color: var(--text-mute); font-size: var(--fs-sm); }

/* ---------- 22. PROGRAM (coming soon) pages ------------------------------ */
.soon-hero {
  padding-top: calc(var(--header-h) + clamp(64px, 9vw, 128px));
  padding-bottom: clamp(64px, 9vw, 128px);
  background: var(--ink); color: var(--text-light);
}
.soon-badge {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--violet); border: 1px solid rgba(169,139,224,.4);
  padding: 6px 12px; border-radius: 999px; margin-bottom: var(--s5);
}
.soon-badge::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--violet);
}

/* ---------- 23. FOOTER --------------------------------------------------- */
.site-footer {
  background: var(--ink); color: var(--text-light);
  padding-block: clamp(var(--s7), 7vw, var(--s9)) var(--s6);
}
.footer-top {
  display: grid; gap: clamp(var(--s6), 5vw, var(--s8));
  padding-bottom: clamp(var(--s6), 5vw, var(--s7));
}
@media (min-width: 900px) { .footer-top { grid-template-columns: 1fr 1.35fr; } }

.footer-tagline { margin-top: var(--s4); color: var(--text-lmute); max-width: 30ch; }
.footer-area {
  margin-top: var(--s4); display: flex; align-items: center; gap: 8px;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--text-lmute); letter-spacing: .03em;
}
.footer-area .ico { width: 15px; height: 15px; }

.social-row { display: flex; gap: var(--s3); margin-top: var(--s5); }
.social-link {
  width: 42px; height: 42px; display: grid; place-items: center;
  border: var(--line-dark); border-radius: var(--r-sm);
  color: var(--text-lmute);
  transition: border-color var(--t-fast) var(--e-out), color var(--t-fast) var(--e-out);
}
.social-link:hover { color: #fff; border-color: var(--violet); }

.footer-cols { display: grid; gap: var(--s6); }
@media (min-width: 560px) { .footer-cols { grid-template-columns: repeat(3, 1fr); } }

.footer-h {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--violet);
  margin-bottom: var(--s4); font-weight: 500;
}
.footer-col ul { display: grid; gap: 2px; }
.footer-col a {
  display: inline-flex; align-items: center; min-height: 36px;
  color: var(--text-lmute); font-size: var(--fs-sm);
  transition: color var(--t-fast) var(--e-out);
}
.footer-col a:hover { color: #fff; }
.footer-hours { margin-top: var(--s4); font-size: var(--fs-xs); color: var(--text-lmute); opacity: .8; }

.footer-bottom {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--s4); padding-top: var(--s5); border-top: var(--line-dark);
}
.footer-legal, .footer-legal-links a { font-size: var(--fs-xs); color: var(--text-lmute); }
.footer-legal-links { display: flex; gap: var(--s5); align-items: center; }
.footer-legal-links a { display: inline-flex; align-items: center; min-height: 32px; }
.footer-legal-links a:hover { color: #fff; }
.footer-disclosure {
  margin-top: var(--s5); font-size: var(--fs-xs); color: var(--text-lmute);
  opacity: .62; max-width: 70ch;
}

/* ---------- 24. MOTION --------------------------------------------------- */
/* Every rule below is scoped to .js. With scripting off or broken, none of it
   applies and the page renders fully visible. Content is never hidden by
   default on a site whose job is to be trusted. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--t-slow) var(--e-out), transform var(--t-slow) var(--e-out);
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

.js [data-reveal-group] > * {
  opacity: 0; transform: translateY(20px);
  transition: opacity var(--t-slow) var(--e-out), transform var(--t-slow) var(--e-out);
}
.js [data-reveal-group].is-in > * { opacity: 1; transform: none; }
.js [data-reveal-group].is-in > *:nth-child(1) { transition-delay: 0ms; }
.js [data-reveal-group].is-in > *:nth-child(2) { transition-delay: 70ms; }
.js [data-reveal-group].is-in > *:nth-child(3) { transition-delay: 140ms; }
.js [data-reveal-group].is-in > *:nth-child(4) { transition-delay: 210ms; }
.js [data-reveal-group].is-in > *:nth-child(5) { transition-delay: 280ms; }
.js [data-reveal-group].is-in > *:nth-child(6) { transition-delay: 350ms; }

/* The hero photograph is the largest paint on the page, so it is never faded
   in: doing that delays LCP and makes a fast site feel slow. It gets a slow
   scale settle instead, which reads as motion without holding up the pixels.
   The words above it carry the actual entrance. */
.hero-media img { animation: heroSettle 2600ms var(--e-out) both; }
@keyframes heroSettle {
  from { transform: scale(1.055); }
  to   { transform: none; }
}

.hero-inner > * { animation: heroText 760ms var(--e-out) both; }
.hero-inner > *:nth-child(1) { animation-delay: 60ms; }
.hero-inner > *:nth-child(2) { animation-delay: 130ms; }
.hero-inner > *:nth-child(3) { animation-delay: 210ms; }
.hero-inner > *:nth-child(4) { animation-delay: 290ms; }
.hero-inner > *:nth-child(5) { animation-delay: 360ms; }
@keyframes heroText {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  [data-reveal], [data-reveal-group] > * { opacity: 1 !important; transform: none !important; }
  .hero-media img, .hero-inner > * { animation: none !important; opacity: 1 !important; transform: none !important; }
  .hero-scroll::after { animation: none; transform: scaleY(1); }
}

/* ---------- 25. PAGE LAYOUTS --------------------------------------------- */

/* Fleet index */
.fleet-bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--s4); margin-bottom: clamp(var(--s5), 3vw, var(--s6));
  padding-bottom: var(--s5); border-bottom: var(--line);
}
.filter-bar { display: flex; flex-wrap: wrap; gap: var(--s2); }

/* On phones the chips become one swipeable row instead of wrapping and
   stranding a single category on a second line. */
@media (max-width: 700px) {
  .fleet-bar { align-items: flex-start; gap: var(--s3); }
  .filter-bar {
    flex-wrap: nowrap; overflow-x: auto; width: 100%;
    scrollbar-width: none; -ms-overflow-style: none;
    padding-bottom: 2px;
    scroll-snap-type: x proximity;
  }
  .filter-bar::-webkit-scrollbar { display: none; }
  .filter { flex: none; scroll-snap-align: start; }
}
.filter {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px var(--s4); min-height: 42px;
  border: 1px solid var(--paper-line); border-radius: var(--r-sm);
  background: var(--paper-raise);
  font-size: var(--fs-sm); font-weight: 500;
  transition: border-color var(--t-fast) var(--e-out), background var(--t-fast) var(--e-out),
              color var(--t-fast) var(--e-out);
}
.filter:hover { border-color: #cfc7db; }
.filter.is-active { background: var(--purple); border-color: var(--purple); color: #fff; }
.filter-n {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  opacity: .62; font-variant-numeric: tabular-nums;
}
.fleet-count { font-size: var(--fs-xs); color: var(--text-mute); letter-spacing: .04em; }

.fleet-note {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--s6);
}
.fleet-note .section-title { max-width: 24ch; }

/* Vehicle detail */
.v-detail-cat {
  font-size: var(--fs-xs); letter-spacing: .14em; text-transform: uppercase;
  color: var(--purple-lift);
}
.booking-head { margin-bottom: var(--s5); }
.booking-gig { margin-bottom: var(--s5); }
.booking-mileage { margin-top: var(--s6); padding-top: var(--s5); border-top: var(--line); }
.booking-mileage-val {
  font-family: var(--font-mono); font-size: var(--fs-sm);
  margin-top: 5px; line-height: 1.5;
}
.booking-contact {
  margin-top: var(--s5); padding-top: var(--s5); border-top: var(--line);
  font-size: var(--fs-sm); color: var(--text-mute);
}
.booking-contact a { color: var(--purple-lift); font-weight: 600; }
.booking-contact a:hover { text-decoration: underline; }

.booking-embed { border-radius: var(--r-lg); overflow: hidden; border: var(--line); }
.booking-embed iframe { width: 100%; min-height: 780px; border: 0; display: block; }

/* About */
.about-layout { display: grid; gap: clamp(var(--s6), 5vw, var(--s8)); align-items: start; }
/* Image column widened slightly. The copy column is capped at 60ch by .about-p,
   so it was never using the extra width anyway - this spends it on the photo. */
@media (min-width: 940px) { .about-layout { grid-template-columns: .95fr 1.15fr; } }

/* The source photo is a 3:2 landscape, so at this column width it finished
   ~340px above the end of the copy and left a void. Cropping it to a portrait
   container lets it carry down the page instead. The key and fob sit dead
   centre in the frame, so a centred cover crop keeps the subject whole and
   nothing is stretched. */
.about-media { border-radius: var(--r-lg); overflow: hidden; aspect-ratio: 4 / 3; }
.about-media .pic { display: block; width: 100%; height: 100%; }
.about-media img { width: 100%; height: 100%; object-fit: cover; }
@media (min-width: 940px) {
  .about-media { position: sticky; top: calc(var(--header-h) + var(--s5)); aspect-ratio: 4 / 5; }
}

/* Now that the photo runs the full height of the copy, the full --section-y
   step below it left ~222px of white before the tinted San Antonio band. Eased
   back so the three bands flow at a consistent rhythm; still generous. */
.about-section { padding-bottom: clamp(var(--s7), 6.5vw, 96px); }

/* Closing CTA, /about/ only. The shared band is sized like a hero (h1 title,
   up to 168px of padding), which competed with the About copy. Scoped to the
   page body class so /faq/ and the other bands are untouched. */
.page-about .cta-band   { padding-block: clamp(var(--s7), 6.5vw, 96px); }
.page-about .cta-title  { font-size: var(--fs-h2); }
.page-about .cta-sub    { margin-top: var(--s4); }
.page-about .cta-actions{ margin-top: var(--s6); }
.page-about .cta-note   { margin-top: var(--s5); }
.about-text { display: grid; gap: clamp(var(--s6), 4vw, var(--s7)); }
.about-h {
  font-size: var(--fs-h3); letter-spacing: -0.025em; margin-bottom: var(--s3);
  padding-top: var(--s5); border-top: var(--line);
}
.about-p { color: var(--text-mute); max-width: 60ch; }

/* FAQ */
.faq-layout { display: grid; gap: clamp(var(--s6), 5vw, var(--s8)); align-items: start; }
@media (min-width: 1000px) { .faq-layout { grid-template-columns: 1.5fr .8fr; } }
@media (min-width: 1000px) {
  .faq-aside { position: sticky; top: calc(var(--header-h) + var(--s5)); }
}

/* Book */
.book-layout { display: grid; gap: clamp(var(--s6), 5vw, var(--s8)); align-items: start; }
@media (min-width: 1000px) { .book-layout { grid-template-columns: 1.4fr .75fr; } }
@media (min-width: 1000px) {
  .book-aside { position: sticky; top: calc(var(--header-h) + var(--s5)); }
}

.fieldset { border: 0; padding: 0; margin: 0 0 clamp(var(--s7), 5vw, var(--s8)); }
.fieldset-legend {
  display: flex; align-items: center; gap: var(--s3);
  width: 100%; margin-bottom: var(--s5); padding-bottom: var(--s3);
  border-bottom: var(--line);
  font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.025em;
}
.fieldset-n {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--purple-lift); letter-spacing: .1em; font-weight: 500;
}
.form-submit { padding-top: var(--s5); border-top: var(--line); }

.check-list { display: grid; gap: var(--s4); }
.check {
  display: grid; grid-template-columns: auto 1fr; gap: var(--s3);
  align-items: start; cursor: pointer;
}
.check input { position: absolute; opacity: 0; width: 0; height: 0; }
.check-face {
  width: 24px; height: 24px; flex: none; margin-top: 1px;
  display: grid; place-items: center;
  border: 1px solid var(--paper-line); border-radius: 5px;
  background: var(--paper-raise); color: transparent;
  transition: background var(--t-fast) var(--e-out), border-color var(--t-fast) var(--e-out),
              color var(--t-fast) var(--e-out);
}
.check-face .ico { width: 15px; height: 15px; }
.check input:checked + .check-face {
  background: var(--purple); border-color: var(--purple); color: #fff;
}
.check input:focus-visible + .check-face { outline: 2px solid var(--purple-lift); outline-offset: 2px; }
.check-text { font-size: var(--fs-sm); color: var(--text-mute); line-height: 1.55; }

/* Contact */
.contact-photo { border-radius: var(--r-lg); overflow: hidden; }
.contact-photo img { width: 100%; height: auto; }

/* ---------- 26. FLEET PAGE CARD (/fleet/ only) ---------------------------- */
/* Vehicle CLASSES, not stock. Namespaced .fc-* and kept apart from both
   .v-card and the homepage .f-card so the fleet page can evolve without
   touching either. No availability chip, no year, no trim, no weekly or
   monthly rate: the booking flow owns what is actually free. */
.fc-grid {
  display: grid;
  gap: clamp(var(--s5), 2.4vw, var(--s6));
  grid-template-columns: 1fr;                      /* mobile: 1 column  */
  /* The grid used to butt straight against the filter row, so controls and
     results read as one squeezed block. Kept clearly larger than the grid's
     own row gap (24-32px) at every width, so this boundary reads as a section
     break rather than just another card row. */
  margin-top: clamp(36px, 4vw, 56px);
}
@media (min-width: 620px) {
  .fc-grid { grid-template-columns: repeat(2, 1fr); }   /* tablet: 2     */
}
@media (min-width: 1000px) {
  .fc-grid { grid-template-columns: repeat(3, 1fr); }   /* desktop: 3x2  */
}

.fc-card {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--paper-raise);
  border: var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  transition: border-color var(--t) var(--e-out), box-shadow var(--t) var(--e-out),
              transform var(--t) var(--e-out);
}
.fc-card:hover { border-color: #d3cbdf; box-shadow: var(--shadow); transform: translateY(-3px); }
.fc-card:has(.fc-link:focus-visible) { border-color: var(--purple-lift); }
.fc-card[hidden] { display: none; }
.fc-link { position: absolute; inset: 0; z-index: 3; }

/* One aspect for all six, so the grid reads as a set however the source
   photographs were shot. */
.fc-media {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--paper-sink);
  overflow: hidden;
}
.fc-img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 50%;
  transition: transform var(--t-slow) var(--e-out);
}
.fc-card:hover .fc-img { transform: scale(1.045); }
.fc-blank { position: absolute; inset: 0; background: var(--paper-sink); }

.fc-body {
  padding: var(--s5);
  display: flex; flex-direction: column; gap: var(--s2);
  flex: 1;
}

.fc-class {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--purple-lift);
}
.fc-name {
  font-size: var(--fs-h3); letter-spacing: -0.025em;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 7px;
}
.fc-similar {
  font-size: var(--fs-sm); font-weight: 400; color: var(--text-mute);
  letter-spacing: 0;
}

.fc-attrs {
  display: flex; flex-wrap: wrap;
  font-size: var(--fs-sm); color: var(--text-mute);
  margin-top: 2px;
}
.fc-attrs span + span::before { content: "\00b7"; margin: 0 8px; opacity: .55; }

.fc-foot {
  margin-top: auto;
  padding-top: var(--s4);
  border-top: var(--line);
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s4); flex-wrap: wrap;
}
.fc-price { font-size: var(--fs-sm); color: var(--text-mute); white-space: nowrap; }
.fc-price-num {
  font-family: var(--font-mono); font-size: 1.35rem; font-weight: 500;
  letter-spacing: -0.02em; color: var(--text); margin-left: 4px;
}
.fc-price-unit { font-size: var(--fs-xs); color: var(--text-mute); }

/* One quiet disclaimer under the intro replaces per-image badges. */
.fleet-disclaimer {
  display: flex; align-items: flex-start; gap: var(--s2);
  margin-top: var(--s5);
  max-width: 62ch;
  font-size: var(--fs-sm);
  color: var(--text-mute);
}
.fleet-disclaimer .ico {
  width: 17px; height: 17px; margin-top: 2px;
  color: var(--purple-lift); opacity: .8;
}

/* The fleet intro is deliberately shorter than other page heads: the grid is
   the point of this page, so the vehicles start higher up the screen. Both the
   head's own padding and the grid section's top padding are trimmed, because
   stacked section padding was putting ~109px between the disclaimer and the
   filters. Still generous, just not a gap. */
.page-head--fleet {
  padding-top: calc(var(--header-h) + clamp(24px, 3.2vw, 44px));
  padding-bottom: clamp(var(--s4), 2.5vw, var(--s5));
}
.fleet-grid-section {
  padding-top: clamp(28px, 3vw, 44px);
  /* Trimmed back from the shared --tight step (56-88px). The note below sits
     on a tinted band that carries its own top padding, so the white gap here
     does not need the full section break to read as a separation. */
  padding-bottom: clamp(40px, 4.2vw, 60px);
}

/* ---------- 27. FEATURED CARD (homepage preview only) --------------------- */
/* A teaser, not an inventory listing. Photography leads, one price, one line of
   context, one action. Kept separate from .v-card, which serves /fleet/ and the
   related-vehicles strip, so the two can evolve independently.

   There is deliberately no availability chip here: the fleet is still
   placeholder data, and a homepage badge reading "Available now" would be an
   inventory claim the business cannot stand behind yet. */
.f-grid {
  display: grid;
  gap: clamp(var(--s5), 2.4vw, var(--s6));
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
}

.f-card {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--paper-raise);
  border: var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  transition: border-color var(--t) var(--e-out), box-shadow var(--t) var(--e-out),
              transform var(--t) var(--e-out);
}
.f-card:hover { border-color: #d3cbdf; box-shadow: var(--shadow); transform: translateY(-3px); }
.f-card:has(.f-card-link:focus-visible) { border-color: var(--purple-lift); }
.f-card-link { position: absolute; inset: 0; z-index: 3; }

/* The image is the point of this card, so it takes the largest share of it. */
.f-media {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--paper-sink);
  overflow: hidden;
}
.f-media .pic, .f-media img { width: 100%; height: 100%; object-fit: cover; }
/* Supplied photos vary in size and aspect. The 4:3 box plus object-fit
   centre-crops every one of them identically, so the row stays uniform
   whatever dimensions the files happen to have. */
.f-img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; }
.f-media img { transition: transform var(--t-slow) var(--e-out); }
.f-card:hover .f-media img { transform: scale(1.05); }

/* Says plainly that the shot stands in for the vehicle rather than showing it. */
/* Understated on purpose: legible against any photograph, but it must not
   compete with the vehicle. Sits in the corner, not across the image. */
.f-note {
  position: absolute; left: var(--s3); bottom: var(--s3);
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .05em;
  background: rgba(11, 7, 16, .5); color: rgba(255, 255, 255, .92);
  padding: 3px 7px; border-radius: 3px;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}

.f-draw {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  color: var(--purple); opacity: .3;
  background:
    radial-gradient(90% 70% at 50% 35%, rgba(86, 29, 226, .09), transparent 70%),
    var(--paper-sink);
}
.f-draw .silhouette { width: min(74%, 250px); height: auto; }

.f-body {
  padding: var(--s5);
  display: flex; flex-direction: column; gap: var(--s3);
  flex: 1;
}

.f-title { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.f-year {
  font-family: var(--font-mono); font-size: var(--fs-sm);
  color: var(--text-mute); font-weight: 400;
}
.f-name { font-size: var(--fs-h3); letter-spacing: -0.025em; }
.f-trim {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--text-mute); letter-spacing: .06em; text-transform: uppercase;
}

/* One quiet line instead of a spec grid: category, transmission, gig status. */
.f-meta { display: flex; flex-wrap: wrap; font-size: var(--fs-sm); color: var(--text-mute); }
.f-meta span + span::before { content: "\00b7"; margin: 0 8px; opacity: .55; }

.f-foot {
  margin-top: auto;
  padding-top: var(--s4);
  border-top: var(--line);
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s4); flex-wrap: wrap;
}
.f-price { font-size: var(--fs-sm); color: var(--text-mute); white-space: nowrap; }
.f-price-num {
  font-family: var(--font-mono); font-size: 1.35rem; font-weight: 500;
  letter-spacing: -0.02em; color: var(--text); margin-left: 4px;
}
.f-price-unit { font-size: var(--fs-xs); color: var(--text-mute); }

/* The section head carries a quiet text link; this is the deliberate CTA after
   the cards, since the whole point of the preview is to send people to /fleet/. */
.fleet-more {
  margin-top: clamp(var(--s6), 4vw, var(--s7));
  display: flex; justify-content: center;
}
@media (max-width: 600px) { .fleet-more .btn { width: 100%; } }

/* ---------- 28. THIRD-PARTY EMBED (iFleet test page) ---------------------- */
/* The widget controls its own height via postMessage, so nothing here caps it.
   The shell is the site's normal container width so the booking flow is not
   squeezed, and the background is left alone to honour the widget's
   bg=transparent setting. */
.embed-shell { max-width: var(--shell-max); }
.embed-shell > iframe { width: 100%; display: block; border: 0; background: transparent; }

/* iFleet's inline min-height:500px is deliberately left alone. It is the floor
   that holds the funnel open until their resize message arrives, and the embed
   sets scrolling="no", so a lower floor clips the form instead of merely
   shortening it if that message is slow or never lands. On the opening step
   they report 474px, so the floor leaves ~26px of transparent slack. That is a
   fair trade for not risking a cut-off booking form, and it disappears on every
   later step, where the reported height is well above the floor. */

/* Dedicated booking page: the widget is the page's content, not a band inside
   a longer page, so the intro sits closer and the support line follows the
   widget directly instead of after a second section's padding. */
.embed-section--compact { padding-block: clamp(32px, 4vw, 56px) clamp(36px, 4vw, 64px); }
.embed-after { margin-top: clamp(20px, 2.5vw, 32px); }
@media (max-width: 700px) {
  /* Edge to edge on phones: the widget's own padding is enough, and the
     container gutters would otherwise narrow the booking form. */
  .embed-section > .embed-shell { padding-inline: 0; }
}

/* ---------- 29. INVESTOR PREVIEW ----------------------------------------- */
/* Typography-led by design: no imagery, no icons, no figures. It sits between
   the white FAQ and the purple road CTA, so the near-black ground gives it
   contrast above and lets it hand off cleanly to the purple below. All rules
   are namespaced .inv so nothing here can reach another section. */
/* Each sentence is its own block above 700px, so the headline always breaks at
   the full stop. No text-wrap:balance: balancing pulls "We" onto the first
   line, and no max-width can fix it because the second sentence is the wider
   of the two. Below 700px the spans wrap naturally. */
.inv-headline {
  font-size: var(--fs-h2);
  letter-spacing: -0.034em;
  max-width: 26ch;
}
@media (min-width: 700px) { .inv-headline span { display: block; } }
.inv-sub {
  margin-top: var(--s5);
  font-size: var(--fs-lead);
  color: var(--text-lmute);
  max-width: 54ch;
}

.inv-points {
  display: grid;
  gap: var(--s6);
  margin-top: clamp(var(--s7), 6vw, var(--s8));
}
@media (min-width: 860px) {
  .inv-points { grid-template-columns: repeat(3, 1fr); gap: clamp(var(--s6), 3.5vw, var(--s7)); }
}

/* A hairline per point, with a short accent in the logo purple sitting on top
   of it. That is the whole ornament: no cards, no borders around the content. */
.inv-point {
  position: relative;
  padding-top: var(--s5);
  border-top: 1px solid var(--ink-line);
}
.inv-point::before {
  content: "";
  position: absolute; top: -1px; left: 0;
  width: 34px; height: 1px;
  background: var(--violet);
}
.inv-n {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .14em;
  color: var(--violet);
  margin-bottom: var(--s4);
}
.inv-title {
  font-size: 1.12rem;
  letter-spacing: -0.02em;
  margin-bottom: var(--s3);
}
.inv-body {
  color: var(--text-lmute);
  font-size: var(--fs-sm);
  max-width: 40ch;
}

.inv-actions { margin-top: clamp(var(--s7), 6vw, var(--s8)); }

/* ---------- 30. BOOKING FLOW (/how-it-works/) ----------------------------- */
/* Six light stages, not six cards. Vertical with a connecting rule on phones,
   horizontal once all six genuinely fit across. Intermediate widths wrap into a
   plain grid with no rule, so a connector never dangles at the end of a row. */
.flow {
  display: grid;
  gap: var(--s6);
  grid-template-columns: 1fr;
}
.flow-item { position: relative; padding-left: 46px; }

.flow-n {
  position: absolute; left: 0; top: 0;
  width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--purple-lift);
  border: var(--line);
  /* Transparent so the node sits correctly on paper or sink backgrounds. */
  background: transparent;
}
.flow-title { font-size: var(--fs-body); font-weight: 600; padding-top: 5px; margin-bottom: var(--s2); }
.flow-body  { font-size: var(--fs-sm); color: var(--text-mute); }

/* Connector: vertical in the stacked layout. */
.flow-item::before {
  content: ""; position: absolute;
  left: 16px; top: 38px; bottom: calc(var(--s6) * -1 + 2px);
  width: 1px; background: var(--paper-line);
}
/* Higher specificity than the layout rules below, so the tail never draws. */
.flow-item:last-child::before { display: none; }

@media (min-width: 520px) {
  .flow { grid-template-columns: repeat(2, 1fr); }
  .flow-item::before { display: none; }
}
@media (min-width: 760px) { .flow { grid-template-columns: repeat(3, 1fr); } }

/* Only here is there room for all six across without crushing the labels. */
@media (min-width: 1200px) {
  .flow { grid-template-columns: repeat(6, 1fr); gap: var(--s5); }
  .flow-item { padding-left: 0; padding-top: 46px; }
  .flow-title { padding-top: 0; }
  .flow-item::before {
    display: block;
    left: 40px; right: calc(var(--s5) * -1 + 2px);
    top: 15px; bottom: auto;
    width: auto; height: 1px;
  }
}

/* ---------- 31. CONTACT MAP (/contact/) ----------------------------------- */
/* Google Maps embed: a plain iframe, so no map library, no API key and no
   extra JavaScript ship for it. The URL centers by ll and carries NO 'q'
   search term, so the frame shows the San Antonio service area without
   pinning an office or the vehicle storage location. Ratio keeps it contained
   rather than letting it dominate the row, and it stays fluid down to phones. */
.map-frame {
  border: var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--paper-sink);
  aspect-ratio: 4 / 3;
}
.map-frame iframe { display: block; width: 100%; height: 100%; border: 0; }
.map-note { margin-top: var(--s3); font-size: var(--fs-sm); color: var(--text-mute); }

/* "Call us" matches the header "Book now" button. That button is not a solid
   colour: it is rgba(86,29,226,.38) washed over the dark header (--ink), and
   it lifts to .58 on hover. Copied literally onto this light page the same
   wash composites to #BAA4F1 and drops white text to 2.17:1, so the values
   below are that exact wash pre-composited against --ink - the colour "Book
   now" actually renders as, not a new purple. Border and text come straight
   from the header rule (--violet, #B49CF4, #fff), and the fade is inherited
   from .btn, so the hover behaves identically. */
.contact-actions .btn-primary {
  --btn-bg: #280F60; --btn-bd: var(--violet); --btn-fg: #fff;
}
.contact-actions .btn-primary:hover {
  --btn-bg: #36148A; --btn-bd: #B49CF4;
}

/* ---------- 32. UTILITIES ------------------------------------------------ */
.stack-4 { display: grid; gap: var(--s4); }
.stack-5 { display: grid; gap: var(--s5); }
.stack-6 { display: grid; gap: var(--s6); }
.mt-6 { margin-top: var(--s6); }
.mt-7 { margin-top: var(--s7); }
.text-mute { color: var(--text-mute); }
.mono { font-family: var(--font-mono); }
.img-missing { background: var(--paper-sink); aspect-ratio: 16/9; border-radius: var(--r); }

.print-only { display: none; }
@media print {
  .site-header, .mobile-nav, .sticky-cta, .cta-band, .site-footer { display: none !important; }
  body { background: #fff; }
}
