/* =========================================================================
   CLEAR&GO — DESIGN SYSTEM
   Palette de marque : bleu #2660BD / orange #FC7100 / orange clair #FF8E16
   Typos : Montserrat (titres) + Inter (texte courant)
   ========================================================================= */

:root{
  /* Marque */
  --c-blue:        #2660BD;
  --c-blue-dark:   #1c4a94;
  --c-blue-darker: #163a75;
  --c-orange:      #FC7100;
  --c-orange-light:#FF8E16;
  --c-navy:        #132238;
  --c-navy-soft:   #1b2f4a;
  --c-grey-light:  #F3F6FA;
  --c-white:       #FFFFFF;
  --c-input-bg:    #fbfcfe;
  --c-header-bg:   rgba(255,255,255,.9);

  /* Texte */
  --c-text:        #1c2733;
  --c-text-soft:   #4a5768;
  --c-text-on-dark: #eaf0fb;
  --c-text-on-dark-soft: #b7c4da;
  --c-heading:     #132238;

  /* Etats */
  --c-border:      #e3e9f2;
  --c-success:     #1c8a53;
  --c-focus:       #ff9d3d;

  /* Typo */
  --f-title: "Montserrat", "Segoe UI", Arial, sans-serif;
  --f-body:  "Inter", "Source Sans 3", "Segoe UI", Arial, sans-serif;

  /* Rayons / ombres */
  --radius-s: 10px;
  --radius-m: 16px;
  --radius-l: 26px;
  --shadow-s: 0 2px 10px rgba(19,34,56,.07);
  --shadow-m: 0 12px 32px rgba(19,34,56,.10);
  --shadow-l: 0 24px 60px rgba(19,34,56,.16);

  /* Rythme */
  --gap-xs: .5rem;
  --gap-s: 1rem;
  --gap-m: 1.75rem;
  --gap-l: 3rem;
  --gap-xl: 6rem;

  --container: 1180px;

  --ease: cubic-bezier(.22,.88,.32,1);
  --dur-s: .28s;
  --dur-m: .5s;
  --dur-l: .9s;
}

/* =========================================================================
   MODE SOMBRE — piste "Nuit douce" : prolonge le bleu nuit déjà utilisé sur
   le héros / bandeaux de page / bloc CTA final à l'ensemble du site plutôt
   que d'inventer une nouvelle palette. Activé via [data-theme="dark"] sur
   <html>, posé par assets/js/main.js (bascule manuelle + mémorisation
   localStorage, lu avant le premier rendu pour éviter tout flash clair).
   Seuls les tokens réutilisés partout (fond, cartes, bordures, texte,
   titres) sont redéfinis ici ; les sections déjà sombres en mode clair
   (héros, bandeau de page, CTA final, pied de page) n'ont besoin d'aucun
   changement, elles utilisent déjà --c-navy/--c-text-on-dark.
   ========================================================================= */
:root[data-theme="dark"]{
  --c-white:       #1b2f4a; /* cartes / surfaces (= --c-navy-soft) */
  --c-grey-light:  #132238; /* sections alternées, fond de page (= --c-navy) */
  --c-input-bg:    #16263e; /* champs de formulaire, légèrement en retrait */
  --c-header-bg:   rgba(19,34,56,.85);
  --c-border:      #2c496f;
  --c-text:        #eaf0fb; /* = --c-text-on-dark */
  --c-text-soft:   #b7c4da; /* = --c-text-on-dark-soft */
  --c-heading:     #eaf0fb;
}

/* =========================================================================
   RESET
   ========================================================================= */
*, *::before, *::after{ box-sizing: border-box; }
html{
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  /* Nécessaire pour que les éléments position:fixed volontairement hors
     champ (menu mobile fermé, décorations du hero...) ne comptent pas dans
     la largeur défilable du document — un position:fixed n'est jamais
     contenu par l'overflow d'un ancêtre non racine (dont <body>), seule la
     racine (<html>) a cet effet particulier. Piste initialement suspectée
     dans le bug de la vidéo pendant le scroll (retirée puis remise ici) :
     ce n'était pas la cause — le vrai correctif est la compensation
     window.visualViewport dans scroll-video-section.js — et son absence
     ici causait à la place un débordement horizontal bien réel (barre
     Appeler/Devis, menu mobile) sur Chrome Android. */
  overflow-x: hidden;
}
@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;
  }
}
body{
  margin:0;
  font-family: var(--f-body);
  color: var(--c-text);
  background: var(--c-white);
  line-height: 1.6;
  font-size: 16px;
  transition: background var(--dur-m) var(--ease), color var(--dur-m) var(--ease);
}
@media (prefers-reduced-motion: reduce){ body{ transition:none; } }
img{ max-width:100%; display:block; }
svg{ display:block; }
a{ color: var(--c-blue); text-decoration: none; }
ul, ol{ padding-left: 1.2em; }
button{ font-family: inherit; }
input, textarea, select{ font-family: inherit; font-size: 1rem; }

h1,h2,h3,h4{
  font-family: var(--f-title);
  color: var(--c-heading);
  line-height: 1.16;
  margin: 0 0 .6em;
  font-weight: 800;
  letter-spacing: -.01em;
}
h1{ font-size: clamp(2.1rem, 4.6vw, 3.4rem); }
h2{ font-size: clamp(1.7rem, 3.2vw, 2.4rem); }
h3{ font-size: clamp(1.2rem, 2vw, 1.5rem); }
p{ margin: 0 0 1em; }

.on-dark h1, .on-dark h2, .on-dark h3, .on-dark p, .on-dark li{ color: var(--c-text-on-dark); }
.on-dark .eyebrow{ color: var(--c-orange-light); }

/* Focus visible partout (accessibilité clavier) */
:focus-visible{
  outline: 3px solid var(--c-focus);
  outline-offset: 3px;
  border-radius: 4px;
}
a:focus-visible, button:focus-visible{ outline-offset: 4px; }

.skip-link{
  position:absolute; left:-9999px; top:auto;
  background:var(--c-navy); color:#fff; padding:.8em 1.2em;
  z-index:1000; border-radius:0 0 8px 0;
}
.skip-link:focus{ left:0; top:0; }

/* =========================================================================
   LAYOUT UTILITAIRES
   ========================================================================= */
.container{
  width:100%;
  max-width: var(--container);
  margin-inline:auto;
  padding-inline: 1.25rem;
}
@media (min-width:640px){ .container{ padding-inline: 2rem; } }

.section{ padding-block: var(--gap-xl); }
.section-tight{ padding-block: var(--gap-l); }
.bg-navy{ background: var(--c-navy); }
.bg-grey{ background: var(--c-grey-light); }
.bg-white{ background: var(--c-white); }
.bg-gradient-blue{
  background: linear-gradient(160deg, var(--c-navy) 0%, var(--c-blue-darker) 55%, var(--c-blue) 100%);
}

.eyebrow{
  display:inline-flex; align-items:center; gap:.5em;
  font-family: var(--f-title);
  font-weight:700;
  font-size:.78rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color: var(--c-orange);
  margin-bottom: .9em;
}
.eyebrow::before{
  content:""; width:22px; height:2px; background: var(--c-orange); display:inline-block; border-radius:2px;
}

.text-center{ text-align:center; }
.max-prose{ max-width: 62ch; }
.mx-auto{ margin-inline:auto; }
.mt-0{ margin-top:0; } .mb-0{ margin-bottom:0; }
.hidden{ display:none !important; }
.visually-hidden{
  position:absolute !important; width:1px;height:1px; padding:0;margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;
}

/* minmax(0, 1fr) plutôt qu'un simple 1fr : par défaut, un item de grille a
   min-width:auto, donc une piste "1fr" équivaut en réalité à
   minmax(auto, 1fr) — un contenu large à l'intérieur (ex. un <select> dont
   la plus longue option impose une taille minimale) peut alors forcer la
   piste, et donc toute la grille, à déborder de son conteneur plutôt que de
   se réduire. minmax(0, 1fr) autorise la piste à rétrécir sous la taille de
   son contenu (qui se réajuste alors normalement à l'intérieur : retour à
   la ligne, réduction du select, etc.) — observé concrètement sur le
   formulaire de devis, décentré/débordant sur mobile à cause de cela. */
