/* ============================================================
   Parisian Driver — feuille de style
   Palette : encre #0E0F11 · texte #ECECE8 · bleu #9BB4D8
             navy #0C2340 · surface #15171A
   ============================================================ */

:root {
  --ink: #0E0F11;
  --surface: #15171A;
  --surface-2: #191C20;
  --paper: #ECECE8;
  --blue: #9BB4D8;
  --navy: #0C2340;
  --line: rgba(255, 255, 255, 0.14);
  --line-soft: rgba(255, 255, 255, 0.12);
  --txt-60: rgba(236, 236, 232, 0.74); /* corps de texte secondaire — contraste AA renforcé */
  --txt-42: rgba(236, 236, 232, 0.58); /* libellés / méta — contraste AA renforcé */
  --mobile-bar-h: 65px; /* hauteur réelle de la barre sticky (64px + 1px de bordure) */
  --sans: 'Instrument Sans', Helvetica, Arial, sans-serif;
  --maxw: 1320px;
  --gutter: clamp(20px, 5vw, 56px);
  /* Padding vertical partagé par toutes les sections (Services, Véhicule,
     Van, Zone, Événementiel, Réservation, À propos, Contact) — desktop
     ~96-140px. Réduit sous 1080px (cf. --header-h) à ~56-72px. */
  --section-padding-y: clamp(96px, 9vw, 140px);
  --header-h: 76px; /* hauteur du header fixe, desktop (≥1080px) */
  --header-h-narrow: 124px; /* hauteur du header + rail de nav, mobile/tablette (<1080px) */
}

/* Sous 1080px, le header affiche un second rang (rail de nav horizontal)
   qui l'agrandit — mêmes seuils que la nav (.nav-desktop / .nav-rail). */
@media (max-width: 1079px) {
  :root { --section-padding-y: clamp(56px, 10vw, 72px); }
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  line-height: 1.5;
  overflow-x: hidden;
}

a { color: var(--blue); text-decoration: none; }
a:hover { color: #fff; }

::selection { background: #2A4977; color: #fff; }

input, select, textarea, button { font-family: inherit; font-size: inherit; }
input::placeholder, textarea::placeholder { color: rgba(236, 236, 232, 0.34); }

h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -0.03em; }

.hidden { display: none !important; }

@keyframes pd-rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/* ── Layout helpers ─────────────────────────────────────── */
.container { max-width: var(--maxw); margin: 0 auto; }

.section { background: var(--ink); padding: var(--section-padding-y) var(--gutter); }

/* Décale l'ancrage natif (#id direct, favori, retour navigateur) de la
   hauteur du header fixe, pour que le titre de la section ne se
   retrouve jamais caché dessous. Les clics via la nav (JS) calculent
   déjà cet offset eux-mêmes — cette règle couvre les cas non gérés
   par ce JS (navigation par ancre native). */
section[id] {
  scroll-margin-top: var(--header-h);
}
@media (max-width: 1079px) {
  section[id] { scroll-margin-top: var(--header-h-narrow); }
}

.grid-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: clamp(32px, 4vw, 72px);
  align-items: start;
}
.grid-2-center { align-items: center; }
.grid-2-top { align-items: start; }
.grid-2 > div { min-width: 0; }

h2 { font-size: clamp(27px, 3.4vw, 48px); line-height: 1.07; }

.lead {
  margin: 22px 0 0;
  font-size: 16.5px;
  line-height: 1.68;
  color: var(--txt-60);
  max-width: 48ch;
}
.lead + .lead { margin-top: 16px; }
.lead-light { color: rgba(255, 255, 255, 0.76); }

.hr { height: 1px; background: var(--line-soft); margin: 22px 0; }
.hr-sm { margin: 16px 0; }

/* ── Buttons ────────────────────────────────────────────── */
.btn-primary {
  padding: 17px 28px;
  background: var(--paper);
  color: var(--ink);
  border: 0;
  border-radius: 2px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background .18s ease, color .18s ease, transform .12s ease-out;
  -webkit-tap-highlight-color: transparent;
}
.btn-primary:hover { background: var(--blue); }
/* CTA du header : bleu accent pour se détacher du fond sombre au lieu du
   blanc quasi neutre du bouton primaire par défaut. */
.btn-accent { background: var(--blue); color: var(--ink); }
.btn-accent:hover { background: var(--paper); }
.btn-sm { padding: 12px 20px; font-size: 13px; letter-spacing: 0.02em; }
.btn-block { display: block; width: 100%; text-align: center; }
.btn-on-navy { margin-top: 34px; color: var(--navy); }
.btn-on-navy:hover { background: var(--ink); color: var(--paper); }

.btn-outline {
  padding: 17px 26px;
  border: 1px solid rgba(255, 255, 255, 0.24);
  border-radius: 2px;
  font-size: 15px;
  font-weight: 500;
  color: var(--paper);
  white-space: nowrap;
  transition: border-color .18s ease, background .18s ease, transform .12s ease-out;
  -webkit-tap-highlight-color: transparent;
}
.btn-outline:hover { border-color: var(--blue); background: rgba(255, 255, 255, 0.05); color: var(--paper); }

.btn-ghost {
  padding: 14px;
  background: none;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 2px;
  font-size: 14px;
  font-weight: 500;
  color: var(--paper);
  cursor: pointer;
  transition: border-color .18s ease, transform .12s ease-out;
  -webkit-tap-highlight-color: transparent;
}
.btn-ghost:hover { border-color: var(--blue); }

.link-arrow {
  margin-top: 20px;
  display: inline-block;
  text-align: left;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-size: 15px;
  font-weight: 600;
  color: var(--blue);
  border-bottom: 1px solid rgba(155, 180, 216, 0.4);
  transition: color .18s ease;
}
.link-arrow:hover { color: #fff; }

/* ── Header ─────────────────────────────────────────────── */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 60;
  background: rgba(14, 15, 17, 0.9);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--line-soft);
  transition: box-shadow .25s ease;
}
.site-header.scrolled { box-shadow: 0 1px 26px rgba(0, 0, 0, 0.5); }

.header-inner {
  max-width: var(--maxw);
  margin: 0 auto;
  min-height: 74px;
  padding: 0 var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(12px, 2vw, 32px);
}

.brand {
  display: flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  flex: none;
}
.brand-name {
  font-weight: 600;
  font-size: clamp(12px, 1.1vw, 15px);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper);
  white-space: nowrap;
}
.brand-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--blue); display: inline-block; }

.nav-desktop {
  display: flex;
  align-items: center;
  gap: clamp(12px, 1.8vw, 28px);
  min-width: 0;
}
.nav-link {
  position: relative;
  background: none;
  border: 0;
  padding: 6px 0;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  color: rgba(236, 236, 232, 0.55);
  transition: color .18s ease;
}
.nav-link:hover { color: var(--paper); }
.nav-bar {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1.5px;
  background: transparent;
}
.nav-link.active { color: var(--paper); }
.nav-link.active .nav-bar { background: var(--blue); }

