/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   K&L Nettoyage — la DA de la carte de visite V10 (verso noir) :
   la poussière sur une surface noire, la traînée propre d'un chiffon bleu, la crème, les points
   bleus, Fraunces (opsz 144) et Jost. Sources : claude-master/transverse/kl-nettoyage/*.py.

   ⚠️ L'EFFET EST UNE COUCHE. Sans JavaScript, ou en prefers-reduced-motion, la page est la
   version FINALE : traînées posées, poussière immobile, tout le texte lisible. Les états de départ
   des animations ne vivent que sous `.mouvement` (posée par le script en ligne de base.html.twig).
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */

@font-face {
    font-family: "Fraunces";
    src: url("../fonts/fraunces-600-o3bxYJ0.woff2") format("woff2");
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Fraunces";
    src: url("../fonts/fraunces-italique-400-TLUbqrb.woff2") format("woff2");
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}
@font-face {
    font-family: "Jost";
    src: url("../fonts/jost-fxw6rnC.woff2") format("woff2");
    font-weight: 400 700;
    font-style: normal;
    font-display: swap;
}

/* Les polices de REPLI, à la largeur des vraies (mesurée le 5 oct. 2026 sur un paragraphe : Jost =
   95 % d'Arial, Fraunces 600 = 75 % de Georgia, Fraunces italique = 79,5 % de Georgia italique).
   Sans elles, le passage du repli à la vraie police (font-display: swap) déplace le texte : un CLS
   de 0,24 a été mesuré une fois sur trois à l'accueil, après le grossissement des textes. */
@font-face { font-family: "Jost repli"; src: local("Arial"); size-adjust: 95%; }
@font-face { font-family: "Fraunces repli"; src: local("Georgia"); size-adjust: 75%; }
@font-face { font-family: "Fraunces repli"; src: local("Georgia Italic"), local("Georgia-Italic"); font-style: italic; size-adjust: 79.5%; }

:root {
    /* la surface propre (verso-noir.py : « propre = 8 + 30 × lum^1.6 ») */
    --noir: #0c0c0d;
    --noir-2: #131314;
    /* CREME (236, 229, 214) et CR2 (210, 204, 193) de la carte */
    /* LISIBILITÉ (Alexandre, 5 oct. : « le noir mange le texte ») : crème plus franche, seconds plans
       relevés — contrastes MESURÉS sur le rendu (rapport K-SITE) : texte courant >= 7:1 sur le noir */
    --creme: #f6f1e7;
    --creme-2: #e6e0d4;
    --gris: #c9c3b7;
    /* BLEU (96, 150, 230) : les points entre les prestations, le chiffon */
    --bleu: #6096e6;
    /* le bleu en TEXTE (numéros, petites capitales) : plus clair que le bleu des points, pour l'AAA */
    --bleu-texte: #9cc0f5;
    --filet: rgba(236, 229, 214, 0.16);

    --serif: "Fraunces", "Fraunces repli", Georgia, serif;
    --sans: "Jost", "Jost repli", Arial, sans-serif;

    --gouttiere: 20px;
    --largeur: 76rem;
    --courbe: cubic-bezier(0.4, 0, 0.2, 1);
    color-scheme: dark;
}
@media (min-width: 700px) { :root { --gouttiere: 40px; } }
@media (min-width: 1100px) { :root { --gouttiere: 64px; } }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body {
    margin: 0;
    min-width: 320px;
    background: var(--noir) url("../images/grain-SH52G40.webp") repeat;
    color: var(--creme);
    font: 400 1.125rem/1.6 var(--sans);
    overflow-x: clip;
}
img { max-width: 100%; display: block; }
a { color: inherit; }
h1, h2, h3, p, ul, ol, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
address { font-style: normal; }
main:focus { outline: none; }

:focus-visible { outline: 2px solid var(--bleu); outline-offset: 3px; border-radius: 2px; }

.evitement {
    position: absolute; left: 12px; top: -100px; z-index: 50;
    background: var(--creme); color: var(--noir); padding: 10px 16px; font-weight: 600; text-decoration: none;
}
.evitement:focus { top: 12px; }

.point { color: var(--bleu); font-weight: 800; }

