/* ==========================================================================
   BASSARD Toiture & Zinguerie — Design system (version claire, v2)
   Rouge de marque #DB011C (le rouge Milwaukee) · titres Saira Extra Condensed
   ========================================================================== */

/* ------------------------------------------------------------ 0. Polices - */
/* Hebergees ici plutot que chez Google Fonts : la feuille de fonts.googleapis.com
   bloquait le premier affichage, et chaque origine tierce coute une connexion de
   plus (DNS + TLS) avant la moindre lettre. Sous-ensemble « latin » de Google,
   qui couvre le francais (œ, €, guillemets et tirets compris).
   Inter est une police variable : un seul fichier pour les graisses 400 a 700. */
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url(../fonts/inter-latin.woff2) format('woff2');
}
@font-face {
  font-family: 'Saira Extra Condensed'; font-style: normal; font-weight: 600; font-display: swap;
  src: url(../fonts/saira-extra-condensed-600-latin.woff2) format('woff2');
}
@font-face {
  font-family: 'Saira Extra Condensed'; font-style: normal; font-weight: 700; font-display: swap;
  src: url(../fonts/saira-extra-condensed-700-latin.woff2) format('woff2');
}

/* ------------------------------------------------------------- 1. Tokens - */
:root {
  /* `dark` alors que le site est clair : ce n'est pas une erreur.
     Safari iOS teinte ses barres et la zone de rebond d'apres le schema
     **declare par la page**, pas d'apres l'apparence du telephone ni d'apres
     `theme-color` — teste sur un iPhone en apparence sombre, barres blanches.
     Tant que la page se declarait claire, ces zones restaient blanches sous un
     en-tete et une barre du bas noirs.
     Aucun risque pour le dessin du site : `color-scheme` ne repeint que ce que
     fournit le navigateur — canevas, controles natifs, ascenseurs. Or tous les
     fonds du site sont poses explicitement en CSS, et le canevas l'est juste
     en dessous. Declarer un schema desactive aussi l'assombrissement
     automatique de Chrome Android, ce que `light` faisait deja.
     Les champs du bloc #devis ont leur propre `color-scheme: dark`. */
  color-scheme: dark;

  --red: #db011c;
  --red-dark: #b40117;
  --red-deep: #850111;
  --red-tint: #fdecee;
  --red-tint-2: #fbd9dd;
  --red-glow: rgba(219, 1, 28, 0.26);

  --ink: #211d1d;
  --ink-2: #322c2c;
  --ink-soft: rgba(33, 29, 29, 0.66);
  --slate: #6c6666;
  --surface: #f4f5f7;
  --surface-2: #ebedf1;
  --line: #e4e5ea;
  --line-dark: rgba(255, 255, 255, 0.13);
  --white: #fff;

  --display: "Saira Extra Condensed", "Arial Narrow", sans-serif;
  --body: "Inter", "Segoe UI", system-ui, sans-serif;

  --r-sm: 10px;
  --r: 18px;
  --r-lg: 26px;
  --r-pill: 999px;

  --sh-sm: 0 1px 2px rgba(33, 29, 29, 0.05), 0 4px 12px rgba(33, 29, 29, 0.05);
  --sh: 0 10px 30px rgba(33, 29, 29, 0.09);
  --sh-lg: 0 28px 70px rgba(33, 29, 29, 0.16);

  --wrap: 1220px;
  --pad: clamp(20px, 5vw, 52px);
  --sec: clamp(64px, 8.5vw, 118px);

  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);
  --hdr: 82px;
  /* hauteur reelle de la barre : --hdr est la hauteur interieure, le filet bas
     ajoute 1 px. Valeur utilisee pour faire remonter les heros sous la barre. */
  --hdr-full: calc(var(--hdr) + 1px);
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--hdr) + 24px);
  -webkit-text-size-adjust: 100%;
  /* Fond du canevas : ce qu'on voit dans les zones de rebond du defilement sur
     iOS. Meme noir que le body, sinon un lisere plus clair y apparait. Ce n'est
     pas une couleur de charte : le body la recouvre partout ailleurs. */
  background-color: #000;
}

body {
  font-family: var(--body);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.72;
  color: var(--slate);
  /* Sombre, alors que le site est clair — et c'est volontaire.
     Safari 26 sur iOS teinte ses barres translucides d'apres le fond du
     **body**, pas d'apres celui de html ni d'apres theme-color. Tant que le
     body etait blanc, les barres restaient blanches sous un en-tete et une
     barre du bas noirs. Diagnostic etabli en comparant, sur l'appareil, une
     page de test au body sombre : barres noires.
     Le blanc du site est donc porte par `main` juste en dessous. Deplacer ce
     fond ailleurs, ou le remettre ici, ramene les bandes blanches.
     Noir pur et non `--ink` : le verre translucide de Safari eclaircit ce
     qu'il recouvre, `--ink` y virait au gris fonce. Ce n'est pas une couleur
     de charte, elle n'apparait nulle part dans la mise en page — `main` la
     recouvre entierement et les autres blocs ont chacun leur fond. */
  background: #000;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
/* toutes les sections claires vivent dans main : c'est lui qui porte
   desormais le blanc que le body portait. L'en-tete, le tiroir mobile, le pied
   de page et la barre du bas ont chacun leur propre fond. */
main { display: block; background: var(--white); }

img, svg, video, iframe { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
ul, ol { list-style: none; padding: 0; }

::selection { background: var(--red); color: #fff; }
:focus-visible { outline: 3px solid var(--red); outline-offset: 3px; border-radius: 4px; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--red); color: #fff; padding: 13px 24px;
  font-weight: 700; border-radius: 0 0 var(--r-sm) 0;
}
.skip-link:focus { left: 0; top: 0; }

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

/* -------------------------------------------------------- 3. Typographie - */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: 0.004em;
  text-transform: uppercase;
  color: var(--ink);
  text-wrap: balance;
}

h1 { font-size: clamp(2.7rem, 6.6vw, 5rem); }
h2 { font-size: clamp(2.05rem, 4.4vw, 3.4rem); }
h3 { font-size: clamp(1.4rem, 2.4vw, 1.95rem); }
/* les intertitres de carte sont des h3 (ordre des titres sans saut apres un h2),
   dessines a la taille d'un h4 */
h4, .feature h3, .why__item h3, .step h3, .tile h3, .info-list h3, .site-footer h3 { font-size: clamp(1.14rem, 1.8vw, 1.4rem); }

p { text-wrap: pretty; }
p + p { margin-top: 1.05em; }

.eyebrow {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 7px 15px 7px 12px;
  background: var(--red-tint);
  border-radius: var(--r-pill);
  font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--red-deep);
  margin-bottom: 20px;
}
.eyebrow::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--red); flex: none;
}
.eyebrow--light { background: rgba(255, 255, 255, 0.12); color: #fff; }
.eyebrow--light::before { background: var(--red); }

.lead { font-size: clamp(1.02rem, 1.4vw, 1.14rem); }
.muted { color: var(--slate); }

.head { max-width: 720px; margin-bottom: clamp(38px, 4.6vw, 64px); }
.head--center { margin-inline: auto; text-align: center; }
.head--center .eyebrow { justify-content: center; }
.head p { margin-top: 20px; }
.head--wide { max-width: none; display: grid; grid-template-columns: minmax(0,1fr) minmax(0,.78fr); gap: clamp(20px,4vw,64px); align-items: end; }

/* ---------------------------------------------------------- 4. Structure - */
.container { width: min(100% - (var(--pad) * 2), var(--wrap)); margin-inline: auto; }
.section { padding-block: var(--sec); }
.section--sm { padding-block: clamp(44px, 5.4vw, 76px); }
.section--surface { background: var(--surface); }
.section--dark { background: var(--ink); color: rgba(255, 255, 255, 0.72); }
.section--dark h1, .section--dark h2, .section--dark h3, .section--dark h4 { color: #fff; }

/* ------------------------------------------------------------ 5. Boutons - */
.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 16px 28px;
  background: var(--red); color: #fff;
  border: 2px solid var(--red);
  border-radius: var(--r-pill);
  font-size: 0.82rem; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase;
  cursor: pointer; overflow: hidden; isolation: isolate;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease),
              color .3s var(--ease), border-color .3s var(--ease);
}
/* Le voile de survol reste dans la palette de marque : jamais de noir. */
.btn::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--red-deep); transform: translateY(101%);
  transition: transform .38s var(--ease);
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 14px 30px var(--red-glow); border-color: var(--red-deep); }
.btn:hover::after { transform: translateY(0); }
.btn svg { width: 17px; height: 17px; flex: none; }