/* Sélecteur de langue (FR/EN/ES) : drapeau de la langue courante +
   chevron, ouvre un petit menu vers les pages statiques /en/ et /es/.
   Le menu est en position:fixed (positionné en JS au clic sur le
   drapeau) plutôt qu'absolute, pour ne jamais être rogné par
   l'overflow-y:hidden du rail de nav mobile — même mécanisme utilisé
   pour les deux instances (header desktop et nav-rail mobile). */
.lang-switch { position: relative; display: inline-flex; align-items: center; flex: none; }
.lang-toggle {
  display: inline-flex; align-items: center; gap: 5px;
  background: none; border: 0; padding: 4px;
  cursor: pointer;
  color: rgba(236, 236, 232, 0.65);
  -webkit-tap-highlight-color: transparent;
}
.lang-toggle:hover { color: var(--paper); }
.nav-rail-track .lang-toggle { min-height: 48px; padding: 0 14px; }
.lang-flag {
  width: 20px; height: 14px;
  border-radius: 2px;
  display: block; flex: none;
  overflow: hidden;
}
.lang-chevron { width: 9px; height: 9px; flex: none; transition: transform .15s ease; }
.lang-toggle[aria-expanded="true"] .lang-chevron { transform: rotate(180deg); }

.lang-menu {
  position: fixed;
  z-index: 90;
  min-width: 132px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  padding: 6px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity .16s ease, transform .16s ease, visibility 0s linear .16s;
}
.lang-menu.is-open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition: opacity .16s ease, transform .16s ease, visibility 0s linear 0s;
}
.lang-option {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 10px;
  border-radius: 6px;
  font-size: 13.5px; font-weight: 500;
  color: var(--paper);
  white-space: nowrap;
  transition: background .12s ease;
}
a.lang-option:hover { background: rgba(255, 255, 255, 0.06); }
.lang-option.lang-option-current { color: rgba(236, 236, 232, 0.4); cursor: default; }
@media (prefers-reduced-motion: reduce) {
  .lang-chevron { transition: none; }
  .lang-menu { transition: none; }
}

.header-actions { display: flex; align-items: center; gap: 10px; flex: none; }
.btn-phone {
  padding: 11px 16px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 2px;
  font-size: 13px;
  font-weight: 500;
  color: var(--paper);
  white-space: nowrap;
  transition: border-color .18s ease, color .18s ease, transform .12s ease-out;
  -webkit-tap-highlight-color: transparent;
}
.btn-phone:hover { border-color: var(--blue); color: #fff; }
.btn-appel {
  min-height: 44px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 14px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 2px;
  font-size: 13px;
  font-weight: 500;
  color: var(--paper);
  white-space: nowrap;
  transition: transform .12s ease-out;
  -webkit-tap-highlight-color: transparent;
}
.btn-appel:hover { border-color: var(--blue); }

/* ── Feedback de pression (tap/click) — tous les boutons du site ────
   Compression brève au tap/clic : ~100ms à l'entrée dans :active
   (transition portée par la règle :active elle-même), ~120ms au
   relâchement (transition portée par l'état de base de chaque bouton,
   ajoutée ci-dessus à chaque `transition` existante). Sur mobile,
   c'est ce :active qui porte l'essentiel du feedback (pas de hover
   réel) ; -webkit-tap-highlight-color: transparent (posé sur chaque
   bouton plus haut) évite le flash gris/bleu natif iOS/Android qui
   parasiterait le scale. */
.btn-primary:active,
.btn-accent:active,
.btn-outline:active,
.btn-ghost:active,
.btn-whatsapp:active,
.btn-phone:active,
.btn-appel:active,
.mobile-bar-call:active,
.mobile-bar-book:active {
  transform: scale(0.96);
  transition: transform .1s ease-out;
}
/* prefers-reduced-motion : le scale au tap reste (feedback fonctionnel
   < 200ms, pas une animation d'agrément) mais devient quasi instantané
   plutôt que supprimé. Seule l'animation en boucle du bouton WhatsApp
   (plus haut) est neutralisée. */
@media (prefers-reduced-motion: reduce) {
  .btn-primary { transition: background .18s ease, color .18s ease, transform .05s ease-out; }
  .btn-outline { transition: border-color .18s ease, background .18s ease, transform .05s ease-out; }
  .btn-ghost { transition: border-color .18s ease, transform .05s ease-out; }
  .btn-phone { transition: border-color .18s ease, color .18s ease, transform .05s ease-out; }
  .btn-appel { transition: transform .05s ease-out; }
  .mobile-bar-call, .mobile-bar-book { transition: transform .05s ease-out, background .05s ease-out; }
  .btn-primary:active,
  .btn-accent:active,
  .btn-outline:active,
  .btn-ghost:active,
  .btn-whatsapp:active,
  .btn-phone:active,
  .btn-appel:active,
  .mobile-bar-call:active,
  .mobile-bar-book:active {
    transition-duration: .05s;
  }
}

.nav-rail {
  position: relative;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  box-shadow: inset -12px 0 12px -12px rgba(0, 0, 0, 0.4);
}
.nav-rail::-webkit-scrollbar { display: none; }
/* Fondus en bord de rail : indiquent qu'il y a plus d'onglets à scroller
   horizontalement. Masqués par défaut, révélés par JS (nav-rail--start /
   nav-rail--end) selon la position de scroll réelle du rail. */
.nav-rail::before, .nav-rail::after {
  content: "";
  position: absolute; top: 0; bottom: 0;
  width: 40px;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  transition: opacity .2s ease;
}
.nav-rail::before { left: 0; background: linear-gradient(to right, rgba(14, 15, 17, 1) 0%, rgba(14, 15, 17, 0.7) 40%, rgba(14, 15, 17, 0) 100%); }
.nav-rail::after { right: 0; background: linear-gradient(to left, rgba(14, 15, 17, 1) 0%, rgba(14, 15, 17, 0.7) 40%, rgba(14, 15, 17, 0) 100%); }
.nav-rail.nav-rail--start::before { opacity: 1; }
.nav-rail.nav-rail--end::after { opacity: 1; }
.nav-rail-track {
  display: flex;
  gap: 2px;
  padding: 0 var(--gutter);
  width: max-content;
}
.rail-link {
  min-height: 48px;
  padding: 0 14px;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  font-size: 14.5px;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  color: rgba(236, 236, 232, 0.55);
}
.rail-link.active { color: var(--paper); border-bottom-color: var(--blue); }
/* Langue courante dans le rail mobile : même gabarit que .rail-link
   (elle vit parmi les autres onglets du rail), non cliquable. */
.rail-link.lang-current { color: var(--paper); cursor: default; }

/* ── Hero ───────────────────────────────────────────────────────
   Refonte alignée sur le prototype validé : plus d'eyebrow, plus de
   numérotation sur les piliers, CTA principal sans flèche, dégradé de
   protection sur la photo, piliers en pied de section façon "verre
   dépoli", icône WhatsApp inline, tout en Instrument Sans. ────────── */
.hero {
  position: relative;
  overflow: hidden;
  background: var(--ink);
  min-height: 92vh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  /* Dégagement sous le header fixe — mêmes hauteurs que le header lui-même. */
  padding-top: var(--header-h);
}
@media (max-width: 1079px) {
  .hero { padding-top: var(--header-h-narrow); }
}
/* Fond plein cadre : vidéo cinématique + repli image (poster / connexions lentes).
   Débordement de 64px en haut/bas (au lieu d'un inset:0 strict) pour absorber
   le léger décalage du parallax au scroll sans jamais révéler de bande vide ;
   .hero garde overflow:hidden donc ce débordement reste invisible au repos. */
.hero-backdrop {
  position: absolute; left: 0; right: 0; top: -64px; bottom: -64px; z-index: 0;
  background: #0E0F11 url('../assets/hero-paris-nuit.jpg') center / cover no-repeat;
  will-change: transform;
}
.hero-video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  border: 0;
}
/* Dégradé de protection : sombre à gauche/bas (côté texte), plus clair à
   droite — garantit la lisibilité quelle que soit la photo utilisée. */