.grid{ display:grid; gap: var(--gap-m); }
.grid-2{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3{ grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4{ grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width:920px){
  .grid-3, .grid-4{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width:640px){
  .grid-2, .grid-3, .grid-4{ grid-template-columns: minmax(0, 1fr); }
}

.section-head{ max-width: 700px; margin-bottom: var(--gap-l); }
.section-head.center{ margin-inline:auto; text-align:center; }

/* =========================================================================
   BOUTONS
   ========================================================================= */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:.6em;
  font-family: var(--f-title);
  font-weight:700;
  font-size:.98rem;
  padding: .95em 1.7em;
  border-radius: 999px;
  border: 2px solid transparent;
  cursor:pointer;
  transition: transform var(--dur-s) var(--ease), box-shadow var(--dur-s) var(--ease), background var(--dur-s) var(--ease), border-color var(--dur-s) var(--ease), color var(--dur-s) var(--ease);
  white-space: nowrap;
}
.btn svg{ width:1.15em; height:1.15em; flex:none; }
.btn:hover{ transform: translateY(-2px); }
.btn:active{ transform: translateY(0); }

.btn-primary{
  background: var(--c-orange);
  color:#fff;
  box-shadow: 0 10px 24px rgba(252,113,0,.32);
}
.btn-primary:hover{ background: var(--c-orange-light); box-shadow: 0 14px 30px rgba(252,113,0,.4); color:#fff; }

.btn-secondary{
  background: transparent;
  border-color: currentColor;
  color: var(--c-blue);
}
.btn-secondary:hover{ background: var(--c-blue); color:#fff; border-color: var(--c-blue); }

.on-dark .btn-secondary{ color:#fff; }
.on-dark .btn-secondary:hover{ background:#fff; color: var(--c-navy); }

.btn-ghost{
  background: rgba(255,255,255,.08);
  color:#fff;
  border-color: rgba(255,255,255,.35);
}
.btn-ghost:hover{ background: rgba(255,255,255,.18); }

.btn-call{
  background: var(--c-navy);
  color:#fff;
  /* Le fond de l'en-tête reste toujours semi-transparent (voir
     --c-header-bg), même tout en haut de page — un fond sombre (héros,
     séquence d'images) peut donc se deviner derrière, et se confondre avec
     le fond navy plein de ce bouton, lui-même sans bordure jusqu'ici. */
  border-color: rgba(255,255,255,.3);
}
.btn-call:hover{ background: var(--c-blue); color:#fff; border-color: var(--c-blue); }

.btn-block{ width:100%; }
.btn-sm{ padding:.6em 1.1em; font-size:.85rem; }
.btn-icon{ width:40px; height:40px; padding:0; border-radius:50%; flex:none; }
.btn-icon svg{ width:18px; height:18px; }
.header-actions .mobile-header-call{ display:none; }
.btn-label-short{ display:none; }

.btn-group{ display:flex; flex-wrap:wrap; gap:.9rem; }

/* =========================================================================
   HEADER
   ========================================================================= */
.site-header{
  position: sticky; top:0; z-index: 500;
  background: var(--c-header-bg);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--c-border);
  transition: box-shadow var(--dur-s) var(--ease), padding var(--dur-s) var(--ease);
}
.site-header.is-scrolled{ box-shadow: var(--shadow-s); }
.header-inner{
  display:flex; align-items:center; justify-content:space-between;
  gap: .6rem;
  padding-block: .85rem;
  /* Padding latéral resserré (au lieu d'hériter du 2rem de .container,
     voir plus bas) : sur un ordinateur portable "normal" (13"-14", ~1280-
     1440px de large), la nav complète + le texte intégral du bouton devis
     ont besoin de cette place pour tenir sur une seule ligne sans repli en
     menu ☰ ni retour à la ligne — voir l'échange avec l'utilisateur du
     2026-09-03 ("je veux que 13 pouces ce soit la même vue que 27 pouces").
     S'applique à toutes les tailles d'écran par choix explicite (pas de
     palier intermédiaire "compact") : seul le menu mobile, avec sa propre
     mise en page, a un rendu différent. */
  padding-inline: 1rem;
  max-width: 1440px; /* l'en-tête a besoin de plus de place que le reste du site pour ne jamais chevaucher */
}
.brand{ display:flex; align-items:center; flex: 0 0 auto; }
.brand img{ height: 42px; width:auto; max-width:none; transition: height var(--dur-s) var(--ease); }
.site-header.is-scrolled .brand img{ height: 36px; }
.brand-text-only{ display:none; }

/* Deux déclinaisons du logo (bleu+orange / blanc+orange) : le fond de
   l'en-tête (--c-header-bg) change de couleur selon le thème, donc le
   logo doit suivre — même mécanique de bascule que .theme-toggle
   .icon-sun/.icon-moon juste plus bas dans ce fichier. */
.brand img.brand-logo-white{ display:none; }
:root[data-theme="dark"] .brand img.brand-logo-color{ display:none; }
:root[data-theme="dark"] .brand img.brand-logo-white{ display:block; }

.main-nav{ display:flex; flex-wrap:wrap; row-gap:.5rem; align-items:center; gap: 1.1rem; flex: 1 1 auto; justify-content:center; min-width:0; }
.main-nav a{
  /* Espacement généreux entre les liens (voir .main-nav ci-dessus) et
     padding horizontal ici : sans séparation nette, une suite de liens en
     ligne peut se lire comme une seule phrase plutôt que comme des
     éléments cliquables distincts, en particulier pour un public peu
     familier du web. */
  color: var(--c-heading); font-weight:600; font-size:.9rem;
  position:relative; padding: .3em .1em; white-space:nowrap;
}
.main-nav a::after{
  content:""; position:absolute; left:0; right:100%; bottom:0; height:2px;
  background: var(--c-orange); transition: right var(--dur-s) var(--ease);
}
.main-nav a:hover::after, .main-nav a[aria-current="page"]::after{ right:0; }
.main-nav a[aria-current="page"]{ color: var(--c-blue); }

/* Masqué par défaut, dès la feuille de style — avant même l'exécution de
   main.js — plutôt que laissé visible puis retiré une fois le réglage
   réel connu (gateway/site-settings.php, appel réseau asynchrone) :
   sinon, tant que la page "Nos réalisations" est désactivée dans le
   panel, ce lien restait visible le temps du chargement puis disparaissait,
   ce qui faisait passer "Contact" à la ligne suivante du menu (le temps de
   ce court affichage) avant de revenir en place — effet de saut visible.
   Réaffiché par JS (applyRealisationsVisibility() dans main.js) dès que le
   panel confirme la page active — voir ce fichier pour la valeur inline
   explicite utilisée à la réaffichage plutôt qu'un simple retrait du style
   (qui laisserait cette règle s'appliquer). */
.main-nav a[href$="nos-realisations.html"],
.main-nav a[href$="our-work.html"]{
  display:none;
}

.header-actions{ display:flex; align-items:center; gap:.4rem; flex: 0 0 auto; }
.lang-switch{
  display:flex; border:1px solid var(--c-border); border-radius:999px; overflow:hidden; font-size:.82rem; font-weight:700;
}
.lang-switch a{ padding:.5em .85em; color:var(--c-text-soft); }
.lang-switch a[aria-current="true"]{ background: var(--c-navy); color:#fff; }
.lang-switch--mobile{ display:none; }

/* Sélecteur de langue — menu déroulant avec drapeaux */
.flag{ width:22px; height:16px; border-radius:3px; flex:none; box-shadow: inset 0 0 0 1px rgba(19,34,56,.14); }
.lang-toggle{
  display:inline-flex; align-items:center; gap:.45rem;
  border:1px solid var(--c-border); border-radius:999px;
  padding:.42rem .7rem .42rem .5rem; background: var(--c-white); cursor:pointer;
  transition: border-color var(--dur-s) var(--ease), box-shadow var(--dur-s) var(--ease);
}
.lang-toggle:hover{ border-color: var(--c-blue); }
.lang-toggle .flag{ width:22px; height:16px; }
.lang-toggle .chev{ width:11px; height:11px; color: var(--c-text-soft); transition: transform var(--dur-s) var(--ease); }
.lang-dropdown[data-open="true"] .lang-toggle .chev{ transform: rotate(180deg); }
.lang-dropdown[data-open="true"] .lang-toggle .flag{ transform:none; }
.lang-dropdown[data-open="true"] .lang-toggle{ border-color: var(--c-blue); box-shadow: 0 0 0 4px rgba(38,96,189,.12); }
.lang-menu{
  list-style:none; margin:0; padding:.4rem; display:none; flex-direction:column; gap:.15rem;
  position:absolute; top:100%; right:0; margin-top:.6rem;
  background: var(--c-white); border:1px solid var(--c-border); border-radius: var(--radius-m);
  box-shadow: var(--shadow-m); min-width:172px; z-index:60;
}
.lang-dropdown[data-open="true"] .lang-menu{ display:flex; }
.lang-menu a{
  display:flex; align-items:center; gap:.65rem;
  padding:.55rem .65rem; border-radius: var(--radius-s);
  font-size:.9rem; font-weight:600; color: var(--c-text-soft);
}
.lang-menu a:hover{ background: var(--c-grey-light); color: var(--c-heading); }
.lang-menu a[aria-current="true"]{ background: rgba(38,96,189,.09); color: var(--c-blue); font-weight:700; }

.nav-toggle{
  display:none; background:none; border:none; cursor:pointer; padding:.4em;
  width:44px; height:44px; align-items:center; justify-content:center;
}
.nav-toggle span, .nav-toggle span::before, .nav-toggle span::after{
  content:""; display:block; width:24px; height:2px; background: var(--c-heading);
  transition: transform var(--dur-s) var(--ease), opacity var(--dur-s) var(--ease);
  position:relative;
}
.nav-toggle span::before{ position:absolute; top:-8px; }
.nav-toggle span::after{ position:absolute; top:8px; }
.nav-toggle[aria-expanded="true"] span{ background: transparent; }
.nav-toggle[aria-expanded="true"] span::before{ top:0; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] span::after{ top:0; transform: rotate(-45deg); }

@media (max-width: 1180px){
  .main-nav{
    position: fixed; top:0; right:0; bottom:0; left:30%;
    height: 100vh; height: 100dvh;
    background: var(--c-white);
    flex-direction:column; align-items:flex-start;
    padding: 6rem 2rem 2rem;
    gap: 1.4rem;
    transform: translateX(calc(100% + 40px));
    transition: transform var(--dur-m) var(--ease);
    box-shadow: var(--shadow-l);
    overflow-y:auto;
    /* display:none tant que le tiroir n'est pas "prêt" (voir .is-ready et
       main.js::openNav()/closeNav()) : constaté le 2026-09-30, une boîte
       position:fixed repoussée hors champ par translateX reste quand même
       prise en compte par certains navigateurs mobiles pour calculer la
       largeur "idéale" de la page (même avec overflow-x:hidden/clip sur
       html) — ça forçait un zoom arrière permanent de tout le site dès le
       chargement, avant même la première ouverture du menu. .is-ready
       rétablit display:flex juste le temps de l'animation d'ouverture/
       fermeture, pendant laquelle le tiroir est de toute façon visible ou
       en train de le devenir/disparaître (donc légitimement dans le
       calcul), jamais au repos fermé. */
    display:none;
  }
  .main-nav.is-ready{ display:flex; }
  .main-nav.is-open{ transform: translateX(0); }
  .main-nav a{ font-size:1.05rem; }
  .nav-toggle{ display:inline-flex; }
  .header-actions .desktop-only{ display:none; }
  .header-actions .lang-switch{ display:none; }
  .header-actions .lang-dropdown{ display:none; }
  .header-actions .mobile-header-call{ display:inline-flex; }
  .lang-switch--mobile{ display:flex; margin-bottom: 1.6rem; }
}

/* En dessous de cette largeur, l'en-tête (logo + appeler + devis + menu) est
   trop serré pour garder les tailles "tablette" : on compacte tout pour que
   le bouton menu reste toujours visible, sans jamais passer à la ligne. */
@media (max-width: 420px){
  .header-inner{ gap:.6rem; padding-block:.65rem; }
  .brand img, .site-header.is-scrolled .brand img{ height:32px; }
  .header-actions{ gap:.4rem; }
  .header-actions .btn-icon{ width:36px; height:36px; }
  .header-actions .btn-icon svg{ width:16px; height:16px; }
  .header-actions .btn-primary.btn-sm{ padding:.55em .8em; font-size:.78rem; }
  .nav-toggle{ width:38px; height:38px; }
}

/* Le libellé complet du bouton devis ("Demander un devis gratuit") ne
   tient plus dans la barre étroite du header mobile (menu ☰ + logo)  — on
   le raccourcit en "Devis". Aligné exactement sur le seuil de bascule
   vers le menu ☰ (voir plus bas) : dès que la nav desktop complète est
   affichée, le texte complet du bouton l'est aussi — demande explicite de
   l'utilisateur le 2026-09-03 ("je veux que 13 pouces ce soit la même vue
   que 27 pouces"), pas de palier intermédiaire avec un texte raccourci. */
@media (max-width: 1180px){
  .header-actions .btn-label-full{ display:none; }
  .header-actions .btn-label-short{ display:inline; }
}
@media (min-width: 1181px){
  .nav-scrim{ display:none !important; }
}

/* Sous-menu Prestations */
.has-dropdown{ position:relative; }
.nav-drop-toggle{
  display:inline-flex; align-items:center; gap:.35em; white-space:nowrap;
  background:none; border:none; cursor:pointer; padding:.3em 0;
  font: inherit; font-weight:600; color: var(--c-heading); font-size:.9rem;
}
/* "Nos prestations" doit attirer l'œil dans la barre de nav : couleur
   accent orange, à distinguer du sélecteur de langue qui réutilise la même
   classe de base (:not(.lang-dropdown) l'exclut). */
.has-dropdown:not(.lang-dropdown) .nav-drop-toggle{ color: var(--c-orange); }
.has-dropdown:not(.lang-dropdown) .nav-drop-toggle:hover{ color: var(--c-orange-light); }
/* Équivalent pour les pages EN, où l'entrée "Services" est un simple lien
   (pas de menu déroulant traduit) plutôt qu'un .nav-drop-toggle. */
.main-nav a.nav-highlight{ color: var(--c-orange); }
.main-nav a.nav-highlight:hover{ color: var(--c-orange-light); }
.nav-drop-toggle svg{ width:.85em; height:.85em; transition: transform var(--dur-s) var(--ease); }
.has-dropdown[data-open="true"] .nav-drop-toggle svg{ transform: rotate(180deg); }
.nav-dropdown{
  list-style:none; margin:0; padding:.6rem; display:none; flex-direction:column; gap:.2rem;
}
.has-dropdown[data-open="true"] .nav-dropdown{ display:flex; }
@media (min-width:1181px){
  .nav-dropdown{
    position:absolute; top:100%; left:50%; transform: translateX(-50%) translateY(6px);
    background: var(--c-white); border:1px solid var(--c-border); border-radius: var(--radius-m);
    box-shadow: var(--shadow-m); min-width:280px; z-index:50;
  }
  .nav-dropdown a{ padding:.7em .9em !important; border-radius: var(--radius-s); display:block; font-size:.92rem; }
  .nav-dropdown a::after{ display:none; }
  .nav-dropdown a:hover{ background: var(--c-grey-light); }
}
@media (max-width:1180px){
  .nav-dropdown{ padding-left:1rem; border-left:2px solid var(--c-border); margin-top:.4rem; }
}
.nav-scrim{
  position:fixed; inset:0; background: rgba(19,34,56,.4); z-index:490;
  opacity:0; pointer-events:none; transition: opacity var(--dur-m) var(--ease);
}
.nav-scrim.is-open{ opacity:1; pointer-events:auto; }

/* Barre mobile fixe Appeler / Devis */
.mobile-cta-bar{
  position: fixed; left:0; right:0; bottom:0; z-index: 480;
  display:none; gap:.6rem; padding: .6rem .7rem;
  background: var(--c-white); border-top:1px solid var(--c-border);
  box-shadow: 0 -8px 24px rgba(19,34,56,.12);
}
.mobile-cta-bar .btn{ flex:1; padding:.85em .6em; font-size:.88rem; }
@media (max-width: 720px){
  .mobile-cta-bar{ display:flex; }
  body{ padding-bottom: 74px; }
}

/* =========================================================================
   HERO
   ========================================================================= */
.hero{
  position:relative;
  overflow:hidden;
  min-height: calc(100vh - var(--header-h, 76px));
  min-height: calc(100dvh - var(--header-h, 76px));
  display:flex;
  align-items:center;
  padding-block: 4.2rem 7rem;
  background: linear-gradient(165deg, var(--c-navy) 0%, #163a72 48%, var(--c-blue) 100%);
  isolation:isolate;
}
/* Variante utilisée uniquement sur les pages qui ont aussi la section
   vidéo pilotée par le scroll (accueil FR/EN) : .scroll-video-visual (voir
   plus bas) est en position:fixed et couvre tout l'écran en permanence,
   derrière ce dégradé — la vidéo est donc visible, teintée de bleu, dès le
   chargement de la page, avant même que l'utilisateur ne fasse défiler
   jusqu'à sa section dédiée. Le dégradé va d'une teinte marquée en haut à
   une transparence totale en bas : la vidéo apparaît donc progressivement
   "en clair" à mesure qu'on descend, avec une ligne de séparation nette au
   niveau du bas du hero. */
.hero.has-scroll-video{
  background: linear-gradient(180deg, rgba(19,34,56,.86) 0%, rgba(22,58,114,.6) 55%, rgba(38,96,189,0) 100%);
}
.hero > .container{ position:relative; z-index:2; width:100%; }
.hero::before, .hero::after{
  content:""; position:absolute; border-radius:50%; filter: blur(10px);
  opacity:.5; z-index:-1;
}
.hero::before{
  width:520px; height:520px; background: radial-gradient(circle at 30% 30%, rgba(252,113,0,.5), transparent 70%);
  top:-180px; right:-160px;
  animation: float-slow 16s ease-in-out infinite;
}
.hero::after{
  width:380px; height:380px; background: radial-gradient(circle at 60% 40%, rgba(255,142,22,.35), transparent 70%);
  bottom:-160px; left:-120px;
  animation: float-slow 20s ease-in-out infinite reverse;
}
@keyframes float-slow{
  0%,100%{ transform: translate(0,0) scale(1); }
  50%{ transform: translate(30px,-24px) scale(1.08); }
}
.hero-grid{
  display:grid; grid-template-columns: 1.05fr .95fr; gap: 3rem; align-items:center;
}
@media (max-width: 940px){ .hero-grid{ grid-template-columns: 1fr; } }

.hero-badges{ display:flex; flex-wrap:wrap; gap:.6rem 1.2rem; margin: 1.6rem 0 0; padding:0; list-style:none; }
.hero-badges li{
  display:flex; align-items:center; gap:.5em;
  color: var(--c-text-on-dark-soft); font-size:.86rem; font-weight:600;
}
.hero-badges svg{ width:1.2em; height:1.2em; color: var(--c-orange-light); flex:none; }

.hero-visual{
  position:relative;
}
.hero-actions{ margin-top: 2.1rem; }
.hero-note{ margin-top:1.1rem; font-size:.88rem; color: var(--c-text-on-dark-soft); }

/* Illustration ligne (maison / carton) en CSS, pas le logo */
.illustration-card{
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.18);
  border-radius: var(--radius-l);
  padding: 1.4rem;
  backdrop-filter: blur(6px);
}
.placeholder-frame{
  position:relative;
  border-radius: var(--radius-m);
  overflow:hidden;
  aspect-ratio: 4/3;
  background:
    linear-gradient(135deg, rgba(255,255,255,.08), rgba(255,255,255,0)),
    repeating-linear-gradient(45deg, rgba(255,255,255,.05) 0 12px, rgba(255,255,255,.02) 12px 24px);
  border: 1px dashed rgba(255,255,255,.35);
  display:flex; align-items:center; justify-content:center; flex-direction:column; gap:.6rem;
  text-align:center; padding: 1.5rem;
}
.placeholder-frame.light{
  background:
    linear-gradient(135deg, rgba(38,96,189,.06), rgba(38,96,189,0)),
    repeating-linear-gradient(45deg, rgba(19,34,56,.035) 0 12px, rgba(19,34,56,.015) 12px 24px);
  border-color: rgba(19,34,56,.18);
}
.placeholder-frame.is-photo{ border-style:solid; background:none; padding:0; }
.placeholder-frame.is-photo::after{
  content:""; position:absolute; inset:0;
  background: linear-gradient(160deg, rgba(19,34,56,.5) 0%, rgba(38,96,189,.35) 100%);
  pointer-events:none;
}
/* Sur fond clair (ex. page Diogène), le voile bleu marine tranche trop :
   on garde juste un léger assombrissement neutre de l'image elle-même. */
.placeholder-frame.light.is-photo::after{ display:none; }
/* Photo héro (page d'accueil) : voile désactivable depuis le CRM
   (admin/site_media.php → assets/data/site-media.json → main.js). */
.placeholder-frame.is-photo.no-overlay::after{ display:none; }
.placeholder-frame img{
  width:100%; height:100%; object-fit:cover; display:block;
  filter: brightness(.88) saturate(.92);
}
.illustration-caption{
  margin-top:.9rem; font-size:.78rem; line-height:1.5; color: var(--c-text-soft);
}
.placeholder-frame svg{ width:56px; height:56px; color: var(--c-orange-light); }
.placeholder-frame.light svg{ color: var(--c-blue); }
.placeholder-frame .ph-label{
  font-family: var(--f-title); font-weight:700; font-size:.82rem;
  letter-spacing:.06em; text-transform:uppercase; color: var(--c-text-on-dark-soft);
}
.placeholder-frame.light .ph-label{ color: var(--c-text-soft); }
.placeholder-frame .ph-sub{ font-size:.78rem; color: rgba(255,255,255,.55); max-width:26ch; }
.placeholder-frame.light .ph-sub{ color: var(--c-text-soft); opacity:.8; }

/* =========================================================================
   SCROLL VIDEO SECTION — animation pilotée par le défilement
   ========================================================================= */
.scroll-video-section{
  position:relative;
  /* Pas de fond opaque ici : .scroll-video-visual est en position:fixed
     (voir plus bas) et doit rester visible derrière cette section pendant
     toute la phase d'épinglage — un fond opaque ici la cacherait
     complètement. */
}
.scroll-video-pin{
  position:relative;
  height:0; /* la boîte épinglée par GSAP ne doit avoir AUCUNE hauteur propre :
               sinon ScrollTrigger ajoute cette hauteur en plus de la distance
               de scroll pour dimensionner le pin-spacer, et il faut alors
               re-défiler tout un écran de la dernière image après la fin de
               l'animation avant d'atteindre la section suivante. */
}
.scroll-video-visual{
  /* position:fixed (et non plus absolute) : la vidéo est désormais visible
     en continu depuis le tout début de la page (derrière le hero, teintée
     de bleu) jusqu'à la fin de l'épinglage, pas seulement pendant la phase
     épinglée. z-index très bas : elle doit toujours rester DERRIÈRE le
     contenu normal du site (le hero avec son propre fond semi-transparent
     la teinte ; les sections suivantes, opaques, la recouvrent
     naturellement une fois atteintes) — aucune superposition possible,
     quel que soit son état d'opacité, par construction plutôt que par un
     minutage JS précis. */
  position:fixed; inset:0;
  z-index:-1;
  height:100vh;
  height:100dvh; /* évite les sauts liés à la barre d'adresse des navigateurs mobiles */
  overflow:hidden;
  display:flex; align-items:center; justify-content:center;
  /* Chrome (Android + F12 "mode mobile") peut, pendant un scroll continu,
     repositionner un élément position:fixed en retard par rapport à la
     page si celui-ci n'a pas sa PROPRE couche de composition GPU stable —
     le canvas à l'intérieur étant redessiné à chaque frame de scroll
     (drawImage), Chrome doit sinon recomposer tout l'arrière-plan à chaque
     fois, ce qui peut laisser affiché, un instant, un mauvais décalage
     vertical (on ne voit alors qu'une tranche basse de l'image en haut de
     l'écran) tant que le scroll continue — corrigé dès l'arrêt du scroll,
     une fois la recomposition rattrapée. Non reproduit sur Safari/Chrome
     iOS. La forcer sur sa propre couche, indépendante du contenu qui
     défile, évite ce recalcul tardif.
     -> transform ne change PAS le référentiel de positionnement de cet
     élément lui-même (position:fixed reste relatif à la fenêtre) : cela
     n'affecterait que d'éventuels descendants position:fixed, il n'y en a
     pas ici (le canvas est en position:absolute). */
  transform: translateZ(0);
  will-change: transform;
  backface-visibility: hidden;
}
.scroll-video-visual.is-out-of-range{ visibility:hidden; }
.scroll-video-canvas{
  position:absolute; inset:0;
  width:100%; height:100%;
  display:block;
  opacity:0;
  transition: opacity .5s var(--ease);
  /* Même raison qu'au-dessus : couche GPU propre pour le canvas
     lui-même, séparée de celle de son conteneur, pour que ses
     redessins fréquents (à chaque frame de scroll) n'obligent jamais
     Chrome à recomposer le conteneur position:fixed qui l'entoure. */
  transform: translateZ(0);
  will-change: transform;
}
.scroll-video-visual.is-ready .scroll-video-canvas,
.scroll-video-visual.is-reduced-motion .scroll-video-canvas{ opacity:1; }
.scroll-video-overlay{
  position:absolute; inset:0;
  /* Assombrissement local, centré derrière le texte uniquement (pas de
     teinte pleine image) : le texte reste lisible grâce au léger
     text-shadow ci-dessous, sans assombrir toute la vidéo. */
  background: radial-gradient(ellipse 60% 45% at 50% 50%, rgba(19,34,56,.35) 0%, rgba(19,34,56,0) 70%);
  pointer-events:none;
}
.scroll-video-content{
  position:relative; z-index:2;
  text-align:center;
  padding-inline:1.5rem;
  max-width:760px;
  pointer-events:none; /* purement décoratif : ne doit jamais gêner un clic */
}
.scroll-video-text{
  opacity:0;
  color:#fff;
  font-family: var(--f-title); font-weight:800;
  font-size: clamp(1.6rem, 4.4vw, 2.7rem);
  line-height:1.25;
  text-shadow: 0 6px 30px rgba(0,0,0,.45);
  position:absolute; left:50%; top:50%;
  width: min(90vw, 720px);
  transform: translate(-50%, -50%);
}
.scroll-video-hint{
  position:absolute; left:50%; bottom:2.2rem; transform:translateX(-50%);
  z-index:2; color: rgba(255,255,255,.8); font-size:.78rem; font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; display:flex; flex-direction:column; align-items:center; gap:.4rem;
  opacity:0; transition: opacity .6s var(--ease) .3s;
}
.scroll-video-visual.is-ready .scroll-video-hint{ opacity:1; }
.scroll-video-hint svg{ width:18px; height:18px; animation: scrollhint-bounce 1.8s ease-in-out infinite; }
@keyframes scrollhint-bounce{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(6px); } }

/* Repli "mouvement réduit" : la vidéo reste un simple fond fixe statique
   (figée sur la 1re image, aucun défilement ne la fait plus avancer —
   voir scroll-video-section.js), textes toujours visibles et empilés
   normalement plutôt qu'en fondu au scroll. */
.scroll-video-visual.is-reduced-motion .scroll-video-hint{ display:none; }
.scroll-video-visual.is-reduced-motion .scroll-video-text{
  opacity:1 !important; position:static; transform:none; width:auto;
  display:block; margin:0 auto .8rem; max-width:34ch;
}
.scroll-video-visual.is-reduced-motion .scroll-video-content{
  display:flex; flex-direction:column; gap:.4rem;
}
@media (max-width:640px){
  .scroll-video-text{ font-size: clamp(1.3rem, 6vw, 1.9rem); }
}

/* =========================================================================
   TRUST BAR
   ========================================================================= */
.trust-bar{ padding-block: 8rem 6rem; }
.trust-card{
  display:flex; gap:1rem; align-items:flex-start;
  background: var(--c-white);
  border:1px solid var(--c-border);
  border-radius: var(--radius-m);
  padding: 1.5rem;
  box-shadow: var(--shadow-s);
  transition: transform var(--dur-s) var(--ease), box-shadow var(--dur-s) var(--ease);
}
.trust-card:hover{ transform: translateY(-5px); box-shadow: var(--shadow-m); }
.trust-card .icon{
  flex:none; width:48px; height:48px; border-radius:12px;
  background: rgba(38,96,189,.09); color: var(--c-blue);
  display:flex; align-items:center; justify-content:center;
}
.trust-card .icon svg{ width:24px; height:24px; }
.trust-card h3{ margin-bottom:.3em; font-size:1.05rem; }
.trust-card p{ margin:0; font-size:.92rem; color: var(--c-text-soft); }

/* =========================================================================
   CARTES SERVICES
   ========================================================================= */
.service-card{
  position:relative;
  background: var(--c-white);
  border:1px solid var(--c-border);
  border-radius: var(--radius-l);
  padding: 2rem 1.7rem;
  box-shadow: var(--shadow-s);
  transition: transform var(--dur-m) var(--ease), box-shadow var(--dur-m) var(--ease), border-color var(--dur-m) var(--ease);
  overflow:hidden;
}
.service-card::before{
  content:""; position:absolute; inset:0 0 auto 0; height:5px;
  background: linear-gradient(90deg, var(--c-blue), var(--c-orange));
  transform: scaleX(0); transform-origin:left; transition: transform var(--dur-m) var(--ease);
}
.service-card:hover{ transform: translateY(-8px); box-shadow: var(--shadow-l); border-color: transparent; }
.service-card:hover::before{ transform: scaleX(1); }
.service-card .icon{
  width:58px; height:58px; border-radius: 16px;
  background: rgba(38,96,189,.09); color: var(--c-blue);
  display:flex; align-items:center; justify-content:center; margin-bottom:1.2rem;
  transition: background var(--dur-m) var(--ease), color var(--dur-m) var(--ease), transform var(--dur-m) var(--ease);
}
.service-card .icon svg{ width:28px; height:28px; }
.service-card:hover .icon{ background: var(--c-orange); color:#fff; transform: rotate(-6deg) scale(1.05); }
.service-card h3{ font-size:1.15rem; margin-bottom:.5em; }
.service-card p{ color: var(--c-text-soft); font-size:.95rem; }
.service-card .card-link{
  display:inline-flex; align-items:center; gap:.4em; font-weight:700; font-size:.9rem;
  color: var(--c-blue); margin-top:.6rem;
}
.service-card .card-link svg{ width:1em; height:1em; transition: transform var(--dur-s) var(--ease); }
.service-card:hover .card-link svg{ transform: translateX(4px); }

/* =========================================================================
   PROCESSUS / ÉTAPES
   ========================================================================= */
.steps{
  position:relative;
  display:grid; grid-template-columns: repeat(4,1fr); gap: 1.6rem;
  counter-reset: step;
}
@media (max-width: 920px){ .steps{ grid-template-columns: repeat(2,1fr);} }
@media (max-width: 560px){ .steps{ grid-template-columns: 1fr; } }
.step{
  position:relative; padding: 1.6rem 1.4rem 1.4rem;
  background: var(--c-white); border:1px solid var(--c-border);
  border-radius: var(--radius-m);
}
.step .step-num{
  display:flex; align-items:center; justify-content:center;
  width:40px; height:40px; border-radius:50%;
  background: var(--c-blue); color:#fff; font-family: var(--f-title); font-weight:800;
  margin-bottom: 1rem; font-size:1.05rem;
}
.step h3{ font-size:1.02rem; margin-bottom:.35em; }
.step p{ font-size:.9rem; color: var(--c-text-soft); margin:0; }
.steps-progress{
  position:absolute; left:0; right:0; top:20px; height:2px; background: var(--c-border); z-index:-1;
}
@media (max-width: 920px){ .steps-progress{ display:none; } }

/* =========================================================================
   CAS D'USAGE (chips)
   ========================================================================= */
.usecases{ display:flex; flex-wrap:wrap; justify-content:center; gap:.8rem; }
.usecase-chip{
  display:flex; align-items:center; gap:.6em;
  background: var(--c-white); border:1px solid var(--c-border);
  border-radius: 999px; padding: .8em 1.3em .8em 1em;
  font-size:.92rem; font-weight:600; color: var(--c-heading);
  transition: transform var(--dur-s) var(--ease), box-shadow var(--dur-s) var(--ease);
}
.usecase-chip:hover{ transform: translateY(-3px); box-shadow: var(--shadow-s); }
.usecase-chip .dot{ width:8px; height:8px; border-radius:50%; background: var(--c-orange); flex:none; }

/* Cartes claires (var(--c-white)) posées sur une section elle-même
   bg-white : leur propre fond se confondait alors avec celui de la
   section (strictement identiques en mode sombre, où les deux tokens
   restent distincts entre eux mais chacun peut coïncider avec la section
   qui le contient selon sa position dans l'alternance blanc/gris). Bascule
   vers la teinte "grey" du site dans ce cas précis pour rester
   visuellement détachées, quelle que soit la section qui les contient —
   sans rien changer sur une section bg-grey, où le contraste existe déjà. */
.bg-white .trust-card,
.bg-white .service-card,
.bg-white .step,
.bg-white .usecase-chip,
.bg-white .partner-card{
  background: var(--c-grey-light);
}

/* =========================================================================
   PARTENAIRES — cadre horizontal qui défile (page Professionnels), rempli
   par assets/js/main.js::syncPartners() à partir de assets/data/partners.json
   (poussé depuis le panel, admin/partners.php). Reste absent du DOM/masqué
   tant que le cadre n'est pas activé ou qu'il n'y a aucun partenaire.
   ========================================================================= */
.partners-track{
  display:flex; gap:1.5rem; overflow-x:auto; padding:.5rem .25rem 1.2rem;
  scroll-snap-type:x proximity; -webkit-overflow-scrolling:touch;
}
.partner-card{
  flex:none; scroll-snap-align:start; width:220px;
  background: var(--c-white); border:1px solid var(--c-border); border-radius: var(--radius-m);
  padding:1.4rem 1.2rem; text-align:center; box-shadow: var(--shadow-s);
}
.partner-card img{
  max-width:100%; max-height:72px; object-fit:contain; margin:0 auto .9rem; display:block;
}
.partner-card .partner-title{ font-weight:700; color: var(--c-heading); font-size:.95rem; margin:0 0 .3rem; }
.partner-card .partner-desc{ color: var(--c-text-soft); font-size:.82rem; margin:0; }

/* =========================================================================
   TARIFS — page "Nos tarifs", grille remplie par
   assets/js/main.js::syncTarifs() à partir de assets/data/tarifs.json
   (poussé depuis le panel, admin/tarifs.php). #tarifsGrid reste hidden et
   #tarifsEmpty (voir .proof-block) reste seul tant qu'aucune ligne n'existe
   — jamais de prix inventé affiché par défaut.
   ========================================================================= */
.price-card{
  position:relative;
  background: var(--c-white);
  border:1px solid var(--c-border);
  border-radius: var(--radius-l);
  padding: 1.8rem 1.6rem;
  box-shadow: var(--shadow-s);
  transition: transform var(--dur-m) var(--ease), box-shadow var(--dur-m) var(--ease), border-color var(--dur-m) var(--ease);
  overflow:hidden;
}
.price-card::before{
  content:""; position:absolute; inset:0 0 auto 0; height:5px;
  background: linear-gradient(90deg, var(--c-blue), var(--c-orange));
  transform: scaleX(0); transform-origin:left; transition: transform var(--dur-m) var(--ease);
}
.price-card:hover{ transform: translateY(-6px); box-shadow: var(--shadow-l); border-color: transparent; }
.price-card:hover::before{ transform: scaleX(1); }
.price-card h3{ font-size:1.08rem; margin-bottom:.5em; }
.price-card .price{
  font-family: var(--f-title); font-weight:800; font-size:1.3rem;
  color: var(--c-orange); margin:0 0 .5em;
}
.price-card p:not(.price){ color: var(--c-text-soft); font-size:.9rem; margin:0; }

/* Bannière "prix moyen" (page "Nos tarifs") — contenu statique pour le
   moment, pas encore relié au CRM (voir commentaire dans nos-tarifs.html).
   Traitement H choisi le 2026-09-20 après un premier essai en dégradé
   bleu->orange sur le texte, jugé terne (bleu/orange quasi opposés, leur
   mélange au centre du dégradé donne un gris-violet délavé) et trop peu
   contrasté avec le fond de page en sombre. Fond marque toujours sombre,
   qu'importe le thème actif — même convention que .page-hero.on-dark et
   .cta-final, déjà utilisée ailleurs sur ce site pour les mêmes raisons. */
.avg-price-banner{
  position:relative; overflow:hidden;
  text-align:center; padding: 2.6rem 2.2rem; max-width: 720px; margin-inline:auto;
  border-radius: var(--radius-l); box-shadow: var(--shadow-l);
  color: var(--c-text-on-dark);
  background: linear-gradient(135deg, var(--c-navy) 0%, var(--c-blue-darker) 60%, var(--c-blue) 100%);
}
/* Fine barre de marque, même traitement que .service-card::before — ici
   toujours visible (pas de scaleX(0)/hover : ce n'est pas une carte d'une
   grille, elle n'a pas de survol à révéler). Remplace le halo orange
   radial-gradient précédent, retiré : il se voyait comme un grand carré
   flou près de "Prix moyen constaté", signalé le 2026-09-20. */
.avg-price-banner::before{
  content:""; position:absolute; inset:0 0 auto 0; height:5px;
  background: linear-gradient(90deg, var(--c-blue), var(--c-orange));
}
.avg-price-banner .eyebrow{ justify-content:center; margin-bottom:.9rem; color: var(--c-orange-light); }
.avg-price-banner .price-line{ display:flex; align-items:flex-end; justify-content:center; gap:.4rem; margin-bottom:.7rem; }
.avg-price-banner .price-num{
  font-family: var(--f-title); font-weight:800; font-size:clamp(2.8rem,8vw,4.4rem); line-height:.9;
  color:#fff;
}
.avg-price-banner .price-unit{ font-family: var(--f-title); font-weight:700; font-size:1.15rem; color: var(--c-text-on-dark-soft); padding-bottom:.5rem; }
.avg-price-banner h2{ font-size:1.3rem; margin-bottom:.5rem; color:#fff; }
.avg-price-banner .lead{ color: var(--c-text-on-dark-soft); font-size:.95rem; margin:0 auto .9rem; max-width:52ch; }
.avg-price-banner .fee-chip{
  display:inline-flex; align-items:flex-start; gap:.5em; text-align:left;
  background: rgba(255,255,255,.1); border:1px solid rgba(255,255,255,.2);
  border-radius: var(--radius-s); padding:.7em 1em; font-size:.82rem; color: var(--c-text-on-dark-soft); max-width:480px;
}
.avg-price-banner .fee-chip svg{ flex:none; width:16px; height:16px; color: var(--c-orange-light); margin-top:.1em; }

/* =========================================================================
   GALERIE — grille d'exemples avant/après, deux par ligne (nos-realisations.html)
   ========================================================================= */
.gallery-grid{ row-gap: 3.5rem; }
.gallery-item h2{ font-size:1.4rem; margin: .3em 0 1.1em; }
.gallery-item .ba-slider{ max-width:none; }

/* =========================================================================
   AVANT / APRÈS — slider
   ========================================================================= */
.ba-slider{
  position:relative;
  max-width: 760px; margin-inline:auto;
  aspect-ratio: 16/10;
  border-radius: var(--radius-l);
  overflow:hidden;
  box-shadow: var(--shadow-l);
  border: 1px solid var(--c-border);
  user-select:none;
  touch-action: pan-y;
}
.ba-slider .ba-pane{
  position:absolute; inset:0;
  display:flex; align-items:center; justify-content:center; flex-direction:column; gap:.7rem;
  text-align:center;
}
.ba-slider .ba-before{
  z-index:1;
  background: linear-gradient(135deg,#e7ecf6,#f6f8fc);
}
.ba-slider .ba-after{
  /* Doit rester au-dessus de .ba-before (sinon la photo "Avant", non
     recadrée, déborde par-dessus la moitié droite normalement réservée à
     "Après" et masque son étiquette) — constaté empiriquement : le simple
     ordre du DOM ne suffisait pas à garantir cet ordre d'empilement une
     fois clip-path en jeu, d'où ce z-index explicite. */
  z-index:2;
  background: linear-gradient(135deg,#eef4ff,#ffffff);
  clip-path: inset(0 0 0 50%);
}
.ba-slider .ba-tag{
  position:absolute; top:14px; z-index:2; font-family: var(--f-title); font-weight:800; font-size:.78rem;
  letter-spacing:.08em; text-transform:uppercase; padding:.4em .9em; border-radius:999px; color:#fff;
}
.ba-before .ba-tag{ left:14px; background: var(--c-navy); }
.ba-after .ba-tag{ right:14px; background: var(--c-orange); }
/* Volets avec une vraie photo (envoyée depuis le panel) plutôt que l'icône
   de substitution : l'image remplit tout le volet, le dégradé de fond
   d'origine (pensé pour centrer une icône) n'a plus besoin d'être visible.
   z-index:1 (sous .ba-tag ci-dessus) : sans ça, deux éléments position:absolute
   sans z-index se départagent par ordre du DOM — l'image, insérée après le
   tag par main.js, passait dessus et masquait "Avant"/"Après" pour toute
   photo non transparente. */
.ba-slider .ba-pane img{
  position:absolute; inset:0; z-index:1; width:100%; height:100%; object-fit:cover;
}
.ba-slider svg{ width:60px; height:60px; color: var(--c-blue); opacity:.7; }
.ba-caption{ font-size:.82rem; color: var(--c-text-soft); font-weight:600; }
.ba-handle{
  position:absolute; top:0; bottom:0; left:50%; width:52px; margin-left:-26px; z-index:3;
  display:flex; align-items:center; justify-content:center; cursor: ew-resize;
}
.ba-handle::before{
  content:""; position:absolute; top:0; bottom:0; left:50%; width:3px; background:#fff;
  box-shadow: 0 0 0 1px rgba(19,34,56,.15);
  transform: translateX(-50%);
}
.ba-handle-grip{
  position:relative; width:46px; height:46px; border-radius:50%; background:#fff;
  box-shadow: var(--shadow-m); display:flex; align-items:center; justify-content:center;
  color: var(--c-blue);
}
.ba-handle-grip svg{ width:20px; height:20px; color:inherit; opacity:1; }
.ba-note{ text-align:center; font-size:.85rem; color: var(--c-text-soft); margin-top:1rem; }

/* =========================================================================
   PREUVES / AVIS (placeholder honnête)
   ========================================================================= */
.proof-block{
  background: var(--c-white); border:1px dashed var(--c-border);
  border-radius: var(--radius-m); padding: 2rem;
  display:flex; gap:1.2rem; align-items:flex-start;
}
.proof-block svg{ flex:none; width:34px; height:34px; color: var(--c-orange); }
.proof-block p{ margin:0; color: var(--c-text-soft); font-size:.95rem; }

/* =========================================================================
   BANDEAU AVIS GOOGLE (hero) — carte-ancre (note moyenne, fixe) + ruban de
   cartes d'avis qui défile. La carte-ancre reprend le même traitement
   "verre" (fond translucide + bordure + flou) que les cartes d'avis
   elles-mêmes, teinté navy plutôt que blanc pour rester distincte.
   ========================================================================= */
.gr-widget{
  grid-column: 1 / -1;
  min-width:0;
  margin-top:2.4rem;
  display:flex; align-items:stretch; gap:1rem;
}
/* "display:flex" ci-dessus l'emporterait sur la règle navigateur
   [hidden]{display:none} à spécificité égale (même piège que
   .phone-reveal-trigger/.cg-cookie-prefs) — d'où le "!important" ici. */
.gr-widget[hidden]{ display:none !important; }
.gr-anchor{
  flex:none; width:148px;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:.3rem;
  text-align:center; text-decoration:none; border-radius: var(--radius-m); padding:1rem .8rem;
  background: rgba(19,34,56,.55);
  border:1px solid rgba(255,255,255,.16);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  transition: border-color var(--dur-s) var(--ease), transform var(--dur-s) var(--ease);
}
.gr-anchor:hover{ border-color: rgba(255,142,22,.55); transform: translateY(-2px); }
.gr-anchor-score{ font-family: var(--f-title); font-weight:800; font-size:1.7rem; color:#fff; line-height:1; }
.gr-anchor-stars{ color: var(--c-orange-light); letter-spacing:1.5px; font-size:.85rem; }
.gr-anchor-count{ font-size:.72rem; color: var(--c-text-on-dark-soft); }
.gr-anchor .gr-glogo{ width:17px; height:17px; margin-top:.15rem; flex:none; }
.gr-viewport{
  flex:1; min-width:0;
  overflow-x:scroll; overflow-y:hidden;
  scrollbar-width:none; -ms-overflow-style:none;
  cursor:grab;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 3%, #000 97%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 3%, #000 97%, transparent);
}
.gr-viewport::-webkit-scrollbar{ display:none; }
.gr-viewport.is-dragging{ cursor:grabbing; }
.gr-track{
  display:flex; align-items:stretch; gap:1rem; width:max-content; padding:.15rem 0;
  animation: gr-scroll 34s linear infinite;
}
.gr-viewport.is-hover .gr-track, .gr-viewport.is-dragging .gr-track{ animation-play-state:paused; }
@keyframes gr-scroll{ from{ transform:translateX(0); } to{ transform:translateX(-50%); } }
.gr-item{
  flex:none; width:250px; display:block; text-decoration:none;
  background: rgba(255,255,255,.08);
  border:1px solid rgba(255,255,255,.16);
  border-radius: var(--radius-m); padding:.9rem 1rem;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  transition: border-color var(--dur-s) var(--ease), transform var(--dur-s) var(--ease);
}
.gr-item:hover{ border-color: rgba(255,142,22,.55); transform: translateY(-2px); }
.gr-item-top{ display:flex; align-items:center; gap:.6rem; margin-bottom:.5rem; }
.gr-avatar{
  width:32px; height:32px; border-radius:50%; flex:none;
  display:flex; align-items:center; justify-content:center;
  font-family: var(--f-title); font-weight:800; font-size:.7rem; color:#fff;
}
.gr-item-who{ display:flex; flex-direction:column; gap:.1rem; min-width:0; }
.gr-name{ color:#fff; font-weight:700; font-size:.82rem; font-family: var(--f-title); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.gr-stars{ color: var(--c-orange-light); letter-spacing:1px; font-size:.76rem; }
.gr-text{
  margin:0; font-size:.78rem; line-height:1.5; color: var(--c-text-on-dark-soft);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.gr-more{ flex:none; align-self:center; font-size:.82rem; font-weight:600; color: var(--c-orange-light); white-space:nowrap; text-decoration:none; }
@media (max-width:640px){
  .gr-widget{ flex-wrap:wrap; }
  .gr-anchor{ width:100%; flex-direction:row; padding:.8rem; gap:.7rem; }
  .gr-more{ display:none; }
}

/* =========================================================================
   PAGE AVIS CLIENTS
   ========================================================================= */
.reviews-intro{ max-width:68ch; }
.reviews-summary{
  display:flex; align-items:center; gap:.8rem; margin-top:1.6rem;
  background: rgba(255,255,255,.1); border-radius:999px;
  padding:.5rem 1.1rem; width:fit-content;
}
.reviews-summary[hidden]{ display:none !important; }
.reviews-summary svg{ width:19px; height:19px; flex:none; }
.reviews-summary .gr-stars{ color: var(--c-orange-light); letter-spacing:1px; }
.reviews-summary strong{ color: var(--c-text-on-dark); font-size:.95rem; }
.reviews-summary span{ color: var(--c-text-on-dark-soft); font-size:.9rem; }
.reviews-grid{
  display:grid; grid-template-columns: repeat(auto-fill, minmax(280px,1fr));
  gap:1.2rem; margin-top:2.5rem;
}
.review-card{
  background: var(--c-white); border:1px solid var(--c-border);
  border-radius: var(--radius-m); padding:1.3rem 1.4rem;
  scroll-margin-top:6rem; transition: box-shadow .3s, border-color .3s;
}
.review-card:target{ border-color: var(--c-orange); box-shadow:0 0 0 3px rgba(252,113,0,.18); }
.review-card .rc-top{ display:flex; align-items:center; gap:.7rem; margin-bottom:.6rem; }
.review-card .rc-avatar{
  width:38px; height:38px; border-radius:50%; flex:none;
  display:flex; align-items:center; justify-content:center;
  font-size:.85rem; font-weight:700; color:#fff; background: var(--c-blue);
}
.review-card .rc-name{ font-weight:600; font-size:.95rem; color: var(--c-text); }
.review-card .rc-date{ font-size:.78rem; color: var(--c-text-soft); }
.review-card .gr-stars{ color: var(--c-orange); letter-spacing:1px; font-size:.85rem; margin-bottom:.5rem; display:block; }
.review-card p{ margin:0; font-size:.9rem; line-height:1.55; color: var(--c-text-soft); }

/* =========================================================================
   ZONE / CARTE
   ========================================================================= */
.zone-map{
  position:relative; border-radius: var(--radius-l); overflow:hidden;
  background: linear-gradient(160deg,#eef3fb,#dfe8f7);
  border: 1px solid var(--c-border);
  aspect-ratio: 4/3;
  display:block;
}
/* Aperçu miniature de la vraie carte Leaflet (voir initHomeZoneMapPreview()
   dans main.js) : toutes les interactions de la carte sont désactivées
   (survol/zoom/glisser), c'est un lien à part entière vers la page carte
   complète, pas un mini-outil. */
.zone-map-preview-canvas{ position:absolute; inset:0; pointer-events:none; }
.zone-map-preview-canvas .leaflet-control-attribution{ font-size:.6rem; }
a.zone-map{ cursor:pointer; transition: box-shadow var(--dur-s) var(--ease), transform var(--dur-s) var(--ease); }
a.zone-map:hover{ box-shadow: var(--shadow-m); transform: translateY(-2px); }
.zone-map-preview-cta{
  position:absolute; left:14px; bottom:14px; z-index:1000; pointer-events:none;
  display:inline-flex; align-items:center; gap:.5rem;
  font-family: var(--f-title); font-weight:700; font-size:.82rem; color:#fff;
  background: var(--c-orange); padding:.55em 1em; border-radius:999px;
  box-shadow: 0 8px 20px rgba(19,34,56,.28);
}
.zone-map-preview-cta svg{ width:15px; height:15px; flex:none; }

.zones-towns-toggle{
  display:inline; background:none; border:none; padding:0; margin-left:.3em;
  font:inherit; font-weight:700; color: var(--c-blue); cursor:pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.zones-towns-toggle:hover{ color: var(--c-orange); }

/* =========================================================================
   CARTE INTERACTIVE DES ZONES (Leaflet.js + fonds OpenStreetMap, gratuits,
   sans clé ni facturation — voir zones-intervention.html). Les tuiles/le
   contrôle de zoom sont stylés par leaflet.css (chargé séparément) ; ici,
   seuls l'habillage (cadre, panneau latéral, recherche) et les marqueurs
   personnalisés (DivIcon) sont définis.
   ========================================================================= */
.zmap-shell{
  border-radius: var(--radius-l); overflow:hidden; border:1px solid var(--c-border);
  box-shadow: var(--shadow-m); background: var(--c-white); margin-top:2rem;
}
.zmap-layout{ display:grid; grid-template-columns: 1fr 280px; }
@media (max-width:820px){ .zmap-layout{ grid-template-columns:1fr; } }
.zmap-area{ position:relative; }
.zmap-canvas{ width:100%; height:600px; background: var(--c-grey-light); }
@media (max-width:640px){ .zmap-canvas{ height:460px; } }

.zmap-search{
  position:absolute; top:14px; right:14px; left:auto; z-index:1000;
  display:flex; align-items:center; gap:.5rem;
  background: var(--c-white); border-radius:999px; padding:.55rem 1rem;
  box-shadow: 0 4px 14px rgba(19,34,56,.18); width:min(240px, 60%);
}
.zmap-search-icon{ width:15px; height:15px; flex:none; color: var(--c-text-soft); }
.zmap-search input{
  border:none; background:none; outline:none; font-family: var(--f-body);
  font-size:.85rem; width:100%; color: var(--c-text); min-width:0;
}
.zmap-search-suggestions{
  position:absolute; z-index:1000; top:100%; right:0; margin:.4rem 0 0; width:260px;
  max-width:80vw; list-style:none; padding:.3rem; background: var(--c-white);
  border:1px solid var(--c-border); border-radius: var(--radius-s); box-shadow: var(--shadow-m);
  max-height:220px; overflow-y:auto;
}
.zmap-search-suggestions[hidden]{ display:none; }
.zmap-search-suggestions li{ padding:.55em .7em; border-radius:6px; cursor:pointer; font-size:.86rem; color: var(--c-heading); }
.zmap-search-suggestions li:hover{ background: rgba(38,96,189,.1); }
.zmap-search-note{
  position:absolute; z-index:1000; bottom:14px; left:14px; right:14px;
  background: var(--c-white); border-radius: var(--radius-s); padding:.75rem 1rem;
  font-size:.82rem; color: var(--c-text-soft); border-left:3px solid var(--c-orange);
  box-shadow: 0 4px 16px rgba(19,34,56,.2), 0 0 0 5px rgba(252,113,0,.14);
  max-width:340px;
  animation: zmapNoteIn .35s var(--ease);
}
.zmap-search-note[hidden]{ display:none; }
.zmap-search-note strong{ color: var(--c-heading); }
@keyframes zmapNoteIn{
  0%{ transform: translateY(8px) scale(.96); opacity:0; }
  100%{ transform: translateY(0) scale(1); opacity:1; }
}
@media (prefers-reduced-motion: reduce){ .zmap-search-note{ animation:none; } }

.zmap-sidebar{ padding:1.2rem 1.3rem; border-left:1px solid var(--c-border); overflow-y:auto; max-height:600px; }
@media (max-width:820px){ .zmap-sidebar{ border-left:none; border-top:1px solid var(--c-border); max-height:none; } }
.zmap-sidebar-title{
  font-family: var(--f-title); font-weight:800; font-size:.72rem; text-transform:uppercase;
  letter-spacing:.06em; color: var(--c-orange); margin:0 0 .9rem;
}

/* Groupe par secteur, dépliable : l'en-tête (nom + nombre de points) reste
   toujours visible ; replié, les 4 premiers points restent visibles quand
   même (pas juste l'en-tête seul) — un bouton "+N" révèle le reste. */
.zmap-group{ margin-bottom:.5rem; }
.zmap-group:last-child{ margin-bottom:0; }
.zmap-group-title{
  display:flex; align-items:center; gap:.5rem; width:100%;
  font-family: var(--f-title); font-weight:800; font-size:.7rem; text-transform:uppercase;
  letter-spacing:.05em; color: var(--c-text-soft); margin: .9rem 0 .45rem; padding:0;
  background:none; border:none;
}
.zmap-group:first-child .zmap-group-title{ margin-top:0; }
.zmap-group-count{
  font-family: var(--f-body); font-weight:700; font-size:.7rem; letter-spacing:0; text-transform:none;
  background: var(--c-grey-light); color: var(--c-text-soft); border-radius:999px; padding:.1em .55em;
}
.zmap-chip{
  display:flex; align-items:center; gap:.55rem; width:100%; text-align:left;
  background:none; border:none; font: inherit; font-size:.86rem; color: var(--c-heading);
  padding:.4rem .4rem; border-radius:8px; cursor:pointer;
  transition: background var(--dur-s) var(--ease);
}
.zmap-chip[hidden]{ display:none; }
.zmap-chip:hover, .zmap-chip.is-active{ background: var(--c-grey-light); }
.zmap-chip .dotm{ width:9px; height:9px; border-radius:50%; flex:none; }
.zmap-group-more{
  display:flex; align-items:center; gap:.4rem; width:100%; text-align:left;
  background:none; border:none; font-family: var(--f-body); font-weight:600; font-size:.8rem;
  color: var(--c-blue); padding:.4rem .4rem; cursor:pointer; border-radius:8px;
  transition: background var(--dur-s) var(--ease);
}
.zmap-group-more:hover{ background: var(--c-grey-light); }
.zmap-group-more svg{ width:12px; height:12px; transition: transform var(--dur-s) var(--ease); }
.zmap-group.is-expanded .zmap-group-more svg{ transform: rotate(180deg); }

/* Marqueur "intervention" — piste D ("double halo doux") : un petit point
   plein et fixe, et deux anneaux fins qui se détachent en alternance (jamais
   synchronisés) plutôt qu'un pulse uniforme — rythme moins mécanique/répétitif
   quand plusieurs points sont proches. Positions volontairement approximatives
   (pas une adresse précise), d'où l'absence d'épingle nommée en permanence.
   ⚠️ display:block est nécessaire : .zmap-dot est un <span> (display:inline
   par défaut), et width/height ne s'appliquent jamais à un élément inline
   non remplacé — sans cette ligne, le point s'effondre à 0×0 et seul un
   carré de repli (icône par défaut de Leaflet) reste visible. Bug réel
   constaté (points affichés en petits carrés blancs plutôt qu'en cercles). */
.zmap-dot{
  position:relative; display:block; width:14px; height:14px; cursor:pointer;
}
.zmap-dot::before{
  content:""; position:absolute; inset:0; border-radius:50%; z-index:2;
  background: var(--zmap-dot-color, var(--c-blue));
  box-shadow: 0 1px 4px rgba(19,34,56,.45);
  transform-origin:center;
  transition: transform var(--dur-s) var(--ease);
}
.zmap-dot.is-hi::before{ transform: scale(1.4); }
.zmap-dot-ring{
  position:absolute; inset:-4px; border-radius:50%;
  border:1px solid var(--zmap-dot-color, var(--c-blue));
}
.zmap-dot-ring--1{ animation: zmapHaloOut 3.6s ease-out infinite; }
.zmap-dot-ring--2{ animation: zmapHaloOut 3.6s ease-out infinite 1.8s; }
@keyframes zmapHaloOut{
  0%{ transform:scale(.5); opacity:.6; }
  100%{ transform:scale(2.3); opacity:0; }
}
@media (prefers-reduced-motion: reduce){ .zmap-dot-ring{ animation:none; opacity:0; } }

/* Variante "siège" — un seul point, plus gros, immobile (pas d'anneaux) :
   se distingue délibérément des points d'intervention plutôt que de s'y
   fondre. */
.zmap-dot--hq{ width:26px; height:26px; }
.zmap-dot--hq::before{ box-shadow: 0 0 0 3px rgba(255,255,255,.9), 0 3px 10px rgba(19,34,56,.5); }
.zmap-dot--hq .zmap-dot-ring{ display:none; }

/* Mode sombre du fond de carte : inversion CSS des tuiles OpenStreetMap
   gratuites plutôt qu'un jeu de tuiles sombres dédié (voir main.js pour le
   choix). hue-rotate ramène l'eau vers du bleu plutôt que l'orange obtenu
   par un simple invert(). Appliqué uniquement au calque des tuiles
   (Leaflet tilePane), jamais aux marqueurs/contours par-dessus. */
.zmap-tiles-dark{
  filter: invert(100%) hue-rotate(180deg) brightness(95%) contrast(90%);
}

/* Leaflet ajoute sa propre attribution/contrôles ; on les fait juste
   correspondre au style du site plutôt que le thème par défaut brut. En
   mode sombre, les boutons +/- blancs par défaut de Leaflet sont presque
   invisibles sur le reste de l'habillage sombre — réhabillage complet. */
.leaflet-control-zoom a{ font-family: var(--f-title); color: var(--c-heading) !important; }
.leaflet-popup-content{ font-family: var(--f-body); font-size:.86rem; }
.leaflet-popup-content strong{ font-family: var(--f-title); color: var(--c-heading); }
:root[data-theme="dark"] .leaflet-control-zoom a{
  background: var(--c-white) !important; color: var(--c-heading) !important;
  border-color: var(--c-border) !important;
}
:root[data-theme="dark"] .leaflet-control-zoom a:hover{ background: var(--c-grey-light) !important; }
:root[data-theme="dark"] .leaflet-control-attribution{
  background: rgba(19,34,56,.75) !important; color: var(--c-text-soft) !important;
}
:root[data-theme="dark"] .leaflet-control-attribution a{ color: var(--c-text) !important; }
:root[data-theme="dark"] .leaflet-popup-content-wrapper,
:root[data-theme="dark"] .leaflet-popup-tip{ background: var(--c-white) !important; color: var(--c-text) !important; }
:root[data-theme="dark"] .leaflet-tooltip{
  background: var(--c-navy) !important; color:#fff !important; border:none !important;
}
:root[data-theme="dark"] .leaflet-tooltip-top:before{ border-top-color: var(--c-navy) !important; }

/* =========================================================================
   FAQ ACCORDION
   ========================================================================= */
.faq-list{ border-top:1px solid var(--c-border); }
.faq-item{ border-bottom:1px solid var(--c-border); }
.faq-q{
  width:100%; display:flex; align-items:center; justify-content:space-between; gap:1rem;
  background:none; border:none; text-align:left; cursor:pointer;
  padding: 1.3rem 0; font-family: var(--f-title); font-weight:700; color: var(--c-heading); font-size:1.02rem;
}
.faq-q .faq-icon{
  flex:none; width:30px; height:30px; border-radius:50%; background: var(--c-grey-light);
  color: var(--c-blue); display:flex; align-items:center; justify-content:center;
  transition: transform var(--dur-s) var(--ease), background var(--dur-s) var(--ease), color var(--dur-s) var(--ease);
}
.faq-q[aria-expanded="true"] .faq-icon{ transform: rotate(45deg); background: var(--c-orange); color:#fff; }
.faq-a{
  overflow:hidden; max-height:0; transition: max-height var(--dur-m) var(--ease);
}
.faq-a-inner{ padding-bottom: 1.4rem; color: var(--c-text-soft); font-size:.96rem; max-width: 68ch; }

/* =========================================================================
   BLOC ANGLAIS
   ========================================================================= */
.en-block{
  border-radius: var(--radius-l);
  padding: 2.6rem;
  background: linear-gradient(135deg, var(--c-navy), var(--c-blue-darker));
  color:#fff;
  display:grid; grid-template-columns: 1fr auto; gap:1.6rem; align-items:center;
}
@media (max-width:720px){ .en-block{ grid-template-columns:1fr; text-align:center; } }
.en-block h2{ color:#fff; }
.en-block p{ color: var(--c-text-on-dark-soft); margin-bottom:0; }

/* =========================================================================
   CTA FINAL
   ========================================================================= */
.cta-final{
  border-radius: var(--radius-l);
  padding: 3rem;
  background: radial-gradient(120% 140% at 20% 0%, rgba(252,113,0,.28), transparent 60%), var(--c-navy);
  color:#fff; text-align:center;
}
.cta-final h2, .cta-final h3{ color:#fff; }
.cta-final .btn-group{ justify-content:center; }
.contact-strip{
  display:grid; grid-template-columns: repeat(3,1fr); gap:1rem; margin-top:2.4rem;
}
@media (max-width:760px){ .contact-strip{ grid-template-columns:1fr; } }
.contact-strip--split{ grid-template-columns:repeat(2,1fr); }
@media (max-width:760px){ .contact-strip--split{ grid-template-columns:1fr; } }
.contact-strip a{
  display:flex; flex-direction:column; gap:.3rem; align-items:center;
  background: rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.18);
  border-radius: var(--radius-m); padding:1.3rem; color:#fff;
  transition: background var(--dur-s) var(--ease), transform var(--dur-s) var(--ease);
}
.contact-strip a:hover{ background: rgba(255,255,255,.14); transform: translateY(-4px); }
.contact-strip svg{ width:26px; height:26px; color: var(--c-orange-light); }
.contact-strip strong{ font-family: var(--f-title); font-size:.95rem; }
.contact-strip span{ font-size:.82rem; color: var(--c-text-on-dark-soft); }
.contact-strip-item{
  display:flex; flex-direction:column; gap:.3rem; align-items:center; text-align:center;
  background: rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.18);
  border-radius: var(--radius-m); padding:1.3rem; color:#fff;
}
.contact-strip-item > svg{ width:26px; height:26px; color: var(--c-orange-light); }
.contact-strip-item .phone-reveal{ align-items:center; margin-top:.15rem; }

/* =========================================================================
   NUMÉRO DE TÉLÉPHONE MASQUÉ (protection anti-collecte automatisée)
   ========================================================================= */
.phone-reveal{ display:inline-flex; flex-direction:column; gap:.4rem; align-items:flex-start; }
.phone-reveal-trigger{
  display:inline-flex; align-items:center; gap:.5em;
  background:none; border:1.5px dashed var(--c-border); border-radius:999px;
  padding:.55em 1.1em; font-family: var(--f-title); font-weight:700; font-size:.88rem;
  color: var(--c-blue); cursor:pointer;
  transition: border-color var(--dur-s) var(--ease), background var(--dur-s) var(--ease);
}
.phone-reveal-trigger:hover{ border-color: var(--c-blue); background: rgba(38,96,189,.07); }
.phone-reveal-trigger svg{ width:15px; height:15px; flex:none; }
.phone-reveal-number{
  display:inline-flex; align-items:center; gap:.5em;
  font-family: var(--f-title); font-weight:800; font-size:1.05rem; color: inherit;
}
.phone-reveal-number svg{ width:16px; height:16px; color: var(--c-orange); flex:none; }
.phone-reveal-trigger[hidden], .phone-reveal-number[hidden]{ display:none !important; }
.phone-reveal-note{ font-size:.72rem; line-height:1.4; color: var(--c-text-soft); max-width:30ch; }

.on-dark .phone-reveal-trigger, .site-footer .phone-reveal-trigger, .cta-final .phone-reveal-trigger{
  color:#fff; border-color: rgba(255,255,255,.35);
}
.on-dark .phone-reveal-trigger:hover, .site-footer .phone-reveal-trigger:hover, .cta-final .phone-reveal-trigger:hover{
  border-color:#fff; background: rgba(255,255,255,.12);
}
:root[data-theme="dark"] .contact-method .phone-reveal-trigger{
  color: var(--c-orange-light); border-color: var(--c-orange-light);
}
:root[data-theme="dark"] .contact-method .phone-reveal-trigger:hover{
  border-color: var(--c-orange-light); background: rgba(255,142,22,.14);
}
.on-dark .phone-reveal-note, .site-footer .phone-reveal-note, .cta-final .phone-reveal-note{ color: var(--c-text-on-dark-soft); }
.on-dark .phone-reveal-number, .site-footer .phone-reveal-number, .cta-final .phone-reveal-number{ color:#fff; }
.contact-strip-item .phone-reveal-note{ text-align:center; }

/* Variante compacte pour le pied de page */
.phone-reveal--compact .phone-reveal-trigger{
  padding:.35em .8em; font-size:.82rem; border-style:solid;
}
.phone-reveal--compact .phone-reveal-note{ font-size:.7rem; }

/* Variante où un bouton "Appeler" existant (habillé .btn : header, CTA,
   barre mobile fixe) sert lui-même de coque visuelle pour la révélation :
   le déclencheur et le lien révélé n'ajoutent aucun style propre et
   héritent entièrement de l'apparence .btn portée par l'élément englobant,
   pour qu'aucun saut visuel n'ait lieu au clic.
   Le padding visuel du bouton doit être porté par le déclencheur/lien
   cliquable lui-même (ci-dessous), pas par cette coque .btn englobante :
   sinon la zone réellement cliquable se limite au texte/icône centré
   (width/height:100% ne remplit que la boîte de CONTENU du parent, pas son
   padding), et cliquer près du bord visible du bouton ne fait rien. */
.phone-reveal--btn{ flex-direction:row; align-items:center; gap:0; }
/* !important nécessaire : .mobile-cta-bar .btn (et d'éventuelles autres
   règles contextuelles similaires) a une spécificité plus élevée que
   .phone-reveal--btn seul et réintroduirait sinon un padding sur cette
   coque, recréant la zone morte que ce correctif élimine. */
.btn.phone-reveal--btn{ padding:0 !important; }
.phone-reveal--btn .phone-reveal-trigger,
.phone-reveal--btn .phone-reveal-number{
  display:inline-flex; align-items:center; justify-content:center; gap:.6em;
  width:100%; height:100%; margin:0; background:none; border:0;
  color:inherit; font:inherit; cursor:pointer;
  padding: .95em 1.7em;
}
.phone-reveal--btn.btn-sm .phone-reveal-trigger,
.phone-reveal--btn.btn-sm .phone-reveal-number{
  padding: .6em 1.1em;
}
.phone-reveal--btn.btn-icon .phone-reveal-trigger,
.phone-reveal--btn.btn-icon .phone-reveal-number{
  padding: 0;
}

/* =========================================================================
   FOOTER
   ========================================================================= */
.site-footer{ background: var(--c-navy); color: var(--c-text-on-dark-soft); padding-block: var(--gap-l) var(--gap-m); }
.footer-grid{
  display:grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 2.4rem;
  padding-bottom: 2.4rem; border-bottom: 1px solid rgba(255,255,255,.12);
}
@media (max-width: 860px){ .footer-grid{ grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px){ .footer-grid{ grid-template-columns: 1fr; } }
.footer-brand{ text-align:center; }
.footer-logo{ display:flex; justify-content:center; width:100%; margin-bottom:1.2rem; }
.footer-brand img{ display:block; height:60px; width:auto; max-width:none; margin:0 auto; }
.footer-brand p{ margin-inline:auto; }
.footer-brand p{ font-size:.9rem; max-width:32ch; }
.footer-col h3{ color:#fff; font-size:.92rem; text-transform:uppercase; letter-spacing:.08em; margin-bottom:1rem; }
.footer-col ul{ list-style:none; padding:0; margin:0; display:flex; flex-direction:column; gap:.6rem; }
.footer-col a{ color: var(--c-text-on-dark-soft); font-size:.92rem; }
.footer-col a:hover{ color:#fff; }
.footer-bottom{
  display:flex; flex-wrap:wrap; justify-content:space-between; gap:1rem;
  padding-top: 1.6rem; font-size:.82rem;
}
.footer-bottom a{ color: var(--c-text-on-dark-soft); }
.cg-footer-link-btn{
  background:none; border:none; padding:0; margin:0; font:inherit; color: var(--c-text-on-dark-soft);
  cursor:pointer;
}
.cg-footer-link-btn:hover{ color:#fff; }
.footer-socials{ display:flex; gap:.7rem; }
.footer-socials a{
  width:36px; height:36px; border-radius:50%; background: rgba(255,255,255,.08);
  display:flex; align-items:center; justify-content:center; color:#fff;
}
.footer-socials svg{ width:16px; height:16px; }

/* =========================================================================
   PAGE INTÉRIEURE — bandeau titre
   ========================================================================= */
.page-hero{
  padding-block: 3.4rem 3rem;
  background: linear-gradient(160deg, var(--c-navy), var(--c-blue-darker));
  color:#fff;
}
.breadcrumb{ font-size:.85rem; color: var(--c-text-on-dark-soft); margin-bottom:1rem; }
.breadcrumb a{ color: var(--c-text-on-dark-soft); }
.breadcrumb a:hover{ color:#fff; }
.page-hero h1{ color:#fff; max-width: 24ch; }
.page-hero-subtitle{ color:#fff; font-size:1.35rem; font-weight:600; margin:.5rem 0 1rem; }
.page-hero .lead{ color: var(--c-text-on-dark-soft); max-width:62ch; font-size:1.08rem; }
/* Tableau posé sur le bandeau de page (voir zones-intervention.html) :
   .page-hero est toujours sombre, quel que soit le thème du site (comme le
   reste de son contenu, déjà en blanc/clair en dur) — le tableau doit donc
   suivre la même règle plutôt que ses couleurs par défaut pensées pour un
   fond clair. */
.page-hero .simple-table th, .page-hero .simple-table td{
  border-bottom-color: rgba(255,255,255,.18); color: var(--c-text-on-dark);
}
.page-hero .simple-table th{ background: rgba(255,255,255,.08); }
.page-hero .simple-table .placeholder-tag{ background: rgba(252,113,0,.22); color:#ffb066; }

.inclu-grid{ display:grid; grid-template-columns:1fr 1fr; gap:1.6rem; }
@media (max-width:760px){ .inclu-grid{ grid-template-columns:1fr; } }
.inclu-card{ border-radius: var(--radius-m); padding:1.6rem 1.7rem; }
.inclu-card.is-in{ background: rgba(38,96,189,.06); border:1px solid rgba(38,96,189,.18); }
.inclu-card.is-out{ background: rgba(252,113,0,.06); border:1px solid rgba(252,113,0,.22); }
.inclu-card h3{ display:flex; align-items:center; gap:.5em; font-size:1.05rem; }
.inclu-card h3 svg{ width:1.2em; height:1.2em; }
.inclu-card.is-in h3 svg{ color: var(--c-blue); }
.inclu-card.is-out h3 svg{ color: var(--c-orange); }
.inclu-card ul{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:.6rem; }
.inclu-card li{ display:flex; gap:.6em; font-size:.94rem; color: var(--c-text-soft); }
.inclu-card li svg{ flex:none; width:1.1em; height:1.1em; margin-top:.15em; }
.inclu-card.is-in li svg{ color: var(--c-blue); }
.inclu-card.is-out li svg{ color: var(--c-orange); }

.vocab-note{
  background: var(--c-grey-light); border-left:4px solid var(--c-orange);
  border-radius: 0 var(--radius-s) var(--radius-s) 0; padding: 1.2rem 1.5rem; font-size:.94rem; color: var(--c-text-soft);
}

/* =========================================================================
   FORMULAIRE DEVIS
   ========================================================================= */
.form-card{
  background: var(--c-white); border:1px solid var(--c-border); border-radius: var(--radius-l);
  padding: 2.2rem; box-shadow: var(--shadow-m);
}

/* Formulaire de devis, présenté comme une carte posée sur un fond sombre,
   plutôt que comme un simple bloc dans la page (page contact-devis.html /
   en/contact.html — la section id="devis" tout entière). */
.devis-hero{
  /* Même dégradé que .page-hero (bandeau tout en haut de la page) — pour
     que ce bleu ne fasse pas dépareillé avec le reste du site. */
  background: linear-gradient(160deg, var(--c-navy), var(--c-blue-darker));
}
.devis-wrap{ max-width:640px; margin:0 auto; }
.devis-wrap .section-head{ text-align:center; }
.devis-wrap .section-head .eyebrow{ justify-content:center; }
.devis-wrap .section-head h2{ color:#fff; font-size: clamp(1.5rem, 2.7vw, 1.95rem); white-space:nowrap; }
@media (max-width:480px){ .devis-wrap .section-head h2{ white-space:normal; } }
.devis-wrap .section-head p{ color: var(--c-text-on-dark-soft) !important; }
/* Le message de résultat (#form-message) se retrouve désormais sur le fond
   sombre du bandeau (autrefois sur fond blanc) — les couleurs pastel
   d'origine, pensées pour un fond clair, y sont quasi illisibles. */
.devis-wrap .form-msg{ background: rgba(255,255,255,.08); backdrop-filter: blur(4px); }
.devis-wrap .form-msg.success{ background: rgba(46,196,120,.18); color:#c9ffe1; border-color: rgba(46,196,120,.55); }
.devis-wrap .form-msg.error{ background: rgba(255,120,120,.16); color:#ffdcdc; border-color: rgba(255,120,120,.5); }
.devis-wrap .form-card{
  position:relative; overflow:hidden; border:none;
  box-shadow: 0 30px 60px rgba(0,0,0,.35), 0 4px 14px rgba(0,0,0,.2);
  /* Les CTA "Devis"/"Remplir le formulaire" pointent directement ici
     (#devis-form) plutôt que sur toute la section #devis — signalé le
     2026-09-26 : sur mobile, le bloc "3 étapes" + délai de réponse au-dessus
     du formulaire remplissait tout l'écran une fois le clic effectué,
     donnant l'impression d'un cul-de-sac (le vrai formulaire semblait
     introuvable, alors qu'il suffisait de continuer à défaire défiler).
     scroll-margin-top évite que l'en-tête collant du site ne rogne le haut
     du formulaire au moment du saut. */
  scroll-margin-top:6rem;
}
.devis-wrap .form-card::before{
  content:""; position:absolute; top:0; left:0; right:0; height:5px;
  background: linear-gradient(90deg, var(--c-orange), var(--c-orange-light));
}
.devis-next-steps{
  display:flex; justify-content:center; gap:2.2rem; flex-wrap:wrap;
  margin-top:2rem;
}
.devis-next-steps .next-step{ text-align:center; max-width:150px; }
.devis-next-steps .ico{
  width:40px; height:40px; border-radius:50%; background:rgba(255,255,255,.08);
  border:1px solid rgba(255,255,255,.18); color: var(--c-orange-light);
  font-family: var(--f-title); font-weight:800;
  display:flex; align-items:center; justify-content:center; margin:0 auto .7rem;
}
.devis-next-steps p{ color: var(--c-text-on-dark-soft); font-size:.85rem; line-height:1.5; margin:0; }
/* Enveloppe autour de la note statique + de la statistique live, plutôt que
   des marges sur chacune séparément : garantit un espacement constant avant
   la carte du formulaire, que la statistique live ait pu se charger ou non
   (élément [hidden] tant que le CRM n'a pas encore assez d'historique). */
.devis-response-wrap{ margin: 1.6rem 0 2.2rem; text-align:center; }
.devis-response-note{
  color: var(--c-text-on-dark-soft); font-size:.85rem; margin:0 0 .5rem;
}
.devis-live-response-time{
  display:inline-flex; align-items:center; gap:.55em; margin:0;
  font-size:.85rem; font-weight:600; color:#c9ffe1;
}
.devis-live-response-time .live-dot{
  width:8px; height:8px; border-radius:50%; background:#2ecc71; flex:none;
  animation: cgLiveDotPulse 1.8s ease-out infinite;
}
@keyframes cgLiveDotPulse{
  0%{ box-shadow:0 0 0 0 rgba(46,204,113,.55); }
  70%{ box-shadow:0 0 0 8px rgba(46,204,113,0); }
  100%{ box-shadow:0 0 0 0 rgba(46,204,113,0); }
}
@media (prefers-reduced-motion: reduce){
  .devis-live-response-time .live-dot{ animation:none; }
}

/* Formulaire en étapes ("+" un pas à la fois plutôt qu'un long formulaire à
   faire défiler) : chaque .form-step est masqué/affiché en JS, un seul
   visible à la fois. Les boutons "Étape suivante" ne sont jamais de type
   submit — la validation HTML5 de l'étape en cours est vérifiée à la main
   au clic (voir main.js), pour ne jamais laisser un champ obligatoire d'une
   étape encore masquée bloquer silencieusement l'envoi final. */
.wizard-progress{ display:flex; align-items:center; gap:.9rem; margin-bottom:1rem; flex-wrap:wrap; }
.wizard-dots{ display:flex; gap:.45rem; }
.wizard-dot{
  width:8px; height:8px; border-radius:50%; background: var(--c-border);
  transition: background var(--dur-s) var(--ease), transform var(--dur-s) var(--ease);
}
.wizard-dot.is-active{ background: var(--c-orange); transform: scale(1.35); }
.wizard-dot.is-done{ background: var(--c-blue); }
.wizard-step-label{
  font-family: var(--f-title); font-weight:700; font-size:.78rem; color: var(--c-heading);
  text-transform:uppercase; letter-spacing:.05em;
}
.wizard-nav{ display:flex; justify-content:space-between; gap:1rem; margin-top:1.8rem; }
.wizard-nav .btn{ flex:1; }
.wizard-nav .btn-secondary{ flex:0 0 auto; }
@media (max-width:520px){
  .wizard-nav{ flex-direction:column-reverse; }
  .wizard-nav .btn{ width:100%; }
}
.field{ margin-bottom: 1.3rem; }
.field label{
  display:block; font-weight:700; font-size:.9rem; margin-bottom:.4rem; color: var(--c-heading);
}
.field .hint{ font-weight:400; color: var(--c-text-soft); font-size:.82rem; }
/* Notes sous les boutons de chaque étape du formulaire de devis (astérisque
   + "montant non calculé automatiquement") — .hint hors de tout .field ici,
   la règle ci-dessus ne s'appliquait donc pas : elles s'affichaient à la
   taille de texte normale, signalé trop grand le 2026-09-20. */
.wizard-nav ~ .hint{ font-size:.82rem; }
.field input[type=text], .field input[type=email], .field input[type=tel], .field input[type=date], .field input[type=number],
.field select, .field textarea{
  width:100%; padding:.85em 1em; border:1.5px solid var(--c-border); border-radius: var(--radius-s);
  background: var(--c-input-bg); color: var(--c-text); box-shadow: 0 3px 8px rgba(19,34,56,.16);
  transition: border-color var(--dur-s) var(--ease), box-shadow var(--dur-s) var(--ease);
}
.field input:focus, .field select:focus, .field textarea:focus{
  border-color: var(--c-blue); box-shadow: 0 0 0 4px rgba(38,96,189,.14); outline:none;
}
.field textarea{ min-height:110px; resize:vertical; }
.field-row{ display:grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap:1.2rem; }
@media (max-width:640px){ .field-row{ grid-template-columns:1fr; } }

/* Champs secondaires repliés par défaut ("+" pour dérouler) : évite que le
   formulaire paraisse plus long/complexe qu'il ne l'est vraiment pour les
   champs facultatifs peu utilisés. Repose sur le flux normal du document
   (pas de hauteur fixe) : un champ replié n'occupe que la hauteur de son
   bouton, l'espacement entre champs reste celui de .field quel que soit
   l'état ouvert/fermé. */
.field-toggle-btn{
  display:flex; align-items:center; gap:.6em; width:100%; text-align:left;
  background:none; border:none; padding:0; margin:0; font: inherit; font-weight:700;
  font-size:.9rem; color: var(--c-heading); cursor:pointer;
}
.field-toggle-btn .hint{ font-weight:400; }
.field-toggle-icon{
  display:inline-flex; align-items:center; justify-content:center;
  width:22px; height:22px; border-radius:50%; border:1.5px solid var(--c-border);
  font-size:1.05rem; line-height:1; flex:none; color: var(--c-blue);
  transition: transform var(--dur-s) var(--ease), border-color var(--dur-s) var(--ease);
}
.field-toggle-btn:hover .field-toggle-icon{ border-color: var(--c-blue); }
.field-toggle-btn[aria-expanded="true"] .field-toggle-icon{ transform: rotate(45deg); border-color: var(--c-blue); }
.field-toggle-body{ margin-top:.6rem; }

/* Champs marqués * en rouge, partout dans le formulaire, avec une légende
   explicite en tête pour lever toute ambiguïté. */
.req-star{ color:#c0392b; }
.required-legend{
  font-weight:600; font-size:.85rem; color: var(--c-text-soft); margin:0 0 1.1rem;
}

/* Zones ou pièces concernées / Risques : mêmes proportions qu'un champ texte
   simple ("Accès") plutôt que la hauteur par défaut d'un textarea — reste
   redimensionnable et multi-lignes (resize:vertical hérité de .field
   textarea), seule la hauteur de départ change. */
.field textarea.field-compact{ min-height:auto; }

/* "Informations / Éléments à conserver / Détails" : la zone de texte
   principale du formulaire, volontairement plus grande pour encourager un
   vrai niveau de détail. */
.field textarea.field-primary{ min-height:170px; }

/* Suggestions d'adresse (voir assets/js/main.js, autocomplete Adresse ligne 1
   via l'API adresse.data.gouv.fr, gratuite et sans clé). */
.autocomplete-wrap{ position:relative; }
.autocomplete-suggestions{
  position:absolute; z-index:20; top:100%; left:0; right:0; margin:.3rem 0 0;
  padding:.3rem; list-style:none; background: var(--c-white); border:1.5px solid var(--c-border);
  border-radius: var(--radius-s); box-shadow: var(--shadow-m); max-height:220px; overflow-y:auto;
}
.autocomplete-suggestions[hidden]{ display:none; }
.autocomplete-suggestions li{
  padding:.55em .7em; border-radius:6px; cursor:pointer; font-size:.92rem; color: var(--c-heading);
}
.autocomplete-suggestions li:hover, .autocomplete-suggestions li.is-active{ background: rgba(38,96,189,.1); }

/* Bouton "Sélect. fichiers" personnalisé (l'input natif est masqué en
   visually-hidden) + texte de statut qu'on contrôle nous-même, plutôt que
   de dépendre du "Aucun fichier choisi" du navigateur qui ne peut pas
   refléter une liste gérée en JS. */
.cg-file-input-row{ display:flex; align-items:center; flex-wrap:wrap; gap:.8rem; }
.cg-file-btn{
  display:inline-flex; align-items:center; margin:0; font-weight:600; font-size:.88rem;
  color: var(--c-heading); background: var(--c-input-bg); border:1.5px solid var(--c-orange);
  border-radius: var(--radius-s); padding:.6em 1.1em; cursor:pointer;
  transition: border-color var(--dur-s) var(--ease), background var(--dur-s) var(--ease);
}
.cg-file-btn:hover{ border-color: var(--c-blue); background: var(--c-white); }
.cg-file-btn:has(+ input:focus-visible){ outline: 2px solid var(--c-blue); outline-offset:2px; }

/* Zone de dépôt des photos (clic ou glisser-déposer) — remplace le petit
   bouton "Sélect. photos" ci-dessus, demandé le 2026-09-25 : plus visible,
   plus facile à viser, et gère le glisser-déposer en plus du clic. Le
   <label> entoure directement l'input (comme .cg-file-btn ci-dessus) : un
   clic n'importe où dans le rectangle ouvre le sélecteur de fichiers, sans
   JS pour cette partie-là. */
/* .field label{display:block;...} (plus haut dans ce fichier) est plus
   spécifique qu'une simple classe et écrasait silencieusement le
   display:flex ci-dessous — d'où le texte qui ne s'empilait/centrait pas
   (signalé le 2026-09-25). Sélecteur renforcé (.field label.cg-dropzone)
   pour gagner explicitement, plutôt que !important. */
.field label.cg-dropzone{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:.6rem; text-align:center; cursor:pointer; margin:0;
  border:2px dashed var(--c-orange); border-radius: var(--radius-m);
  background: var(--c-input-bg); padding:2.4rem 1.5rem;
  transition: border-color var(--dur-s) var(--ease), background var(--dur-s) var(--ease);
}
.cg-dropzone:hover{ border-color: var(--c-blue); background: var(--c-white); }
.cg-dropzone:focus-within{ outline: 2px solid var(--c-blue); outline-offset:2px; }
.cg-dropzone.is-dragover{ border-style:solid; border-color: var(--c-blue); background: var(--c-white); }
.cg-dropzone-icon{
  width:52px; height:52px; border-radius:50%; flex:none;
  display:flex; align-items:center; justify-content:center;
  background: rgba(252,113,0,.12); color: var(--c-orange);
}
.cg-dropzone-text{ font-weight:700; color: var(--c-heading); font-size:.98rem; }
.cg-dropzone-hint{ font-size:.82rem; font-weight:400; color: var(--c-text-soft); max-width:42ch; }
.field .cg-photo-error{
  color:#8a2222; font-weight:600; background: rgba(220,60,60,.08);
  border:1px solid rgba(220,60,60,.3); border-radius: var(--radius-s); padding:.6em .9em;
}
.cg-wizard-error{
  color:#8a2222; font-weight:600; background: rgba(220,60,60,.08);
  border:1px solid rgba(220,60,60,.3); border-radius: var(--radius-s); padding:.6em .9em;
  margin-top:.7rem;
}

/* Notice transitoire sous un champ ("nombre maximal atteint", "caractère non
   autorisé") — n'empêche jamais la saisie, disparaît d'elle-même après
   quelques secondes (voir cgSetupFieldGuards dans main.js). */
.cg-field-notice{
  display:block; margin-top:.35rem; font-size:.78rem; font-weight:600;
  color:#7a4600; background: rgba(252,113,0,.1);
  border:1px solid rgba(252,113,0,.35); border-radius: var(--radius-s);
  padding:.4em .7em;
}
.cg-field-notice[hidden]{ display:none; }

/* Traitement des photos en cours (conversion/compression) — bien visible
   pour qu'on comprenne qu'il faut attendre avant d'envoyer le formulaire. */
.cg-photo-processing{
  display:flex; align-items:flex-start; gap:.6em;
  color:#7a4600; font-weight:600; background: rgba(252,113,0,.1);
  border:1px solid rgba(252,113,0,.35); border-radius: var(--radius-s);
  padding:.6em .9em; margin-top:.6rem;
}
.cg-photo-spinner{
  width:1.1em; height:1.1em; flex:none; margin-top:.15em; border-radius:50%;
  border:2px solid rgba(252,113,0,.3); border-top-color: var(--c-orange);
  animation: cg-spin .8s linear infinite;
}
@keyframes cg-spin{ to{ transform:rotate(360deg); } }
/* display:flex ci-dessus l'emporte sur la règle navigateur [hidden]{display:none}
   (une règle d'auteur bat toujours une règle par défaut du navigateur) — sans
   ceci, le cadre restait visible en permanence malgré l'attribut hidden. */
.cg-photo-processing[hidden]{ display:none; }

/* Vignettes des photos sélectionnées, avec bouton de suppression */
.cg-photo-preview-grid{
  display:flex; flex-wrap:wrap; gap:.6rem; margin-top:.7rem;
}
.cg-photo-preview-grid:empty{ margin-top:0; }
.cg-photo-thumb-wrap{
  position:relative; width:84px; height:84px; border-radius: var(--radius-s);
  overflow:hidden; border:1.5px solid var(--c-border); background:#f2f4f7; flex:none;
}
.cg-photo-thumb-wrap img{ width:100%; height:100%; object-fit:cover; display:block; }
.cg-photo-thumb-remove{
  position:absolute; top:3px; right:3px; width:22px; height:22px; border-radius:50%;
  border:none; background:rgba(19,34,56,.72); color:#fff; font-size:16px; line-height:1;
  cursor:pointer; display:flex; align-items:center; justify-content:center;
  transition: background var(--dur-s) var(--ease);
}
.cg-photo-thumb-remove:hover, .cg-photo-thumb-remove:focus-visible{ background: var(--c-orange); outline:none; }

.choice-group{ display:flex; flex-wrap:wrap; gap:.6rem; }
.choice-group input{ position:absolute; opacity:0; width:1px; height:1px; }
.choice-group label{
  margin:0; font-weight:600; font-size:.88rem; color: var(--c-heading);
  padding:.6em 1em; border:1.5px solid var(--c-border); border-radius:999px; cursor:pointer;
  transition: all var(--dur-s) var(--ease);
}
.choice-group input:checked + label{ background: var(--c-blue); border-color: var(--c-blue); color:#fff; }
.choice-group input:focus-visible + label{ outline: 3px solid var(--c-focus); outline-offset:2px; }

.consent{ display:flex; gap:.7em; align-items:flex-start; font-size:.88rem; color: var(--c-text-soft); }
.consent input{ margin-top:.3em; }

.form-msg{
  border-radius: var(--radius-s); padding:1rem 1.2rem; font-size:.92rem; margin-bottom:1.2rem;
  display:flex; gap:.6em; align-items:flex-start;
}
.form-msg.success{ background: rgba(28,138,83,.1); color:#0f5c37; border:1px solid rgba(28,138,83,.3); }
.form-msg.error{ background: rgba(220,60,60,.08); color:#8a2222; border:1px solid rgba(220,60,60,.3); }
.form-msg svg{ width:1.3em; height:1.3em; flex:none; margin-top:.05em; }

.conditional-field{ display:none; }
.conditional-field.is-active{ display:block; }

/* ------------------------------------------------------------------
   Overlay de chargement à l'envoi du formulaire — l'upload de photos
   peut prendre plusieurs secondes en ligne : sans retour visuel clair,
   le client peut croire que la page a planté et fermer/renvoyer.
   ------------------------------------------------------------------ */
.form-loading-overlay{
  position: fixed; inset: 0; z-index: 999; display:flex; align-items:center; justify-content:center;
  background: rgba(19,34,56,.72); backdrop-filter: blur(3px); padding:1.5rem;
}
.form-loading-overlay[hidden]{ display:none; }
.form-loading-box{
  background: var(--c-white); border-radius: var(--radius-m); box-shadow: var(--shadow-l);
  padding:2.2rem 2rem; max-width:360px; width:100%; text-align:center;
}
.form-loading-spinner{
  width:48px; height:48px; margin:0 auto 1.2rem; border-radius:50%;
  border:4px solid rgba(38,96,189,.15); border-top-color: var(--c-blue);
  animation: cg-spin 0.8s linear infinite;
}
@keyframes cg-spin{ to{ transform: rotate(360deg); } }
.form-loading-title{ font-weight:700; color: var(--c-heading); margin:0 0 .5rem; font-size:1.05rem; }
.form-loading-hint{ color: var(--c-text-soft); font-size:.88rem; margin:0; }

.cg-confirm-overlay{
  position: fixed; inset: 0; z-index: 999; display:flex; align-items:center; justify-content:center;
  background: rgba(19,34,56,.72); backdrop-filter: blur(3px); padding:1.5rem;
}
.cg-confirm-overlay[hidden]{ display:none; }
.cg-confirm-box{
  background: var(--c-white); border-radius: var(--radius-m); box-shadow: var(--shadow-l);
  padding:2rem; max-width:420px; width:100%; text-align:center;
}
.cg-confirm-title{ font-weight:700; color: var(--c-heading); margin:0 0 .6rem; font-size:1.02rem; }
.cg-confirm-hint{ color: var(--c-text-soft); font-size:.88rem; margin:0; }
.cg-confirm-actions{ display:flex; gap:.8rem; margin-top:1.4rem; justify-content:center; flex-wrap:wrap; }

/* =========================================================================
   POP-UP DE CHOIX DE LANGUE (première visite, ET à nouveau à chaque nouvelle
   version du site — voir main.js::cgInitLangPopup()) — même famille visuelle
   que .cg-confirm-overlay ci-dessus. Couleurs entièrement basées sur les
   tokens (--c-white, --c-heading...), donc déjà correctes qu'elle apparaisse
   en mode clair ou sombre (un visiteur déjà passé en sombre avant la
   prochaine mise en ligne du site la reverra en sombre) — pas de variante
   spécifique à écrire ici.
   ========================================================================= */
.cg-lang-popup-overlay{
  position: fixed; inset: 0; z-index: 999; display:flex; align-items:center; justify-content:center;
  background: rgba(19,34,56,.55); backdrop-filter: blur(3px); padding:1.5rem;
  opacity:0; transition: opacity var(--dur-m) var(--ease);
  /* Sur certains navigateurs mobiles, la fenêtre utilisée pour calculer
     position:fixed/inset:0 peut être plus grande que ce qui est réellement
     visible à l'écran (constaté le 2026-09-30 : window.innerWidth/Height
     bien supérieurs à la taille d'écran réelle). Sans défilement possible
     ICI, la partie basse de .cg-lang-popup-box tombe alors hors-écran et
     devient injoignable (seul un défilement de toute la PAGE la révèle,
     ce qui casse le caractère "fixe" de la fenêtre). overflow-y:auto
     garantit que le bouton reste toujours atteignable en défilant la
     fenêtre elle-même, quelle que soit la taille réelle disponible. */
  overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.cg-lang-popup-overlay.is-visible{ opacity:1; }
.cg-lang-popup-box{
  background: var(--c-white); border-radius: var(--radius-l); box-shadow: var(--shadow-l);
  padding:2.2rem 2rem; max-width:400px; width:100%; text-align:center;
  transform: translateY(12px) scale(.97); transition: transform var(--dur-m) var(--ease);
  margin: auto; /* centre horizontalement ET verticalement tout en restant
                   scrollable si le contenu ou la fenêtre disponible l'impose */
}
.cg-lang-popup-overlay.is-visible .cg-lang-popup-box{ transform: translateY(0) scale(1); }
.cg-lang-popup-icons{ display:flex; justify-content:center; gap:1rem; margin-bottom:1.1rem; }
.cg-lang-popup-icons span{ width:52px; height:52px; border-radius:50%; overflow:hidden; display:flex; align-items:center; justify-content:center; flex:none; background: var(--c-grey-light); }
.cg-lang-popup-icons svg{ width:28px; height:19px; border-radius:3px; }
.cg-lang-popup-title{ font-family: var(--f-title); font-weight:800; font-size:1.15rem; margin:0 0 .5rem; color: var(--c-heading); }
.cg-lang-popup-hint{ font-size:.86rem; color: var(--c-text-soft); margin:0 0 1.4rem; line-height:1.5; }
.cg-lang-popup-choices{ display:flex; gap:.8rem; }
.cg-lang-popup-choice{
  flex:1; display:flex; flex-direction:column; align-items:center; gap:.5rem;
  border:1.5px solid var(--c-border); border-radius: var(--radius-s); padding:1rem .6rem; background:none; cursor:pointer;
  font-family: var(--f-body); font-weight:600; font-size:.82rem; color: var(--c-heading);
  transition: border-color var(--dur-s) var(--ease), background var(--dur-s) var(--ease), transform var(--dur-s) var(--ease);
}
.cg-lang-popup-choice:hover{ border-color: var(--c-orange); transform: translateY(-2px); }
.cg-lang-popup-choice.is-current{ border-color: var(--c-orange-light); background: rgba(255,142,22,.08); }
.cg-lang-popup-choice svg{ width:26px; height:18px; border-radius:3px; }
.cg-lang-popup-skip{
  display:block; margin:1.1rem auto 0; font-size:.76rem; color: var(--c-text-soft); text-decoration:underline;
  cursor:pointer; background:none; border:none; font-family: var(--f-body); padding:0;
}
@media (prefers-reduced-motion: reduce){
  .cg-lang-popup-overlay, .cg-lang-popup-box{ transition:none; }
}

/* =========================================================================
   POP-UP DE PRÉFÉRENCE DE THÈME — tiroir discret ancré au bord droit
   (jamais en plein écran, contrairement à la pop-up de langue ci-dessus :
   voir main.js::cgInitThemeDrawer()). Affiché juste après la pop-up de
   langue (ou immédiatement si celle-ci n'a rien à demander), même
   mécanique de réapparition à chaque nouvelle version du site.
   ========================================================================= */
.cg-theme-drawer{
  position: fixed; top:50%; right:0; z-index: 998;
  transform: translate(110%, -50%);
  background: var(--c-white); border:1px solid var(--c-border); border-right:none;
  border-radius: var(--radius-m) 0 0 var(--radius-m); box-shadow: var(--shadow-l);
  padding:1.2rem 1.3rem 1.2rem 1.4rem; width:220px;
  transition: transform var(--dur-m) var(--ease);
}
.cg-theme-drawer.is-visible{ transform: translate(0,-50%); }
.cg-theme-drawer-close{
  position:absolute; top:.5rem; right:.6rem; width:24px; height:24px; border-radius:50%;
  display:flex; align-items:center; justify-content:center; color: var(--c-text-soft);
  background:none; border:none; cursor:pointer; font-size:1rem; line-height:1; padding:0;
}
.cg-theme-drawer-close:hover{ background: var(--c-grey-light); color: var(--c-text); }
.cg-theme-drawer-icon{
  width:36px; height:36px; border-radius:50%; background: rgba(255,142,22,.12);
  display:flex; align-items:center; justify-content:center; margin-bottom:.7rem;
}
.cg-theme-drawer-icon svg{ width:19px; height:19px; }
.cg-theme-drawer-text{ font-family: var(--f-title); font-size:.86rem; font-weight:700; color: var(--c-heading); margin:0 0 .35rem; line-height:1.4; }
.cg-theme-drawer-hint{ font-size:.74rem; color: var(--c-text-soft); margin:0 0 .8rem; line-height:1.45; }
.cg-theme-drawer-choices{ display:flex; gap:.5rem; }
.cg-theme-drawer-choice{
  flex:1; display:flex; align-items:center; justify-content:center; gap:.35em;
  font-family: var(--f-body); font-size:.78rem; font-weight:700; padding:.5em .5em; border-radius:999px;
  border:1.5px solid var(--c-border); background:none; color: var(--c-heading); cursor:pointer;
  transition: border-color var(--dur-s) var(--ease), background var(--dur-s) var(--ease);
}
.cg-theme-drawer-choice svg{ width:15px; height:15px; flex:none; }
.cg-theme-drawer-choice:hover{ border-color: var(--c-orange); }
@media (max-width:640px){
  .cg-theme-drawer{
    left:1rem; right:1rem; top:auto; bottom:1rem; width:auto;
    border-radius: var(--radius-m); border-right:1px solid var(--c-border);
    transform: translateY(140%);
  }
  .cg-theme-drawer.is-visible{ transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce){
  .cg-theme-drawer{ transition:none; }
}

/* =========================================================================
   MODALE "POLITIQUE DE CONFIDENTIALITÉ" (étape 5 du devis, voir
   main.js::cgInitPrivacyModal()) — même famille visuelle que
   .cg-lang-popup-overlay ci-dessus, mais panneau plus grand et défilant
   (contenu de page réelle, pas un simple choix), avec en-tête + pied fixes.
   ========================================================================= */
.cg-privacy-modal-overlay{
  display:none;
  position: fixed; inset: 0; z-index: 999; align-items:center; justify-content:center;
  background: rgba(19,34,56,.55); backdrop-filter: blur(3px); padding:1.5rem;
  opacity:0; transition: opacity var(--dur-m) var(--ease);
}
/* Le sélecteur ":not([hidden])" ci-dessous est nécessaire (et non redondant
   avec l'attribut "hidden" seul) : une règle CSS d'auteur comme ".cg-..{
   display:flex }" l'emporte TOUJOURS sur la règle par défaut du navigateur
   "[hidden]{display:none}", même à spécificité égale — un ".hidden = true"
   posé en JS n'aurait donc aucun effet visuel sans cette ligne, et l'overlay
   serait rendu en display:flex/position:fixed/inset:0 en permanence, invisible
   (opacity:0) mais bloquant tous les clics de toute la page. (Bug réel
   constaté le 2026-09-26, corrigé ici.) */
.cg-privacy-modal-overlay:not([hidden]){ display:flex; }
.cg-privacy-modal-overlay.is-visible{ opacity:1; }
.cg-privacy-modal{
  background: var(--c-white); border-radius: var(--radius-l); box-shadow: var(--shadow-l);
  max-width:640px; width:100%; max-height:85vh; display:flex; flex-direction:column; overflow:hidden;
  transform: translateY(12px) scale(.97); transition: transform var(--dur-m) var(--ease);
}
.cg-privacy-modal-overlay.is-visible .cg-privacy-modal{ transform: translateY(0) scale(1); }
.cg-privacy-modal-head{
  display:flex; align-items:center; justify-content:space-between; gap:1rem;
  padding:1.2rem 1.4rem; border-bottom:1px solid var(--c-border); flex:none;
}
.cg-privacy-modal-title{ font-family: var(--f-title); font-weight:800; font-size:1.05rem; margin:0; color: var(--c-heading); }
.cg-privacy-modal-close{
  width:32px; height:32px; border-radius:50%; flex:none; display:flex; align-items:center; justify-content:center;
  background: var(--c-grey-light); border:none; color: var(--c-text-soft); font-size:1.3rem; line-height:1; cursor:pointer;
}
.cg-privacy-modal-close:hover{ background: var(--c-border); color: var(--c-heading); }
.cg-privacy-modal-body{ padding:1.4rem; overflow-y:auto; }
.cg-privacy-modal-body .legal-content{ max-width:none; }
.cg-privacy-modal-body .legal-content h2:first-child{ margin-top:0; }
.cg-privacy-modal-lead{ color: var(--c-text-soft); margin:0 0 1.2rem; }
.cg-privacy-modal-loading{ color: var(--c-text-soft); text-align:center; margin:2rem 0; }
.cg-privacy-modal-foot{ padding:1rem 1.4rem 1.4rem; flex:none; }
.cg-privacy-modal-foot .btn{ width:100%; font-weight:800; }
@media (prefers-reduced-motion: reduce){
  .cg-privacy-modal-overlay, .cg-privacy-modal{ transition:none; }
}

/* =========================================================================
   CONSENTEMENT COOKIES (Google Analytics 4, voir main.js::cgInitCookieConsent())
   — overlay plein écran assombri/flouté, même famille visuelle que
   .cg-lang-popup-overlay ci-dessus : mis en avant volontairement (sujet de
   conformité), contrairement au tiroir de thème qui reste non bloquant.
   Rouvrable à tout moment via le bouton "Préférences cookies" du footer.
   ========================================================================= */
.cg-cookie-overlay{
  position: fixed; inset:0; z-index: 997; display:flex; align-items:flex-end; justify-content:center;
  background: rgba(19,34,56,.55); backdrop-filter: blur(3px); padding:1.5rem;
  opacity:0; transition: opacity var(--dur-m) var(--ease);
  /* Même correctif que .cg-lang-popup-overlay ci-dessus (voir son
     commentaire) : rend le bandeau toujours atteignable par défilement
     de la fenêtre elle-même si la hauteur réellement disponible sur
     mobile est plus petite que ce que le navigateur utilise pour
     calculer position:fixed/inset:0. */
  overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.cg-cookie-overlay.is-visible{ opacity:1; }
.cg-cookie-banner{
  max-width:760px; width:100%; margin-top:auto;
  background: var(--c-white); border:1px solid var(--c-border); border-radius: var(--radius-m); box-shadow: var(--shadow-l);
  padding:1.3rem 1.4rem; display:flex; flex-direction:column; align-items:center; gap:1rem; text-align:center;
  transform: translateY(24px); transition: transform var(--dur-m) var(--ease);
}
.cg-cookie-overlay.is-visible .cg-cookie-banner{ transform: translateY(0); }
.cg-cookie-banner-text{ margin:0; font-size:.86rem; color: var(--c-text-soft); line-height:1.5; }
.cg-cookie-banner-actions{ display:flex; flex-wrap:wrap; justify-content:center; gap:.6rem; }
.cg-cookie-banner-reject{
  background:none; border:1.5px solid var(--c-border); border-radius:999px; padding:.55em 1.1em;
  font-family: var(--f-body); font-weight:700; font-size:.82rem; color: var(--c-heading); cursor:pointer;
}
.cg-cookie-banner-reject:hover{ border-color: var(--c-text-soft); }
.cg-cookie-banner-actions .btn{ padding:.55em 1.3em; font-size:.82rem; }
.cg-cookie-banner-policy-link{ font-size:.76rem; color: var(--c-text-soft); text-decoration:underline; }
@media (prefers-reduced-motion: reduce){
  .cg-cookie-overlay, .cg-cookie-banner{ transition:none; }
}

/* =========================================================================
   WIDGET DE CHAT VISITEUR (bouton bas-droite, voir main.js::cgInitChatWidget()
   et gateway/chat.php) — z-index volontairement sous les pop-ups thème/langue
   (998/999 ci-dessus) : ce widget ne doit jamais leur passer devant.
   ========================================================================= */
.cg-chat-launcher{
  position: fixed; right:1.2rem; bottom:1.2rem; z-index: 485;
  width:56px; height:56px; border-radius:50%; flex:none;
  display:flex; align-items:center; justify-content:center;
  background: linear-gradient(135deg, var(--c-blue), var(--c-blue-dark));
  color:#fff; border:none; cursor:pointer; box-shadow: var(--shadow-m);
  transition: transform var(--dur-s) var(--ease), box-shadow var(--dur-s) var(--ease);
}
.cg-chat-launcher:hover{ transform: translateY(-2px); box-shadow: var(--shadow-l); }
.cg-chat-launcher svg{ width:24px; height:24px; }
.cg-chat-launcher .cg-chat-close-icon{ display:none; }
.cg-chat-launcher.is-open .cg-chat-open-icon{ display:none; }
.cg-chat-launcher.is-open .cg-chat-close-icon{ display:block; }

/* Anneau qui s'étend et s'estompe pour attirer l'œil sur le bouton — sans ça
   il passe inaperçu (signalé par l'utilisateur le 2026-09-02). z-index:-1
   le maintient sous le propre fond du bouton (dans le même contexte
   d'empilement, posé par position:fixed ci-dessus), pour qu'il ne recouvre
   jamais l'icône. Se met juste en pause pendant que le panneau est ouvert
   (.is-open) et reprend à la fermeture — volontairement PAS un
   "vu une fois, plus jamais" façon pop-up (l'utilisateur a explicitement
   demandé le 2026-09-02 que ça ne se comporte pas comme les popups). */
.cg-chat-launcher::before{
  content:""; position:absolute; inset:0; border-radius:50%;
  background: var(--c-blue); z-index:-1;
  animation: cgChatPulseRing 2.6s ease-out infinite;
}
.cg-chat-launcher.is-open::before{ animation:none; opacity:0; }
@keyframes cgChatPulseRing{
  0%{ transform:scale(1); opacity:.55; }
  100%{ transform:scale(1.9); opacity:0; }
}

.cg-chat-panel{
  position: fixed; right:1.2rem; bottom:5.2rem; z-index: 484;
  width:min(360px, calc(100vw - 2.4rem)); max-height:min(560px, calc(100vh - 7.5rem));
  display:flex; flex-direction:column;
  background: var(--c-white); border:1px solid var(--c-border); border-radius: var(--radius-m);
  box-shadow: var(--shadow-l); overflow:hidden;
  opacity:0; transform: translateY(12px) scale(.97); pointer-events:none;
  transition: opacity var(--dur-s) var(--ease), transform var(--dur-s) var(--ease);
}
.cg-chat-panel.is-visible{ opacity:1; transform: translateY(0) scale(1); pointer-events:auto; }

.cg-chat-panel-header{
  display:flex; align-items:center; gap:.6rem; padding:.9rem 1.1rem;
  background: linear-gradient(135deg, var(--c-navy), var(--c-blue-darker)); color:#fff; flex:none;
}
.cg-chat-panel-header .icon{ width:30px; height:30px; border-radius:50%; background:rgba(255,255,255,.14); display:flex; align-items:center; justify-content:center; flex:none; }
.cg-chat-panel-header .icon svg{ width:16px; height:16px; }
.cg-chat-panel-title{ font-family: var(--f-title); font-weight:800; font-size:.92rem; margin:0; }
.cg-chat-panel-subtitle{ font-size:.72rem; color: rgba(255,255,255,.75); margin:0; }

.cg-chat-panel-body{ flex:1 1 auto; overflow-y:auto; padding:1rem 1.1rem; }
.cg-chat-intro{ font-size:.82rem; color: var(--c-text-soft); margin:0 0 .8rem; line-height:1.5; }
.cg-chat-chips{ display:flex; flex-wrap:wrap; gap:.4rem; margin-bottom:.9rem; }
.cg-chat-chip{
  font-family: var(--f-body); font-size:.74rem; font-weight:600; color: var(--c-blue);
  background: rgba(38,96,189,.08); border:1px solid rgba(38,96,189,.35); border-radius:999px;
  padding:.4em .8em; cursor:pointer; text-align:left;
  transition: border-color var(--dur-s) var(--ease), background var(--dur-s) var(--ease);
}
.cg-chat-chip:hover{ border-color: var(--c-blue); background: rgba(38,96,189,.14); }
/* --c-blue (#2660BD) est une valeur fixe, non adaptée au mode sombre (même
   défaut de contraste déjà corrigé sur .phone-reveal-trigger) — sur le fond
   navy du panneau, le texte et la bordure devenaient à peine visibles. */
:root[data-theme="dark"] .cg-chat-chip{
  color:#bcd2f7; background: rgba(120,168,240,.14); border-color: rgba(120,168,240,.4);
}
:root[data-theme="dark"] .cg-chat-chip:hover{ border-color:#bcd2f7; background: rgba(120,168,240,.22); }

.cg-chat-exchange{ margin-bottom:.9rem; }
.cg-chat-bubble{
  border-radius: var(--radius-s); padding:.7em .9em; font-size:.84rem; line-height:1.5;
  margin-bottom:.5rem; max-width:92%;
}
.cg-chat-bubble.visitor{ background: var(--c-grey-light); color: var(--c-text); margin-left:auto; }
.cg-chat-bubble.answer{ background: rgba(38,96,189,.08); color: var(--c-text); border:1px solid rgba(38,96,189,.18); }
.cg-chat-bubble.fallback{ background: rgba(38,96,189,.08); color: var(--c-text); border:1px solid rgba(38,96,189,.18); }
.cg-chat-loading{ display:flex; align-items:center; gap:.5em; font-size:.8rem; color: var(--c-text-soft); padding:.3em 0; }
.cg-chat-spinner{ width:1em; height:1em; flex:none; border-radius:50%; border:2px solid rgba(38,96,189,.25); border-top-color: var(--c-blue); animation: cg-spin .8s linear infinite; }
.cg-chat-fallback-actions{ display:flex; flex-wrap:wrap; gap:.5rem; margin-top:.6rem; }
.cg-chat-fallback-actions .btn{ font-size:.76rem; padding:.5em .9em; }

.cg-chat-panel-footer{ flex:none; border-top:1px solid var(--c-border); padding:.8rem 1.1rem; }
.cg-chat-form{ display:flex; gap:.5rem; }
.cg-chat-input{
  flex:1 1 auto; min-width:0; border:1.5px solid var(--c-border); border-radius:999px;
  padding:.6em 1em; font-family: var(--f-body); font-size:.84rem; color: var(--c-text); background: var(--c-input-bg);
}
.cg-chat-input:focus{ outline:none; border-color: var(--c-blue); box-shadow: 0 0 0 3px rgba(38,96,189,.14); }
.cg-chat-send{
  flex:none; width:38px; height:38px; border-radius:50%; border:none; cursor:pointer;
  background: var(--c-orange); color:#fff; display:flex; align-items:center; justify-content:center;
  transition: background var(--dur-s) var(--ease);
}
.cg-chat-send:hover{ background: var(--c-orange-light); }
.cg-chat-send:disabled{ opacity:.5; cursor:default; }
.cg-chat-send svg{ width:16px; height:16px; }
.cg-chat-privacy{ font-size:.68rem; color: var(--c-text-soft); margin:.6rem 0 0; line-height:1.4; }

@media (max-width:720px){
  /* Sous 720px, .mobile-cta-bar (Appeler/Devis) occupe une bande fixe de
     74px en bas d'écran (voir sa règle plus haut, body{padding-bottom:74px})
     — le lanceur du chat doit rester au-dessus, jamais recouvert ni la
     recouvrir lui-même. */
  .cg-chat-launcher{ right:1rem; bottom:5.6rem; }
  .cg-chat-panel{ right:.6rem; left:.6rem; bottom:9.6rem; width:auto; max-height:min(480px, calc(100vh - 11rem)); }
}
@media (prefers-reduced-motion: reduce){
  .cg-chat-panel, .cg-chat-launcher{ transition:none; }
  .cg-chat-launcher::before{ animation:none; opacity:0; }
}

.honeypot{ position:absolute; left:-9999px; top:auto; width:1px; height:1px; overflow:hidden; }

.contact-method-featured{
  display:flex; align-items:center; gap:1.5rem; flex-wrap:wrap; margin-bottom:1rem; padding:2rem 2.2rem;
  border-radius: var(--radius-l); background: linear-gradient(135deg, var(--c-orange-light), var(--c-orange));
  box-shadow: 0 16px 36px rgba(252,113,0,.28); color:#fff; text-decoration:none;
  transition: box-shadow var(--dur-s) var(--ease), transform var(--dur-s) var(--ease);
}
.contact-method-featured:hover{ box-shadow: 0 20px 44px rgba(252,113,0,.36); transform: translateY(-3px); }
.contact-method-featured .icon{
  flex:none; width:60px; height:60px; border-radius:16px; background: rgba(255,255,255,.22); color:#fff;
  display:flex; align-items:center; justify-content:center;
}
.contact-method-featured .icon svg{ width:28px; height:28px; }
.contact-method-featured-text{ flex:1 1 260px; min-width:0; }
.contact-method-featured .badge{
  display:inline-block; font-size:.74rem; font-weight:800; letter-spacing:.04em; text-transform:uppercase;
  background: rgba(255,255,255,.22); padding:.3em .8em; border-radius:999px; margin-bottom:.6em;
}
.contact-method-featured h3{ font-size:1.3rem; margin-bottom:.3em; color:#fff; }
.contact-method-featured p{ margin:0; font-size:.95rem; color: rgba(255,255,255,.92); max-width:46em; }
.contact-method-featured .cta-arrow{
  flex:none; display:inline-flex; align-items:center; gap:.5em; font-weight:800; font-size:.95rem;
  background:#fff; color: var(--c-orange); padding:.8em 1.3em; border-radius:999px;
  transition: transform var(--dur-s) var(--ease);
}
.contact-method-featured:hover .cta-arrow{ transform: translateX(4px); }

.contact-methods{ display:grid; gap:1rem; }
.contact-method{
  display:flex; gap:1rem; align-items:flex-start; padding:1.3rem; border:1.5px solid var(--c-orange);
  border-radius: var(--radius-m); background: var(--c-white); transition: box-shadow var(--dur-s) var(--ease), transform var(--dur-s) var(--ease);
}
.contact-method:hover{ box-shadow: var(--shadow-s); transform: translateY(-3px); }
.contact-method .icon{
  flex:none; width:46px; height:46px; border-radius:12px; background: rgba(38,96,189,.09); color: var(--c-blue);
  display:flex; align-items:center; justify-content:center;
}
.contact-method .icon svg{ width:22px; height:22px; }
.contact-method h3{ font-size:1rem; margin-bottom:.2em; }
.contact-method p{ margin:0; font-size:.88rem; color: var(--c-text-soft); }

@media (max-width:640px){
  .contact-method-featured{ flex-direction:column; align-items:flex-start; padding:1.6rem; }
  .contact-method-featured .cta-arrow{ align-self:stretch; justify-content:center; }
}

/* =========================================================================
   TABLE DE CONTENU LÉGALE
   ========================================================================= */
.legal-content h2{ margin-top:2rem; }
.legal-content{ max-width: 76ch; }
.legal-content .placeholder-tag{
  display:inline-block; background: rgba(252,113,0,.12); color:#a3450a;
  border-radius:6px; padding:.05em .5em; font-weight:700; font-size:.92em;
}

/* =========================================================================
   SCROLL REVEAL
   ========================================================================= */
[data-reveal]{
  opacity:0; transform: translateY(28px);
  transition: opacity .8s var(--ease), transform .8s var(--ease);
}
[data-reveal].is-visible{ opacity:1; transform:none; }
[data-reveal-group] > *{ transition-delay: calc(var(--i, 0) * 90ms); }

/* Compteur d'étape animée (barre de progression scroll) */
.scroll-progress{
  position: fixed; top:0; left:0; height:3px; background: linear-gradient(90deg, var(--c-orange), var(--c-orange-light));
  z-index: 600; width:0%; transition: width .1s linear;
}

/* Marquee logos partenaires / valeurs (discret) */
.value-strip{
  display:flex; flex-wrap:wrap; gap:1rem 2rem; justify-content:center;
  padding-block: 1.6rem; color: var(--c-text-soft); font-size:.86rem; font-weight:600;
}
.value-strip span{ display:flex; align-items:center; gap:.5em; }
.value-strip svg{ width:1.1em; height:1.1em; color: var(--c-orange); }

/* Table simple */
.simple-table{ width:100%; border-collapse:collapse; font-size:.94rem; }
.simple-table th, .simple-table td{ text-align:left; padding:.9em 1em; border-bottom:1px solid var(--c-border); }
.simple-table th{ font-family: var(--f-title); color: var(--c-heading); background: var(--c-grey-light); }
.table-wrap{ overflow-x:auto; border:1px solid var(--c-border); border-radius: var(--radius-m); }

/* Divers */
.divider{ height:1px; background: var(--c-border); border:none; margin: var(--gap-l) 0; }
.stack{ display:flex; flex-direction:column; gap: var(--gap-s); }

/* =========================================================================
   MODE SOMBRE — cas ponctuels non couverts par les tokens ci-dessus
   (couleurs de messages/badges pensées pour un fond clair, illisibles
   telles quelles sur --c-white une fois celui-ci basculé en bleu nuit).
   ========================================================================= */
:root[data-theme="dark"] .form-msg.success{
  background: rgba(46,196,120,.18); color:#c9ffe1; border-color: rgba(46,196,120,.55);
}
:root[data-theme="dark"] .form-msg.error{
  background: rgba(255,120,120,.16); color:#ffdcdc; border-color: rgba(255,120,120,.5);
}
:root[data-theme="dark"] .cg-photo-error{
  color:#ffc2c2; background: rgba(255,110,110,.14); border-color: rgba(255,110,110,.4);
}
:root[data-theme="dark"] .cg-wizard-error{
  color:#ffc2c2; background: rgba(255,110,110,.14); border-color: rgba(255,110,110,.4);
}
:root[data-theme="dark"] .cg-field-notice{
  color:#ffd9ab; background: rgba(252,113,0,.16); border-color: rgba(252,113,0,.4);
}
:root[data-theme="dark"] .cg-photo-processing{
  color:#ffd9ab; background: rgba(252,113,0,.16); border-color: rgba(252,113,0,.4);
}
:root[data-theme="dark"] .cg-photo-thumb-wrap{ background: var(--c-white); border-color: var(--c-border); }
:root[data-theme="dark"] .legal-content .placeholder-tag{ color:#ffb066; background: rgba(252,113,0,.18); }
:root[data-theme="dark"] .placeholder-frame.light{
  background:
    linear-gradient(135deg, rgba(255,255,255,.08), rgba(255,255,255,0)),
    repeating-linear-gradient(45deg, rgba(255,255,255,.05) 0 12px, rgba(255,255,255,.02) 12px 24px);
  border-color: rgba(255,255,255,.35);
}
:root[data-theme="dark"] .placeholder-frame.light svg{ color: var(--c-orange-light); }
:root[data-theme="dark"] .placeholder-frame.light .ph-label{ color: var(--c-text-on-dark-soft); }
:root[data-theme="dark"] .placeholder-frame.light .ph-sub{ color: var(--c-text-on-dark-soft); opacity:.8; }
:root[data-theme="dark"] .ba-slider .ba-before{ background: linear-gradient(135deg,#1b2f4a,#132238); }
:root[data-theme="dark"] .ba-slider .ba-after{ background: linear-gradient(135deg,#1c3151,#1b2f4a); }
:root[data-theme="dark"] .zone-map{ background: linear-gradient(160deg,#1b2f4a,#132238); }

/* =========================================================================
   INTERRUPTEUR MODE SOMBRE (en-tête)
   ========================================================================= */
.theme-toggle{
  position:relative;
  display:inline-flex; align-items:center; justify-content:center;
  width:40px; height:40px; border-radius:50%; flex:none;
  background:none; border:1.5px solid var(--c-border); cursor:pointer;
  color: var(--c-heading);
  transition: border-color var(--dur-s) var(--ease), background var(--dur-s) var(--ease), color var(--dur-s) var(--ease), transform var(--dur-s) var(--ease);
}
/* Info-bulle au survol/focus : le texte vient de aria-label, déjà tenu à
   jour par main.js (cgInitThemeToggle::applyLabel(), FR/EN et sombre/clair
   inclus) — rien à dupliquer ici. */
.theme-toggle::after{
  content: attr(aria-label);
  position:absolute; top:calc(100% + 10px); left:50%;
  transform:translateX(-50%) translateY(-4px);
  background: var(--c-navy); color:#fff; font-family: var(--f-body); font-weight:600; font-size:.76rem;
  white-space:nowrap; padding:.4em .85em; border-radius:8px;
  box-shadow: var(--shadow-m);
  opacity:0; visibility:hidden; pointer-events:none;
  transition: opacity var(--dur-s) var(--ease), transform var(--dur-s) var(--ease), visibility var(--dur-s);
  z-index:70;
}
.theme-toggle::before{
  content:""; position:absolute; top:calc(100% + 5px); left:50%; transform:translateX(-50%);
  border:5px solid transparent; border-bottom-color: var(--c-navy);
  opacity:0; visibility:hidden; pointer-events:none;
  transition: opacity var(--dur-s) var(--ease), visibility var(--dur-s);
  z-index:70;
}
.theme-toggle:hover::after, .theme-toggle:focus-visible::after{ opacity:1; visibility:visible; transform:translateX(-50%) translateY(0); }
.theme-toggle:hover::before, .theme-toggle:focus-visible::before{ opacity:1; visibility:visible; }
@media (max-width:640px){
  .theme-toggle::after, .theme-toggle::before{ display:none; }
}
.theme-toggle svg{ width:19px; height:19px; }
.theme-toggle .icon-sun{ display:none; }
.theme-toggle .icon-moon{ display:block; }
:root[data-theme="dark"] .theme-toggle .icon-sun{ display:block; }
:root[data-theme="dark"] .theme-toggle .icon-moon{ display:none; }
/* Halo orange pulsé (repris de la couleur d'accent de la marque), dans les
   deux états — lune (passer en sombre) comme soleil (repasser en clair) —
   pour que ce bouton se remarque sans qu'on ait besoin de le chercher,
   quel que soit le mode déjà actif. */
.theme-toggle{
  border-color: rgba(255,142,22,.6);
  color: var(--c-orange-light);
  background: rgba(255,142,22,.08);
  animation: cgThemeToggleGlow 2.6s ease-in-out infinite;
}
.theme-toggle:hover{
  animation-play-state: paused;
  border-color: var(--c-orange-light);
  background: rgba(255,142,22,.16);
  transform: scale(1.06);
}
@keyframes cgThemeToggleGlow{
  0%, 100%{ box-shadow: 0 0 0 0 rgba(255,142,22,.5); }
  50%{ box-shadow: 0 0 0 8px rgba(255,142,22,0); }
}
@media (prefers-reduced-motion: reduce){
  .theme-toggle{ animation:none; }
}
@media (max-width:420px){
  .theme-toggle{ width:36px; height:36px; }
  .theme-toggle svg{ width:17px; height:17px; }
}