.btn--ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn--ghost::after { background: var(--red); }
.btn--ghost:hover { color: #fff; border-color: var(--red); box-shadow: 0 12px 26px var(--red-glow); }

/* Seul bouton du site qui ne bascule pas au rouge au survol : il mene a Google,
   il en prend la couleur. A placer apres .btn--ghost, meme specificite. */
.btn--google::after { background: #4285f4; }
.btn--google:hover { color: #fff; border-color: #4285f4; box-shadow: 0 12px 26px rgba(66, 133, 244, .3); }

.btn--light { background: transparent; color: #fff; border-color: rgba(255,255,255,.45); }
.btn--light::after { background: #fff; }
.btn--light:hover { color: var(--red); border-color: #fff; box-shadow: none; }

/* Bouton blanc sur fond rouge : la bordure blanche est conservee pour garder
   le contour lisible quand le fond passe en rouge profond. */
.btn--white { background: #fff; color: var(--red); border-color: #fff; }
.btn--white::after { background: var(--red-deep); }
.btn--white:hover { color: #fff; border-color: #fff; box-shadow: 0 14px 30px rgba(0,0,0,.18); }

.btn--sm { padding: 11px 20px; font-size: 0.74rem; }
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 32px; }

/* ------------------------------------------------- 6. Topbar & en-tête --- */
.topbar {
  background: var(--ink); color: rgba(255, 255, 255, 0.7);
  font-size: 0.78rem;
}
.topbar__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; min-height: 44px; padding-block: 8px;
}
.topbar__list { display: flex; flex-wrap: wrap; gap: 24px; }
.topbar__list li { display: flex; align-items: center; gap: 8px; }
.topbar__list svg { width: 15px; height: 15px; color: var(--red); flex: none; }
.topbar a:hover { color: #fff; }
.topbar__badge { display: inline-flex; align-items: center; gap: 8px; color: #fff; white-space: nowrap; }
.topbar__dot {
  position: relative;
  width: 8px; height: 8px; border-radius: 50%; background: #2ed07f;
}
/* l'onde est un calque anime en transform + opacity, que le navigateur confie
   au compositeur : animer box-shadow repeignait la page a chaque image, en
   continu, et pesait sur le temps de blocage mesure par PageSpeed.
   8 px + 9 px d'onde de chaque cote = 26 px, soit une echelle de 3,25 */
.topbar__dot::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: rgba(46, 208, 127, .6); animation: pulse 2.4s infinite;
}
@keyframes pulse {
  0% { transform: scale(1); opacity: 1; }
  70% { transform: scale(3.25); opacity: 0; }
  100% { transform: scale(3.25); opacity: 0; }
}

/* En-tete noir translucide : quasi opaque, il laisse juste transparaitre la
   photo du hero qui remonte dessous. Au-dessus d'une section blanche le fond
   composite retombe a ~#201e1e, soit la teinte de la topbar. */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(15, 13, 13, .93);
  backdrop-filter: blur(16px) saturate(170%);
  border-bottom: 1px solid transparent;
  transition: box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.site-header.is-stuck { box-shadow: 0 10px 30px rgba(33, 29, 29, .28); border-bottom-color: var(--line-dark); }
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; min-height: var(--hdr);
}

.brand { display: flex; align-items: center; gap: 12px; }
.brand img { width: 46px; height: 46px; object-fit: contain; }
.brand__text { display: flex; flex-direction: column; line-height: 1; }
.brand__name {
  font-family: var(--display); font-size: 1.62rem; font-weight: 700;
  letter-spacing: .05em; color: var(--ink);
}
.site-header .brand__name { color: #fff; }
.brand__tag {
  font-size: .58rem; font-weight: 700; letter-spacing: .22em;
  text-transform: uppercase; color: var(--red); margin-top: 5px;
}
/* sur l'encre de l'en-tete et du pied, le rouge de marque plafonne a 3,2:1 a
   cette taille (9 px) : une teinte eclaircie du meme rouge passe les 4,5:1 */
.site-header .brand__tag,
.site-footer .brand__tag { color: #fe344d; }

.nav { display: flex; align-items: center; gap: 2px; }
.nav__link {
  position: relative; display: inline-flex; align-items: center; gap: 6px;
  padding: 10px 14px; background: none; border: 0; cursor: pointer;
  font-size: .82rem; font-weight: 600; color: rgba(255, 255, 255, .86);
  border-radius: var(--r-pill);
  transition: color .25s var(--ease), background-color .25s var(--ease);
}
/* sur fond sombre, le rouge de marque ne passe pas le contraste a cette taille :
   la pastille garde la teinte rouge, le texte passe en blanc */
.nav__link:hover { color: #fff; background: rgba(255, 255, 255, .13); }
/* La pastille est posee par le JS (`.is-current`), qui la fait suivre la section
   a l'ecran. Sans JS, elle retombe sur le marqueur ecrit dans le HTML. */
.nav__link.is-current,
html:not(.js) .nav__link[aria-current="page"] { color: #fff; background: rgba(219, 1, 28, .34); }
.nav__link svg { width: 11px; height: 11px; transition: transform .3s var(--ease); }
.nav__item { position: relative; }
.nav__item:hover .nav__link svg, .nav__item:focus-within .nav__link svg { transform: rotate(180deg); }

.submenu {
  position: absolute; top: calc(100% + 8px); left: 0;
  min-width: 300px; padding: 10px;
  /* meme encre que l'en-tete d'ou il sort, meme flou : le panneau se lit comme
     un prolongement de la barre et non comme une carte posee dessus. Un cran
     plus opaque que la barre, en revanche : il flotte au-dessus de la photo du
     hero, et a .93 la toiture transparaissait derriere les libelles. */
  background: rgba(15, 13, 13, .97);
  backdrop-filter: blur(16px) saturate(170%);
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: var(--r); box-shadow: 0 24px 60px rgba(0, 0, 0, .45);
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity .26s var(--ease), transform .26s var(--ease), visibility .26s;
}
.nav__item:hover .submenu, .nav__item:focus-within .submenu {
  opacity: 1; visibility: visible; transform: translateY(0);
}
.submenu a {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 13px; border-radius: 11px;
  font-size: .87rem; font-weight: 500; color: rgba(255, 255, 255, .88);
  transition: background-color .2s var(--ease), color .2s var(--ease);
}
.submenu a span {
  display: grid; place-items: center; width: 30px; height: 30px; flex: none;
  border-radius: 9px; background: rgba(219, 1, 28, .26); color: #fff;
}
.submenu a span svg { width: 16px; height: 16px; }
/* comme dans la nav : au survol le texte passe en blanc et c'est la pastille
   qui porte le rouge — le rouge sur ce fond ne tient pas la lecture a 14 px */
.submenu a:hover { background: rgba(219, 1, 28, .28); color: #fff; }

.header__cta { display: flex; align-items: center; gap: 10px; }

.burger {
  position: relative; display: none;
  width: 46px; height: 46px; padding: 0;
  background: rgba(255, 255, 255, .11); border: 1px solid rgba(255, 255, 255, .24); border-radius: 14px;
  cursor: pointer;
  transition: background-color .3s var(--ease), border-color .3s var(--ease);
}
/* barres positionnees en absolu : la croix se referme exactement au centre,
   sans dependre de la hauteur des marges */
.burger span {
  position: absolute; left: 50%; top: 50%;
  width: 19px; height: 2px; margin: 0;
  background: #fff; border-radius: 2px;
  transition: transform .32s var(--ease), opacity .2s, background-color .3s var(--ease);
}
.burger span:nth-child(1) { transform: translate(-50%, calc(-50% - 6px)); }
.burger span:nth-child(2) { transform: translate(-50%, -50%); }
.burger span:nth-child(3) { transform: translate(-50%, calc(-50% + 6px)); }
.burger:hover { background: rgba(255, 255, 255, .2); border-color: rgba(255, 255, 255, .36); }
.burger[aria-expanded="true"] { background: var(--red); border-color: var(--red); }
.burger[aria-expanded="true"] span { background: #fff; }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translate(-50%, -50%) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translate(-50%, -50%) rotate(-45deg); }

/* ------------------------------------------- Panneau lateral mobile (drawer)
   Tiroir ancre a droite, ouvert juste sous l'en-tete. Le voile est un ::after
   du body : rien a dupliquer dans les 9 pages. La position haute est calculee
   en JS (--nav-top = bas reel de l'en-tete, topbar comprise) puis posee sur
   :root ; la valeur de repli --hdr sert si le JS n'a pas tourne. */
body::after {
  content: ""; position: fixed; top: var(--nav-top, 0); left: 0; right: 0; bottom: 0; z-index: 98;
  background: rgba(24, 20, 20, .5);
  backdrop-filter: blur(4px);
  opacity: 0; visibility: hidden;
  transition: opacity .38s var(--ease), visibility .38s;
}
body.nav-open::after { opacity: 1; visibility: visible; }
body.nav-open { overflow: hidden; }

.mobile-nav {
  position: fixed; top: var(--nav-top, var(--hdr)); right: 0; bottom: 0; z-index: 99;
  display: flex; flex-direction: column;
  width: min(392px, 87vw);
  padding: 20px 18px calc(20px + env(safe-area-inset-bottom));
  background: #fff;
  border-left: 1px solid var(--line);
  border-top-left-radius: 26px;
  box-shadow: -28px 0 64px rgba(33, 29, 29, .2);
  overflow-y: auto; overscroll-behavior: contain;
  transform: translateX(100%); visibility: hidden;
  transition: transform .44s var(--ease), visibility .44s;
}
.mobile-nav.is-open { transform: none; visibility: visible; }

.mobile-nav__list { display: flex; flex-direction: column; gap: 3px; }

/* entrees de premier niveau : pastilles arrondies, pas de filets */
.mobile-nav__list > a,
.mobile-nav__toggle {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; margin: 0; padding: 13px 12px 13px 15px;
  background: none; border: 0; border-radius: 15px;
  font-family: var(--display); font-size: 1.34rem; font-weight: 700; line-height: 1.15;
  letter-spacing: .01em; text-transform: uppercase; color: var(--ink); text-align: left;
  cursor: pointer;
  transition: color .25s var(--ease), background-color .25s var(--ease),
              opacity .45s var(--ease), transform .45s var(--ease);
}
/* fleche en pastille, a droite */
.mobile-nav__list > a::after {
  content: "→"; flex: none;
  display: grid; place-items: center; width: 30px; height: 30px;
  border-radius: 50%; background: var(--surface);
  font-family: var(--body); font-size: .82rem; font-weight: 600; color: var(--slate);
  transition: background-color .25s var(--ease), color .25s var(--ease),
              transform .25s var(--ease);
}
.mobile-nav__list > a:hover { background: var(--surface); color: var(--red); }
.mobile-nav__list > a:hover::after { transform: translateX(3px); }
.mobile-nav__list > a[aria-current="page"] { background: var(--red-tint); color: var(--red); }
.mobile-nav__list > a[aria-current="page"]::after { background: var(--red); color: #fff; }

/* bouton d'ouverture des prestations */
.mobile-nav__toggle svg {
  width: 32px; height: 32px; padding: 8px; flex: none;
  border: 1px solid var(--line); border-radius: 50%; color: var(--ink);
  transition: transform .35s var(--ease), background-color .3s var(--ease),
              border-color .3s var(--ease), color .3s var(--ease);
}
.mobile-nav__toggle:hover { background: var(--surface); }
.mobile-nav__toggle[aria-expanded="true"] { color: var(--red); }
.mobile-nav__toggle[aria-expanded="true"] svg {
  transform: rotate(180deg); background: var(--red); border-color: var(--red); color: #fff;
}

/* sous-liste depliante : 0fr -> 1fr, pas de hauteur a mesurer en JS */
/* overflow ici aussi : replie, la piste vaut 0 et coupe le filet guide du div */
.mobile-nav__sub { display: grid; grid-template-rows: 0fr; overflow: hidden; transition: grid-template-rows .38s var(--ease); }
.mobile-nav__toggle[aria-expanded="true"] + .mobile-nav__sub { grid-template-rows: 1fr; }
/* le filet vertical sert de guide : il grandit avec le depliage */
.mobile-nav__sub > div {
  overflow: hidden;
  min-height: 0; margin: 0 0 0 26px; padding: 0;
  border-left: 2px solid var(--red-tint-2);
}
.mobile-nav__sub a {
  display: flex; align-items: center; gap: 11px;
  margin: 1px 0 1px 8px; padding: 10px 12px; border-radius: 12px;
  font-size: .92rem; font-weight: 500; color: var(--slate);
  transition: color .25s var(--ease), background-color .25s var(--ease);
}
/* respiration portee par les marges des liens : le conteneur clippe garde
   une hauteur nulle une fois replie (padding/bordure compteraient, pas eux) */
.mobile-nav__sub a:first-child { margin-top: 5px; }
.mobile-nav__sub a:last-child { margin-bottom: 9px; }
/* pastille d'icone, comme le menu desktop — mais sur fond clair : voile rouge
   et icone rouge au repos, pastille pleine et icone blanche a l'etat courant */
.mobile-nav__sub a span {
  display: grid; place-items: center; width: 30px; height: 30px; flex: none;
  border-radius: 9px; background: var(--red-tint); color: var(--red);
  transition: background-color .25s var(--ease), color .25s var(--ease);
}
.mobile-nav__sub a span svg { width: 16px; height: 16px; }
.mobile-nav__sub a:hover { background: var(--surface); }
.mobile-nav__sub a:hover,
.mobile-nav__sub a[aria-current="page"] { color: var(--red); }
.mobile-nav__sub a[aria-current="page"] { background: var(--red-tint); font-weight: 600; }
.mobile-nav__sub a:hover span,
.mobile-nav__sub a[aria-current="page"] span { background: var(--red); color: #fff; }

/* pied : actions principales sur une carte, collee en bas */
.mobile-nav__foot {
  margin: auto -4px 0; padding: 16px 14px 14px;
  display: grid; gap: 10px;
  background: var(--surface); border-radius: 20px;
}
.mobile-nav__foot .btn { width: 100%; padding: 15px 16px; font-size: .76rem; letter-spacing: .04em; }
.mobile-nav__promise {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  margin-top: 4px; padding-top: 14px; border-top: 1px solid var(--line);
  font-size: .78rem; line-height: 1.5; color: var(--slate); text-align: center;
}

/* entree en cascade des blocs, uniquement a l'ouverture */
.mobile-nav__list > a,
.mobile-nav__group,
.mobile-nav__foot { opacity: 0; transform: translateX(18px); }
.mobile-nav__group,
.mobile-nav__foot { transition: opacity .45s var(--ease), transform .45s var(--ease); }
.mobile-nav.is-open .mobile-nav__list > a,
.mobile-nav.is-open .mobile-nav__group,
.mobile-nav.is-open .mobile-nav__foot { opacity: 1; transform: none; }
.mobile-nav.is-open .mobile-nav__list > *:nth-child(1) { transition-delay: .10s; }
.mobile-nav.is-open .mobile-nav__list > *:nth-child(2) { transition-delay: .15s; }
.mobile-nav.is-open .mobile-nav__list > *:nth-child(3) { transition-delay: .20s; }
.mobile-nav.is-open .mobile-nav__list > *:nth-child(4) { transition-delay: .25s; }
.mobile-nav.is-open .mobile-nav__list > *:nth-child(5) { transition-delay: .30s; }
.mobile-nav.is-open .mobile-nav__foot { transition-delay: .34s; }

/* ---------------------------------------------------------------- 7. Hero */
/* Le hero remonte de la hauteur de l'en-tete pour passer dessous : sans ca, la
   barre collante (translucide) se detachait sur le blanc de la page au premier
   ecran. Les trois valeurs vont ensemble — la marge negative fait remonter la
   boite, le padding rend la meme place au contenu, le min-height rend la meme
   hauteur : rien ne bouge a l'ecran, seule la photo gagne la bande de l'en-tete.
   Idem pour .page-hero plus bas. */
.hero {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; justify-content: flex-end;
  margin-top: calc(-1 * var(--hdr-full));
  min-height: calc(min(90vh, 860px) + var(--hdr-full));
  padding-top: calc(clamp(70px, 12vh, 130px) + var(--hdr-full));
  /* réserve la place du bandeau blanc qui remonte par-dessus */
  padding-bottom: clamp(46px, 5vw, 72px);
  color: #fff;
}
/* sans cela les blocs se compriment et la ligne de specs déborde du hero */
.hero > * { flex: none; }
/* Image verrouillee : l'image est en `position: fixed`, elle ne bouge donc pas
   au defilement, et c'est `clip` sur le conteneur absolu qui la decoupe a la
   fenetre du hero. Deux remplacements a ne pas tenter : `overflow: hidden` ne
   clippe pas un enfant fixed, et `clip-path` lui creerait un bloc conteneur
   (l'image redeviendrait solidaire du hero et defilerait avec lui).
   Largeur en %  : resolue sur le viewport, donc sans la barre de defilement.
   Hauteur en vh : stable quand la barre d'adresse mobile se retracte. */
.hero__media { position: absolute; inset: 0; clip: rect(0, auto, auto, 0); }
.hero__media img {
  position: fixed; top: 0; left: 0;
  width: 100%; height: 100vh; object-fit: cover;
  transform: scale(1.07); animation: zoomOut 16s var(--ease) forwards;
}
@keyframes zoomOut { to { transform: scale(1); } }
.hero__media::after {
  content: ""; position: absolute; inset: 0;
  /* noir pur et non --ink : l'anthracite vire au gris sur une photo lumineuse */
  background:
    linear-gradient(to top, rgba(0,0,0,.86) 0%, rgba(0,0,0,.56) 40%, rgba(0,0,0,.18) 100%),
    linear-gradient(to right, rgba(0,0,0,.54), transparent 65%);
}
.hero__inner { position: relative; padding-bottom: clamp(34px, 4.6vw, 56px); }
.hero h1 { color: #fff; margin-bottom: 22px; }
.hero h1 em { font-style: normal; color: var(--red); }
.hero__sub { max-width: 50ch; color: rgba(255, 255, 255, .82); font-size: clamp(1rem, 1.4vw, 1.14rem); }

.rating {
  display: inline-flex; align-items: center; gap: 12px;
  padding: 9px 18px 9px 12px; margin-bottom: 22px;
  background: rgba(255, 255, 255, .1);
  border: 1px solid rgba(255, 255, 255, .22);
  border-radius: var(--r-pill);
  backdrop-filter: blur(8px);
}
.rating__stars { display: flex; gap: 2px; color: #ffc531; flex: none; }
.rating__stars svg { width: 15px; height: 15px; }
.rating span { font-size: .82rem; color: #fff; font-weight: 500; }
.rating b { font-weight: 700; }
/* La localite est un element a part pour pouvoir l'attenuer et regler sa
   separation independamment du libelle principal. */
.rating__label i { font-style: normal; }
/* l'espace avant le point median vient du HTML : c'est lui qui separe les deux
   parties a la lecture d'ecran, le pseudo-element n'etant que decoratif */
.rating__label i::before { content: "·"; margin-right: .42em; opacity: .65; }

/* Mobile : pastille fine, sur une seule ligne. Le libelle ne peut pas se rompre
   (`nowrap`), c'est donc la taille de texte et celle des etoiles qui font tenir
   l'ensemble dans la colonne — ~292 px pour 335 px disponibles a 375 px, et
   encore 12 px de marge a 320 px. Ne pas regrossir sans reverifier ces largeurs. */
@media (max-width: 620px) {
  .rating {
    gap: 7px;
    padding: 4px 12px 4px 8px;
    margin-bottom: 16px;
    background: rgba(255, 255, 255, .14);
  }
  .rating__stars { gap: 1px; }
  .rating__stars svg { width: 11px; height: 11px; }
  .rating__label { font-size: .66rem; line-height: 1.45; white-space: nowrap; }
  .rating__label i { color: rgba(255, 255, 255, .78); }
  .rating__label i::before { margin-right: .3em; }
}

/* Sous 360 px la localite ne rentre plus sans descendre le texte a une taille
   illisible : on ne garde que la mention principale. L'information n'est pas
   perdue, le H1 juste dessous annonce deja Lyon. */
@media (max-width: 359px) {
  .rating__label i { display: none; }
}

/* Bandeau de specs sous le hero */
.spec {
  position: relative;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid rgba(255, 255, 255, .17);
}
/* le filet est a droite de chaque cellule : il faut donc une respiration
   a gauche aussi, sinon le texte de la cellule suivante colle la ligne */
.spec > div { padding: 24px 30px 30px; border-right: 1px solid rgba(255, 255, 255, .17); }
.spec > div:first-child { padding-left: 0; }
.spec > div:last-child { padding-right: 0; border-right: 0; }
.spec dt { font-size: .7rem; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--red); margin-bottom: 9px; }
.spec dd { margin: 0; font-family: var(--display); font-weight: 700; font-size: clamp(1.2rem,1.9vw,1.6rem); text-transform: uppercase; color: #fff; }
.spec dd small { display: block; font-family: var(--body); font-weight: 400; font-size: .8rem; text-transform: none; color: rgba(255,255,255,.62); margin-top: 3px; letter-spacing: 0; }

/* Hero des pages intérieures */
.page-hero {
  position: relative; overflow: hidden;
  display: flex; align-items: flex-end;
  margin-top: calc(-1 * var(--hdr-full));
  min-height: calc(clamp(320px, 48vw, 520px) + var(--hdr-full));
  padding-top: calc(clamp(64px, 10vh, 110px) + var(--hdr-full));
  color: #fff;
}
/* meme verrouillage que le hero d'accueil, voir le commentaire plus haut */
.page-hero__media { position: absolute; inset: 0; clip: rect(0, auto, auto, 0); }
.page-hero__media img {
  position: fixed; top: 0; left: 0;
  width: 100%; height: 100vh; object-fit: cover;
}
.page-hero__media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(33,29,29,.95), rgba(33,29,29,.6) 60%, rgba(33,29,29,.34));
}
/* pas de width ici : l'élément porte aussi .container, qui gère la largeur */
.page-hero__inner { position: relative; padding-bottom: clamp(78px, 8vw, 112px); }
.page-hero h1 { color: #fff; }
.page-hero p { max-width: 56ch; margin-top: 18px; color: rgba(255,255,255,.8); }

.breadcrumb {
  display: flex; flex-wrap: wrap; align-items: center; gap: 9px;
  margin-bottom: 20px; font-size: .78rem; color: rgba(255,255,255,.6);
}
.breadcrumb a:hover { color: #fff; }
.breadcrumb i { font-style: normal; color: var(--red); }
.breadcrumb [aria-current] { color: #fff; }

/* --------------------------------------------------------- 8. Réassurance */
.assurance { position: relative; margin-top: -50px; z-index: 3; }
.assurance__grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  background: #fff; border-radius: var(--r-lg);
  box-shadow: var(--sh-lg); overflow: hidden;
}
.assurance__item {
  display: flex; align-items: center; justify-content: center;
  gap: 15px; padding: 26px 24px;
  border-right: 1px solid var(--line);
}
/* largeur de texte identique partout : les icônes restent alignées d'une colonne à l'autre */
.assurance__item > div { flex: 0 1 196px; min-width: 0; }
.assurance__item:last-child { border-right: 0; }
.assurance__icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 50px; height: 50px; flex: none;
  border-radius: 15px; background: var(--red-tint); color: var(--red);
}
.assurance__icon svg { width: 24px; height: 24px; flex: none; }
.assurance__item strong { display: block; font-family: var(--display); font-size: 1.24rem; text-transform: uppercase; color: var(--ink); line-height: 1.1; }
/* cible uniquement la ligne de description, pas la pastille (qui est aussi un span) */
.assurance__item > div span { display: block; font-size: .84rem; line-height: 1.45; }

/* Carte = photo pleine, contenu posé dessus. Pas de bloc texte blanc sous une
   vignette : la photo occupe toute la carte, un voile la fonce vers le bas et
   le texte s'y appuie. */
.services {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(18px, 2vw, 26px);
}

.service-card {
  position: relative; isolation: isolate;
  display: flex; flex-direction: column; justify-content: flex-end;
  min-height: clamp(420px, 33vw, 520px);
  padding: clamp(20px, 1.9vw, 26px);
  border-radius: var(--r-lg); overflow: hidden;
  background: var(--ink); box-shadow: var(--sh-sm);
  transition: transform .5s var(--ease), box-shadow .5s var(--ease);
}
/* le liseré rouge du survol est un calque à part : une vraie bordure
   décalerait le contenu de 2 px à chaque passage de souris */
.service-card::before {
  content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  border-radius: inherit; border: 2px solid transparent;
  transition: border-color .45s var(--ease);
}
.service-card:hover,
.service-card:focus-within { transform: translateY(-8px); box-shadow: var(--sh-lg); }
.service-card:hover::before,
.service-card:focus-within::before { border-color: var(--red); }

/* z-index 0 et non -1 : la carte a son propre fond, un calque négatif
   passerait derrière et disparaîtrait */
.service-card__media { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.service-card__media img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform 1.1s var(--ease);
}
/* dégagé en haut pour laisser voir la photo, franc en bas pour le texte */
.service-card__media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg,
    rgba(18, 15, 15, .02) 0%, rgba(18, 15, 15, .13) 32%,
    rgba(18, 15, 15, .54) 58%, rgba(18, 15, 15, .90) 100%);
  transition: opacity .5s var(--ease);
}
.service-card:hover .service-card__media img,
.service-card:focus-within .service-card__media img { transform: scale(1.07); }

.service-card__num {
  position: absolute; z-index: 2;
  top: clamp(18px, 1.7vw, 24px); left: clamp(18px, 1.7vw, 24px);
  display: grid; place-items: center; width: 46px; height: 46px;
  border-radius: 15px;
  background: rgba(255, 255, 255, .15); border: 1px solid rgba(255, 255, 255, .28);
  backdrop-filter: blur(9px) saturate(150%);
  -webkit-backdrop-filter: blur(9px) saturate(150%);
  font-family: var(--display); font-weight: 700; font-size: 1.12rem; line-height: 1;
  color: #fff;
  transition: background-color .4s var(--ease), border-color .4s var(--ease);
}
.service-card:hover .service-card__num { background: var(--red); border-color: var(--red); }

/* l'ombre compense le voile allege : la photo reste claire, le texte lisible */
.service-card__body {
  position: relative; z-index: 2;
  text-shadow: 0 1px 14px rgba(10, 8, 8, .58);
}
.service-card h3 {
  color: #fff; font-size: clamp(1.26rem, 1.55vw, 1.6rem);
  line-height: 1.04; text-wrap: balance;
}
/* petite barre de marque entre le titre et le texte */
.service-card h3::after,
.tile h3::after {
  content: ""; display: block; width: 34px; height: 2px;
  margin-top: 14px; border-radius: 2px; background: var(--red);
}
.service-card__body p {
  margin-top: 12px; font-size: .89rem; line-height: 1.62;
  color: rgba(255, 255, 255, .78);
}

.service-card__go {
  display: flex; align-items: center; gap: 12px;
  margin-top: clamp(18px, 1.8vw, 24px); padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, .24);
  font-family: var(--display); font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; font-size: .95rem; color: #fff;
}
.service-card__go span:first-child { margin-top: 1px; }
.service-card__go i {
  display: grid; place-items: center; flex: none;
  width: 38px; height: 38px; margin-left: auto;
  border: 1.5px solid rgba(255, 255, 255, .34); border-radius: 50%; color: #fff;
  transition: background-color .35s var(--ease), border-color .35s var(--ease),
              transform .35s var(--ease);
}
.service-card__go svg { width: 16px; height: 16px; }
.service-card:hover .service-card__go i,
.service-card:focus-within .service-card__go i {
  background: var(--red); border-color: var(--red); transform: translateX(4px);
}

.service-card__link { position: absolute; inset: 0; z-index: 5; border-radius: var(--r-lg); }
.service-card__link:focus-visible { outline: 3px solid var(--red); outline-offset: 3px; }

/* --------------------------------------------------------- 10. Duo image - */
.split {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: clamp(32px, 4.6vw, 70px); align-items: center;
}
.split--reverse .split__media { order: 2; }
.split__media { position: relative; }
.split__media img { width: 100%; border-radius: var(--r-lg); object-fit: cover; box-shadow: var(--sh); }

.badge-float {
  position: absolute; left: -16px; bottom: 26px;
  display: flex; align-items: center; gap: 14px;
  padding: 16px 22px; background: #fff;
  border-radius: var(--r); box-shadow: var(--sh-lg);
}
.badge-float strong { font-family: var(--display); font-size: 2.1rem; line-height: 1; color: var(--red); }
.badge-float span { font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink); line-height: 1.35; }

/* Atouts avec icône */
.feature-duo { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 18px; margin: 28px 0; }
.feature { padding: 22px 20px; background: var(--surface); border-radius: var(--r); transition: background-color .3s var(--ease); }
.feature:hover { background: var(--red-tint); }
.feature__icon { display: grid; place-items: center; width: 42px; height: 42px; border-radius: 12px; background: #fff; color: var(--red); margin-bottom: 14px; box-shadow: var(--sh-sm); }
.feature__icon svg { width: 21px; height: 21px; }
.feature h3 { font-size: 1.05rem; margin-bottom: 7px; }
.feature p { font-size: .89rem; line-height: 1.58; }

.checks { display: grid; gap: 12px; margin-top: 24px; }
.checks li { display: flex; align-items: flex-start; gap: 12px; font-size: .95rem; }
.checks svg { width: 20px; height: 20px; flex: none; margin-top: 3px; color: var(--red); }

.tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 26px; }
.tags li {
  padding: 7px 15px; background: #fff; border: 1px solid var(--line);
  border-radius: var(--r-pill); font-size: .78rem; font-weight: 500; color: var(--ink);
  transition: border-color .25s var(--ease), color .25s var(--ease);
}
.tags li:hover { border-color: var(--red); color: var(--red); }

/* ------------------------------------------------ 11. Pourquoi nous (dark) */
.why { position: relative; overflow: hidden; }
.why__bg { position: absolute; inset: 0; }
.why__bg img { width: 100%; height: 100%; object-fit: cover; }
.why__bg::after { content: ""; position: absolute; inset: 0; background: linear-gradient(100deg, rgba(33,29,29,.97), rgba(33,29,29,.86)); }
.why__inner { position: relative; }
.why__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 1px; background: var(--line-dark); border: 1px solid var(--line-dark); border-radius: var(--r); overflow: hidden; }
.why__item { background: var(--ink); padding: clamp(24px, 3vw, 36px); transition: background-color .35s var(--ease); }
.why__item:hover { background: var(--ink-2); }
.why__item .assurance__icon { background: rgba(219, 1, 28, .16); margin-bottom: 18px; }
.why__item h3 { margin-bottom: 9px; }
.why__item p { font-size: .91rem; color: rgba(255,255,255,.66); }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: clamp(20px, 3vw, 40px); margin-top: clamp(40px, 5vw, 64px); }
.stat__value { display: flex; align-items: baseline; font-family: var(--display); font-weight: 700; font-size: clamp(3rem, 6vw, 4.6rem); line-height: .9; color: var(--red); }
.stat__label { font-size: .78rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: #fff; margin-top: 12px; }
.stat p:not([class]) { font-size: .87rem; margin-top: 6px; color: rgba(255,255,255,.6); }
.section--surface .stat__label, .section:not(.section--dark) .stat__label { color: var(--ink); }
.section:not(.why) .stat p:not([class]) { color: var(--slate); }

/* -------------------------------------------------------- 12. Témoignages */
/* Les avis defilent en boucle dans un `.marquee` (meme mecanique que le bandeau
   partenaires, voir section 15 : pas de `gap` sur la piste, l'espacement passe
   par `margin-right`, sinon le -50% de l'animation ne vaut plus une periode).
   La vitesse propre du bandeau est portee par `data-speed` sur la piste. */
.marquee--reviews { padding-block: 8px 16px; }
/* les cartes s'alignent sur la plus haute, sinon la piste est en dents de scie */
.marquee--reviews .marquee__track { align-items: stretch; }
/* Largeur reprise de l'ancienne grille a trois colonnes : (1220 - 2 x 22) / 3 */
.marquee--reviews .review {
  flex: none; width: clamp(292px, 31vw, 392px); margin-right: 22px;
}
/* Avis tronque a 5 lignes, avec les points de suspension du navigateur. Sans ce
   plafond, la carte la plus bavarde imposait sa hauteur aux neuf autres et le
   bandeau devenait un mur. Le bouton mene aux avis complets.
   Le clamp porte sur un `span` interieur et non sur le `blockquote` : celui-ci
   est un enfant flex de la carte, son `display` est donc blockifie et
   `-webkit-box` n'y survivrait pas. */
.marquee--reviews .review__text {
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 5; line-clamp: 5;
  overflow: hidden;
}
/* Pas de pause au survol : demande du client, comme pour le bandeau
   partenaires. Le seul arret reste `prefers-reduced-motion`, plus bas. */

.review {
  display: flex; flex-direction: column;
  padding: 28px 26px; background: #fff;
  border: 1px solid var(--line); border-radius: var(--r-lg);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}
.review:hover { transform: translateY(-5px); box-shadow: var(--sh); }
/* bleu Google : les avis viennent de la fiche Google, les etoiles en portent la
   couleur plutot que l'or generique */
.review__stars { display: flex; gap: 3px; color: #4285f4; margin-bottom: 16px; }
.review__stars svg { width: 17px; height: 17px; }
.review blockquote { flex: 1; font-size: .96rem; color: var(--ink-soft); }
.review blockquote::before { content: "“"; font-family: var(--display); font-size: 2.6rem; line-height: 0; color: var(--red-tint-2); display: block; margin-bottom: 14px; }
.review__who { display: flex; align-items: center; gap: 12px; margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--line); }
/* Avatar facon fiche Google : initiales dans un rond, pastille « G » en bas a
   gauche. Le rond reste dans la palette de marque ; c'est la pastille seule qui
   porte la provenance. */
.review__av {
  position: relative;
  display: grid; place-items: center; width: 46px; height: 46px; flex: none;
  border-radius: 50%; background: var(--red-tint); color: var(--red-deep);
  font-family: var(--display); font-size: 1.1rem; font-weight: 700;
  letter-spacing: .04em;
}
.review__g {
  position: absolute; left: -3px; bottom: -3px;
  width: 19px; height: 19px; padding: 3px; box-sizing: border-box;
  background: #fff; border-radius: 50%;
  box-shadow: 0 1px 4px rgba(33, 29, 29, .24);
}
/* Le « G » garde ses quatre couleurs : ne pas le passer en currentColor. Comme
   l'une d'elles est le bleu du voile de survol, il lui faut son propre disque
   blanc, sinon la branche bleue disparait dans le fond au survol. Sur le bouton
   au repos, pose sur une section blanche, ce disque ne se voit pas.
   Selecteur descendant obligatoire, sinon la regle `.btn svg` impose 17 px. */
.btn .btn__g {
  width: 20px; height: 20px; padding: 3px;
  background: #fff; border-radius: 50%;
}
.review__who b { display: block; font-size: .92rem; color: var(--ink); }
.review__who span { font-size: .78rem; }

/* ------------------------------------------------------- 13. Réalisations */
.gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px; }
.gallery figure {
  position: relative; margin: 0; overflow: hidden; height: 100%;
  border-radius: var(--r); aspect-ratio: 4 / 5; background: var(--surface-2);
  transition: transform .5s var(--ease), box-shadow .5s var(--ease);
}
.gallery img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .8s var(--ease); }
.gallery figure::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to top, rgba(20,17,17,.93) 0%, rgba(20,17,17,.58) 38%, rgba(20,17,17,0) 70%);
  transition: opacity .4s var(--ease);
}
.gallery figure:hover { transform: translateY(-6px); box-shadow: var(--sh-lg); }
.gallery figure:hover img { transform: scale(1.06); }

.gallery figcaption {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  display: flex; align-items: flex-end; justify-content: space-between; gap: 16px;
  padding: clamp(16px, 1.7vw, 24px);
  font-size: .82rem; font-weight: 600; color: #fff;
}
.gallery figcaption h3 {
  color: #fff; font-size: clamp(1.02rem, 1.25vw, 1.34rem);
  line-height: 1.05; text-wrap: balance;
}
.gallery figcaption p {
  margin-top: 7px; font-size: .855rem; font-weight: 400; line-height: 1.45;
  color: rgba(255, 255, 255, .78);
}
.gallery__tag {
  flex: none; align-self: flex-end;
  padding: 8px 15px; border-radius: var(--r-pill);
  background: var(--red); color: #fff;
  font-family: var(--display); font-weight: 700;
  font-size: .92rem; line-height: 1; letter-spacing: .05em; text-transform: uppercase;
  box-shadow: 0 8px 20px rgba(143, 7, 20, .35);
  transition: background-color .35s var(--ease);
}
.gallery figure:hover .gallery__tag { background: var(--red-deep); }

/* Mosaique : rangees alternees large / etroit, comme 3+2 puis 2+3 */
.gallery--mosaic {
  grid-template-columns: repeat(5, minmax(0, 1fr));
  grid-auto-rows: clamp(240px, 25vw, 380px);
  gap: clamp(14px, 1.6vw, 20px);
}
.gallery--mosaic figure { aspect-ratio: auto; grid-column: span 3; }
.gallery--mosaic figure:nth-child(4n + 2),
.gallery--mosaic figure:nth-child(4n + 3) { grid-column: span 2; }

/* --------------------------------------------------------- 14. Étapes ---- */
/* Chronologie : les quatre etapes sont reliees par un rail qui se remplit au
   fil du defilement. Chaque .step porte son propre segment — ::before le trace
   en gris, ::after le repeint en rouge a hauteur de --sp (0 -> 1), pose par
   main.js. Un segment par etape plutot qu'un rail unique : il se dimensionne
   tout seul, et le dernier n'en a pas, donc le trait s'arrete a la 4e pastille.
   Repli sans JS et en mouvement reduit : --sp vaut 1, le rail est plein. */
.steps { display: grid; }
.step { --sp: 1; position: relative; }
.js .step { --sp: 0; }
.step::before,
.step::after { content: ""; position: absolute; border-radius: 2px; }
.step::before { background: var(--line); }
.step::after { background: var(--red); }
.step:last-child::before,
.step:last-child::after { display: none; }

.step__node {
  position: absolute; z-index: 1;
  display: grid; place-items: center; width: 42px; height: 42px;
  border-radius: 50%; background: var(--white); border: 2px solid var(--line);
  color: var(--slate);
  transition: background-color .45s var(--ease), border-color .45s var(--ease),
              color .45s var(--ease), box-shadow .45s var(--ease),
              transform .45s var(--ease);
}
.step em {
  font-style: normal; font-family: var(--display);
  font-size: 1.02rem; font-weight: 700; line-height: 1;
}
/* is-reached est pose par le JS quand le segment precedent est parcouru */
.step.is-reached .step__node,
html:not(.js) .step__node {
  background: var(--red); border-color: var(--red); color: #fff;
}
.step.is-reached .step__node { box-shadow: 0 0 0 6px var(--red-tint); }
.step:hover .step__node { transform: scale(1.08); }
.step h3 { margin-bottom: 9px; transition: color .35s var(--ease); }
.step:hover h3,
.step.is-reached h3 { color: var(--red); }
.step p { font-size: .91rem; }

/* Desktop : rail horizontal, colonnes centrees sous le chapeau centre.
   La pastille est au milieu de sa colonne (left 50% + marge negative, et non
   translateX : le survol garde ainsi son scale pour lui seul). Le segment va
   d'un bord de pastille a l'autre, gouttiere comprise — d'ou les 50 % et la
   gouttiere dans le calc. Ces trois valeurs (--st-gap, rayon 21, jeu de 12)
   vont ensemble : changer la gouttiere sans le calc decale le trait. */
@media (min-width: 900px) {
  .steps { --st-gap: 30px; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--st-gap); }
  .step { padding-top: 62px; text-align: center; }
  .step__node { top: 0; left: 50%; margin-left: -21px; }
  .step::before,
  .step::after {
    top: 20px; height: 2px;
    left: calc(50% + 33px);
    right: calc(33px - 50% - var(--st-gap));
  }
  .step::after { transform: scaleX(var(--sp)); transform-origin: left center; }
}

/* Mobile et tablette : la meme chronologie, a la verticale. */
@media (max-width: 899.98px) {
  .steps { grid-template-columns: 1fr; }
  .step { padding: 0 0 34px 62px; }
  .step:last-child { padding-bottom: 0; }
  .step__node { top: 0; left: 0; }
  .step::before,
  .step::after { top: 54px; left: 20px; bottom: -12px; width: 2px; }
  .step::after { transform: scaleY(var(--sp)); transform-origin: center top; }
}

@media (prefers-reduced-motion: reduce) {
  .js .step { --sp: 1; }
}


/* -------------------------------------------------------- 15. Partenaires */
.marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee__track { display: flex; align-items: center; width: max-content; animation: scrollX 30s linear infinite; will-change: transform; }
@keyframes scrollX { to { transform: translateX(-50%); } }
.marquee img {
  height: clamp(42px, 5vw, 60px); width: auto; object-fit: contain;
  margin-right: clamp(36px, 6vw, 78px); flex: none;
  filter: grayscale(1); opacity: .48;
  transition: filter .3s var(--ease), opacity .3s var(--ease);
}
.marquee img:hover { filter: none; opacity: 1; }

/* --------------------------------------------------------------- 16. FAQ - */
/* Accordéon natif : les <details> partagent un name, le navigateur n'en garde
   donc qu'un seul ouvert — aucun JS. Là où name n'est pas géré, ils s'ouvrent
   indépendamment, ce qui reste correct.

   La carte ouverte se signale par trois choses plutôt qu'une bordure rouge sur
   tout le tour : un rail rouge à gauche (::before, mis à l'échelle), la question
   en rouge, et un relief plus marqué. */
.faq { display: grid; gap: 12px; max-width: 880px; margin-inline: auto; }
.faq details {
  position: relative; overflow: hidden;
  background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease),
              transform .3s var(--ease);
}
.faq details::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 3px;
  background: var(--red); transform: scaleY(0); transform-origin: center;
  transition: transform .35s var(--ease);
}
.faq details:hover { border-color: var(--red-tint-2); box-shadow: var(--sh-sm); }
.faq details[open] {
  border-color: var(--red-tint-2); box-shadow: var(--sh);
}
.faq details[open]::before { transform: scaleY(1); }

.faq summary {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 21px 24px; cursor: pointer; list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq__q {
  font-family: var(--display); font-size: 1.16rem; font-weight: 700;
  text-transform: uppercase; color: var(--ink);
  transition: color .3s var(--ease);
}
.faq summary:hover .faq__q,
.faq details[open] .faq__q { color: var(--red); }

/* Le signe est dessiné en deux barres plutôt qu'en glyphe « + » : une croix
   faite d'un texte tourné à 135° ne se referme jamais tout à fait, et la barre
   verticale peut disparaître seule pour donner un « − ». */
.faq__sign {
  position: relative; flex: none; width: 34px; height: 34px; border-radius: 50%;
  background: var(--red-tint);
  transition: background-color .3s var(--ease), transform .35s var(--ease);
}
.faq__sign::before,
.faq__sign::after {
  content: ""; position: absolute; top: 50%; left: 50%;
  width: 13px; height: 2px; margin: -1px 0 0 -6.5px; border-radius: 2px;
  background: var(--red); transition: transform .35s var(--ease);
}
.faq__sign::after { transform: rotate(90deg); }
.faq summary:hover .faq__sign { transform: scale(1.08); }
.faq details[open] .faq__sign { background: var(--red); }
.faq details[open] .faq__sign::before,
.faq details[open] .faq__sign::after { background: #fff; }
.faq details[open] .faq__sign::after { transform: rotate(0deg); }

/* le filet part de la marge de la question, pas du bord de la carte */
.faq__body { padding: 0 24px 22px; font-size: .95rem; }
.faq__body p { padding-top: 18px; border-top: 1px solid var(--line); }

/* Ouverture animée, là où le navigateur sait interpoler vers `auto`
   (Chrome 131+, Safari 18.4+, Firefox 139+). Ailleurs le bloc entier est
   ignoré et le panneau s'ouvre d'un coup, comme avant : rien n'est masqué.
   interpolate-size est posé sur .faq et non sur :root — il est hérité, autant
   ne pas ouvrir l'interpolation des mots-clés à toute la page. */
@supports selector(::details-content) {
  .faq { interpolate-size: allow-keywords; }
  .faq details::details-content {
    block-size: 0; overflow: hidden;
    transition: block-size .4s var(--ease), content-visibility .4s allow-discrete;
  }
  .faq details[open]::details-content { block-size: auto; }
}

/* -------------------------------------------------- 17. Zone d'intervention */
.zone-grid { display: grid; grid-template-columns: minmax(0, .92fr) minmax(0, 1.08fr); gap: clamp(28px, 4vw, 56px); align-items: center; }

/* Communes : pastilles plutot qu'une liste a filets */
.zone-chips { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 28px; padding: 0; list-style: none; }
.zone-chips li {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 9px 16px; border-radius: var(--r-pill);
  background: var(--surface); border: 1px solid var(--line);
  font-size: .865rem; font-weight: 500; color: var(--ink);
  transition: background-color .3s var(--ease), border-color .3s var(--ease), color .3s var(--ease);
}
.zone-chips li::before {
  content: ""; flex: none; width: 6px; height: 6px;
  border-radius: 50%; background: var(--red);
  transition: transform .3s var(--ease);
}
.zone-chips li:hover { background: var(--red-tint); border-color: var(--red-tint-2); color: var(--red); }
.zone-chips li:hover::before { transform: scale(1.5); }

.zone-note {
  display: flex; align-items: flex-start; gap: 11px;
  margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--line);
  font-size: .9rem;
}
.zone-note svg { width: 17px; height: 17px; flex: none; margin-top: 4px; color: var(--red); }
.zone-note strong { color: var(--ink); }

/* Carte statique + rayon de 40 km trace en SVG.
   Le repere 1400x1000 reprend la geometrie de la tuile OSM d'origine
   (zoom 10, Givors au centre) : 1 unite = 1 px de carte, donc 374 unites = 40 km.
   L'agrandissement de 1,15 se fait a deux endroits qui doivent rester d'accord :
   `transform: scale(1.15)` sur l'image et le viewBox recadre du SVG dans le HTML.
   Ne pas changer le recadrage de l'image sans recalculer ce rayon. */
.zone-map {
  position: relative; margin: 0;
  border-radius: var(--r-lg); overflow: hidden;
  border: 1px solid var(--line); box-shadow: var(--sh-sm);
  line-height: 0; background: var(--surface-2);
}
.zone-map img {
  width: 100%; height: auto; display: block;
  /* zoom optique : la figure porte deja overflow:hidden, qui fait le recadrage.
     Le SVG ne recoit pas ce scale, c'est son viewBox qui cadre la meme fenetre. */
  transform: scale(1.15);
  filter: saturate(.8) contrast(1.03);
}
.zone-map__overlay { position: absolute; inset: 0; width: 100%; height: 100%; }
.zone-map__halo { fill: rgba(219, 1, 28, .11); }
.zone-map__ring { fill: none; stroke: var(--red); stroke-width: 3; }
.zone-map__radius { stroke: var(--red); stroke-width: 2.2; stroke-dasharray: 10 8; opacity: .85; }
.zone-map__pulse { fill: rgba(219, 1, 28, .3); }
.zone-map__dot { fill: var(--red); stroke: #fff; stroke-width: 3.5; }
.zone-map__city, .zone-map__km {
  font-family: var(--display); font-weight: 700; text-transform: uppercase;
  text-anchor: middle; letter-spacing: .02em;
  paint-order: stroke; stroke: #fff; stroke-width: 7; stroke-linejoin: round;
}
.zone-map__city { font-size: 33px; fill: var(--ink); }
.zone-map__km { font-size: 28px; fill: var(--red); }

/* Communes reperees autour de Givors : pastille sombre + nom en petit.
   Tailles exprimees en unites du viewBox, donc reduites d'autant par le recadrage. */
.zone-map__towns circle { fill: var(--ink-2); stroke: #fff; stroke-width: 2.6; }
.zone-map__towns text {
  font-family: var(--body); font-size: 22px; font-weight: 600;
  fill: var(--ink-2); letter-spacing: .01em;
  paint-order: stroke; stroke: rgba(255, 255, 255, .92); stroke-width: 5.5; stroke-linejoin: round;
}
.zone-map__credit {
  position: absolute; right: 10px; bottom: 9px;
  padding: 4px 10px; border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .82); color: rgba(33, 29, 29, .6);
  font-size: .66rem; line-height: 1.5;
}

/* ----------------------------------------------------------- 18. Contact - */
.contact-grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: clamp(30px, 4vw, 56px); align-items: start; }
.card { padding: clamp(26px, 3.2vw, 42px); background: #fff; border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--sh-sm); }
.section--dark .card { background: var(--ink-2); border-color: var(--line-dark); box-shadow: none; }

.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 16px; }
.field { display: flex; flex-direction: column; gap: 7px; }
.field--full { grid-column: 1 / -1; }
.field label { font-size: .74rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--ink); }
.section--dark .field label { color: rgba(255,255,255,.72); }
.field label b { color: var(--red); }
/* background-color et non background : le raccourci ecraserait le chevron du
   select, qui est une background-image posee plus bas */
.field input, .field select, .field textarea {
  padding: 14px 16px; background-color: var(--surface);
  border: 1px solid transparent; border-radius: 12px;
  font-size: .95rem;
  transition: border-color .25s var(--ease), background-color .25s var(--ease),
              box-shadow .25s var(--ease);
}
/* Safari iOS zoome sur un champ des que son texte fait moins de 16 px, et ne
   dezoome jamais ensuite. Les .95rem valent 15,2 px : on passe a 16 px pile sur
   les appareils tactiles. Requete sur `pointer` et non sur la largeur, parce
   que c'est le mode de saisie qui declenche le zoom, pas la taille d'ecran.
   Ne pas « corriger » en ajoutant maximum-scale au viewport : cela desactive
   aussi le zoom a deux doigts. Valeur en px et non en rem : c'est bien le
   calcule qui doit atteindre 16, quelle que soit la taille de police du
   navigateur. */
@media (pointer: coarse) {
  .field input, .field select, .field textarea { font-size: 16px; }
}
.section--dark .field input, .section--dark .field select, .section--dark .field textarea {
  background-color: rgba(255,255,255,.06); border-color: var(--line-dark); color: #fff;
  /* fait basculer les widgets natifs (liste deroulante incluse) en theme sombre */
  color-scheme: dark;
}
.field textarea { resize: vertical; min-height: 130px; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--red); background-color: #fff;
  box-shadow: 0 0 0 3px rgba(219, 1, 28, .16);
}
.section--dark .field input:focus, .section--dark .field select:focus, .section--dark .field textarea:focus { background-color: rgba(255,255,255,.1); }
.field input::placeholder, .field textarea::placeholder { color: #a5a0a0; }

/* ---- Selecteur de prestation ------------------------------------------- */
/* Chevron maison : meme trace que celui de la navigation. La couleur passe par
   --chev, une variable qui porte l'URL entiere — on ne peut pas interpoler une
   couleur a l'interieur d'un url(). */
.field select {
  appearance: none; -webkit-appearance: none;
  padding-right: 44px; cursor: pointer;
  --chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236c6666' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-image: var(--chev);
  background-repeat: no-repeat;
  background-position: right 16px center;
  background-size: 13px 13px;
}
.section--dark .field select {
  --chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round' opacity='.62'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
}
.field select:hover, .field select:focus,
.section--dark .field select:hover, .section--dark .field select:focus {
  --chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23db011c' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
}
.field select:hover { border-color: var(--red-tint-2); }
.section--dark .field select:hover { border-color: rgba(219, 1, 28, .45); }
/* replis pour les navigateurs sans appearance: base-select (Firefox, Safari) :
   la liste reste native, mais au moins aux couleurs du formulaire */
.section--dark .field select option { background-color: var(--ink); color: #fff; }

/* Liste deroulante entierement dessinee — Chromium 135+. Ailleurs, le bloc est
   ignore et l'on garde le champ ci-dessus avec la liste native. */
@supports (appearance: base-select) {
  .field select, .field select::picker(select) { appearance: base-select; }
  .field select {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding-right: 16px; text-align: left; background-image: none;
  }
  .field select::picker-icon {
    content: var(--chev);
    width: 13px; height: 13px; flex: none;
    transition: transform .28s var(--ease);
  }
  .field select:open::picker-icon { transform: rotate(180deg); }

  .field select::picker(select) {
    /* les deux marges : le panneau bascule au-dessus du champ quand il manque
       de place en bas, il faut alors la respiration de l'autre cote */
    margin-top: 8px; margin-bottom: 8px;
    padding: 7px; width: anchor-size(width);
    scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.22) transparent;
    background: var(--ink); border: 1px solid var(--line-dark); border-radius: 16px;
    box-shadow: 0 22px 50px rgba(0, 0, 0, .45);
    /* l'ouverture est animee : overlay et display doivent etre transitionnes
       en allow-discrete, sinon le panneau apparait d'un coup */
    opacity: 0; transform: translateY(-6px);
    transition: opacity .2s var(--ease), transform .2s var(--ease),
                overlay .2s allow-discrete, display .2s allow-discrete;
  }
  .field select:open::picker(select) { opacity: 1; transform: none; }
  @starting-style {
    .field select:open::picker(select) { opacity: 0; transform: translateY(-6px); }
  }

  .field select option {
    display: flex; align-items: center; gap: 10px;
    padding: 11px 13px; border-radius: 11px;
    background-color: transparent; color: rgba(255,255,255,.82);
    font-size: .92rem; line-height: 1.35;
    transition: background-color .18s var(--ease), color .18s var(--ease);
  }
  .field select option:hover,
  .field select option:focus { background-color: rgba(255,255,255,.08); color: #fff; }
  .field select option:checked { background-color: rgba(219, 1, 28, .18); color: #fff; }
  .field select option::checkmark { order: 1; margin-left: auto; color: var(--red); }
}
.form-note { font-size: .78rem; margin-top: 14px; }
.form-status { display: none; margin-top: 14px; padding: 14px 18px; border-radius: 12px; font-size: .89rem; line-height: 1.55; }
.form-status.is-visible { display: block; }
/* Deux etats seulement : l'attente et l'echec. Le succes ne passe plus par ici,
   c'est la carte entiere qui bascule (voir `.form-done` plus bas). Le bloc
   #devis etant sombre, les deux restent sur fond translucide clair — un aplat
   blanc y ferait un trou dans la section. */
.form-status--info { background: rgba(255,255,255,.08); color: rgba(255,255,255,.82); }
.form-status--err { background: rgba(255,255,255,.08); color: #fff; box-shadow: inset 3px 0 0 var(--red); }
.form-status--err a { color: #fff; font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }

/* Champ piege. Pas de `display: none` ni de `hidden` : les robots les mieux
   faits sautent ce qui est masque ainsi, alors qu'ils remplissent un champ
   simplement pousse hors de l'ecran. `.field` etant un flex, l'attribut
   `hidden` serait de toute facon sans effet ici. */
.field--hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Pendant l'envoi. Le bouton reste en place — le retirer ferait sauter la
   page au moment ou le visiteur regarde le message d'etat juste en dessous. */
.btn[disabled] { opacity: .55; cursor: default; pointer-events: none; }

/* ------------------------------------------ Confirmation d'envoi (.form-done)

   Au succes, la carte entiere bascule : tout ce qu'elle portait s'efface et ce
   panneau prend sa place, la hauteur de la carte suivant le changement. Le
   message tenait avant sur une ligne sous le bouton, au bas d'un formulaire
   toujours rempli — rien ne disait clairement que la demande etait partie.

   Le panneau est **fabrique par main.js**, pas ecrit dans les 8 pages : il
   n'apparait que dans un etat que seul le script peut atteindre, et le
   dupliquer huit fois n'offrirait qu'une occasion de divergence de plus. */
.form-vanished { display: none !important; }
.card .is-leaving { opacity: 0; transform: translateY(-10px); transition: opacity .2s var(--ease), transform .2s var(--ease); }

/* La transition est portee par `.form-done` et non par `.is-in` : declaree sur
   la seule classe d'arrivee, elle disparaitrait avec elle et le panneau
   s'effacerait d'un coup au retour vers le formulaire. */
.form-done { text-align: center; padding: clamp(8px, 2vw, 26px) 0; opacity: 0; transform: translateY(18px); transition: opacity .4s var(--ease), transform .45s var(--ease); }
.form-done.is-in { opacity: 1; transform: none; transition: opacity .5s var(--ease), transform .55s var(--ease); }
.form-done:focus { outline: none; }
.form-done:focus-visible { outline: 2px solid var(--red); outline-offset: 8px; border-radius: var(--r); }

.form-done__mark { position: relative; display: grid; place-items: center; width: 92px; height: 92px; margin: 0 auto 24px; }
/* L'onde qui part de la pastille. Un `::after` plutot qu'un element : rien a
   nettoyer quand le visiteur revient au formulaire. */
.form-done__mark::after { content: ""; position: absolute; inset: 0; border-radius: 50%; border: 2px solid var(--red); opacity: 0; }
.form-done.is-in .form-done__mark::after { animation: done-onde .9s var(--ease) .25s 1; }
.form-done__mark svg { width: 92px; height: 92px; }
/* `pathLength="1"` sur le cercle et la coche : le trace se decrit alors en
   fractions, sans avoir a mesurer la longueur reelle de chaque forme — qui
   changerait au premier ajustement du dessin. */
.form-done__mark circle,
.form-done__mark path { stroke-dasharray: 1; stroke-dashoffset: 1; }
.form-done.is-in .form-done__mark circle { animation: done-trace .55s var(--ease) .05s forwards; }
.form-done.is-in .form-done__mark path { animation: done-trace .3s var(--ease) .5s forwards; }

.form-done h3 { font-family: var(--display); font-size: clamp(1.75rem, 3.6vw, 2.4rem); line-height: 1.05; text-transform: uppercase; color: #fff; }
.form-done p { margin-top: 14px; color: rgba(255,255,255,.72); font-size: .95rem; line-height: 1.65; max-width: 42ch; margin-left: auto; margin-right: auto; }
.form-done p b { color: #fff; font-weight: 700; }
.form-done__acts { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 14px 22px; margin-top: 28px; }
.form-done__again { background: none; border: 0; padding: 0; cursor: pointer; font: inherit; font-size: .84rem; color: rgba(255,255,255,.62); text-decoration: underline; text-underline-offset: 4px; transition: color .2s var(--ease); }
.form-done__again:hover { color: #fff; }

@keyframes done-trace { to { stroke-dashoffset: 0; } }
@keyframes done-onde {
  0%   { opacity: .7; transform: scale(.72); }
  100% { opacity: 0;  transform: scale(1.5); }
}

/* Le panneau doit rester lisible sans animation : on ne coupe que le
   mouvement, jamais l'affichage — un trace fige a `stroke-dashoffset: 1`
   laisserait une pastille vide a la place de la coche. */
@media (prefers-reduced-motion: reduce) {
  .card .is-leaving { transition: none; }
  .form-done { opacity: 1; transform: none; transition: none; }
  .form-done__mark circle, .form-done__mark path { stroke-dashoffset: 0; animation: none; }
  .form-done .form-done__mark::after { animation: none; }
}

.info-list { display: grid; }
.info-list li { display: flex; gap: 15px; padding: 18px 0; border-bottom: 1px solid var(--line); }
.section--dark .info-list li { border-color: var(--line-dark); }
.info-list li:last-child { border-bottom: 0; }
.info-list__icon { display: grid; place-items: center; width: 44px; height: 44px; flex: none; border-radius: 13px; background: var(--red-tint); color: var(--red); }
.section--dark .info-list__icon { background: rgba(219, 1, 28, .16); }
.info-list__icon svg { width: 21px; height: 21px; }
.info-list h3 { font-size: .98rem; margin-bottom: 2px; }
.info-list a:hover { color: var(--red); }

/* ------------------------------------------------------------- 19. CTA --- */
/* Bande rouge pleine largeur, juste avant le footer */
.cta-band { background: var(--red); }
.cta-red {
  background: none; color: #fff;
  border-radius: 0; box-shadow: none;
  padding: clamp(6px, 1.4vw, 20px) 0;
  text-align: center;
}
.cta-red h2 { color: #fff; }
.cta-red p { max-width: 620px; margin: 18px auto 0; color: #fff; }
.cta-red .btn-row { justify-content: center; }

.callout {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 24px; padding: clamp(26px, 3.4vw, 42px) clamp(24px, 4vw, 48px);
  background: var(--ink); border-radius: var(--r-lg); color: #fff;
}
.callout h3 { color: #fff; margin-bottom: 5px; }
.callout p { color: rgba(255,255,255,.66); font-size: .93rem; }

/* ---------------------------------------------------------- 20. Footer --- */
.site-footer { background: var(--ink); color: rgba(255,255,255,.6); padding-top: clamp(52px, 6.5vw, 84px); }
.footer-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1.2fr; gap: clamp(28px, 4vw, 54px); padding-bottom: clamp(42px, 5vw, 62px); }
.site-footer h3 { color: #fff; font-size: 1.08rem; letter-spacing: .08em; margin-bottom: 20px; }
.site-footer .brand__name { color: #fff; }
.site-footer p { font-size: .9rem; }
.footer-links { display: grid; gap: 10px; }
.footer-links a { font-size: .9rem; display: inline-block; transition: color .22s var(--ease), transform .22s var(--ease); }
.footer-links a:hover { color: var(--red); transform: translateX(4px); }
.footer-contact { display: grid; gap: 15px; }
.footer-contact li { display: flex; gap: 12px; font-size: .9rem; }
.footer-contact svg { width: 16px; height: 16px; color: var(--red); flex: none; margin-top: 4px; }
.footer-contact a:hover { color: #fff; }
.footer-bottom {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 12px; padding-block: 22px; border-top: 1px solid var(--line-dark); font-size: .8rem;
}
.footer-bottom a:hover { color: var(--red); }

/* Acces a l'espace admin (devis) : volontairement discret, il ne s'adresse
   qu'au gerant. Il vit dans la ligne de copyright pour ne pas modifier la
   mise en page en deux colonnes du bas de pied. La page elle-meme est en
   noindex et refusee par robots.txt. */
.footer-admin {
  margin-left: 10px; padding-left: 11px; border-left: 1px solid var(--line-dark);
  color: rgba(255, 255, 255, .46); font-size: .74rem;
}

/* Credit d'agence, en pastille. Le logo est fourni en blanc : il ne tient que
   sur le fond sombre du pied de page, ne pas le reprendre ailleurs. */
.made {
  display: inline-flex; align-items: center; gap: 9px; flex: 0 0 auto;
  padding: 4px 12px; border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .14);
  transition: background-color .2s var(--ease), border-color .2s var(--ease);
}
.made:hover { background: rgba(255, 255, 255, .1); border-color: rgba(255, 255, 255, .3); }
.made span {
  font-size: 9.5px; font-weight: 500; letter-spacing: .2em; text-transform: uppercase;
  color: rgba(255, 255, 255, .6); transition: color .2s var(--ease);
}
.made:hover span { color: #fff; }
.made img { height: 14px; width: auto; display: block; }
/* la pastille ne doit pas heriter du survol rouge des autres liens du pied */
.footer-bottom .made:hover { color: inherit; }

/* meme traitement que l'en-tete : encre translucide et filet clair */
.mobile-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
  display: none; gap: 9px; padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  background: rgba(15,13,13,.92); backdrop-filter: blur(14px) saturate(170%);
  border-top: 1px solid var(--line-dark); box-shadow: 0 -8px 26px rgba(33,29,29,.3);
}
.mobile-bar .btn { flex: 1; padding: 14px 8px; font-size: .72rem; }
/* le bouton fantome est dessine pour un fond clair : on l'inverse ici */
.mobile-bar .btn--ghost { color: #fff; border-color: rgba(255,255,255,.34); }

/* -------------------------------------------------------- 21. Animations - */
.js [data-reveal] { opacity: 0; transform: translateY(24px); transition: opacity .75s var(--ease), transform .75s var(--ease); }
.js [data-reveal].is-visible { opacity: 1; transform: none; }
.js [data-reveal][data-delay="1"] { transition-delay: .08s; }
.js [data-reveal][data-delay="2"] { transition-delay: .16s; }
.js [data-reveal][data-delay="3"] { transition-delay: .24s; }
.js [data-reveal][data-delay="4"] { transition-delay: .32s; }
.js [data-reveal][data-delay="5"] { transition-delay: .40s; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
  /* La regle generique ci-dessus ecrase la duree a .001ms : le bandeau d'avis
     se figerait a -50%, sur une carte coupee au hasard. On coupe l'animation
     net et on rend la piste parcourable a la main. */
  .marquee--reviews .marquee__track { animation: none !important; transform: none !important; }
  .marquee--reviews { overflow-x: auto; }
  /* La regle generique ne vise que ::before et ::after : ::details-content
     garderait sa transition, et la FAQ s'ouvrirait encore en glissant. */
  .faq details::details-content { transition: none !important; }
}

/* -------------------------------------------------------- 22. Responsive - */
@media (max-width: 1180px) {
  .nav__link { padding: 10px 10px; font-size: .78rem; }
  .services { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 1024px) {
  .nav, .header__cta .btn { display: none; }
  .site-header { border-bottom-color: var(--line-dark); }
  .burger { display: block; }
  .contact-grid, .zone-grid { grid-template-columns: 1fr; }
  .head--wide { grid-template-columns: 1fr; align-items: start; }
  .assurance__item { border-right: 0; border-bottom: 1px solid var(--line); }
  .assurance__item:last-child { border-bottom: 0; }
  /* 2 colonnes : le filet vertical ne separe plus que les paires */
  .spec { grid-template-columns: 1fr 1fr; }
  .spec > div { padding: 22px 26px 26px; }
  .spec > div:nth-child(odd) { padding-left: 0; border-right: 1px solid rgba(255,255,255,.17); }
  .spec > div:nth-child(even) { padding-right: 0; border-right: 0; }
  .spec > div:nth-child(-n+2) { border-bottom: 1px solid rgba(255,255,255,.17); }
}

@media (max-width: 860px) {
  :root { --hdr: 70px; }
  .topbar__list { display: none; }
  .topbar__inner { justify-content: center; gap: 0; }
  .topbar__badge { white-space: normal; text-align: center; font-size: .74rem; }
  .split--reverse .split__media { order: 0; }
  .hero { min-height: auto; }
  .assurance { margin-top: -30px; }
  .mobile-bar { display: flex; }
  body { padding-bottom: 72px; }
  .badge-float { left: 12px; bottom: 12px; padding: 12px 16px; }
  /* Le bandeau de reperes ne sort pas en mobile : demande du client. Les memes
     promesses sont reprises juste en dessous par .assurance, et par la barre
     fixe du bas — rien n'est perdu. Le contenu reste dans le HTML pour le
     desktop, c'est la mise en page qui le retire ici. */
  .spec { display: none; }
}

@media (max-width: 680px) {
  .services { grid-template-columns: 1fr; gap: 16px; }
  /* la photo n'a plus de ratio propre : elle remplit la carte, c'est donc la
     hauteur de la carte qui se regle */
  .service-card { min-height: 400px; }
}

@media (max-width: 560px) {
  .footer-grid { grid-template-columns: 1fr; }
  .brand img { width: 40px; height: 40px; }
  .brand__name { font-size: 1.35rem; }
  .btn { width: 100%; }
  .btn-row .btn { width: auto; flex: 1 1 190px; }
  .gallery { grid-template-columns: 1fr 1fr; }
  .gallery figcaption { padding: 14px; font-size: .74rem; }
  .gallery figcaption p { display: none; }
  .gallery__tag { padding: 6px 11px; font-size: .8rem; }
}

/* Mosaique : 2 colonnes en tablette, 1 colonne en mobile */
@media (max-width: 960px) {
  .gallery--mosaic { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: clamp(210px, 32vw, 300px); }
  .gallery--mosaic figure,
  .gallery--mosaic figure:nth-child(4n + 2),
  .gallery--mosaic figure:nth-child(4n + 3) { grid-column: span 1; }
}

@media (max-width: 620px) {
  .gallery--mosaic { grid-template-columns: 1fr; grid-auto-rows: clamp(230px, 62vw, 300px); }
  .gallery--mosaic figcaption p { display: block; }
  /* la carte tombe a ~335 px : on grossit les libelles, exprimes en unites de
     viewBox, et on retire les communes qui se chevaucheraient a cette echelle */
  .zone-map__towns-dense { display: none; }
  .zone-map__towns text { font-size: 34px; stroke-width: 8; }
  .zone-map__city { font-size: 48px; }
  .zone-map__km { font-size: 40px; }
}

@media print {
  .site-header, .topbar, .mobile-bar, .marquee, .cta-red { display: none !important; }
  body { color: #000; background: #fff; }
}

/* ------------------------------- 23. Tuiles de prestation (pages internes) */
/* Meme dessin que les cartes de l'accueil (.service-card) : photo pleine,
   degrade vers le bas, contenu pose dessus, numero en pastille de verre en
   haut a gauche. La difference : ces tuiles ne menent nulle part, elles n'ont
   donc pas de ligne « Voir la prestation » ni de lien de recouvrement. */
.tiles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(255px, 1fr));
  gap: clamp(16px, 1.8vw, 26px);
}
.tile {
  position: relative; isolation: isolate;
  display: flex; flex-direction: column; justify-content: flex-end;
  min-height: clamp(380px, 29vw, 460px);
  padding: clamp(20px, 1.9vw, 26px);
  border-radius: var(--r-lg); overflow: hidden;
  background: var(--ink); box-shadow: var(--sh-sm);
  transition: transform .5s var(--ease), box-shadow .5s var(--ease);
}
/* liseré du survol en calque : une vraie bordure decalerait le contenu */
.tile::after {
  content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  border-radius: inherit; border: 2px solid transparent;
  transition: border-color .45s var(--ease);
}
.tile:hover { transform: translateY(-6px); box-shadow: var(--sh-lg); }
.tile:hover::after { border-color: var(--red); }

/* z-index 0 et non -1 : la tuile a son propre fond, un calque negatif
   passerait derriere et disparaitrait */
.tile__media { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.tile__media img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform 1.1s var(--ease);
}
.tile__media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg,
    rgba(18, 15, 15, .02) 0%, rgba(18, 15, 15, .13) 32%,
    rgba(18, 15, 15, .54) 58%, rgba(18, 15, 15, .90) 100%);
}
.tile:hover .tile__media img { transform: scale(1.07); }

.tile__num {
  position: absolute; z-index: 2;
  top: clamp(18px, 1.7vw, 24px); left: clamp(18px, 1.7vw, 24px);
  display: grid; place-items: center; width: 46px; height: 46px; margin: 0;
  border-radius: 15px;
  background: rgba(255, 255, 255, .15); border: 1px solid rgba(255, 255, 255, .28);
  backdrop-filter: blur(9px) saturate(150%);
  -webkit-backdrop-filter: blur(9px) saturate(150%);
  font-family: var(--display); font-weight: 700;
  font-size: 1.12rem; line-height: 1; letter-spacing: normal; color: #fff;
  transition: background-color .4s var(--ease), border-color .4s var(--ease);
}
.tile:hover .tile__num { background: var(--red); border-color: var(--red); }

.tile__body {
  position: relative; z-index: 2; padding: 0;
  text-shadow: 0 1px 14px rgba(10, 8, 8, .58);
}
.tile h3 { margin-bottom: 12px; color: #fff; }
.tile p { font-size: .89rem; line-height: 1.62; color: rgba(255, 255, 255, .78); }