.hero-overlay {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, rgba(0, 0, 0, 0.72) 0%, rgba(0, 0, 0, 0.42) 42%, rgba(0, 0, 0, 0.15) 68%);
}
/* Accessibilité : pas de vidéo si l'utilisateur réduit les animations */
@media (prefers-reduced-motion: reduce) {
  .hero-video { display: none; }
  .hero-backdrop { transform: none !important; }
}
/* .hero-inner est un item flex (colonne) : lui donner à la fois un
   max-width et des margin auto casserait le stretch par défaut (les
   deux mécanismes sont incompatibles en flexbox) et le ferait
   "rétrécir" au lieu de s'étirer. Le padding gère les marges latérales
   ici ; le centrage sur --maxw est délégué à .hero-container, un bloc
   normal imbriqué — même mécanisme que .container ailleurs sur le
   site, pour que le texte du hero reste calé sur la même colonne que
   le reste des sections sur grand écran. */
.hero-inner {
  position: relative;
  z-index: 1;
  margin-top: 14vh;
  margin-bottom: 48px;
  padding: 0 var(--gutter);
}
.hero-container { max-width: var(--maxw); margin: 0 auto; }
.hero-content { max-width: 760px; }

.hero h1 { font-size: clamp(34px, 5vw, 70px); line-height: 1.04; letter-spacing: -0.035em; text-wrap: balance; }
.hero-lead {
  margin: 22px 0 0;
  max-width: 46ch;
  font-size: clamp(16px, 1.2vw, 19px);
  line-height: 1.62;
  color: var(--txt-60);
}
.hero-cta { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 34px; margin-bottom: 56px; }

.btn-whatsapp { display: inline-flex; align-items: center; gap: 8px; -webkit-tap-highlight-color: transparent; }
/* Respiration douce de l'icône pour signaler discrètement une alternative
   au CTA principal, sans jamais distraire de la lecture du hero : un
   aller-retour de scale très bref (~600ms) puis une longue pause. */