/* ─── Boutons ──────────────────────────────────────────────────────────────────────────────── */
.bouton {
    display: inline-flex; align-items: center; justify-content: center; gap: 0.5em;
    min-height: 48px; padding: 0.7em 1.4em;
    background: var(--creme); color: var(--noir);
    font: 600 1.0625rem/1.2 var(--sans); letter-spacing: 0.02em; text-decoration: none;
    border: 1px solid var(--creme); border-radius: 2px;
    transition: background-color 0.2s, color 0.2s, transform 0.2s;
}
.bouton:hover { background: #fff; }
.bouton:active { transform: translateY(1px); }
.bouton--fantome { background: rgba(12, 12, 13, 0.55); color: var(--creme); font-variant-numeric: tabular-nums; }
.bouton--fantome:hover { background: var(--noir); color: #fff; }
.bouton--petit { min-height: 44px; padding: 0.55em 1em; font-size: 1rem; }
.large-seulement { display: none; }
@media (min-width: 700px) { .large-seulement { display: inline; } }

/* ─── En-tête (posé sur le héros, il ne suit pas le défilement) ───────────────────────────── */
.entete {
    position: absolute; top: 0; left: 0; right: 0; z-index: 20;
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    padding: 16px var(--gouttiere);
}
.marque { display: inline-flex; align-items: baseline; gap: 0.55em; text-decoration: none; min-height: 44px; align-items: center; }
.marque__kl { font: 600 1.75rem/1 var(--serif); letter-spacing: -0.01em; }
.marque__mot { font: 500 0.8125rem/1 var(--sans); letter-spacing: 0.32em; text-transform: uppercase; }
.entete__nav { display: none; }
@media (min-width: 900px) {
    .entete__nav { display: flex; gap: 32px; margin-left: auto; margin-right: 16px; }
    .entete__nav a {
        font: 600 0.9375rem/1 var(--sans); letter-spacing: 0.12em; text-transform: uppercase; text-decoration: none;
        padding: 14px 0; color: var(--creme); text-shadow: 0 0 10px #000, 0 0 3px #000;
    }
    .entete__nav a:hover { color: var(--creme); }
}

/* ═══ LA TRAÎNÉE — la bande propre au bord irrégulier ═════════════════════════════════════════
   L'image porte le bord déchiqueté et le bourrelet de poussière poussée (trainee-*.webp, générée
   par tools/generer-medias.py comme la carte). Elle part EXACTEMENT du bord gauche de l'écran
   (--debord : la distance du texte au bord, selon la mise en page) et s'arrête là où le texte
   finit — là où est posé le chiffon. ⚠️ Pas « -100vw » : l'essuyage passerait la moitié de sa
   durée hors de l'écran, et l'entrée commencerait par une seconde où rien ne bouge. */
.heros, .section, .devis { --debord: calc(max(var(--gouttiere), (100vw - var(--largeur)) / 2) + 12px); }
.page-texte { --debord: calc(max(var(--gouttiere), (100vw - 52rem) / 2) + 12px); }
.trainee, .titre__trainee {
    position: absolute; z-index: 0;
    left: calc(-1 * var(--debord, 100vw)); right: 0; top: -19%; bottom: -19%;
    background: url("../images/trainee-court-T1keyTm.webp") right center / 100% 100% no-repeat;
    pointer-events: none;
    /* le BOUT de la bande (l'ellipse dessinée par generer-medias.py : demi-hauteur + bourrelet, sur la taille de l'image)
       — le bord de l'essuyage le reprend, sinon la découpe est un bout CARRÉ tant que l'entrée n'est pas finie */
    --bout-x: 9.3%; --bout-y: 47%;
}
@media (min-width: 900px) {
    .trainee, .titre__trainee { background-image: url("../images/trainee-long-gjGuPri.webp"); top: -15%; bottom: -15%; --bout-x: 5.5%; }
}

/* ═══ LE HÉROS ═══════════════════════════════════════════════════════════════════════════════ */
.heros {
    position: relative; z-index: 1;
    display: flex; align-items: center;
    min-height: 100vh; min-height: 100svh;
    padding: 104px var(--gouttiere) 56px;
    overflow: hidden;
    background: #161617 url("../images/poussiere-portrait-Wqec-9O.webp") center / cover no-repeat;
    /* le geste d'essuyage ne prend JAMAIS le défilement vertical ni le zoom */
    touch-action: pan-y pinch-zoom;
}
@media (min-width: 700px) {
    .heros { background-image: url("../images/poussiere-1600-A4a6doR.webp"); padding-top: 120px; }
}
/* au doigt, le héros se touche pour essuyer : pas de sélection ni de menu « Copier » à l'appui long (Alexandre, 5 oct.) ;
   seulement sur écran tactile — à la souris, le texte reste sélectionnable. Le numéro reste un lien d'appel. */
@media (pointer: coarse) {
    .heros.est-vivant { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
}
/* une fois la poussière reprise par le canvas, le fond devient la surface PROPRE qu'on découvre */
.heros.est-vivant { background: radial-gradient(120% 90% at 12% 0%, #29292a 0%, #121213 48%, #09090a 100%); }
.heros__poussiere, .heros__grains {
    position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none;
}
.heros__grains { z-index: 1; }
/* un voile sous le texte : la poussière la plus claire ne doit jamais faire tomber le contraste
   de la crème sous AA. Il est AU-DESSUS des canvas : la poussière essuyée ou non, même voile. */
.heros::after, .devis::before {
    content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
    background: linear-gradient(90deg, rgba(0, 0, 0, 0.74) 0%, rgba(0, 0, 0, 0.5) 60%, rgba(0, 0, 0, 0.14) 100%);
}
/* le devis a du texte sur toute sa largeur (le formulaire, « Ou en direct ») : un voile égal */
.devis::before { background: linear-gradient(90deg, rgba(0, 0, 0, 0.72) 0%, rgba(0, 0, 0, 0.58) 100%); }
/* l'en-tête est posé sur la poussière la plus claire (en haut) : un voile vertical sous la navigation */
.entete::before {
    content: ""; position: absolute; inset: 0 0 -24px; z-index: -1; pointer-events: none;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.62) 0%, rgba(0, 0, 0, 0.35) 65%, transparent 100%);
}
.devis::before { z-index: 0; }
.devis__contenu { position: relative; z-index: 1; }
.heros__contenu { position: relative; z-index: 3; width: 100%; max-width: var(--largeur); margin: 0 auto; }

.surtitre {
    margin: 0;
    font: 600 clamp(0.9375rem, 1.6vw, 1.125rem)/1.5 var(--sans); letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--creme);
    text-shadow: 0 0 12px #000, 0 0 3px #000;
}

.promesse {
    position: relative; display: inline-block;
    margin: 1.6rem 0 1.8rem;
    padding: 0.2em 0.3em 0.26em 0;
    /* la place du chiffon, posé au bout de la traînée */
    margin-right: var(--chiffon, 1.9em);
    font-size: clamp(2.35rem, 9.6vw, 6rem);
    --chiffon: 1.75em;
}
@media (min-width: 1000px) { .promesse { --chiffon: 1.15em; } }
.promesse__texte {
    position: relative; z-index: 2;
    font: italic 400 1em/1.04 var(--serif);
    letter-spacing: -0.01em;
    color: var(--creme);
    max-width: 9.2em;
}
@media (min-width: 1000px) { .promesse__texte { max-width: none; white-space: nowrap; } }
.chiffon {
    position: absolute; z-index: 1;
    top: -3%; height: 106%; width: auto; max-width: none;
    left: 100%; margin-left: -0.12em;
    filter: drop-shadow(0.06em 0.1em 0.12em rgba(0, 0, 0, 0.7));
    pointer-events: none;
}

.chapeau {
    max-width: 40rem;
    font-size: clamp(1.1875rem, 2.8vw, 1.4375rem); line-height: 1.55;
    color: var(--creme);
    text-shadow: 0 0 14px #000, 0 0 4px #000;
}
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }

/* L'indice « passez la souris » n'a de sens que si l'essuyage marche. ⚠️ Sa PLACE est réservée dès
   le premier rendu (visibility, pas display) : le héros centre son contenu verticalement, et faire
   apparaître une ligne au chargement de la poussière remontait tout le bloc — CLS mesuré à 0,24. */
.indice { display: none; }
.mouvement .indice {
    display: flex; align-items: center; gap: 12px; margin-top: 28px;
    font: 600 0.875rem/1.4 var(--sans); letter-spacing: 0.16em; text-transform: uppercase; color: var(--creme);
    text-shadow: 0 0 10px #000;
    visibility: hidden;
}
.mouvement .heros.est-vivant .indice { visibility: visible; animation: apparition 0.8s 2.2s both; }
.indice::before { content: ""; width: 36px; height: 2px; background: var(--bleu); }
.indice__souris { display: none; }
@media (hover: hover) and (pointer: fine) {
    .indice__souris { display: inline; }
    .indice__doigt { display: none; }
}

.vaporisateur {
    position: absolute; z-index: 3;
    right: 16px; bottom: 20px; height: 150px; width: auto;
    filter: drop-shadow(14px 22px 14px rgba(0, 0, 0, 0.75));
}
@media (max-height: 760px) and (max-width: 699px) { .vaporisateur { display: none; } }
@media (min-width: 700px) { .vaporisateur { height: 240px; right: 4vw; bottom: 8vh; } }
@media (min-width: 1100px) { .vaporisateur { height: min(44vh, 400px); right: 5vw; top: 50%; bottom: auto; transform: translateY(-38%); } }
.mouvement .heros.est-vivant .vaporisateur { cursor: pointer; }

/* — L'entrée : le chiffon traverse et laisse la traînée (CSS seul, sans JavaScript) — */
@media (prefers-reduced-motion: no-preference) {
    .mouvement .heros .trainee { animation: essuie 1.35s 0.15s var(--courbe) both; }
    .mouvement .heros .chiffon { animation: chiffon 1.35s 0.15s var(--courbe) both; }
}
/* le bord qui avance est ARRONDI comme le bout de la bande, et finit au-delà de l'image : le vrai bout apparaît entier */
@keyframes essuie { from { clip-path: inset(0 100% 0 0 round 0 var(--bout-x) var(--bout-x) 0 / 0 var(--bout-y) var(--bout-y) 0); } to { clip-path: inset(0 calc(-1 * var(--bout-x)) 0 0 round 0 var(--bout-x) var(--bout-x) 0 / 0 var(--bout-y) var(--bout-y) 0); } }
/* le bord de l'essuyage et le chiffon avancent ENSEMBLE : même durée, même courbe, même distance
   (du bord de l'écran au bout du texte) */
@keyframes chiffon { from { left: calc(-1 * var(--debord, 100vw)); } to { left: 100%; } }
@keyframes apparition { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ═══ LES SECTIONS ═══════════════════════════════════════════════════════════════════════════ */
.section {
    position: relative;
    padding: 64px max(var(--gouttiere), calc((100% - var(--largeur)) / 2));
    overflow-x: clip;
}
@media (min-width: 900px) { .section { padding-top: 92px; padding-bottom: 92px; } }
/* sur ordinateur, le texte courant grandit encore */
@media (min-width: 1100px) { body { font-size: 1.1875rem; } }
.section + .section { border-top: 1px solid var(--filet); }
.section__entete { margin-bottom: 36px; max-width: 52rem; }
/* Sur ordinateur, « Six prestations, un seul niveau d'exigence. » tient sur UNE ligne (Alexandre,
   5 oct.) : il lui faut 900 px + son chiffon (≈ 990 px, mesuré à 3,5 rem), la colonne en offre
   1 052 à partir de 1 180 px. On lève la borne de l'en-tête (le paragraphe garde la sienne), on ne
   rapetisse pas la police. En dessous, deux lignes, et le chiffon prend la hauteur du titre. */
@media (min-width: 1180px) { .section__entete { max-width: none; } }
.section__intro { margin-top: 20px; font-size: clamp(1.1875rem, 2.4vw, 1.3125rem); color: var(--creme-2); max-width: 48rem; }

.titre {
    position: relative; display: inline-block;
    padding: 0.16em 0.5em 0.2em 0;
    font: 600 clamp(2rem, 7vw, 3.5rem)/1.08 var(--serif);
    letter-spacing: -0.015em;
}
.titre__texte { position: relative; z-index: 1; }
/* ─── Le chiffon au bout de la traînée du titre (Alexandre, 5 oct. : « il manque le chiffon ») ───
   Même image que le héros. Deux réglages, MESURÉS sur les images de traînée (generer-medias.py) :
   - la bande propre de trainee-court.webp finit en arrondi à 86 % de la largeur de l'image (le reste
     est le bout arrondi et du vide) ; trainee-long.webp à 91 %. La traînée d'un titre déborde donc à
     droite de 16 % (9,5 % en large) de sa largeur : le BOUT arrondi commence pile au bout du titre,
     et le chiffon, posé là, le recouvre — sinon on voit un bout de bande « coupé » puis le chiffon ;
   - le chiffon a la hauteur du titre (la bande propre a la même), comme sur le héros.
   ⚠️ LA RÉSERVE : le titre est borné à « 100 % − 1,6 em » de sa colonne, donc il passe à la ligne
   AVANT que le chiffon ne sorte de l'écran (à 390 px, un titre long se replie au lieu de pousser le
   chiffon dehors). Le chiffon est en position absolue : il ne déplace rien, CLS nul. */
.titre { max-width: calc(100% - 1.6em); }
.titre .titre__trainee { right: calc(-0.16 * (100% + var(--debord, 0px))); }
@media (min-width: 900px) { .titre .titre__trainee { right: calc(-0.095 * (100% + var(--debord, 0px))); } }
.titre__chiffon {
    position: absolute; z-index: 0;
    left: 100%; margin-left: -0.35em;
    top: 0; height: 100%; width: auto; max-width: none;
    filter: drop-shadow(0.06em 0.1em 0.1em rgba(0, 0, 0, 0.7));
    pointer-events: none;
}
.titre--grand { font-size: clamp(2.6rem, 11vw, 5.5rem); }
.titre--page { font-size: clamp(2.2rem, 8vw, 4rem); margin-bottom: 40px; }

/* — la traînée d'un TITRE s'arrête SOUS SON CHIFFON —
   Le bord de l'essuyage garde l'arrondi du bout de bande (9313b5c : --bout-x / --bout-y), mais sur
   les titres il ne file plus au-delà de l'image : il s'arrête là où se pose le chiffon (au bout du
   titre, soit 100 % − 13,8 % de la traînée élargie, 8,7 % en large). Le bout visible est donc
   l'arrondi de la découpe, recouvert par le chiffon. C'est ce qui permet au bord et au chiffon de
   faire la MÊME distance (du bord de l'écran au bout du titre), avec la même courbe et la même durée.
   Cet état final est aussi l'état SANS JS et en mouvement réduit : chiffon posé, bande arrondie. */
.titre .titre__trainee {
    --fin: 13.8%;
    clip-path: inset(0 var(--fin) 0 0 round 0 var(--bout-x) var(--bout-x) 0 / 0 var(--bout-y) var(--bout-y) 0);
}
@media (min-width: 900px) { .titre .titre__trainee { --fin: 8.7%; } }
@keyframes essuie-titre {
    from { clip-path: inset(0 100% 0 0 round 0 var(--bout-x) var(--bout-x) 0 / 0 var(--bout-y) var(--bout-y) 0); }
    to { clip-path: inset(0 var(--fin) 0 0 round 0 var(--bout-x) var(--bout-x) 0 / 0 var(--bout-y) var(--bout-y) 0); }
}
@keyframes chiffon-titre { from { left: calc(-1 * var(--debord, 100vw)); } to { left: 100%; } }

/* — les titres s'essuient quand ils arrivent à l'écran (classe posée par essuyage.js) — */
@media (prefers-reduced-motion: no-preference) {
    .titres-prets .titre:not(.titre--page) .titre__trainee { clip-path: inset(0 100% 0 0 round 0 var(--bout-x) var(--bout-x) 0 / 0 var(--bout-y) var(--bout-y) 0); transition: clip-path 1.2s var(--courbe); }
    .titres-prets .titre.est-essuye .titre__trainee { clip-path: inset(0 var(--fin) 0 0 round 0 var(--bout-x) var(--bout-x) 0 / 0 var(--bout-y) var(--bout-y) 0); }
    .mouvement .titre--page .titre__trainee { animation: essuie-titre 1.3s 0.2s var(--courbe) both; }
    /* le chiffon avance AVEC le bord : même durée, même courbe, même distance */
    .titres-prets .titre:not(.titre--page) .titre__chiffon { left: calc(-1 * var(--debord, 100vw)); transition: left 1.2s var(--courbe); }
    .titres-prets .titre.est-essuye .titre__chiffon { left: 100%; }
    .mouvement .titre--page .titre__chiffon { animation: chiffon-titre 1.3s 0.2s var(--courbe) both; }
}

/* ═══ LE DESIGN « VISUEL » (ZigZag et Alexandre, 5 oct. : « trop brut », « que le client tombe
   amoureux ») — des images avant les mots, des sections CLAIRES qui alternent avec le noir
   poussiéreux, une hiérarchie nette : un titre, un visuel, une phrase, un bouton. ═══════════════ */

/* ─── Les icônes (Lucide, une seule famille, templates/_visuels.html.twig) ─── */
.icone { width: 24px; height: 24px; flex: none; }
.icone--petite { width: 18px; height: 18px; }

/* ─── Les sections CLAIRES : la crème de la carte, le texte noir ─── */
.section--claire {
    background: var(--creme);
    color: #121212;
    --texte-2: #45413a;                    /* 9,1:1 sur la crème (mesuré au rendu) */
}
.section--claire + .section, .section + .section--claire, .section--claire + .mosaique { border-top: 0; }
.section--claire .section__intro { color: var(--texte-2); }
/* le titre reste CRÈME : il est écrit dans la bande noire essuyée, même sur la section claire */
.section--claire .titre__texte { color: var(--creme); }
.section__pied { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px 24px; margin-top: 36px; }
.legende { font-size: 0.9375rem; color: #5b564d; font-style: italic; }
.legende--sombre { color: var(--gris); }
.bouton--sombre { background: #121212; color: var(--creme); border-color: #121212; }
.bouton--sombre:hover { background: #000; }
.bouton .icone--petite { transition: transform 0.25s var(--courbe); }
.bouton:hover .icone--petite { transform: translateX(4px); }

/* ─── La bande des atouts, juste sous le héros ─── */
.atouts { background: var(--creme); color: #121212; padding: 22px var(--gouttiere); border-bottom: 1px solid rgba(18, 18, 18, 0.12); }
.atouts__liste { max-width: var(--largeur); margin: 0 auto; display: grid; gap: 14px; }
@media (min-width: 800px) { .atouts__liste { grid-template-columns: repeat(3, 1fr); gap: 24px; } }
.atout { display: flex; align-items: center; gap: 14px; line-height: 1.35; color: #3c3933; }
.atout strong { display: block; color: #121212; font-weight: 600; }
.atout__icone { width: 44px; height: 44px; padding: 10px; border-radius: 50%; background: #121212; color: var(--bleu-texte); }

/* ─── Les prestations : des CARTES avec photo ─── */
.cartes { display: grid; gap: 18px; grid-template-columns: 1fr; }
@media (min-width: 700px) { .cartes { grid-template-columns: repeat(2, 1fr); gap: 22px; } }
@media (min-width: 1100px) { .cartes { grid-template-columns: repeat(3, 1fr); gap: 26px; } }
/* au téléphone : un défilement horizontal qui laisse voir la carte suivante — l'œil comprend qu'il
   y en a d'autres. Le défilement est DANS la liste : la page, elle, ne déborde jamais. */
@media (max-width: 699px) {
    .section--claire .cartes {
        grid-auto-flow: column; grid-template-columns: none; grid-auto-columns: 80%;
        overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
        margin: 0 calc(-1 * var(--gouttiere)); padding: 4px var(--gouttiere) 18px;
        scroll-padding: 0 var(--gouttiere); scrollbar-width: thin;
    }
    .section--claire .carte { scroll-snap-align: start; }
}
.carte {
    position: relative; display: flex; flex-direction: column;
    background: #fffdf8; border-radius: 6px; overflow: hidden;
    box-shadow: 0 1px 2px rgba(18, 18, 18, 0.08), 0 10px 30px -18px rgba(18, 18, 18, 0.45);
    transition: transform 0.4s var(--courbe), box-shadow 0.4s var(--courbe);
}
.carte__photo { width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; transition: transform 0.8s var(--courbe); }
.carte__corps { position: relative; padding: 18px 20px 22px; }
/* le trait bleu du chiffon, qui s'essuie au survol */
.carte__corps::before {
    content: ""; position: absolute; left: 20px; top: 0; height: 3px; width: 48px; background: var(--bleu);
    transform-origin: left; transform: scaleX(0.4); transition: transform 0.5s var(--courbe);
}
.carte .prestation__titre { font: 600 clamp(1.375rem, 4.4vw, 1.5rem)/1.2 var(--serif); color: #121212; margin: 6px 0 6px; }
.carte .prestation__texte { color: #45413a; font-size: 1.0625rem; line-height: 1.5; }
@media (hover: hover) {
    .carte:hover { transform: translateY(-4px); box-shadow: 0 2px 4px rgba(18, 18, 18, 0.08), 0 22px 40px -20px rgba(18, 18, 18, 0.55); }
    .carte:hover .carte__photo { transform: scale(1.05); }
    .carte:hover .carte__corps::before { transform: scaleX(1); }
}

/* ─── La mosaïque : de grandes images, une phrase en grand italique ─── */
.mosaique { position: relative; padding: 64px max(var(--gouttiere), calc((100% - var(--largeur)) / 2)) 56px; overflow-x: clip; }
.mosaique__phrase {
    max-width: 14em; margin-bottom: 28px;
    font: italic 400 clamp(2.4rem, 9vw, 5rem)/1.02 var(--serif); letter-spacing: -0.015em;
}
.mosaique__grille { display: grid; gap: 10px; grid-template-columns: repeat(3, 1fr); }
.mosaique__photo { width: 100%; height: 100%; object-fit: cover; border-radius: 4px; aspect-ratio: 4 / 5; }
.mosaique__photo--grande { grid-column: 1 / -1; aspect-ratio: 3 / 2; }
@media (min-width: 900px) {
    .mosaique { padding-top: 96px; padding-bottom: 80px; }
    .mosaique__grille { grid-template-columns: 2fr 1fr 1fr 1fr; gap: 14px; align-items: stretch; }
    .mosaique__photo--grande { grid-column: auto; aspect-ratio: auto; height: 100%; }
}
.mosaique .legende { margin-top: 14px; }

/* ─── Le déroulé : trois étapes, une icône chacune ─── */
.etapes { display: grid; gap: 28px; }
@media (min-width: 900px) { .etapes { grid-template-columns: repeat(3, 1fr); gap: 40px; } }
.etape { position: relative; display: grid; grid-template-columns: auto 1fr; column-gap: 18px; align-items: start; }
@media (min-width: 900px) { .etape { display: flex; flex-direction: column; } .etape__pastille { grid-row: auto; } }
.etape__pastille {
    grid-row: span 2; display: grid; place-items: center; width: 60px; height: 60px; border-radius: 50%;
    background: #121212; color: var(--bleu-texte);
}
.etape__pastille .icone { width: 26px; height: 26px; }
/* sur ordinateur, un trait relie les pastilles : le chemin du devis à l'intervention */
@media (min-width: 900px) {
    .etape__pastille { margin-bottom: 18px; }
    .etape:not(:last-child)::after {
        content: ""; position: absolute; top: 30px; left: 76px; right: -24px; height: 2px;
        background: repeating-linear-gradient(90deg, #121212 0 8px, transparent 8px 14px); opacity: 0.35;
    }
}
.etape__titre { font: 600 1.5rem/1.2 var(--serif); margin: 6px 0 4px; }
.etape p { color: #45413a; }

/* ─── Les prestations en vignettes (pages de communes) ─── */
.cartes--courtes { grid-template-columns: repeat(2, 1fr); gap: 12px; }
@media (min-width: 700px) { .cartes--courtes { grid-template-columns: repeat(3, 1fr); } }
.cartes--courtes .carte { background: #161617; box-shadow: none; border: 1px solid var(--filet); }
.cartes--courtes .carte__corps { padding: 12px 14px 14px; }
.cartes--courtes .carte__corps::before { left: 14px; }
.cartes--courtes .prestation__titre { color: var(--creme); font-size: 1.0625rem; line-height: 1.3; margin: 4px 0 0; }

/* ─── L'arrivée à l'écran : les visuels montent doucement (classe posée par essuyage.js) ───
   Sans JavaScript ou en mouvement réduit, aucune de ces règles ne s'applique : tout est visible. */
@media (prefers-reduced-motion: no-preference) {
    .apparitions-pretes .apparait { opacity: 0; transform: translateY(18px); transition: opacity 0.7s var(--courbe), transform 0.7s var(--courbe); transition-delay: var(--retard, 0s); }
    .apparitions-pretes .apparait.est-visible { opacity: 1; transform: none; }
}

/* ─── La zone ─────────────────────────────────────────────────────────────────────────────── */
.zone { display: grid; gap: 40px; align-items: center; }
@media (min-width: 900px) { .zone { grid-template-columns: 1.3fr 1fr; gap: 64px; } }
.zone__lieu { display: flex; flex-direction: column; }
.zone__ville { font: italic 400 clamp(3.6rem, 17vw, 9.5rem)/0.95 var(--serif); letter-spacing: -0.02em; }
.zone__alentours { margin-top: 30px; font: 500 clamp(0.875rem, 2.4vw, 1.125rem)/1 var(--sans); letter-spacing: 0.4em; text-transform: uppercase; color: var(--creme-2); }
.zone__texte p { color: var(--creme-2); font-size: clamp(1.1875rem, 2.4vw, 1.3125rem); }
.zone__adresse { margin-top: 24px; padding-left: 16px; border-left: 2px solid var(--bleu); line-height: 1.7; }

/* ═══ LE DEVIS — retour sur la poussière ═════════════════════════════════════════════════════ */
.devis {
    position: relative; overflow: hidden;
    padding: 80px var(--gouttiere) 88px;
    background: #161617 url("../images/poussiere-900-hPXYDfe.webp") center / cover no-repeat;
}
@media (min-width: 900px) { .devis { background-image: url("../images/poussiere-1600-A4a6doR.webp"); padding-top: 112px; padding-bottom: 120px; } }
.devis__contenu { max-width: var(--largeur); margin: 0 auto; }
.devis .titre { text-shadow: none; }
.devis__intro { margin: 24px 0 32px; max-width: 44rem; font-size: clamp(1.1875rem, 2.4vw, 1.375rem); text-shadow: 0 0 14px #000, 0 0 4px #000; }
.contacts { display: grid; gap: 12px; }
@media (min-width: 900px) { .contacts { grid-template-columns: repeat(3, 1fr); gap: 16px; } }
.contact {
    display: flex; flex-direction: column; gap: 8px; height: 100%;
    padding: 22px 22px 24px;
    background: rgba(9, 9, 10, 0.86); border: 1px solid rgba(236, 229, 214, 0.28); border-radius: 2px;
    text-decoration: none;
    transition: border-color 0.2s, background-color 0.2s;
}
.contact:hover { border-color: var(--creme); background: #050505; }
.contact__quoi { display: flex; align-items: center; gap: 10px; font: 600 0.875rem/1.3 var(--sans); letter-spacing: 0.14em; text-transform: uppercase; color: var(--creme-2); }
.contact__quoi::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--bleu); }
.contact__valeur { font: 600 1.625rem/1.2 var(--sans); font-variant-numeric: tabular-nums; letter-spacing: 0.02em; }
.contact__valeur--mail { font-size: 1.1875rem; overflow-wrap: anywhere; }

/* ─── Le formulaire de devis ──────────────────────────────────────────────────────────────── */
.devis__grille { display: grid; gap: 40px; align-items: start; }
@media (min-width: 1000px) {
    .devis__grille { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 56px; }
    .devis .contacts { grid-template-columns: 1fr; gap: 12px; }
}
.devis__ou { margin-bottom: 14px; font: 600 0.9375rem/1.3 var(--sans); letter-spacing: 0.14em; text-transform: uppercase; color: var(--creme); text-shadow: 0 0 10px #000; }
.formulaire {
    position: relative;
    display: grid; gap: 20px;
    padding: 24px 20px 28px;
    background: rgba(9, 9, 10, 0.9); border: 1px solid rgba(236, 229, 214, 0.28); border-radius: 2px;
    scroll-margin-top: 24px;
}
@media (min-width: 700px) { .formulaire { padding: 32px 32px 36px; } }
.page-devis .formulaire { margin-top: 32px; }
.champ { display: grid; gap: 8px; }
.champ label, .champ-groupe legend { font: 600 1.0625rem/1.3 var(--sans); color: var(--creme); }
.champ__requis, .champ__facultatif { margin-left: 6px; font-weight: 400; font-size: 0.9375rem; color: var(--gris); }
.champ-groupe { margin: 0; padding: 0; border: 0; display: grid; gap: 16px; }
@media (min-width: 700px) { .champ-groupe { grid-template-columns: 1fr 1fr; } .champ-groupe legend { grid-column: 1 / -1; } }
.champ-groupe legend { padding: 0; margin-bottom: 10px; float: left; width: 100%; }
.champ input, .champ select, .champ textarea {
    width: 100%; min-height: 48px; padding: 10px 14px;
    background: #050505; color: var(--creme);
    border: 1px solid rgba(236, 229, 214, 0.42); border-radius: 2px;
    font: 400 1.125rem/1.4 var(--sans);
}
.champ textarea { min-height: 112px; resize: vertical; }
.champ select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--creme) 50%), linear-gradient(135deg, var(--creme) 50%, transparent 50%);
    background-position: calc(100% - 20px) 50%, calc(100% - 14px) 50%; background-size: 6px 6px; background-repeat: no-repeat; padding-right: 40px; }
.champ input:focus-visible, .champ select:focus-visible, .champ textarea:focus-visible { outline: 2px solid var(--bleu); outline-offset: 1px; border-color: var(--bleu); }
.champ [aria-invalid="true"] { border-color: #f0a28a; }
.champ__erreur { color: #f8c4b4; font-size: 1rem; }
.champ__erreur::before { content: "— "; }
.formulaire__alerte { padding: 12px 14px; border-left: 3px solid #f0a28a; background: rgba(240, 162, 138, 0.1); color: var(--creme); }
.formulaire__envoyer { justify-self: start; }
.formulaire__note { font-size: 1rem; color: var(--creme-2); }
.formulaire__note a { color: var(--creme); text-underline-offset: 3px; }
/* le pot de miel : hors de l'écran (pas display:none, que certains robots savent lire) */
.piege { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
.lien-retour { margin-top: 16px; }

/* ═══ Les zones d'intervention (accueil) et les pages par commune ════════════════════════════ */
.zones__titre { margin: 28px 0 12px; font: 600 0.9375rem/1.3 var(--sans); letter-spacing: 0.14em; text-transform: uppercase; color: var(--creme); }
.zones { display: flex; flex-wrap: wrap; gap: 10px; }
.zones__lien {
    display: inline-flex; align-items: center; min-height: 44px; padding: 8px 14px;
    border: 1px solid rgba(246, 241, 231, 0.36); border-radius: 2px;
    color: var(--creme); text-decoration: none; font-weight: 500;
}
.zones__lien::before { content: ""; width: 7px; height: 7px; margin-right: 10px; border-radius: 50%; background: var(--bleu); }
.zones__lien .icone { margin-right: 8px; color: var(--bleu-texte); }
.zones__lien:has(.icone)::before { content: none; }
.zones__lien:hover { border-color: var(--creme); background: #050505; }

.page-ville { max-width: calc(52rem + 2 * var(--gouttiere)); margin: 0 auto; padding: 104px var(--gouttiere) 72px; }
.page-ville { --debord: calc(max(var(--gouttiere), (100vw - 52rem) / 2) + 12px); }
.fil ol { display: flex; flex-wrap: wrap; gap: 4px 0; margin-bottom: 20px; font-size: 1rem; color: var(--gris); }
.fil li + li::before { content: "›"; margin: 0 10px; color: var(--gris); }
.fil a { color: var(--creme); text-underline-offset: 3px; display: inline-block; padding: 6px 0; }
.page-ville .titre--page { margin-bottom: 24px; }
.page-ville__chapeau p { font-size: clamp(1.1875rem, 2.4vw, 1.375rem); color: var(--creme); }
.page-ville__visuel { margin: 36px calc(-1 * var(--gouttiere)) 0; }
@media (min-width: 900px) { .page-ville__visuel { margin: 40px 0 0; } }
.page-ville__photo { width: 100%; height: auto; max-height: 520px; object-fit: cover; }
@media (min-width: 900px) { .page-ville__photo { border-radius: 6px; } }
.page-ville__bloc { margin-top: 48px; }
.page-ville__bloc .legende { margin-top: 10px; }
.page-ville__bloc h2 { margin-bottom: 14px; font: 600 clamp(1.625rem, 4.4vw, 2rem)/1.2 var(--serif); }
.page-ville__bloc p { color: var(--creme-2); }
.page-ville__bloc p + p { margin-top: 14px; }
.liste-prestations { display: grid; gap: 6px 24px; }
@media (min-width: 700px) { .liste-prestations { grid-template-columns: 1fr 1fr; } }
.liste-prestations li { display: flex; gap: 10px; align-items: baseline; color: var(--creme); }
.liste-prestations li::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--bleu); transform: translateY(-2px); }
.faq dt { margin-top: 20px; font-weight: 600; color: var(--creme); }
.faq dd { margin: 6px 0 0; color: var(--creme-2); }

/* ═══ Pages de texte (mentions, confidentialité) ═══════════════════════════════════════════ */
.page-texte {
    max-width: calc(52rem + 2 * var(--gouttiere)); margin: 0 auto;
    padding: 116px var(--gouttiere) 80px;
    /* pas d'overflow ici : la traînée du titre doit aller jusqu'au bord de l'écran (body coupe) */
}
.page-texte h2 { margin: 40px 0 12px; font: 600 1.625rem/1.25 var(--serif); }
.page-texte p { color: var(--creme-2); }
.page-texte p + p { margin-top: 14px; }
.page-texte a { color: var(--creme); text-underline-offset: 3px; }
.page-texte__chapeau { font-size: clamp(1.1875rem, 2.4vw, 1.375rem); }
.page-texte a[href^="tel:"], .formulaire__note a { white-space: nowrap; }
.page-texte strong { color: var(--creme); font-weight: 600; }
.fiche { display: grid; grid-template-columns: 1fr; }
.fiche dt { margin-top: 16px; font: 600 0.875rem/1.4 var(--sans); letter-spacing: 0.12em; text-transform: uppercase; color: var(--gris); }
.fiche dd { margin: 4px 0 0; color: var(--creme); }
@media (min-width: 700px) {
    .fiche { grid-template-columns: 15rem 1fr; column-gap: 24px; }
    .fiche dt, .fiche dd { padding: 12px 0; margin: 0; border-bottom: 1px solid var(--filet); }
    .fiche dt { padding-top: 15px; }
}
.a-fournir { background: var(--creme); color: var(--noir); padding: 0.05em 0.4em; font-weight: 600; }

/* ═══ Pied de page ═══════════════════════════════════════════════════════════════════════════ */
.pied {
    padding: 56px max(var(--gouttiere), calc((100% - var(--largeur)) / 2)) 32px;
    border-top: 1px solid var(--filet);
    background: #070708;
}
.pied__haut { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 12px 32px; padding-bottom: 40px; border-bottom: 1px solid var(--filet); }
.pied__marque .marque__kl { font-size: 2.25rem; }
.pied__promesse { font: italic 400 clamp(1.5rem, 4vw, 2rem)/1.2 var(--serif); color: var(--creme-2); }
.pied__colonnes { display: grid; gap: 32px; padding: 40px 0; }
@media (min-width: 700px) { .pied__colonnes { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .pied__colonnes { grid-template-columns: repeat(4, 1fr); } }
.pied__titre { margin-bottom: 12px; font: 600 0.875rem/1.4 var(--sans); letter-spacing: 0.14em; text-transform: uppercase; color: var(--gris); }
.pied__liste { color: var(--creme-2); line-height: 1.6; }
.pied__liste li + li { margin-top: 2px; }
.pied__liste a { display: inline-block; padding: 9px 0; color: var(--creme); text-underline-offset: 3px; font-variant-numeric: tabular-nums; }
.pied__bas { padding-top: 24px; border-top: 1px solid var(--filet); font-size: 1rem; color: var(--gris); }

/* ═══ prefers-reduced-motion : la page propre, directement ═══════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ─── finitions du design ─── */
.contact__quoi:has(.icone)::before { content: none; }
.contact__quoi .icone { color: var(--bleu-texte); }
/* au téléphone, l'aide du carrousel et le fil qui relie les étapes */
.cartes__aide { display: none; }
@media (max-width: 699px) {
    .cartes__aide { display: flex; align-items: center; gap: 8px; margin: -4px 0 14px; font-size: 0.9375rem; color: #45413a; }
    .etape:not(:last-child)::after {
        content: ""; position: absolute; left: 29px; top: 66px; bottom: -24px; width: 2px;
        background: repeating-linear-gradient(180deg, #121212 0 6px, transparent 6px 11px); opacity: 0.3;
    }
}