.btn-whatsapp svg {
  width: 16px; height: 16px; flex: none;
  transform-origin: center;
  animation: pd-whatsapp-breathe 3.6s ease-in-out infinite;
}
@keyframes pd-whatsapp-breathe {
  0%, 83.4% { transform: scale(1); }
  91.7% { transform: scale(1.12); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .btn-whatsapp svg { animation: none; }
}

/* Bande des 3 piliers : pied de section en "verre dépoli", transition
   continue vers la section suivante plutôt qu'une coupure nette. */
.hero-pillars {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--line);
  background: rgba(14, 15, 17, 0.55);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.pillar { padding: 26px 32px; border-right: 1px solid var(--line); }
.pillar:last-child { border-right: none; }
.pillar-title { font-size: 15px; font-weight: 600; }
.pillar p { margin: 6px 0 0; font-size: 13.5px; line-height: 1.45; color: var(--txt-60); }

/* Entrée animée du hero au chargement : .reveal-init/.reveal-in sont
   ajoutées par js/main.js (jamais en CSS pur) pour que le contenu reste
   visible par défaut si le script ne s'exécute pas. .reveal-init fige
   l'état de départ + la transition ; .reveal-in fait apparaître chaque
   élément avec son propre délai, ce qui crée le cascade (h1, lead, cta,
   puis les 3 piliers avec leur micro-stagger). */
.hero.reveal-init h1,
.hero.reveal-init .hero-lead,
.hero.reveal-init .hero-cta,
.hero.reveal-init .pillar {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.56s cubic-bezier(0.16, 1, 0.3, 1), transform 0.56s cubic-bezier(0.16, 1, 0.3, 1);
}
.hero.reveal-init h1 { transition-delay: 0ms; }
.hero.reveal-init .hero-lead { transition-delay: 110ms; }
.hero.reveal-init .hero-cta { transition-delay: 220ms; }
.hero.reveal-init .pillar:nth-child(1) { transition-delay: 330ms; }
.hero.reveal-init .pillar:nth-child(2) { transition-delay: 390ms; }
.hero.reveal-init .pillar:nth-child(3) { transition-delay: 450ms; }
.hero.reveal-init.reveal-in h1,
.hero.reveal-init.reveal-in .hero-lead,
.hero.reveal-init.reveal-in .hero-cta,
.hero.reveal-init.reveal-in .pillar {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .hero.reveal-init h1,
  .hero.reveal-init .hero-lead,
  .hero.reveal-init .hero-cta,
  .hero.reveal-init .pillar {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

@media (max-width: 860px) {
  .hero h1 { font-size: clamp(32px, 9vw, 44px); }
  .hero-content { max-width: 100%; }
  .hero-lead { max-width: 100%; }
  .hero-cta { flex-direction: column; align-items: stretch; margin-bottom: 0; }
  .hero-pillars { grid-template-columns: 1fr; }
  .pillar { border-right: none; border-bottom: 1px solid var(--line); }
}

/* ── Section heads ──────────────────────────────────────── */
.section-head {
  display: flex; flex-wrap: wrap;
  align-items: flex-end; justify-content: space-between;
  gap: 24px; padding-bottom: 34px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 0;
}
.section-head-line { margin-bottom: 0; }
.section-head-left { max-width: 24ch; min-width: min(100%, 260px); }

/* ── Services : ligne d'itinéraire ────────────────────────
   Tient dans la hauteur visible sous le header fixe sur desktop
   (100vh moins var(--header-h)/--header-h-narrow — sinon le bas de
   la section passe sous le header et se fait tronquer par
   overflow:hidden) ; redevient une timeline verticale, hauteur
   automatique, sous 900px. La rangée de points (.route-dots) est
   dissociée du corps des services (.route-body) pour que la ligne
   ne dérive plus dans le texte via un décalage en pixels fixes. */
.section-services {
  position: relative;
  overflow: hidden;
  height: calc(100vh - var(--header-h));
}
@media (max-width: 1079px) {
  .section-services { height: calc(100vh - var(--header-h-narrow)); }
}
/* Filet de sécurité pour les fenêtres courtes en hauteur (zoom
   navigateur, portable avec barre de favoris, etc.) : sur ces
   fenêtres on abandonne le "tient sur un écran" plutôt que de
   tasser ou tronquer le contenu. */
@media (max-height: 700px) {
  .section-services { height: auto; overflow: visible; }
  .services-inner { height: auto; padding-bottom: 64px; }
}
.services-glow {
  position: absolute;
  top: -10%; left: 50%;
  width: 900px; height: 600px;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at center, rgba(47, 102, 144, 0.22), transparent 65%);
  pointer-events: none;
}
.services-dotgrid {
  position: absolute; inset: 0;
  background-image: radial-gradient(rgba(236, 236, 232, 0.05) 1px, transparent 1.5px);
  background-size: 30px 30px;
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 45%, #000 40%, transparent 85%);
  mask-image: radial-gradient(ellipse 70% 60% at 50% 45%, #000 40%, transparent 85%);
  pointer-events: none;
}
/* .section-services n'est volontairement pas lui-même flex : ça
   évite le conflit flexbox entre max-width+margin:auto (centrage sur
   --maxw, même colonne que le reste du site) et align-items:stretch
   (qui casse dès qu'un item flex a des margins auto sur l'axe
   transverse — cf. la refonte du hero). Le flex-column qui répartit
   header-row / route / notes vit donc directement ici, sur un
   parent non-flex. */
.services-inner {
  position: relative;
  z-index: 1;
  max-width: var(--maxw);
  height: 100%;
  margin: 0 auto;
  padding: 56px var(--gutter) 40px;
  display: flex;
  flex-direction: column;
}

.section-services .header-row { flex-shrink: 0; margin-bottom: clamp(28px, 5vh, 72px); }
.section-services h2 {
  font-size: clamp(26px, 3vw, 36px);
  line-height: 1.15;
  font-weight: 600;
  letter-spacing: -0.01em;
  max-width: 520px;
}

.route {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.route-dots {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  align-items: center;
  height: 14px;
  margin-bottom: 28px;
}
.route-track {
  position: absolute;
  left: 12.5%; right: 12.5%; top: 50%;
  height: 1px;
  transform: translateY(-50%);
  background: linear-gradient(90deg, rgba(236, 236, 232, 0.05), var(--line) 15%, var(--line) 85%, rgba(236, 236, 232, 0.05));
}
/* Tracé scroll-linked du trait (desktop uniquement) : --progress (0-100)
   est mis à jour en continu par js/main.js pendant le scroll de la
   section. Gardé derrière .js-enhanced pour que le trait reste
   entièrement visible par défaut (pas de flash "non dessiné" si le
   script ne tourne pas ou si prefers-reduced-motion est actif). */
.route.js-enhanced .route-track {
  clip-path: inset(0 calc(100% - var(--progress, 0) * 1%) 0 0);
  will-change: clip-path;
}
.route-body { display: grid; grid-template-columns: repeat(4, 1fr); }
.stop { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 0 26px; position: relative; }
/* Séparateurs verticaux discrets entre les colonnes — pas de cadre plein. */
.stop:not(:first-child)::before {
  content: "";
  position: absolute; left: 0; top: -42px; bottom: 0;
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--line) 15%, var(--line) 85%, transparent);
}
.dot {
  justify-self: center;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--ink);
  border: 2px solid var(--blue);
  position: relative;
  z-index: 1;
  transition: background-color .25s ease, border-color .25s ease, box-shadow .25s ease;
}
/* État "allumé" : même traitement visuel que .dot-featured (fond plein
   + halo), à l'échelle du point standard (11px). N'est jamais appliqué
   au point Événementiel lui-même (voir js/main.js) : il reste toujours
   allumé via son propre style .dot-featured, plus gros et permanent. */
.dot.is-lit {
  background: var(--blue);
  border-color: var(--blue);
  box-shadow: 0 0 0 4px rgba(155, 180, 216, 0.16), 0 0 16px rgba(155, 180, 216, 0.5);
}
/* Filet de sécurité : si prefers-reduced-motion, js/main.js allume les
   dots directement sans passer par le scroll/IntersectionObserver — au
   cas où le script ne tournerait pas, on force le même résultat visuel
   final ici (trait déjà entièrement visible par défaut, cf. .route-track
   plus haut, qui ne se clippe que sous .js-enhanced). */
@media (prefers-reduced-motion: reduce) {
  .dot:not(.dot-featured) {
    background: var(--blue);
    border-color: var(--blue);
    box-shadow: 0 0 0 4px rgba(155, 180, 216, 0.16), 0 0 16px rgba(155, 180, 216, 0.5);
  }
}
.stop h3 { font-size: 19px; font-weight: 600; line-height: 1.3; margin-bottom: 11px; }
.stop p { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--txt-60); max-width: 240px; }
.tag { margin-top: auto; padding-top: 16px; font-size: 12px; color: rgba(155, 180, 216, 0.65); }

/* Arrêt Événementiel : point plus grand, rempli, avec halo — c'est la
   porte vers une autre section, pas juste un item de liste. */
.dot-featured {
  width: 15px; height: 15px;
  background: var(--blue);
  border: none;
  box-shadow: 0 0 0 5px rgba(155, 180, 216, 0.16), 0 0 24px rgba(155, 180, 216, 0.5);
}
.stop.featured h3 { color: var(--blue); }
.stop > .dot { display: none; }
.event-link {
  margin-top: auto;
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 600;
  color: var(--paper);
  border: 1px solid rgba(236, 236, 232, 0.25);
  padding: 10px 18px;
  border-radius: 999px;
  transition: border-color .15s ease, color .15s ease;
}
.event-link:hover { border-color: var(--blue); color: var(--blue); }
.event-link svg { width: 12px; height: 12px; }

/* Bande basse : Tarifs + À bord fusionnés, séparés par une ligne fine. */
.notes {
  flex-shrink: 0;
  display: flex;
  gap: 56px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
}
.note { font-size: 13.5px; line-height: 1.55; color: var(--txt-60); }
.note strong { color: var(--blue); font-weight: 600; }
.note-link {
  background: none; border: 0; padding: 0; margin: 0;
  text-align: left; cursor: pointer;
  font-family: inherit;
}
.note-link:hover { color: var(--paper); }

@media (max-width: 900px) {
  .section-services { height: auto; }
  .services-inner { height: auto; padding: 64px var(--gutter); }
  .route-dots { display: none; }
  .route-body { grid-template-columns: 1fr; gap: 36px; padding: 36px 0; }
  .stop { align-items: flex-start; text-align: left; padding: 0 0 0 24px; }
  .stop:not(:first-child)::before { display: none; }
  .stop > .dot { display: block; position: absolute; left: 0; top: 6px; }
  .stop p { max-width: 100%; }
  /* Apparition séquentielle au scroll (IntersectionObserver dans
     js/main.js). Gardé derrière .js-enhanced : sans JS ou avec
     prefers-reduced-motion, les arrêts restent visibles par défaut. */
  .route.js-enhanced .stop {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity .5s cubic-bezier(0.16, 1, 0.3, 1), transform .5s cubic-bezier(0.16, 1, 0.3, 1);
  }
  .route.js-enhanced .stop:nth-child(1) { transition-delay: 0ms; }
  .route.js-enhanced .stop:nth-child(2) { transition-delay: 80ms; }
  .route.js-enhanced .stop:nth-child(3) { transition-delay: 160ms; }
  .route.js-enhanced .stop:nth-child(4) { transition-delay: 240ms; }
  .route.js-enhanced .stop.is-visible {
    opacity: 1;
    transform: none;
  }
  .notes { flex-direction: column; gap: 14px; }
}

/* ── Tarifs ─────────────────────────────────────────────── */
#tarifs { position: relative; overflow: hidden; }
#tarifs::before {
  content: "";
  position: absolute;
  top: -10%; left: -8%;
  width: 650px; height: 500px;
  background: radial-gradient(ellipse at center, rgba(47, 102, 144, 0.14), transparent 65%);
  pointer-events: none;
}
#tarifs::after {
  content: "";
  position: absolute;
  bottom: -15%; right: -8%;
  width: 550px; height: 400px;
  background: radial-gradient(ellipse at center, rgba(47, 102, 144, 0.10), transparent 65%);
  pointer-events: none;
}
#tarifs .container { position: relative; z-index: 1; }
.tarifs-note { margin: 0 0 14px; font-size: 13.5px; line-height: 1.55; color: var(--txt-60); }
.tarifs-note + .tarifs-table-wrap { margin-bottom: 14px; }
.tarifs-table-wrap { position: relative; overflow-x: auto; border: 1px solid var(--line-soft); border-radius: 14px; }
.tarifs-table-wrap::after {
  content: "";
  position: absolute; top: 0; right: 0; bottom: 0;
  width: 28px;
  border-radius: 0 14px 14px 0;
  background: linear-gradient(to left, rgba(14, 15, 17, 0.95), rgba(14, 15, 17, 0));
  pointer-events: none;
}
@media (min-width: 620px) {
  .tarifs-table-wrap::after { display: none; } /* le tableau tient sans scroll au-delà de 620px */
}
.tarifs-table { width: 100%; border-collapse: collapse; min-width: 420px; }
.tarifs-table th, .tarifs-table td {
  padding: 13px 16px;
  text-align: left;
  font-size: 14px;
  white-space: nowrap;
}
.tarifs-table th {
  font-weight: 600;
  color: var(--txt-42);
  border-bottom: 1px solid var(--line);
}
.tarifs-table td { color: rgba(236, 236, 232, 0.86); border-bottom: 1px solid var(--line-soft); }
.tarifs-table tr:last-child td { border-bottom: 0; }
.tarifs-table td:last-child, .tarifs-table th:last-child { text-align: right; font-weight: 500; }

/* ── Vehicle gallery ──────────────────────────────────────
   3 colonnes égales pour les vignettes secondaires (aspect-ratio fixe
   4/3 quel que soit leur nombre) + une tuile "large" qui s'étend sur
   toute la rangée (ratio 16/9) — alignement toujours net, jamais de
   case vide en fin de grille. */
.veh-gallery {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; min-width: 0;
  padding: 14px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: 18px;
}
.veh-tile {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: 8px;
  background: linear-gradient(135deg, #191C20 0%, #0E0F11 100%);
  overflow: hidden;
  min-width: 0;
}
.veh-tile img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .4s ease-out, filter .4s ease-out;
}
/* Mise en avant discrète d'une photo au survol — desktop uniquement,
   .veh-tile garde son overflow:hidden pour que le zoom ne déborde
   jamais de la vignette. */
@media (min-width: 768px) {
  .veh-tile:hover img { transform: scale(1.06); filter: brightness(1.05); }
}
@media (prefers-reduced-motion: reduce) {
  .veh-tile img { transition: none; }
  .veh-tile:hover img { transform: none; filter: none; }
}
.veh-tile-wide { grid-column: 1 / -1; aspect-ratio: 4 / 3; }
.veh-tile-placeholder {
  display: flex; align-items: center; justify-content: center;
  border: 1px dashed var(--line-soft);
  background: transparent;
  font-size: 12px; color: var(--txt-42);
}

/* Sous 768px, la grille figée devient un carrousel swipeable en
   scroll-snap natif : même balisage HTML, seule la disposition
   change. .veh-tile-wide n'a plus lieu d'être "large" dans un flux
   horizontal à une seule ligne : grid-column n'a aucun effet dans un
   conteneur flex, elle redevient donc une vignette normale sans
   déclaration supplémentaire. */
@media (max-width: 767px) {
  .veh-gallery {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .veh-gallery::-webkit-scrollbar { display: none; }
  .veh-tile {
    flex: none;
    width: 87%;
    scroll-snap-align: center;
  }
}

/* Dots de position, générés en JS (un jeu par galerie), visibles sous
   768px seulement — purement indicatifs, le swipe reste la seule
   interaction nécessaire. */
.veh-dots { display: none; justify-content: center; gap: 8px; margin-top: 14px; }
@media (max-width: 767px) {
  .veh-dots { display: flex; }
}
.veh-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--line); transition: background .2s ease, transform .2s ease; }
.veh-dot.is-active { background: var(--blue); transform: scale(1.3); }

.spec-list { margin: 36px 0 0; border-top: 1px solid var(--line); }
.spec-row {
  display: flex; flex-wrap: wrap; justify-content: space-between;
  gap: 8px 20px; padding: 16px 0;
  border-bottom: 1px solid var(--line);
}
.spec-row dt {
  font-size: 13.5px; letter-spacing: 0.01em; color: rgba(155, 180, 216, 0.65);
}
.spec-row dd { margin: 0; font-size: 15px; font-weight: 500; text-align: right; }
/* Agrandit la zone tactile des liens (tél./WhatsApp/email) sans décaler la
   mise en page : le padding est compensé par une marge négative égale. */
.spec-row dd a { display: inline-block; padding: 12px 0; margin: -12px 0; }

#vehicule { position: relative; overflow: hidden; }
#vehicule::before {
  content: "";
  position: absolute;
  top: 10%; right: -5%; bottom: -5%;
  width: 700px;
  background: radial-gradient(ellipse at center, rgba(47, 102, 144, 0.16), transparent 65%);
  pointer-events: none;
}
#vehicule .container { position: relative; z-index: 1; }
@media (min-width: 900px) {
  #vehicule .container.grid-2 { grid-template-columns: 1.15fr 1fr; }
}
@media (max-width: 720px) {
  #vehicule .container.grid-2 > div:nth-child(2) { order: -1; }
}

/* ── Zone ───────────────────────────────────────────────── */
.zone-card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: 18px;
  padding: clamp(22px, 3vw, 38px);
  min-width: 0;
  overflow: hidden;
}
.zone-card::before {
  content: "";
  position: absolute;
  top: -20%; right: -15%; bottom: -10%;
  width: 420px;
  background: radial-gradient(ellipse at center, rgba(111, 168, 216, 0.12), transparent 65%);
  pointer-events: none;
}
/* Rayonnement visuel depuis Paris : lecture plus rapide que le texte seul. */
.zone-radar { position: relative; display: block; width: 100%; max-width: 260px; height: auto; margin: 0 auto 28px; }
.zone-radar-ring { fill: none; stroke: var(--blue); stroke-width: 1.5; }
.zone-radar-ring--1 { stroke-opacity: 0.6; }
.zone-radar-ring--2 { stroke-opacity: 0.32; stroke-dasharray: 3 5; }
.zone-radar-ring--3 { stroke: rgba(255, 255, 255, 0.22); stroke-dasharray: 2 6; }
.zone-radar-dot {
  fill: var(--blue);
  transform-box: fill-box;
  transform-origin: center;
}
.zone-radar-label {
  font-size: 12px;
  letter-spacing: 0.03em;
  fill: rgba(236, 236, 232, 0.72);
}

/* Onde façon radar/sonar : un cercle dédié (les 3 anneaux --1/--2/--3
   restent des repères fixes, jamais animés), du centre jusqu'au rayon
   du plus grand anneau (80, cf. .zone-radar-ring--3), en boucle. Deux
   instances décalées de 1.5s pour qu'une deuxième onde démarre avant
   que la première ait fini de s'estomper — effet de pulsation continue
   plutôt qu'un cercle isolé qui clignote. Démarre seulement une fois
   #zone visible (classe .is-active posée par js/main.js, cf. le
   scroll-reveal existant sur .zone-card). */
.zone-radar-wave {
  fill: none;
  stroke: var(--blue);
  stroke-width: 1.5;
  r: 2;
  opacity: 0;
}
.zone-radar.is-active .zone-radar-wave {
  animation: pd-radar-wave 3s ease-out infinite;
}
.zone-radar.is-active .zone-radar-wave--2 { animation-delay: 1.5s; }
.zone-radar.is-active .zone-radar-dot {
  animation: pd-radar-dot-pulse 1.5s ease-in-out infinite;
}
@keyframes pd-radar-wave {
  0% { r: 2; opacity: 0.5; }
  100% { r: 80; opacity: 0; }
}
@keyframes pd-radar-dot-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.15); }
}
@media (prefers-reduced-motion: reduce) {
  .zone-radar.is-active .zone-radar-wave,
  .zone-radar.is-active .zone-radar-dot {
    animation: none;
  }
}

.zone-row { position: relative; display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 12px; }
.zone-label {
  font-size: 13px;
  letter-spacing: 0.01em;
  color: var(--blue); min-width: 118px;
}
.zone-value { font-size: 19px; font-weight: 600; letter-spacing: -0.02em; }

.chips { position: relative; display: flex; flex-wrap: wrap; gap: 8px; margin-top: 26px; }
.chip {
  padding: 7px 12px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 999px;
  font-size: 13px;
  color: rgba(236, 236, 232, 0.7);
}
.chips-light { margin-top: 28px; }
.chip-light {
  padding: 8px 14px;
  border-color: rgba(255, 255, 255, 0.26);
  font-size: 13.5px;
  color: rgba(255, 255, 255, 0.88);
}

/* ── Événementiel ───────────────────────────────────────── */
/* Ce dégradé reste le fond de repli : sous .event-backdrop (semi-
   transparent tant que la vidéo charge) et affiché tel quel si la
   vidéo ne se charge jamais (prefers-reduced-motion, connexion lente,
   ou JS absent). */
.section-event { background: linear-gradient(165deg, #0D2748 0%, #0A1D38 100%); color: #fff; position: relative; overflow: hidden; }
/* Fond vidéo d'ambiance (#evenementiel uniquement) : même logique
   d'intégration que .hero-backdrop/.hero-video (voir plus haut et
   js/main.js) — chargement conditionnel, repli poster/dégradé. */
.event-backdrop {
  position: absolute; inset: 0; z-index: 0;
  background: #0A1D38;
}
.event-video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  border: 0;
}
.event-video-overlay {
  position: absolute; inset: 0; z-index: 1;
  background: rgba(10, 15, 25, 0.5);
  pointer-events: none;
}
/* Accessibilité : pas de vidéo si l'utilisateur réduit les animations
   (le dégradé CSS de .section-event reste affiché en repli). */
@media (prefers-reduced-motion: reduce) {
  .event-video { display: none; }
}
.section-event::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(180deg, var(--ink) 0%, transparent 120px),
    linear-gradient(0deg, var(--ink) 0%, transparent 120px);
  pointer-events: none;
}
.section-event .veh-gallery {
  background: rgba(0, 0, 0, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.10);
  padding: 14px;
}
.section-event .veh-tile-placeholder { border-color: rgba(255, 255, 255, 0.18); }
.section-event::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(ellipse 600px 500px at 108% 15%, rgba(111, 168, 216, 0.14), transparent 65%),
    radial-gradient(ellipse 500px 400px at -6% 92%, rgba(111, 168, 216, 0.10), transparent 65%);
  pointer-events: none;
}
.section-event .grid-2 { position: relative; z-index: 2; }
.section-event .spec-row dt { color: rgba(255, 255, 255, 0.62); }
.van-partner-note {
  margin: 22px 0 0;
  font-size: 13px;
  letter-spacing: 0.01em;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.58);
}
.event-photo {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 5;
  max-height: 520px; /* évite un pavé plein écran quasi vide sur mobile */
  order: 2;
  min-width: 0;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 18px;
  overflow: hidden;
  background-size: cover;
  background-position: center;
}
.event-photo-caption {
  position: absolute; left: 14px; right: 14px; bottom: 14px;
  padding: 12px 16px;
  background: rgba(12, 35, 64, 0.86);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 10px;
  backdrop-filter: blur(4px);
  font-size: 13px;
  letter-spacing: 0.01em;
  line-height: 1.45;
  color: #fff;
}
@media (max-width: 480px) {
  .event-photo-caption {
    font-size: 12.5px;
    padding: 10px 14px;
  }
}
@media (min-width: 900px) {
  .section-event .grid-2 { grid-template-columns: 1fr 1.15fr; }
  .event-photo { order: 0; }
}

#reservation, #contact {
  position: relative;
  /* Pas d'overflow:hidden ici : ces deux sections ont une colonne de texte
     en position:sticky (voir plus bas), et un ancêtre en overflow non-visible
     casse le sticky dans tous les navigateurs. clip-path a le même effet
     visuel de rognage sans ce problème. */
  clip-path: inset(0);
}
#reservation::before, #contact::before {
  content: "";
  position: absolute;
  top: -10%; left: -8%;
  width: 650px; height: 500px;
  background: radial-gradient(ellipse at center, rgba(47, 102, 144, 0.14), transparent 65%);
  pointer-events: none;
}
#reservation .container, #contact .container {
  position: relative;
  z-index: 1;
}

/* ── Réservation & steps ────────────────────────────────── */
.steps { margin-top: 32px; display: flex; flex-direction: column; gap: 14px; }
.step { display: flex; gap: 12px; align-items: flex-start; }
.step-num { font-size: 13px; font-weight: 600; color: var(--blue); padding-top: 3px; flex: none; }
.step > span:last-child { font-size: 15px; color: rgba(236, 236, 232, 0.86); }

/* Le module de réservation est bien plus haut que le texte à côté :
   sans ça, le texte reste planté en haut avec un grand vide noir en
   dessous pendant tout le scroll du module. On le rend "collant" pour
   qu'il accompagne la lecture au lieu de rester figé. Desktop only —
   sur mobile les deux blocs sont empilés, la sticky n'a pas de sens. */
@media (min-width: 901px) {
  #reservation .grid-2 > div:first-child {
    position: sticky;
    top: calc(var(--header-h) + 24px);
    align-self: start;
  }
  #contact .grid-2 > div:first-child {
    position: sticky;
    top: calc(var(--header-h) + 24px);
    align-self: start;
  }
}

.form-panel {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: 18px;
  padding: clamp(22px, 3vw, 38px);
  min-width: 0;
}
.panel-head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 8px 16px; padding-bottom: 18px;
  border-bottom: 1px solid var(--line);
}
.panel-title { font-size: 18px; font-weight: 600; letter-spacing: -0.015em; }
.panel-title-line { display: block; padding-bottom: 18px; border-bottom: 1px solid var(--line); }
.panel-step { font-size: 12.5px; letter-spacing: 0.02em; color: var(--txt-42); }
@media (max-width: 480px) {
  .panel-step {
    display: block;
    margin-top: 4px;
    font-size: 12px;
  }
}

.form-hint { margin: 14px 0 0; font-size: 12.5px; line-height: 1.55; color: rgba(236, 236, 232, 0.45); }
.form-hint a { color: rgba(236, 236, 232, 0.7); text-decoration: underline; text-underline-offset: 2px; }
.form-hint a:hover { color: var(--blue); }

/* ── Module de réservation embarqué (ClickChauffeur) ─────
   Cadre sombre cohérent avec le reste du site autour d'un widget
   tiers dont on ne peut pas restyler l'intérieur (iframe cross-origin).
   Un texte de chargement s'efface dès que le module a fini de charger. */
.booking-embed { margin-top: 22px; }
.booking-embed-frame {
  position: relative;
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
  /* Hauteur de repli avant que le widget ne signale sa taille réelle
     (voir js/main.js) — le contenu variant selon l'étape (une carte
     apparaît une fois une adresse saisie), une valeur fixe unique
     laisse toujours un vide sur les étapes courtes. */
  min-height: 620px;
  background: var(--ink);
  border: 1px solid var(--line-soft);
  border-radius: 14px;
  overflow: hidden;
}
.booking-embed-loading {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  text-align: center;
  font-size: 13px;
  letter-spacing: 0.01em;
  color: var(--txt-42);
}
.booking-embed-loading.hidden { display: none; }
.booking-embed-frame iframe {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: 620px;
  border: 0;
  opacity: 0;
  transition: opacity .35s ease;
}
.booking-embed-frame iframe.is-loaded { opacity: 1; }

/* Le calendrier Google (Contact) a sa propre interface blanche, contrairement
   au module ClickChauffeur (Réservation) qui est déjà sombre — le fond noir
   par défaut du cadre restait visible en bordure/derrière le widget. */
#contact .booking-embed-frame { background: #fff; }
#contact .booking-embed-loading { color: rgba(12, 35, 64, 0.55); }

/* ── FAQ ────────────────────────────────────────────────── */
/* Pas d'overflow:hidden ici : le h2 passe en position:sticky sur desktop
   (voir plus bas), et un ancêtre en overflow non-visible casse le sticky
   dans tous les navigateurs — clip-path rogne le glow sans ce problème
   (même correctif que #reservation/#contact). */
#faq { position: relative; clip-path: inset(0); }
#faq::before {
  content: "";
  position: absolute;
  top: -10%; right: -8%;
  width: 650px; height: 500px;
  background: radial-gradient(ellipse at center, rgba(47, 102, 144, 0.14), transparent 65%);
  pointer-events: none;
}
#faq .container { position: relative; z-index: 1; }
.faq-list {
  margin-top: clamp(28px, 4vw, 44px);
  max-width: 720px;
  border-top: 1px solid var(--line);
}
.faq-item { border-bottom: 1px solid var(--line); }
.faq-question {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px;
  width: 100%;
  padding: 20px 0;
  background: none; border: 0;
  text-align: left;
  cursor: pointer;
  font-size: 16.5px; font-weight: 600; letter-spacing: -0.01em;
  color: var(--paper);
}
.faq-icon {
  position: relative;
  width: 18px; height: 18px;
  flex: none;
}
.faq-icon::before, .faq-icon::after {
  content: "";
  position: absolute; left: 0; top: 50%;
  width: 100%; height: 1.5px;
  background: var(--blue);
  transform: translateY(-50%);
  transition: transform .2s ease;
}
.faq-icon::after { transform: translateY(-50%) rotate(90deg); }
.faq-question[aria-expanded="true"] .faq-icon::after { transform: translateY(-50%) rotate(0deg); }
/* Accordéon : max-height mesurée en JS (scrollHeight) plutôt que
   height:auto, qui ne se transitionne pas. État fermé = transition de
   fermeture (fondu rapide 120ms puis réduction de hauteur 250ms,
   décalée pour démarrer une fois le texte déjà invisible) ; état
   ouvert (.is-open, ajoutée par js/main.js) = transition d'ouverture
   (hauteur 320ms, fondu 220ms démarrant 80ms après pour laisser le
   temps à l'espace de s'ouvrir avant que le texte n'apparaisse). */
.faq-answer {
  padding: 0 0 22px; max-width: 62ch;
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transition: opacity .12s ease, max-height .25s cubic-bezier(0.16, 1, 0.3, 1) .12s;
}
.faq-answer.is-open {
  opacity: 1;
  transition: max-height .32s cubic-bezier(0.16, 1, 0.3, 1), opacity .22s ease .08s;
}
@media (prefers-reduced-motion: reduce) {
  .faq-answer, .faq-answer.is-open { transition: none; }
}
.faq-answer p { margin: 0; font-size: 15px; line-height: 1.68; color: var(--txt-60); }
@media (min-width: 900px) {
  #faq .container {
    display: grid;
    grid-template-columns: 1fr 1.6fr;
    gap: clamp(32px, 4vw, 72px);
    align-items: start;
  }
  #faq h2 {
    position: sticky;
    top: calc(var(--header-h) + 24px);
  }
  .faq-list {
    margin-top: 0;
    max-width: none;
  }
}

/* ── À propos ───────────────────────────────────────────── */
#apropos { position: relative; overflow: hidden; }
#apropos::before {
  content: "";
  position: absolute;
  top: -10%; left: -8%;
  width: 650px; height: 500px;
  background: radial-gradient(ellipse at center, rgba(47, 102, 144, 0.14), transparent 65%);
  pointer-events: none;
}
#apropos .container { position: relative; z-index: 1; }
.about-head {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: clamp(28px, 4vw, 72px);
}
.about-head > div { min-width: 0; }
.about-head .lead:first-child { margin-top: 0; }
.about-grid {
  margin-top: clamp(38px, 5vw, 68px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: 1px;
  background: var(--line);
}
.about-cell { background: var(--ink); padding: clamp(22px, 2.6vw, 32px); }
.about-title { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; }
.about-cell p { margin: 10px 0 0; font-size: 14.5px; line-height: 1.6; color: var(--txt-60); }

/* ── Footer ─────────────────────────────────────────────── */
.site-footer {
  background: var(--ink);
  border-top: 1px solid var(--line-soft);
  padding: clamp(52px, 6vw, 86px) var(--gutter) 34px;
}
.footer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr));
  gap: clamp(26px, 3vw, 56px);
  padding-bottom: 36px;
  border-bottom: 1px solid var(--line-soft);
}
.footer-grid > div { min-width: 0; }
.brand-static { cursor: default; }
.footer-about { margin: 20px 0 0; font-size: 14px; line-height: 1.6; color: var(--txt-60); max-width: 30ch; }
.footer-col-title { font-size: 12.5px; letter-spacing: 0.02em; color: var(--txt-42); }
.footer-links { display: flex; flex-direction: column; align-items: flex-start; gap: 0; margin-top: 8px; }
.footer-links button, .footer-links a {
  text-align: left; background: none; border: 0;
  cursor: pointer; font-size: 14.5px; color: rgba(236, 236, 232, 0.8);
  /* Agrandit la zone tactile (elle grandit légèrement le footer plutôt que
     de décaler d'autres éléments, cf. tentative précédente avec marge
     négative qui rapprochait le premier lien du titre au-dessus). */
  padding: 10px 0;
}
.footer-links button:hover, .footer-links a:hover { color: #fff; }
.footer-muted { font-size: 14.5px; color: rgba(236, 236, 232, 0.38); }
.footer-vtc {
  margin: 14px 0 0;
  font-size: 13px;
  letter-spacing: 0.01em;
  color: rgba(236, 236, 232, 0.55);
}
.footer-bottom {
  display: flex; flex-wrap: wrap; justify-content: space-between;
  gap: 10px 24px; padding-top: 22px;
  font-size: 13px; letter-spacing: 0.01em; color: rgba(236, 236, 232, 0.4);
}

/* ── Mobile bottom bar ──────────────────────────────────── */
.mobile-bar {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: 70;
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--line);
  border-top: 1px solid var(--line);
  /* La barre grandit avec l'encoche du bas (iOS) : son padding — pas
     seulement la hauteur des boutons — doit compter dans l'espace
     réservé côté page pour qu'aucun contenu ne passe dessous. */
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.mobile-bar-call, .mobile-bar-book {
  min-height: 64px;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; font-weight: 600; cursor: pointer; border: 0;
  transition: transform .12s ease-out, background .12s ease-out;
  -webkit-tap-highlight-color: transparent;
}
.mobile-bar-call { background: var(--surface); color: var(--paper); }
.mobile-bar-book { background: var(--paper); color: var(--ink); }
/* Retour tactile renforcé : ce sont les boutons les plus sollicités en
   usage mobile (one-hand, toujours visibles) — un changement de fond
   net à la pression, en plus du scale commun à tous les boutons. */
.mobile-bar-call:active { background: var(--surface-2); }
.mobile-bar-book:active { background: var(--blue); }

/* ── Legal modal ────────────────────────────────────────── */
.legal-overlay {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(6, 7, 9, 0.78);
  display: flex; justify-content: center;
  padding: clamp(12px, 4vh, 56px) clamp(12px, 4vw, 40px);
  overflow: auto;
}
.legal-modal {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 18px;
  width: 100%; max-width: 820px; height: max-content;
  padding: clamp(22px, 4vw, 54px);
  animation: pd-rise .35s ease both;
}
.legal-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; padding-bottom: 22px;
  border-bottom: 1px solid var(--line);
}
.legal-head h2 { margin: 12px 0 0; font-size: clamp(23px, 3vw, 36px); letter-spacing: -0.025em; }
.legal-close {
  width: 40px; height: 40px; flex: none;
  background: none; border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 8px;
  cursor: pointer; font-size: 16px; color: var(--paper);
  transition: border-color .18s ease;
}
.legal-close:hover { border-color: var(--blue); }
.legal-body { margin-top: 26px; display: flex; flex-direction: column; gap: 26px; }
.legal-block { border-top: 1px solid var(--line-soft); padding-top: 18px; }
.legal-block h3 { font-size: 17px; letter-spacing: -0.01em; }
.legal-block p { margin: 12px 0 0; font-size: 15px; line-height: 1.68; color: var(--txt-60); }
#legal-back { margin-top: 32px; padding: 15px 26px; font-size: 14.5px; }

/* ── Responsive visibility ──────────────────────────────── */
.mobile-only { display: none; }
.desktop-only { display: inline-flex; }

@media (max-width: 1079px) {
  .nav-desktop { display: none; }
  .btn-phone.desktop-only { display: none; }
  .mobile-only { display: flex; }
  .btn-appel.mobile-only { display: flex; }
  /* Espace réservé pour la barre sticky (hauteur + encoche iOS) + marge
     de confort, pour qu'aucun contenu de fin de page (footer inclus) ne
     passe dessous. */
  .page {
    padding-bottom: calc(var(--mobile-bar-h) + env(safe-area-inset-bottom, 0px) + 24px);
  }
}

/* ── Apparition au scroll (sections Véhicule, Van, Zone, Événementiel,
   À propos, FAQ) ────────────────────────────────────────────────────
   .reveal n'est ajoutée que par js/main.js (jamais présente par défaut
   dans le HTML/CSS) : sans JS, le contenu reste visible tel quel.
   --reveal-delay est calculée en JS (0 pour les têtes de section,
   120ms + stagger pour le contenu qui suit) et lue ici via
   transition-delay. */
.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity .55s cubic-bezier(0.16, 1, 0.3, 1), transform .55s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: var(--reveal-delay, 0ms);
}
.reveal.is-visible {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

