/* =========================================================
   GFR TRAVAUX — Feuille de styles
   1. Tokens          5. Hero (sticky pinné)
   2. Reset / base    6. Expertise (métiers, déroulé, preuves)
   3. Utilitaires     7. Réalisations
   4. Header / nav    8. Devis (configurateur)  9. Footer
   ========================================================= */

/* ---------- 1. Tokens ----------
   Base noir et blanc, à la demande du client : fond blanc pur, logo et
   textes principaux en noir pur. L'ancienne base crème / ardoise bleutée a
   été déposée — il n'en reste que le principe qui la justifiait :

   • LA TERRE CUITE porte l'action, et elle seule. Les études CTA
     convergent : rouge chaud sur fond clair, +31 % ; teintes cramoisies
     +34 à 36 % sur les pages de génération de leads. Mais l'effet
     documenté vient surtout de l'isolement — un bouton convertit parce
     qu'il ne ressemble à rien d'autre sur la page. D'où la règle : aucune
     autre surface chaude et saturée ailleurs. Sur fond blanc pur, cet
     isolement est encore plus net qu'avant.

   • LES COULEURS DE PÔLE ne servent qu'à distinguer les métiers entre eux
     (étiquette, filet de liste). Jamais une surface pleine.
   -------------------------------------------------------------------- */
:root {
    /* Fonds */
    --bg-dark: #ffffff;        /* fond du site : blanc pur */
    --bg-cream: #F5F5F5;       /* gris neutre : champs et surfaces creusées */
    --bg-light: #ffffff;

    /* Structure : noir pur */
    --graphite: #000000;
    --graphite-soft: #222222;
    --text-main: #000000;
    --text-muted: #565656;

    /* Action — usage strictement réservé aux appels à l'action */
    --action: #BE4128;
    --action-hover: #9E3420;

    /* Pôles métier */
    --pole-habitat: #BE4128;
    --pole-exterieur: #2A5670;
    --pole-pro: #8A6B1F;
    --pole-paysage: #4A7249;

    /* Alias de compatibilité */
    --accent: var(--action);
    --orange-btp: var(--action);
    --orange-hover: var(--action-hover);
    --blue-water: var(--pole-exterieur);
    --green-landscape: var(--pole-paysage);
    --nav-text-dark: var(--graphite);

    --glass-bg: rgba(255, 255, 255, 0.6);
    --glass-border: rgba(0, 0, 0, 0.11);

    --font-heading: 'Outfit', system-ui, sans-serif;
    --font-body: 'Inter', system-ui, sans-serif;

    --sp-sm: 1rem;
    --sp-md: 2rem;
    --sp-lg: clamp(2.5rem, 6vw, 4rem);
    --sp-xl: clamp(4rem, 10vw, 8rem);

    --gutter: clamp(1.25rem, 5vw, 5rem);
    --header-h: 104px;

    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---------- 2. Reset / base ---------- */
* { margin: 0; padding: 0; box-sizing: border-box; }

/* Le filtrage par univers masque des blocs avec l'attribut hidden. Sans
   cette règle, le display posé par leur propre sélecteur (flex, grid-area…)
   l'emporterait et les afficherait quand même. */
[hidden] { display: none !important; }

/* Sans JS, personne ne choisit d'univers et rien ne lèvera ces attributs :
   on montre alors les deux métiers plutôt qu'une page amputée de moitié.
   L'attribut est posé dans le HTML — et non ajouté au chargement — pour
   qu'aucun bloc du mauvais univers n'apparaisse le temps d'une frame. */
html:not(.js) [data-univers][hidden] { display: revert !important; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}
/* Lenis */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }

body {
    font-family: var(--font-body);
    color: var(--text-main);
    background-color: var(--bg-dark);
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }
li { list-style: none; }
img { display: block; max-width: 100%; }
button { font: inherit; color: inherit; }

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

.skip-link {
    position: absolute; top: -100px; left: 1rem; z-index: 2000;
    background: var(--text-main); color: #fff; padding: 0.75rem 1.25rem;
    border-radius: 0 0 12px 12px; font-weight: 600;
    transition: top 0.25s ease;
}
.skip-link:focus { top: 0; }

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

/* Le grain et les deux halos colorés qui portaient le fond crème ont été
   déposés avec lui : sur un blanc pur demandé comme tel, ils se lisent
   comme une salissure et une teinte parasite. */

/* ---------- 3. Utilitaires ---------- */
.glass-panel {
    background: var(--glass-bg);
    backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
    border: 1px solid var(--glass-border); border-radius: 24px;
}
.title-xl {
    font-family: var(--font-heading);
    font-size: clamp(2.6rem, 7.2vw, 7rem);
    font-weight: 900; line-height: 1.02;
    letter-spacing: -0.04em; text-transform: uppercase;
}
.title-lg { font-family: var(--font-heading); font-size: clamp(2rem, 5vw, 3.5rem); font-weight: 700; line-height: 1.1; }
h2 { font-family: var(--font-heading); font-size: clamp(1.9rem, 4vw, 3rem); font-weight: 500; line-height: 1.1; }
h3, h4 { font-family: var(--font-heading); font-weight: 500; }
p { color: var(--text-muted); font-size: clamp(1rem, 0.95rem + 0.3vw, 1.125rem); line-height: 1.6; }
/* Cartes cliquables : ce sont des <button>, dont le contenu doit rester du
   contenu en ligne — ni div, ni titre. Leurs blocs internes sont donc des
   <span>, qu'il faut repasser en block. Sans ça, ni aspect-ratio ni width
   ne s'appliquent et le cadre de 3 px se réduit à deux traits, au-dessus et
   en dessous de la vignette.
   Cette règle vit ici, avec les utilitaires, et non dans le bloc de chaque
   carrousel : elle a déjà disparu une fois lors d'une réécriture de bloc. */
.ring-card .img-wrapper, .project-card .img-wrapper,
.ring-meta, .project-meta,
.ring-name, .project-name { display: block; }

.mt-2 { margin-top: 0.5rem; }
.mt-4 { margin-top: 1.5rem; }
.w-100 { width: 100%; }

.btn-primary {
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--accent); color: #fff;
    padding: 1rem 2rem; border-radius: 50px;
    font-family: var(--font-body); font-weight: 600; font-size: 1rem;
    border: none; cursor: pointer; min-height: 52px;
    box-shadow: 0 6px 18px rgba(190, 65, 40, 0.26);
    transition: background 0.3s ease, transform 0.3s var(--ease-out), box-shadow 0.3s ease;
}
.btn-primary:hover { background: var(--orange-hover); transform: translateY(-2px); box-shadow: 0 10px 24px rgba(190, 65, 40, 0.33); }

/* ---------- 4. Header / navigation ---------- */
.site-header {
    position: fixed; top: 25px; left: 50%; transform: translateX(-50%);
    width: min(95%, 1200px); z-index: 1000;
    background-color: rgba(255, 255, 255, 0.85);
    backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
    border: 1px solid rgba(255, 255, 255, 0.8);
    border-radius: 50px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.05);
    padding: 10px 30px;
    /* Position figée : la barre ne bouge pas au scroll, seul son fond se densifie */
    transition: background-color 0.4s ease, box-shadow 0.4s ease, border-color 0.4s ease;
}
.site-header.scrolled {
    background-color: rgba(255, 255, 255, 0.97);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.09);
}
.nav-content { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
/* Logo officiel des devis, en déclinaison horizontale : le pictogramme à
   gauche, le nom et sa baseline empilés à droite, séparés par le filet du
   logo d'origine. Tout en noir. La baseline est rendue en HTML plutôt qu'en
   SVG : à cette taille, un texte vectoriel mis à l'échelle tomberait
   sous le seuil de lisibilité. */
.logo-container { display: flex; align-items: center; gap: 11px; flex-shrink: 0; color: var(--graphite); }
.logo-svg { width: 58px; height: auto; flex-shrink: 0; }
.logo-lockup { display: flex; flex-direction: column; align-items: stretch; min-width: 0; }
.logo-word {
    font-family: var(--font-heading); font-size: 1.3rem; font-weight: 900;
    line-height: 1; letter-spacing: 0.01em; text-transform: uppercase;
    color: var(--graphite); white-space: nowrap;
}
.logo-baseline {
    margin-top: 4px; padding-top: 4px;
    border-top: 1px solid rgba(0, 0, 0, 0.32);
    font-family: 'Instrument Sans', var(--font-body);
    font-size: 0.475rem; font-weight: 600; line-height: 1.1;
    letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--graphite); white-space: nowrap;
}
.nav-menu { display: contents; }
.nav-links { display: flex; gap: 25px; align-items: center; }
.nav-item { color: var(--nav-text-dark); font-weight: 600; font-size: 1rem; transition: color 0.3s ease; padding: 10px 5px; display: inline-block; }
.nav-item:hover { color: var(--orange-btp); }
/* Bascule d'univers : un bouton, pas un lien — il ne mène nulle part, il
   rejoue le choix fait dans le hero. */
.nav-item-switch {
    display: inline-flex; align-items: center; gap: 6px;
    background: none; border: none; cursor: pointer;
    font-family: inherit; color: var(--graphite);
}
.nav-item-switch:hover { color: var(--action); }
.nav-item-switch svg { width: 15px; height: 15px; stroke: currentColor; stroke-width: 2.4; fill: none; transition: transform 0.3s ease; }
.nav-item-switch:hover svg { transform: translate(3px, -3px); }

.dropdown-trigger { position: relative; }
.dropdown-menu {
    position: absolute; top: 100%; left: 50%; transform: translateX(-50%) translateY(25px) scale(0.95);
    background-color: rgba(255, 255, 255, 0.98); backdrop-filter: blur(20px);
    border: 1px solid rgba(255,255,255,0.8); border-radius: 20px;
    box-shadow: 0 15px 35px rgba(0,0,0,0.2); padding: 25px; width: min(720px, 90vw);
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;
    opacity: 0; visibility: hidden; transition: all 0.3s var(--ease-out);
}
.dropdown-trigger:hover .dropdown-menu,
.dropdown-trigger.open .dropdown-menu { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(15px) scale(1); }
.column-title { display: flex; align-items: center; gap: 10px; font-weight: 700; color: var(--pole-habitat); margin-bottom: 15px; font-size: 0.95rem; text-transform: uppercase; letter-spacing: 0.5px; }
.column-title svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 2; }
.dropdown-column ul li { margin-bottom: 8px; }
.dropdown-column ul li a { color: var(--nav-text-dark); font-size: 0.95rem; padding: 8px 10px; border-radius: 10px; display: block; transition: all 0.2s; font-weight: 500; }
.dropdown-column ul li a:hover { background-color: rgba(190, 65, 40, 0.1); color: var(--pole-habitat); }
.col-pro .column-title { color: var(--pole-pro); }
.col-pro ul li a:hover { background-color: rgba(130, 100, 28, 0.12); color: var(--pole-pro); }
.col-paysagisme .column-title { color: var(--green-landscape); }
.col-paysagisme ul li a:hover { background-color: rgba(74, 114, 73, 0.12); color: var(--pole-paysage); }

/* Pilule pleine, accordée aux angles arrondis de la barre de navigation.
   Les resets de bordure et de police sont là parce que c'est devenu un
   <button> — il ouvre un panneau, il ne mène pas à une adresse. */
.cta-btn {
    background-color: var(--orange-btp); color: #fff;
    border: none; padding: 12px 26px; border-radius: 30px;
    font-family: var(--font-body); font-weight: 700; font-size: 0.95rem;
    white-space: nowrap; cursor: pointer;
    transition: all 0.3s ease; box-shadow: 0 4px 12px rgba(190, 65, 40, 0.33);
}
.cta-btn:hover { background-color: var(--orange-hover); transform: translateY(-2px); box-shadow: 0 6px 18px rgba(190, 65, 40, 0.42); }

@media (prefers-reduced-motion: reduce) {
    .cta-btn:hover { transform: none; }
}

.menu-toggle {
    display: none; flex-direction: column; justify-content: center; align-items: center; gap: 5px;
    width: 44px; height: 44px; background: transparent; border: none; padding: 0; cursor: pointer; flex-shrink: 0;
}
.menu-toggle .bar {
    display: block; width: 22px; height: 2px; background-color: var(--nav-text-dark); border-radius: 2px;
    transition: transform 0.35s var(--ease-out), opacity 0.25s ease;
}
.menu-toggle.active .bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-toggle.active .bar:nth-child(2) { opacity: 0; }
.menu-toggle.active .bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.nav-overlay {
    position: fixed; inset: 0; background: rgba(20, 18, 14, 0.4);
    opacity: 0; visibility: hidden; transition: opacity 0.35s ease, visibility 0.35s ease; z-index: 900;
}
.nav-overlay.open { opacity: 1; visibility: visible; }
body.menu-open { overflow: hidden; }

/* ---------- 5. HERO — porte d'entrée ----------
   Le hero ne raconte plus rien au scroll : ni piste pinnée de 480vh, ni
   mots qui se relaient, ni visuel qui se substitue à lui-même. Un titre
   fixe, puis deux portes. Tant qu'aucune n'est poussée, la page ne défile
   pas et la navigation reste repliée — c'est la condition posée : on ne
   continue pas sans avoir choisi son univers. */
.hero {
    position: relative;
    min-height: 100vh; min-height: 100svh;
    display: flex; flex-direction: column;
    padding: calc(var(--header-h) + 1.5rem) var(--gutter) clamp(2rem, 5vh, 4rem);
}
/* Centrage par marges automatiques plutôt que par align-items: center.
   Les deux centrent à l'identique tant que ça rentre ; mais quand le
   contenu dépasse — petit écran, portes empilées — les marges auto
   retombent à zéro, là où le centrage classique déborde des deux côtés et
   rend le haut du bloc inatteignable au défilement. */
.hero-inner {
    max-width: 1200px; width: 100%;
    margin: auto;
    display: flex; flex-direction: column;
    gap: clamp(2rem, 5vh, 3.5rem);
}

.hero-copy { text-align: center; }
.title-xl { text-wrap: balance; }
.hero-lead {
    margin-top: clamp(0.9rem, 2vh, 1.4rem);
    max-width: 46ch; margin-inline: auto;
    font-size: clamp(1.02rem, 1.4vw, 1.2rem);
}

/* --- Les deux portes ---
   Chaque pôle ayant sa page, ce sont des liens : plus de verrou à tenir,
   c'est la navigation du navigateur qui fait le travail. */
.hero-choice { display: flex; flex-direction: column; align-items: center; gap: clamp(1rem, 2.5vh, 1.5rem); }
.gates-prompt {
    font-family: 'Instrument Sans', var(--font-body);
    font-size: 0.72rem; font-weight: 600; text-transform: uppercase;
    letter-spacing: 0.2em; color: var(--text-muted);
}
.gates {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(0.85rem, 2vw, 1.5rem);
    width: 100%; max-width: 900px;
}
/* 4/3 : c'est le format dans lequel les deux visuels sont préparés. Le
   cadre épouse l'image au lieu de la rogner — et ce ratio ne change plus
   selon la largeur, sinon on retombe sur un recadrage. */
.gate {
    position: relative; display: block; width: 100%; padding: 0;
    aspect-ratio: 4 / 3; overflow: hidden; cursor: pointer;
    background: var(--bg-cream);
    border: 3px solid var(--graphite); border-radius: 0;
    transition: transform 0.35s var(--ease-out), box-shadow 0.35s var(--ease-out);
}
.gate img {
    position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: cover; filter: saturate(0.9);
    transition: transform 0.7s var(--ease-out);
}
.gate-veil {
    position: absolute; inset: 0;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.82) 8%, rgba(0, 0, 0, 0.34) 52%, rgba(0, 0, 0, 0.12) 100%);
    transition: opacity 0.35s ease;
}
.gate:hover, .gate:focus-visible {
    transform: translateY(-4px);
    box-shadow: 0 18px 34px -20px rgba(0, 0, 0, 0.75);
}
.gate:hover img, .gate:focus-visible img { transform: scale(1.05); }
.gate:focus-visible { outline: 3px solid var(--action); outline-offset: 4px; }

.gate-body {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    align-items: center; gap: 0.75rem;
    padding: clamp(1rem, 2.2vw, 1.5rem); text-align: left; color: #fff;
}
.gate-name {
    grid-column: 1; font-family: 'Bricolage Grotesque', var(--font-heading);
    font-weight: 800; font-size: clamp(1.4rem, 3vw, 2.2rem); line-height: 1;
    letter-spacing: -0.03em; text-transform: uppercase;
}
.gate-sub {
    grid-column: 1; font-family: 'Instrument Sans', var(--font-body);
    font-size: clamp(0.7rem, 1vw, 0.82rem); font-weight: 500;
    color: rgba(255, 255, 255, 0.82); margin-top: 0.3rem;
}
.gate-go {
    grid-column: 2; grid-row: 1 / span 2;
    display: grid; place-items: center; flex-shrink: 0;
    width: clamp(38px, 4vw, 48px); height: clamp(38px, 4vw, 48px);
    background: var(--action); color: #fff;
    transition: transform 0.35s var(--ease-out);
}
.gate-go svg { width: 50%; height: 50%; }
.gate:hover .gate-go, .gate:focus-visible .gate-go { transform: translateX(4px); }

/* --- Téléphone du hero : un numéro qu'on lit, pas un second bouton --- */
.hero-phone {
    display: flex; flex-direction: column; align-items: center; gap: 0.35rem;
    text-align: center;
}
.hero-phone-label {
    font-size: 0.66rem; font-weight: 500; line-height: 1;
    text-transform: uppercase; letter-spacing: 0.09em; color: var(--text-muted);
}
.hero-phone-number {
    font-family: var(--font-heading); font-size: clamp(1.05rem, 1.6vw, 1.3rem); font-weight: 700;
    color: var(--text-main); width: fit-content; padding-bottom: 3px; line-height: 1;
    background-image: linear-gradient(currentColor, currentColor);
    background-size: 0% 1.5px; background-repeat: no-repeat; background-position: 0 100%;
    transition: background-size 0.4s var(--ease-out);
}
.hero-phone:hover .hero-phone-number { background-size: 100% 1.5px; }

/* ---------- 6. Pôle travaux — direction « atelier » ----------
   Blocs carrés à bord épais et ombre imprimée décalée : de l'impression,
   pas du glassmorphisme. Les couleurs restent celles du site — chaque bloc
   porte la teinte de son pôle. Le premier ouvre un comparateur avant/après. */
/* Fond blanc comme le reste du site : ce sont les bords noirs épais des
   plaques et leur ombre décalée qui donnent le relief, pas un aplat teinté.
   --at-bg sert aussi de liseré entre la plaque et son ombre : il doit donc
   rester égal au fond réel de la section. */
.expertise {
    --at-bg: var(--bg-light);
    padding: var(--sp-xl) var(--gutter);
    background: var(--at-bg);
    border-block: 1px solid rgba(0, 0, 0, 0.07);
}
.section-shell { max-width: 1400px; margin: 0 auto; }

.section-head {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
    align-items: end; gap: clamp(1rem, 4vw, 4rem);
    margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.section-kicker {
    grid-column: 1 / -1; display: inline-flex; align-items: center; gap: 0.8rem;
    font-family: 'Instrument Sans', var(--font-body);
    font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.2em;
    color: var(--action); margin-bottom: clamp(0.75rem, 2vw, 1.25rem);
}
.section-kicker::before { content: ''; width: 34px; height: 3px; background: currentColor; }
.section-h2 {
    font-family: 'Bricolage Grotesque', var(--font-heading);
    font-weight: 800; font-size: clamp(2.3rem, 5.6vw, 5rem); line-height: 0.94;
    letter-spacing: -0.035em; text-transform: uppercase; color: var(--graphite);
    text-wrap: balance;
}
.section-h2 em { font-style: normal; color: var(--action); }
.section-lead { max-width: 42ch; color: var(--text-muted); }

/* --- Les trois blocs --- */
.atelier { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(1rem, 2vw, 1.75rem); }
/* Plaques figées : ni décollement au survol, ni zoom de l'image, ni repère
   « voir en grand ». Ce ne sont plus des boutons — le lien métier vers les
   réalisations est désactivé le temps que les titres soient arrêtés. */
.at-slab {
    --at-pole: var(--graphite);
    position: relative; background: var(--bg-light); border: 3px solid var(--graphite);
    display: flex; flex-direction: column;
    box-shadow: 10px 10px 0 -3px var(--at-bg), 10px 10px 0 0 var(--graphite);
}
.at-habitat { --at-pole: var(--pole-habitat); }
.at-ext     { --at-pole: var(--pole-exterieur); }
.at-pro     { --at-pole: var(--pole-pro); }
.at-paysage { --at-pole: var(--pole-paysage); }

.at-ph {
    position: relative; display: block; width: 100%; padding: 0;
    aspect-ratio: 1 / 1; overflow: hidden;
    border-bottom: 3px solid var(--graphite); background: var(--bg-cream);
}
.at-ph img {
    width: 100%; height: 100%; object-fit: cover;
    filter: saturate(0.88) contrast(1.05);
}
.at-num {
    position: absolute; top: 0; left: 0; background: var(--graphite); color: var(--bg-light);
    font-family: 'Bricolage Grotesque', var(--font-heading); font-weight: 800; font-size: 1rem;
    letter-spacing: 0.06em; padding: 0.45rem 0.8rem;
}
.at-tag {
    position: absolute; bottom: 0; right: 0; background: var(--at-pole); color: #fff;
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.66rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.16em; padding: 0.5rem 0.85rem;
}
.at-bd { padding: clamp(1.1rem, 2vw, 1.6rem); display: flex; flex-direction: column; flex: 1; }
.at-bd h3 {
    font-family: 'Bricolage Grotesque', var(--font-heading); font-weight: 600;
    font-size: clamp(1.2rem, 1.9vw, 1.5rem); line-height: 1.1;
    letter-spacing: -0.02em; color: var(--graphite);
}
.at-bd ul {
    margin-top: 1rem; padding-top: 0.9rem; display: flex; flex-direction: column; gap: 0.5rem;
    border-top: 1.5px solid rgba(0, 0, 0, 0.18);
}
.at-bd li {
    display: flex; gap: 0.6rem; font-size: 0.9rem; line-height: 1.45; color: var(--text-muted);
}
.at-bd li::before {
    content: ''; flex: 0 0 10px; height: 3px; background: var(--at-pole); margin-top: 0.62em;
}

/* ---------- 6b. Comparateur avant / après ----------
   Il vit dans un panneau plein écran, ouvert depuis une carte du carrousel.
   L'image ne bouge pas : seule la coupure se déplace — pas de zoom, pas de
   recadrage à l'ouverture. Le curseur est un input range transparent, ce
   qui donne souris, tactile et clavier sans une ligne de code de plus. */
.ba {
    position: absolute; inset: 0; z-index: 1; --pos: 50%;
    overflow: hidden; cursor: ew-resize;
}
.ba .ba-img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; }
/* Découpe par clip-path et non par largeur : l'image « avant » garde la
   taille du cadre et se dévoile, au lieu de se comprimer vers la gauche. */
.ba-before {
    position: absolute; inset: 0;
    clip-path: inset(0 calc(100% - var(--pos)) 0 0);
}
.ba-handle {
    position: absolute; top: 0; bottom: 0; left: var(--pos);
    width: 3px; margin-left: -1.5px; background: var(--bg-light); z-index: 3;
    box-shadow: 0 0 22px rgba(0, 0, 0, 0.45);
}
.ba-grip {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    display: grid; place-items: center; width: 54px; height: 54px; border-radius: 50%;
    background: var(--bg-light); color: var(--graphite); border: 3px solid var(--graphite);
}
.ba-grip svg { width: 22px; height: 22px; }
.ba-tag {
    position: absolute; top: clamp(1rem, 3vh, 2rem); z-index: 3;
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.66rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.16em; padding: 0.5rem 0.9rem;
    background: var(--graphite); color: var(--bg-light);
}
/* Les étiquettes suivent le fil : chacune reste du bon côté de la coupure */
.ba-tag--a { left: max(1rem, calc(var(--pos) - 6.5rem)); }
.ba-tag--b { left: calc(var(--pos) + 1rem); background: var(--action); }

/* Repère d'amorçage : il ne sert qu'une fois et disparaît dès la première
   manipulation — après, c'est du bruit. */
.ba-tip {
    position: absolute; z-index: 5; left: var(--pos); top: calc(50% + 52px);
    transform: translateX(-50%);
    display: inline-flex; align-items: center; gap: 0.45rem; white-space: nowrap;
    background: var(--graphite); color: var(--bg-light);
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.68rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.12em; padding: 0.5rem 0.85rem;
    animation: ba-nudge 2.6s ease-in-out infinite;
    transition: opacity 0.35s ease, transform 0.35s var(--ease-out);
}
.ba-used .ba-tip { opacity: 0; transform: translateX(-50%) translateY(8px); pointer-events: none; }
.ba-used .ba-grip { animation: none; }
@keyframes ba-nudge {
    0%, 100% { transform: translateX(-50%); }
    45%      { transform: translateX(calc(-50% - 7px)); }
    70%      { transform: translateX(calc(-50% + 7px)); }
}
/* La poignée respire tant qu'on n'y a pas touché */
.ba-grip { animation: ba-pulse 2.6s ease-in-out infinite; }
@keyframes ba-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(190, 65, 40, 0.55); }
    60%      { box-shadow: 0 0 0 14px rgba(190, 65, 40, 0); }
}
.ba-range {
    position: absolute; inset: 0; z-index: 4; width: 100%; height: 100%;
    margin: 0; opacity: 0; cursor: ew-resize; -webkit-appearance: none; appearance: none; background: none;
}
.ba-range::-webkit-slider-thumb { -webkit-appearance: none; width: 60px; height: 100vh; cursor: ew-resize; }
.ba-range::-moz-range-thumb { width: 60px; height: 100vh; border: none; cursor: ew-resize; }
.ba-range:focus-visible ~ .ba-handle .ba-grip { outline: 3px solid var(--action); outline-offset: 3px; }

/* ---------- 6c. Panneaux plein écran ----------
   Un panneau par usage : le comparateur, et la fiche de chantier. Même
   armature — fond sombre, pavé clair à bord épais, bouton de fermeture. */
.modal {
    position: fixed; inset: 0; z-index: 1400;
    background: var(--graphite); overflow: hidden;
    opacity: 0; visibility: hidden;
    transition: opacity 0.35s ease, visibility 0.35s ease;
}
.modal.is-on { opacity: 1; visibility: visible; }
body.modal-open { overflow: hidden; }

/* Le voile ne couvre que le coin bas gauche : sur le comparateur, il ne
   doit gêner la lecture d'aucune des deux moitiés. */
.modal--ba::after {
    content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 2;
    background: linear-gradient(20deg, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.45) 34%, rgba(0, 0, 0, 0) 62%);
}

.modal-panel {
    position: absolute; z-index: 3;
    left: clamp(1.25rem, 5vw, 5rem); bottom: clamp(1.25rem, 6vh, 4rem);
    width: min(30rem, calc(100% - 2.5rem));
    background: var(--bg-light); border: 3px solid var(--graphite);
    padding: clamp(1.4rem, 2.4vw, 2rem);
    transform: translateY(26px); opacity: 0;
    transition: transform 0.6s var(--ease-out) 0.12s, opacity 0.45s ease 0.12s;
}
.modal.is-on .modal-panel { transform: none; opacity: 1; }
.modal-k {
    display: flex; align-items: center; gap: 0.7rem;
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.68rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.18em; color: var(--m-accent, var(--graphite));
    margin-bottom: 0.7rem;
}
.modal-panel h3, .pj-body h3 {
    font-family: 'Bricolage Grotesque', var(--font-heading); font-weight: 800;
    font-size: clamp(1.6rem, 3vw, 2.4rem); line-height: 0.98;
    letter-spacing: -0.03em; text-transform: uppercase; color: var(--graphite);
}
.modal-sous { margin-top: 0.6rem; font-size: 0.92rem; color: var(--text-muted); }

/* Fermer : une croix, et c'est tout. Pas de cadre, pas de rotation — un
   bouton de fermeture n'a pas à se faire remarquer, il doit juste être
   trouvable et assez grand pour le doigt (40 px de zone de clic pour un
   trait de 15). Blanc par défaut : les panneaux qui l'accueillent sont
   sombres. Le libellé reste porté par aria-label. */
.modal-close {
    position: absolute; z-index: 5; top: clamp(0.9rem, 3vh, 1.6rem); right: clamp(0.9rem, 3vw, 1.6rem);
    display: grid; place-items: center;
    width: 40px; height: 40px; padding: 0;
    background: none; border: none; cursor: pointer;
    color: #fff; opacity: 0.72;
    transition: opacity 0.2s ease;
}
.modal-close svg { width: 15px; height: 15px; }
.modal-close:hover { opacity: 1; }
.modal-close:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; opacity: 1; }

/* Dans le panneau de contact, l'angle est clair : la croix s'y assombrit. */
.modal--contact .modal-close { color: var(--graphite); opacity: 0.55; }

/* --- Fiche de chantier --- */
.modal--pj { background: rgba(0, 0, 0, 0.88); }
.pj-shell {
    position: absolute; inset: 0; z-index: 2;
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    max-width: 1300px; max-height: 88vh;
    margin: auto; inset-inline: clamp(1rem, 5vw, 4rem); inset-block: auto;
    top: 50%; transform: translateY(-50%);
    background: var(--bg-light); border: 3px solid var(--graphite);
    overflow: hidden;
}
.modal--pj .pj-shell { opacity: 0; transition: opacity 0.4s ease, transform 0.5s var(--ease-out); transform: translateY(calc(-50% + 20px)); }
.modal--pj.is-on .pj-shell { opacity: 1; transform: translateY(-50%); }

.pj-visual { position: relative; background: var(--bg-cream); }
.pj-visual img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.pj-body {
    padding: clamp(1.5rem, 3vw, 2.5rem);
    overflow-y: auto; overscroll-behavior: contain;
    display: flex; flex-direction: column;
}

/* Les quatre dates : un tableau de faits, pas un paragraphe. Le retard est
   la ligne que le visiteur cherche — elle est traitée à part. */
.pj-dates {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1px; margin-top: clamp(1.25rem, 2.5vw, 1.75rem);
    background: rgba(0, 0, 0, 0.14); border: 1px solid rgba(0, 0, 0, 0.14);
}
.pj-dates > div { background: var(--bg-light); padding: 0.85rem 1rem; }
.pj-dates dt {
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.62rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.14em; color: var(--text-muted);
}
.pj-dates dd {
    margin-top: 0.3rem; font-family: var(--font-heading);
    font-size: 0.98rem; font-weight: 700; color: var(--text-main);
}
/* Livré sans retard : c'est un argument, il se voit. En retard : on
   l'affiche quand même, c'est tout l'intérêt de publier le chiffre. */
.pj-dates .is-ontime dd { color: var(--pole-paysage); }
.pj-dates .is-late dd { color: var(--action); }

.pj-block { margin-top: clamp(1.25rem, 2.5vw, 1.75rem); }
.pj-block h4 {
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.68rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.16em; color: var(--text-muted);
    margin-bottom: 0.5rem;
}
.pj-block p { font-size: 0.95rem; }

.pj-avis {
    margin-top: clamp(1.25rem, 2.5vw, 1.75rem);
    padding-left: 1.1rem; border-left: 3px solid var(--m-accent, var(--graphite));
}
.pj-avis p { font-size: 0.98rem; font-style: italic; color: var(--text-main); }
.pj-avis figcaption {
    margin-top: 0.6rem;
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.7rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.12em; color: var(--text-muted);
}

.pj-go {
    margin-top: auto; padding-top: clamp(1.25rem, 2.5vw, 1.75rem);
    align-self: flex-start;
    display: inline-flex; align-items: center; gap: 0.5rem;
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.78rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.1em; color: var(--action);
}
.pj-go svg { width: 14px; height: 14px; transition: transform 0.3s var(--ease-out); }
.pj-go:hover svg { transform: translateX(4px); }

/* En colonne, la hauteur doit être fixée : des rangées en fr dans une grille
   de hauteur automatique se comportent comme « auto », et le visuel —
   dont l'image est en position absolue — retomberait à zéro. On donne donc
   sa proportion à l'image, et le reste au texte, qui défile. */
@media (max-width: 900px) {
    .pj-shell {
        grid-template-columns: 1fr;
        grid-template-rows: auto minmax(0, 1fr);
        height: min(88vh, 900px); max-height: none;
    }
    .pj-visual { aspect-ratio: 16 / 10; }
}
@media (max-width: 640px) {
    .pj-shell { inset-inline: 0.75rem; }
    .pj-dates { grid-template-columns: 1fr; }
    .modal-close kbd { display: none; }
}

/* --- Panneau de contact (accueil) ---
   Version courte du formulaire des pages métier. Il s'ouvre par-dessus la
   page, qui ne bouge pas : sur une vitrine de trois sections, envoyer le
   visiteur vers un formulaire plus bas lui ferait quitter le choix qu'il
   était en train de faire. */
/* Le panneau reprend l'armature du formulaire des pages métier : une
   colonne d'accroche sombre, une colonne de saisie claire, un bord épais
   autour. Le visiteur retrouve la même chose qu'il entre par l'accueil ou
   par une page métier — c'est ce qui manquait à la version précédente,
   qui n'était qu'une pile de champs dans une boîte. */
.modal--contact { background: rgba(0, 0, 0, 0.88); display: grid; place-items: center; padding: clamp(0.75rem, 3vw, 2rem); }
.cm-shell {
    --dv: var(--action);
    position: relative; z-index: 2;
    width: min(56rem, 100%);
    max-height: min(92vh, 880px); overflow: hidden;
    display: grid; grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
    background: var(--bg-light); border: 3px solid var(--graphite);
    opacity: 0; transform: translateY(20px);
    transition: opacity 0.4s ease, transform 0.5s var(--ease-out);
}
.modal--contact.is-on .cm-shell { opacity: 1; transform: none; }
/* Le pôle choisi teinte la sélection et les champs — jamais le bouton,
   qui reste le seul élément terre cuite de l'écran. */
.cm-shell[data-pole="paysagisme"] { --dv: var(--pole-paysage); }

/* --- Colonne d'accroche --- */
.cm-side {
    display: flex; flex-direction: column;
    padding: clamp(1.6rem, 3vw, 2.4rem);
    background: var(--graphite); color: #fff;
}
.cm-side .section-kicker { color: #fff; opacity: 0.6; margin-bottom: 0.9rem; }
.cm-title {
    font-family: 'Bricolage Grotesque', var(--font-heading); font-weight: 800;
    font-size: clamp(1.7rem, 3vw, 2.4rem); line-height: 0.98;
    letter-spacing: -0.03em; text-transform: uppercase; color: #fff;
}
.cm-title em { font-style: normal; color: var(--action); }
.cm-lead { margin-top: 0.9rem; font-size: 0.92rem; color: rgba(255, 255, 255, 0.72); }

.cm-trust { margin-top: clamp(1.25rem, 3vw, 2rem); display: flex; flex-direction: column; gap: 0.65rem; }
.cm-trust li { display: flex; align-items: flex-start; gap: 0.6rem; font-size: 0.84rem; color: rgba(255, 255, 255, 0.82); }
.cm-trust svg { width: 14px; height: 14px; flex-shrink: 0; margin-top: 0.3em; color: #fff; opacity: 0.85; }

.cm-phone {
    margin-top: auto; padding-top: clamp(1.25rem, 3vw, 2rem);
    display: flex; flex-direction: column; gap: 0.3rem;
}
.cm-phone-label {
    font-size: 0.64rem; font-weight: 500; text-transform: uppercase;
    letter-spacing: 0.1em; color: rgba(255, 255, 255, 0.55);
}
.cm-phone-number {
    font-family: var(--font-heading); font-size: 1.2rem; font-weight: 700; color: #fff;
    width: fit-content; padding-bottom: 3px; line-height: 1;
    background-image: linear-gradient(currentColor, currentColor);
    background-size: 0% 1.5px; background-repeat: no-repeat; background-position: 0 100%;
    transition: background-size 0.4s var(--ease-out);
}
.cm-phone:hover .cm-phone-number { background-size: 100% 1.5px; }

/* --- Colonne de saisie --- */
.cm-main {
    padding: clamp(1.6rem, 3vw, 2.4rem);
    /* De quoi laisser passer le bouton de fermeture, qui se loge dans
       l'angle : sans ça il recouvrirait la première légende. */
    padding-top: clamp(3rem, 4.5vw, 3.6rem);
    overflow-y: auto; overscroll-behavior: contain;
}
.cm-step { border: none; padding: 0; margin: 0; }
.cm-step + .cm-step { margin-top: clamp(1.5rem, 3vw, 2rem); }
/* Les deux temps sont numérotés : on voit d'un coup d'œil qu'il n'y en a
   que deux, ce qui est l'argument même du formulaire. */
.cm-legend {
    display: flex; align-items: center; gap: 0.65rem; padding: 0; margin-bottom: 0.9rem;
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.7rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.14em; color: var(--text-main);
}
.cm-num {
    display: grid; place-items: center; flex-shrink: 0;
    width: 22px; height: 22px;
    background: var(--graphite); color: var(--bg-light);
    font-family: 'Bricolage Grotesque', var(--font-heading); font-weight: 800;
    font-size: 0.72rem; letter-spacing: 0;
}
.cm-form .btn-send { margin-top: clamp(1.5rem, 3vw, 2rem); margin-left: 0; width: 100%; }
.modal--contact .devis-done { padding: 0; margin: auto 0; }

@media (max-width: 760px) {
    /* La colonne sombre devient un bandeau : sur un écran étroit, deux
       colonnes ne laisseraient de place ni à l'une ni à l'autre. */
    .cm-shell { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); }
    .cm-side { padding-bottom: clamp(1.2rem, 4vw, 1.6rem); padding-right: 3.5rem; }
    .cm-trust, .cm-phone { display: none; }
    .cm-lead { margin-top: 0.6rem; }
    /* En colonne, l'angle du panneau est le bandeau sombre : la croix y
       repasse en blanc. */
    .modal--contact .modal-close { color: #fff; opacity: 0.72; }
    .cm-main { padding-top: clamp(1.6rem, 3vw, 2.4rem); }
}

/* ---------- 6e. L'équipe ----------
   Mêmes plaques à bord épais que les métiers : c'est la même famille
   d'objets, on ne change pas de langage en cours de page. */
.team {
    --at-bg: var(--bg-light);
    padding: var(--sp-xl) var(--gutter);
    background: var(--at-bg);
    border-block: 1px solid rgba(0, 0, 0, 0.07);
}
.team-grid {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: clamp(1.25rem, 2.5vw, 2rem);
}
/* Pas de carte, pas de cadre, pas de pastille : la photo, le nom, le rôle,
   une ligne. Ce sont les images qui portent la section — les empiler dans
   des boîtes arrondies à ombre douce les aurait toutes ramenées au même
   plan, et fait ressembler la page à un gabarit.
   Parti pris photo : le geste plutôt que le visage. Quatre portraits
   souriants alignés sur fond blanc, c'est le cliché du site d'entreprise ;
   des mains au travail disent le métier, et restent vraies. */
.team-card {
    --m-accent: var(--graphite);
    display: flex; flex-direction: column;
}
.team-card.m-habitat   { --m-accent: var(--pole-habitat); }
.team-card.m-exterieur { --m-accent: var(--pole-exterieur); }
.team-card.m-pro       { --m-accent: var(--pole-pro); }
.team-card.m-paysage   { --m-accent: var(--pole-paysage); }

/* Cadre vide en attendant les portraits : il tient la place et le format,
   rien de plus. Format portrait — c'est le cadrage d'un visage, pas d'un
   chantier. Les règles sur img sont déjà là pour le jour où les photos
   arriveront : rien d'autre ne bougera. */
.team-photo {
    margin: 0 0 1.1rem; aspect-ratio: 4 / 5;
    overflow: hidden;
    background: var(--bg-cream);
    border: 1px solid rgba(0, 0, 0, 0.12);
}
.team-photo img {
    width: 100%; height: 100%; object-fit: cover;
    /* Des photos prises par plusieurs photographes se lisent comme une
       banque d'images ; un traitement commun les ramène dans la même
       lumière. À desserrer le jour où elles seront faites en une séance. */
    filter: saturate(0.82) contrast(1.06) brightness(1.02);
    transition: transform 0.7s var(--ease-out);
}
.team-card:hover .team-photo img { transform: scale(1.04); }

.team-name {
    font-family: 'Bricolage Grotesque', var(--font-heading);
    font-weight: 800; font-size: clamp(1.05rem, 1.6vw, 1.22rem); line-height: 1.15;
    letter-spacing: -0.02em; text-transform: uppercase; color: var(--graphite);
}
/* Le filet prend la couleur du pôle : c'est la seule couleur de la carte,
   et elle tient sur deux pixels. */
.team-role {
    margin-top: 0.5rem; padding-top: 0.5rem;
    border-top: 2px solid var(--m-accent);
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.68rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-main);
}
.team-line { margin-top: 0.7rem; font-size: 0.86rem; line-height: 1.5; }

@media (prefers-reduced-motion: reduce) {
    .team-card:hover .team-photo img { transform: none; }
}

/* ---------- 6f. Avis clients ----------
   La seule section qui sort du noir et blanc, et volontairement : la preuve
   vient de Google, elle doit en porter les couleurs. Des cartes dessinées
   comme les plaques métier — bord noir épais, angles vifs — auraient l'air
   d'avoir été écrites par le site lui-même. Ici : angles arrondis, ombres
   douces teintées, pastilles de couleur, étoiles ambre. */
:root {
    /* Couleurs officielles Google, réservées à cette section */
    --g-blue: #4285F4;
    --g-red: #EA4335;
    --g-yellow: #FBBC05;
    --g-green: #34A853;
    --g-star: #FBBC05;
    --g-line: #DADCE0;   /* filet gris des composants Google */
    --g-ink: #3C4043;    /* gris texte Google */
    --g-hover: #F8F9FA;  /* gris de survol Google */
}
/* Le sprite ne sert qu'à porter le symbole : il ne doit rien occuper. */
.svg-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.g-mark { width: 18px; height: 18px; display: block; flex-shrink: 0; }

.reviews { padding: var(--sp-xl) var(--gutter); }

/* Note d'ensemble : le chiffre que le visiteur cherche d'abord */
.reviews-score {
    display: inline-flex; align-items: center; gap: 0.7rem; flex-wrap: wrap;
    margin-bottom: clamp(1.75rem, 3.5vw, 2.5rem);
    padding: 0.7rem 1.2rem; border-radius: 50px;
    background: var(--bg-light); border: 1px solid var(--g-line);
    box-shadow: 0 2px 10px -4px rgba(60, 64, 67, 0.2);
}
.score-mark { display: grid; place-items: center; }
.score-mark .g-mark { width: 22px; height: 22px; }
.score-num {
    font-family: var(--font-heading); font-size: 1.35rem; font-weight: 800;
    line-height: 1; color: var(--g-ink);
}
.score-stars { display: flex; gap: 1px; }
.score-stars svg { width: 17px; height: 17px; fill: var(--g-star); }
.score-count { font-size: 0.8rem; color: var(--text-muted); }

.reviews-grid {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(1rem, 2vw, 1.75rem);
}

/* --rv : la teinte Google de la carte, posée en HTML. Elle colore le liseré
   du haut, la pastille et l'ombre au survol. */
.review {
    --rv: var(--g-blue);
    position: relative; display: flex; flex-direction: column;
    padding: clamp(1.3rem, 2.2vw, 1.8rem);
    background: var(--bg-light);
    border: 1px solid var(--g-line); border-radius: 18px;
    box-shadow: 0 2px 14px -6px rgba(60, 64, 67, 0.18);
    transition: transform 0.35s var(--ease-out), box-shadow 0.35s ease;
}
/* Liseré coloré en tête de carte, rogné aux angles arrondis */
.review::before {
    content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px;
    background: var(--rv);
    border-radius: 18px 18px 0 0;
}
.review:hover {
    transform: translateY(-4px);
    /* Ombre neutre d'abord : color-mix n'est pas partout, la seconde
       déclaration est simplement ignorée là où il manque. */
    box-shadow: 0 16px 30px -18px rgba(60, 64, 67, 0.5);
    box-shadow: 0 16px 30px -18px color-mix(in srgb, var(--rv) 55%, rgba(60, 64, 67, 0.5));
}

/* Provenance : le G en filigrane dans le coin, comme sur une fiche Google */
.review-source { position: absolute; top: clamp(1.1rem, 2vw, 1.5rem); right: clamp(1.1rem, 2vw, 1.5rem); opacity: 0.85; }

.review-stars { display: flex; gap: 2px; margin-bottom: 0.9rem; }
.review-stars svg { width: 17px; height: 17px; fill: rgba(60, 64, 67, 0.16); }
.review-stars svg.is-on { fill: var(--g-star); }

.review-text p { font-size: 0.93rem; line-height: 1.55; color: var(--g-ink); }

.review-by {
    margin-top: auto; padding-top: 1.1rem;
    display: flex; align-items: center; gap: 0.7rem;
    border-top: 1px solid var(--g-line);
}
/* Pastille à l'initiale : ce que Google affiche quand l'auteur n'a pas de
   photo de profil. Remplaçable par une <img> aux mêmes dimensions. */
.review-avatar {
    display: grid; place-items: center; flex-shrink: 0;
    width: 38px; height: 38px; border-radius: 50%;
    background: var(--rv); color: #fff;
    font-family: var(--font-heading); font-size: 1rem; font-weight: 700;
    object-fit: cover;
}
.review-id { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.review-name { font-family: var(--font-heading); font-size: 0.9rem; font-weight: 700; color: var(--g-ink); }
.review-when { font-size: 0.75rem; color: var(--text-muted); }

/* Bouton aux codes Google : fond blanc, filet gris, texte ardoise. Au
   survol il reste chez Google — le gris #F8F9FA et un halo bleu — plutôt
   que de virer à la terre cuite du site : un bouton qui mène ailleurs ne
   doit pas se déguiser en bouton maison. */
.reviews-all {
    margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
    display: inline-flex; align-items: center; gap: 0.7rem;
    padding: 0.85rem 1.4rem; border-radius: 50px;
    background: var(--bg-light); color: var(--g-ink);
    border: 1px solid var(--g-line);
    box-shadow: 0 1px 5px -2px rgba(60, 64, 67, 0.25);
    font-family: var(--font-body); font-size: 0.92rem; font-weight: 600;
    letter-spacing: 0;
    transition: background 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.reviews-all .g-mark { width: 19px; height: 19px; }
.reviews-all-go { width: 15px; height: 15px; opacity: 0.55; transition: transform 0.3s var(--ease-out); }
.reviews-all:hover {
    background: var(--g-hover);
    border-color: #D2E3FC;
    box-shadow: 0 2px 12px -3px rgba(66, 133, 244, 0.4);
}
.reviews-all:hover .reviews-all-go { transform: translate(3px, -3px); }
.reviews-all:focus-visible { outline: 3px solid var(--g-blue); outline-offset: 3px; }
/* Sous le bouton et non centrée comme au footer : elle accompagne le lien */
.google-note { margin-top: 0.9rem; margin-left: 0; text-align: left; max-width: 52ch; }

@media (prefers-reduced-motion: reduce) {
    .review:hover { transform: none; }
}

@media (max-width: 1024px) {
    .team-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 860px) {
    .reviews-grid { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
    .team-grid { grid-template-columns: 1fr; }
}

/* ---------- 6d. Avant / après — carrousel 3D ----------
   Un anneau permanent qu'on manœuvre à la main. Les deux versions
   précédentes déduisaient l'angle d'une piste de défilement — verticale
   d'abord (cinq écrans à descendre pour un mouvement horizontal), puis
   horizontale (un geste que rien n'annonce sur une page qui défile
   verticalement). Ici, deux flèches et un glisser : rien à deviner.
   L'orbite porte la rotation d'ensemble ; chaque carte ne connaît que sa
   place fixe sur le cercle. */
.ring { padding: var(--sp-xl) var(--gutter); }

/* De l'air sous le titre : les cartes avancent vers le regard, et sans
   cette marge le texte semblait posé dessus. */
.ring-head { margin-bottom: clamp(3rem, 7vw, 5rem); }

.ring-stage {
    position: relative;
    height: clamp(360px, 48vh, 520px);
    perspective: 2000px; perspective-origin: 50% 45%;
    /* Le glisser latéral est capté par le script ; le défilement vertical
       de la page reste possible au doigt. */
    touch-action: pan-y;
    cursor: grab;
}
.ring-stage.is-dragging { cursor: grabbing; }

.ring-orbit {
    position: absolute; inset: 0;
    transform-style: preserve-3d;
    will-change: transform;
}

/* Ombre au sol : ancre l'anneau au lieu de le laisser flotter */
.ring-floor {
    position: absolute; left: 50%; bottom: 3%; z-index: 0;
    width: min(70%, 780px); height: 11%;
    transform: translateX(-50%);
    background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.26) 0%, rgba(0, 0, 0, 0.1) 44%, rgba(0, 0, 0, 0) 72%);
    pointer-events: none;
}

.ring-card {
    position: absolute; top: 50%; left: 50%;
    width: clamp(160px, 19vw, 250px);
    margin: 0; padding: 0;
    background: none; border: none; cursor: pointer; text-align: left;
    transform-style: preserve-3d;
    will-change: transform;
}
.ring-card .img-wrapper {
    position: relative; overflow: hidden;
    aspect-ratio: 4 / 5; margin-bottom: 0.9rem;
    background: rgba(0, 0, 0, 0.05);
    border: 3px solid var(--graphite);
}
.ring-card img { width: 100%; height: 100%; object-fit: cover; }
.ring-card:focus-visible { outline: 3px solid var(--action); outline-offset: 6px; }

/* Voile d'ombrage : une carte qui se détourne du regard reçoit moins de
   lumière. Sans lui, des vignettes également éclairées ne lisent jamais
   comme un volume — et l'image vue de dos apparaîtrait en miroir. */
.card-shade {
    position: absolute; inset: 0; pointer-events: none; z-index: 2;
    background: linear-gradient(90deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.62) 55%, #000 100%);
    opacity: 0; transform-origin: center;
    }

/* Seule la carte de face porte sa légende et son repère : les autres sont
   trop inclinées pour qu'un texte y reste lisible. */
/* Légende et repère apparaissent quand la carte arrive face au regard :
   une opacité calculée sur l'angle, plutôt qu'un basculement de classe qui
   clignoterait à chaque passage. */
.ring-meta { text-align: center; opacity: 0; }
.ring-name {
    font-family: var(--font-heading);
    font-size: clamp(0.98rem, 1.5vw, 1.18rem); font-weight: 700;
    letter-spacing: -0.015em; margin-bottom: 0.15rem; color: var(--text-main);
}
.ring-meta > span:last-child { display: block; color: var(--text-muted); font-size: 0.84rem; }

.ring-tag {
    position: absolute; left: 0; bottom: 0; z-index: 3;
    display: inline-flex; align-items: center;
    padding: 0.45rem 0.8rem;
    background: var(--m-accent, var(--graphite)); color: #fff;
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.62rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.14em; white-space: nowrap;
}
.ring-open {
    position: absolute; top: 0.8rem; left: 0.8rem; z-index: 3;
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.4rem 0.75rem;
    background: rgba(255, 255, 255, 0.94); color: var(--graphite);
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.6rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.1em; white-space: nowrap;
    opacity: 0; transition: opacity 0.35s ease, background 0.25s ease, color 0.25s ease;
}
.ring-open svg { width: 12px; height: 12px; flex-shrink: 0; }
.ring-card:hover .ring-open,
.ring-card:focus-visible .ring-open { background: var(--action); color: #fff; }

.ring-card.m-habitat   { --m-accent: var(--pole-habitat); }
.ring-card.m-exterieur { --m-accent: var(--pole-exterieur); }
.ring-card.m-pro       { --m-accent: var(--pole-pro); }
.ring-card.m-paysage   { --m-accent: var(--pole-paysage); }

/* Amorce : rien d'autre sur la page ne se manipule latéralement, il faut
   le dire une fois. Elle s'efface au premier geste. */
.ring-hint {
    position: absolute; z-index: 4; left: 50%; bottom: 0;
    transform: translateX(-50%);
    display: inline-flex; align-items: center; gap: 0.5rem; white-space: nowrap;
    background: var(--graphite); color: var(--bg-light);
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.64rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.12em; padding: 0.45rem 0.8rem;
    transition: opacity 0.4s ease, transform 0.4s var(--ease-out);
}
.ring-hint svg { width: 14px; height: 14px; }
.ring-stage.is-used .ring-hint { opacity: 0; transform: translateX(-50%) translateY(6px); pointer-events: none; }
html:not(.js) .ring-hint { display: none; }

.ring-foot {
    display: flex; align-items: center; gap: clamp(0.75rem, 2vw, 1.5rem);
    margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
}
.ring-progress { flex: 1; height: 2px; background: rgba(0, 0, 0, 0.14); overflow: hidden; }
.ring-progress i {
    display: block; height: 100%; width: 100%; background: var(--action);
    transform: scaleX(0); transform-origin: left;
    transition: transform 0.55s var(--ease-out);
}
.ring-count {
    font-family: var(--font-heading); font-size: 0.78rem; font-weight: 500;
    letter-spacing: 0.12em; color: var(--text-muted);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
.ring-count b { color: var(--text-main); font-weight: 700; }

/* Sans JS, l'anneau ne peut pas se former : les cartes redeviennent une
   bande qu'on fait défiler au doigt. */
html:not(.js) .ring-stage {
    height: auto; perspective: none;
    overflow-x: auto; scrollbar-width: none;
    scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
}
html:not(.js) .ring-stage::-webkit-scrollbar { display: none; }
html:not(.js) .ring-orbit {
    position: static; display: flex; gap: clamp(1rem, 2vw, 2rem);
    transform: none !important;
}
html:not(.js) .ring-card {
    position: static; flex: 0 0 auto; transform: none !important;
    scroll-snap-align: center;
}
html:not(.js) .ring-meta, html:not(.js) .ring-open { opacity: 1; }
html:not(.js) .card-shade, html:not(.js) .ring-floor { display: none; }
html:not(.js) .ring-foot { display: none; }

@media (prefers-reduced-motion: reduce) {
    .ring-orbit { transition-duration: 0.01ms; }
}

/* ---------- 7. Réalisations — slider horizontal ----------
   Ancien fonctionnement : 520vh de piste verticale, cartes assemblées en
   anneau puis un tour complet sur elles-mêmes. Remplacé par un rail qu'on
   fait glisser d'une carte à la fois, avec une flèche de chaque côté.
   Le rail bouge par translation ; le nombre de cartes visibles est une
   variable CSS, ce qui évite d'avoir à le calculer en JS.             */
.showcase { padding: var(--sp-xl) var(--gutter); }
.showcase-head { margin-bottom: clamp(1.75rem, 4vw, 2.75rem); }

.slider {
    --per-view: 3;
    --slider-gap: clamp(1rem, 2vw, 1.75rem);
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: clamp(0.65rem, 1.6vw, 1.25rem);
}
.slider-viewport { overflow: hidden; }
.slider-rail {
    display: flex; align-items: flex-start;
    gap: var(--slider-gap);
    will-change: transform;
    transition: transform 0.55s var(--ease-out);
}

/* Flèches : mêmes bords épais que les plaques métier, pas des pastilles */
.slider-arrow {
    display: grid; place-items: center;
    width: clamp(44px, 4vw, 54px); height: clamp(44px, 4vw, 54px);
    background: var(--bg-light); color: var(--graphite);
    border: 3px solid var(--graphite); cursor: pointer;
    transition: background 0.25s ease, color 0.25s ease, opacity 0.25s ease;
}
.slider-arrow svg { width: 45%; height: 45%; }
.slider-arrow:hover:not([disabled]) { background: var(--action); border-color: var(--action); color: #fff; }
.slider-arrow[disabled] { opacity: 0.25; cursor: not-allowed; }

/* Chaque vignette est un bouton : elle ouvre la fiche du chantier. */
.project-card {
    flex: 0 0 calc((100% - (var(--per-view) - 1) * var(--slider-gap)) / var(--per-view));
    min-width: 0;
    padding: 0; background: none; border: none; cursor: pointer; text-align: left;
}
.project-card .img-wrapper {
    position: relative; overflow: hidden;
    aspect-ratio: 4 / 5; margin-bottom: 1rem;
    background: rgba(0, 0, 0, 0.05);
    border: 3px solid var(--graphite);
}
.project-card img { width: 100%; height: 100%; object-fit: cover; }
.project-card:focus-visible { outline: 3px solid var(--action); outline-offset: 6px; }

/* Bandeau d'ouverture : il monte depuis le bas au survol. Sans lui, rien ne
   dit qu'il y a une fiche derrière la vignette. */
.project-open {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
    padding: 0.7rem 0.85rem;
    background: var(--action); color: #fff;
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.68rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.14em; text-align: center;
    transform: translateY(100%);
    transition: transform 0.32s var(--ease-out);
}
.project-card:hover .project-open,
.project-card:focus-visible .project-open { transform: translateY(0); }
/* Au survol, l'étiquette métier céderait la place au bandeau : on la sort. */
.project-card:hover .project-tag,
.project-card:focus-visible .project-tag { opacity: 0; transition: opacity 0.2s ease; }

/* Étiquette de métier : reprend le code couleur des pôles */
.project-tag {
    position: absolute; left: 0; bottom: 0;
    display: inline-flex; align-items: center;
    padding: 0.5rem 0.85rem;
    background: var(--m-accent, var(--graphite)); color: #fff;
    font-family: 'Instrument Sans', var(--font-body); font-size: 0.66rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.16em; white-space: nowrap;
}
.project-card.m-habitat   { --m-accent: var(--pole-habitat); }
.project-card.m-exterieur { --m-accent: var(--pole-exterieur); }
.project-card.m-pro       { --m-accent: var(--pole-pro); }
.project-card.m-paysage   { --m-accent: var(--pole-paysage); }

.project-meta > span:last-child { display: block; color: var(--text-muted); font-size: 0.88rem; }

/* Pied : jauge de progression + compteur */
.showcase-foot {
    display: flex; align-items: center; gap: clamp(1rem, 3vw, 2rem);
    margin-top: clamp(1.5rem, 3vw, 2.25rem);
}
.showcase-progress { flex: 1; height: 2px; background: rgba(0, 0, 0, 0.14); overflow: hidden; }
.showcase-progress i {
    display: block; height: 100%; width: 100%; background: var(--action);
    transform: scaleX(0); transform-origin: left;
    transition: transform 0.55s var(--ease-out);
}
.showcase-count {
    font-family: var(--font-heading); font-size: 0.78rem; font-weight: 500;
    letter-spacing: 0.12em; color: var(--text-muted);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
.showcase-count b { color: var(--text-main); font-weight: 700; }

/* Sans JS, le rail ne peut pas être translaté : il redevient une bande
   qu'on fait défiler au doigt, et les flèches n'ont plus lieu d'être. */
html:not(.js) .slider-viewport {
    overflow-x: auto; scrollbar-width: none;
    scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
}
html:not(.js) .slider-viewport::-webkit-scrollbar { display: none; }
html:not(.js) .project-card { scroll-snap-align: start; }
html:not(.js) .slider-arrow,
html:not(.js) .showcase-foot { display: none; }

@media (max-width: 1100px) { .slider { --per-view: 2; } }
@media (max-width: 720px)  { .slider { --per-view: 1; } }

/* ---------- 8. Devis — configurateur guidé ----------
   Le bloc sombre pesait comme un pavé en fin de page. Ici, une grande carte
   claire posée sur le crème : la photo porte la chaleur, le formulaire
   respire. La couleur du pôle choisi teinte la sélection et la jauge — mais
   jamais les boutons, qui gardent la terre cuite. Un CTA ne convertit que
   s'il reste la seule chose de cette couleur sur la page.               */
/* L'accent du formulaire suivait le type de projet coché à la question 1 ;
   cette question a disparu, c'est désormais l'univers qui le donne. */
.devis { padding: var(--sp-xl) var(--gutter); --dv: var(--action); }
body[data-univers="paysagisme"] .devis { --dv: var(--pole-paysage); }

.devis-shell {
    max-width: 1400px; margin: 0 auto;
    display: grid; grid-template-columns: minmax(0, 0.84fr) minmax(0, 1.16fr);
    grid-template-areas: "visual panel";
    background: var(--bg-light);
    border: 1px solid rgba(0, 0, 0, 0.07);
    border-radius: 26px; overflow: hidden;
    box-shadow: 0 60px 100px -70px rgba(0, 0, 0, 0.55);
}

/* --- Colonne visuelle --- */
.devis-visual { grid-area: visual; position: relative; min-height: 640px; }
.devis-visual img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.visual-veil {
    position: absolute; inset: 0;
    background: linear-gradient(168deg, rgba(18, 24, 30, 0.78) 0%, rgba(18, 24, 30, 0.34) 46%, rgba(18, 24, 30, 0.9) 100%);
}
.visual-head {
    position: relative; z-index: 2;
    padding: clamp(1.75rem, 3.4vw, 2.75rem);
    color: #fff;
}
.visual-head .section-kicker { color: #fff; opacity: 0.72; margin-bottom: 0.9rem; }
.devis-title {
    font-family: var(--font-heading);
    font-size: clamp(1.9rem, 3.4vw, 2.9rem);
    font-weight: 700; line-height: 1.05; letter-spacing: -0.03em; text-wrap: balance;
}
.devis-lead { color: rgba(255, 255, 255, 0.74); margin-top: 0.9rem; max-width: 34ch; font-size: 1rem; }

/* --- Récapitulatif : sur la photo en grand écran, sous le formulaire en petit --- */
.devis-recap {
    grid-area: visual; align-self: end; position: relative; z-index: 2;
    padding: clamp(1.75rem, 3.4vw, 2.75rem);
    color: #fff;
}
.recap {
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 14px; padding: 0.35rem 1.15rem;
}
.recap li {
    display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
    padding: 0.75rem 0; border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}
.recap li:last-child { border-bottom: none; }
.recap-k { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.12em; color: rgba(255, 255, 255, 0.6); }
.recap-v {
    font-family: var(--font-heading); font-weight: 700; font-size: 0.95rem;
    color: rgba(255, 255, 255, 0.34); text-align: right;
    transition: color 0.4s ease, transform 0.4s var(--ease-out);
}
.recap li.is-set .recap-v { color: #fff; }
.recap li.just-set .recap-v { transform: translateX(-4px); }

.devis-trust { margin-top: 1.25rem; display: flex; flex-direction: column; gap: 0.6rem; }
.devis-trust li { display: flex; align-items: flex-start; gap: 0.6rem; font-size: 0.88rem; color: rgba(255, 255, 255, 0.82); }
.devis-trust svg { width: 14px; height: 14px; flex-shrink: 0; margin-top: 0.3em; color: #fff; opacity: 0.85; }

/* --- Colonne formulaire --- */
.devis-panel {
    grid-area: panel; display: flex; flex-direction: column;
    padding: clamp(1.75rem, 3.4vw, 3rem);
}
.devis-progress { display: flex; gap: 6px; margin-bottom: clamp(1.5rem, 3vw, 2.25rem); }
.devis-progress .bar { flex: 1; height: 3px; border-radius: 3px; background: rgba(0, 0, 0, 0.12); overflow: hidden; }
.devis-progress .bar i {
    display: block; height: 100%; width: 100%; background: var(--dv);
    transform: scaleX(0); transform-origin: left;
    transition: transform 0.55s var(--ease-out), background 0.5s ease;
}
.devis-progress .bar.is-done i { transform: scaleX(1); }

/* Étapes empilées en grille : le panneau ne saute pas d'une question à l'autre */
.steps { display: grid; flex: 1; }
.step {
    grid-area: 1 / 1; border: none; padding: 0; margin: 0; min-width: 0;
    opacity: 0; visibility: hidden; transform: translateY(14px);
    transition: opacity 0.4s ease, transform 0.5s var(--ease-out), visibility 0.4s;
}
.step.is-current { opacity: 1; visibility: visible; transform: none; }
html:not(.js) .step { opacity: 1; visibility: visible; transform: none; margin-bottom: 2.5rem; }
html:not(.js) .steps { display: block; }

.step-num { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.14em; color: var(--text-muted); }
.step-q {
    font-family: var(--font-heading); font-size: clamp(1.3rem, 2.4vw, 1.8rem);
    font-weight: 700; line-height: 1.15; letter-spacing: -0.02em;
    margin: 0.5rem 0 clamp(1.25rem, 2.5vw, 1.75rem); text-wrap: balance;
}

/* Choix pleine largeur */
.opts { display: flex; flex-direction: column; gap: 0.65rem; }
.opt {
    position: relative; display: flex; align-items: center; gap: 1rem;
    padding: 1rem 1.15rem; border-radius: 12px; cursor: pointer;
    background: var(--bg-cream); border: 1px solid rgba(0, 0, 0, 0.1);
    transition: border-color 0.3s ease, background 0.3s ease, transform 0.3s var(--ease-out);
}
.opt:hover { border-color: rgba(0, 0, 0, 0.26); transform: translateX(3px); }
.opt input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.opt-main { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.opt-title { font-family: var(--font-heading); font-weight: 700; font-size: 1.05rem; }
.opt-sub { font-size: 0.84rem; color: var(--text-muted); }
.opt-mark {
    margin-left: auto; flex-shrink: 0; position: relative;
    width: 22px; height: 22px; border-radius: 50%;
    border: 1.5px solid rgba(0, 0, 0, 0.24); transition: border-color 0.3s ease;
}
.opt-mark::after {
    content: ''; position: absolute; inset: 4px; border-radius: 50%;
    background: var(--dv); transform: scale(0);
    transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.opt:has(input:checked) { border-color: var(--dv); background: var(--bg-light); box-shadow: 0 10px 24px -18px var(--dv); }
.opt:has(input:checked) .opt-mark { border-color: var(--dv); }
.opt:has(input:checked) .opt-mark::after { transform: scale(1); }
.opt:focus-within { outline: 2px solid var(--dv); outline-offset: 2px; }

/* Choix courts */
.chips { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.chip { position: relative; cursor: pointer; }
.chip input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.chip span {
    display: inline-flex; align-items: center; min-height: 48px;
    padding: 0 1.25rem; border-radius: 50px;
    background: var(--bg-cream); border: 1px solid rgba(0, 0, 0, 0.12);
    font-family: var(--font-heading); font-weight: 600; font-size: 0.95rem;
    transition: all 0.28s var(--ease-out);
}
.chip:hover span { border-color: rgba(0, 0, 0, 0.3); }
.chip input:checked + span {
    background: var(--dv); border-color: var(--dv); color: #fff;
    transform: translateY(-2px); box-shadow: 0 12px 24px -14px var(--dv);
}
.chip input:focus-visible + span { outline: 2px solid var(--dv); outline-offset: 3px; }

/* Coordonnées */
.fields { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem 1.25rem; }
.field { position: relative; }
.field-wide { grid-column: 1 / -1; }
.field input, .field textarea {
    width: 100%; background: transparent; color: var(--text-main);
    border: none; border-bottom: 1px solid rgba(0, 0, 0, 0.2);
    padding: 0.85rem 0; font-family: var(--font-body); font-size: 1rem;
    border-radius: 0; resize: vertical; transition: border-color 0.3s ease;
}
.field input:focus, .field textarea:focus { outline: none; border-bottom-color: var(--dv); }
.field label {
    position: absolute; top: 0.85rem; left: 0; pointer-events: none;
    color: var(--text-muted); font-size: 1rem; transition: 0.3s var(--ease-out);
}
.field input:focus ~ label, .field input:not(:placeholder-shown) ~ label,
.field textarea:focus ~ label, .field textarea:not(:placeholder-shown) ~ label {
    top: -0.75rem; font-size: 0.72rem; letter-spacing: 0.06em; color: var(--dv);
}
.field.has-error input { border-bottom-color: #C0392B; }
.opt-flag { opacity: 0.55; }
.field-error { color: #A93226; font-size: 0.85rem; margin-top: 1rem; }

/* Navigation — les boutons gardent la terre cuite, jamais la couleur du pôle */
.devis-nav { display: flex; align-items: center; gap: 0.75rem; margin-top: clamp(1.5rem, 3vw, 2.25rem); }
.btn-back, .btn-next, .btn-send {
    display: inline-flex; align-items: center; justify-content: center; gap: 0.6rem;
    min-height: 52px; padding: 0 1.6rem; border-radius: 10px; cursor: pointer;
    font-family: var(--font-heading); font-weight: 700; font-size: 0.98rem;
    border: 1px solid transparent; transition: all 0.3s var(--ease-out);
}
.btn-back { background: transparent; border-color: rgba(0, 0, 0, 0.18); color: var(--text-muted); padding: 0 1.25rem; }
.btn-back:hover { border-color: rgba(0, 0, 0, 0.4); color: var(--text-main); }
.btn-next, .btn-send {
    margin-left: auto; background: var(--action); color: #fff;
    box-shadow: 0 14px 30px -16px rgba(190, 65, 40, 0.9);
}
.btn-next:hover, .btn-send:hover { background: var(--action-hover); transform: translateY(-2px); }
.btn-next[disabled], .btn-send[disabled] { opacity: 0.45; cursor: not-allowed; transform: none; }
.btn-back svg, .btn-next svg, .btn-send svg { width: 17px; height: 17px; transition: transform 0.3s var(--ease-out); }
.btn-next:hover svg, .btn-send:hover svg { transform: translateX(4px); }
.btn-back:hover svg { transform: translateX(-4px); }

/* Confirmation */
.devis-done { text-align: center; padding: clamp(2rem, 5vw, 4rem) 0; margin: auto 0; }
.done-mark {
    display: grid; place-items: center; width: 62px; height: 62px; margin: 0 auto 1.5rem;
    border-radius: 50%; background: var(--action); color: #fff;
}
.done-mark svg { width: 28px; height: 28px; }
.devis-done h3 { font-family: var(--font-heading); font-size: clamp(1.4rem, 2.6vw, 1.9rem); font-weight: 700; }
.devis-done p { margin-top: 0.65rem; max-width: 40ch; margin-inline: auto; }
.done-call { display: inline-block; margin-top: 1.5rem; font-family: var(--font-heading); font-size: 1.4rem; font-weight: 700; color: var(--action); }

/* --- Barre d'action mobile ------------------------------------------------
   Masquée sur desktop. Sans ce display:none, elle s'affiche en pleine page
   avec une icône sans contrainte de taille. */
.quick-bar { display: none; }
@media (max-width: 860px) {
    .quick-bar {
        display: grid; grid-template-columns: auto 1fr; gap: 0.6rem;
        position: fixed; left: 0; right: 0; bottom: 0; z-index: 950;
        padding: 0.6rem var(--gutter) calc(0.6rem + env(safe-area-inset-bottom));
        background: rgba(255, 255, 255, 0.94);
        backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
        border-top: 1px solid var(--glass-border);
        transform: translateY(110%);
        transition: transform 0.45s var(--ease-out);
    }
    .quick-bar.is-visible { transform: translateY(0); }
    body.has-quick-bar { padding-bottom: 76px; }

    .qb-call, .qb-devis {
        display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
        min-height: 48px; border-radius: 8px;
        font-family: var(--font-heading); font-weight: 700; font-size: 0.95rem;
    }
    .qb-call { padding: 0 1.1rem; border: 1px solid rgba(0, 0, 0, 0.22); color: var(--text-main); }
    .qb-call svg { width: 17px; height: 17px; }
    .qb-devis { background: var(--action); color: #fff; padding: 0 1.25rem; }
}

/* ---------- 9. Footer — bannière animée ---------- */
.agency-footer { padding: var(--sp-xl) 0 2rem; border-top: 1px solid var(--glass-border); }
.footer-top { max-width: 1500px; margin: 0 auto; padding: 0 var(--gutter); }

/* Bannière : le camion de chantier entre par la droite, dépose le U et le X,
   puis sort du champ — et l'affaire s'arrête là. Le cycle tournait en boucle :
   le camion repassait indéfiniment devant le nom. Il ne se joue plus qu'une
   fois, à l'entrée de la bannière dans le champ de vision. */
.gfr-banner {
    --gfr-loop: 13s;      /* durée du passage */
    --gfr-in: 1060px;     /* position d'entrée, en unités du viewBox */
    --gfr-out: -2600px;   /* position de sortie */
    width: 100%; overflow: hidden;
}
.gfr-svg { display: block; width: 100%; height: auto; }

/* GFR TRAVAUX en noir pur, sans point d'accent */
.gfr-word { font-family: var(--font-heading); font-weight: 900; fill: #000000; }
.gfr-word--lg { font-size: 210px; letter-spacing: -0.045em; }
.gfr-word--sm { font-size: 160px; letter-spacing: -0.04em; }
.gfr-accent { fill: var(--action); }
.gfr-ink { stroke: var(--graphite); opacity: 0.62; }
.gfr-ink-fill { fill: var(--graphite); opacity: 0.62; }
.gfr-rule line { stroke: rgba(0, 0, 0, 0.22); stroke-width: 1.6; }
.gfr-wheel { fill: var(--bg-light); }
.gfr-fume-fill { fill: rgba(0, 0, 0, 0.3); }

/* Le cycle ne démarre qu'à l'entrée de la bannière dans le champ de vision.
   Sinon il tourne depuis le chargement et l'on arrive en plein milieu :
   les lettres sont déjà posées et le camion déjà reparti. */
html.js .gfr-banner:not(.is-in) * { animation-play-state: paused !important; }

/* Pistes d'animation — une seule passe, état final conservé.
   Le rebond et la fumée sont bornés au nombre de cycles que dure le
   passage, sinon ils continueraient à tourner hors champ pour rien. */
.gfr-drive  { animation: gfr-drive var(--gfr-loop) cubic-bezier(.42,0,.35,1) 1 forwards; }
.gfr-bob    { animation: gfr-bob .34s ease-in-out 24; }
.gfr-roll   { animation: gfr-roll var(--gfr-loop) cubic-bezier(.42,0,.35,1) 1 forwards; }
.gfr-follow { animation: gfr-follow var(--gfr-loop) cubic-bezier(.42,0,.35,1) 1 forwards; }
.gfr-deliver {
    transform-box: fill-box; transform-origin: 0% 100%;
    animation-duration: var(--gfr-loop);
    animation-timing-function: cubic-bezier(.34, 1.3, .64, 1);
    animation-iteration-count: 1;
    animation-fill-mode: forwards;
}
.gfr-deliver--u { animation-name: gfr-deliver-u; }
.gfr-deliver--x { animation-name: gfr-deliver-x; }
.gfr-fume { animation: gfr-fumes 1.6s linear 6; }
.gfr-fume--late { animation-delay: .8s; }

@keyframes gfr-drive {
    0%   { transform: translateX(var(--gfr-in)); }
    22%  { transform: translateX(0); }
    42%  { transform: translateX(0); }
    64%  { transform: translateX(var(--gfr-out)); }
    100% { transform: translateX(var(--gfr-out)); }
}
/* Le groupe porteur accompagne le camion jusqu'à la dépose, puis ne bouge
   plus : les deux lettres restent posées une fois le camion parti. */
@keyframes gfr-follow {
    0%        { transform: translateX(var(--gfr-in)); }
    22%, 100% { transform: translateX(0); }
}
@keyframes gfr-roll {
    0%   { transform: rotate(0deg); }
    22%  { transform: rotate(-1240deg); }
    42%  { transform: rotate(-1240deg); }
    64%  { transform: rotate(-3600deg); }
    100% { transform: rotate(-3600deg); }
}
@keyframes gfr-deliver-u {
    0%, 25%   { transform: translate(0, -62px) scale(.47); opacity: 1; }
    34%       { transform: translate(0, 4px)   scale(1.03); opacity: 1; }
    38%, 100% { transform: translate(0, 0)     scale(1);    opacity: 1; }
}
@keyframes gfr-deliver-x {
    0%, 29%   { transform: translate(0, -62px) scale(.47); opacity: 1; }
    38%       { transform: translate(0, 4px)   scale(1.03); opacity: 1; }
    42%, 100% { transform: translate(0, 0)     scale(1);    opacity: 1; }
}
@keyframes gfr-bob   { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-1.2px); } }
@keyframes gfr-fumes {
    0%   { opacity: 0;  transform: translate(0, 0) scale(.6); }
    30%  { opacity: .5; }
    100% { opacity: 0;  transform: translate(-26px, -34px) scale(1.6); }
}
@media (prefers-reduced-motion: reduce) {
    .gfr-banner * { animation: none !important; }
    .gfr-drive, .gfr-follow { transform: translateX(0); }
    .gfr-deliver { transform: none; }
}

/* --- Pied de page --- */
.footer-follow {
    max-width: 1500px; margin: clamp(1.5rem, 4vw, 2.5rem) auto 0;
    padding: 0 var(--gutter);
    display: flex; flex-direction: column; align-items: center; gap: 1rem;
}
.follow-label {
    font-family: 'Instrument Sans', var(--font-body);
    font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.22em;
    color: var(--text-muted);
}

/* Réseaux : logos officiels, aux couleurs de marque.
   ---------------------------------------------------------------------
   CE QUE LES CHARTES IMPOSENT, ET QUI EST RESPECTÉ ICI :
   • proportions d'origine, jamais étirées (le SVG garde son viewBox carré) ;
   • espace de sécurité autour du glyphe, proportionnel à sa taille — d'où
     l'écart entre les icônes, et non un alignement serré ;
   • pas de forme rapportée autour du logo (l'ancien cercle au trait a été
     retiré pour cette raison) ;
   • couleurs officielles inchangées, portées par le SVG lui-même ;
   • aucun effet appliqué AU logo — ni ombre portée, ni filtre, ni teinte.
     Le mouvement au survol déplace l'icône, il ne la retouche pas. C'est la
     raison du drop-shadow retiré : il modifiait le rendu du glyphe.
   NE PAS : recolorer, détourer, incliner, superposer du texte, ou laisser
   entendre un partenariat avec ces plateformes.                         */
.footer-social { display: flex; align-items: center; gap: clamp(0.85rem, 2.5vw, 1.4rem); }
/* Le glyphe reste à 34 px — c'est la taille juste au pied de page — mais la
   zone touchable fait 44 px, le minimum tenable au doigt. Le padding sert
   aussi d'espace de sécurité, que les chartes de marque imposent. */
.soc {
    display: grid; place-items: center;
    width: 44px; height: 44px; padding: 5px;
    transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.soc svg, .soc img { width: 100%; height: 100%; display: block; }
.soc:hover, .soc:focus-visible { transform: translateY(-5px) scale(1.1); }
.soc:focus-visible { outline: 3px solid var(--action); outline-offset: 6px; border-radius: 4px; }

/* Attribution des marques : obligation d'usage, pas une politesse. */
.brand-note {
    margin-top: 0.9rem; max-width: 46ch; text-align: center;
    font-size: 0.68rem; line-height: 1.45; color: var(--text-muted); opacity: 0.8;
}

@media (prefers-reduced-motion: reduce) {
    .soc:hover, .soc:focus-visible { transform: none; }
}

.footer-bottom {
    max-width: 1500px; margin: clamp(1.5rem, 4vw, 2.5rem) auto 0;
    padding: 1.75rem var(--gutter) 0;
    display: flex; justify-content: space-between; align-items: center; gap: 1.25rem;
    border-top: 1px solid var(--glass-border);
}
.footer-copy { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-muted); }
.footer-links { display: flex; flex-wrap: wrap; gap: 1.5rem; }
.footer-links a {
    font-size: 0.78rem; color: var(--text-muted); padding-bottom: 2px;
    background-image: linear-gradient(currentColor, currentColor);
    background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%;
    transition: color 0.25s ease, background-size 0.35s var(--ease-out);
}
.footer-links a:hover { color: var(--action); background-size: 100% 1px; }

/* =========================================================
   RESPONSIVE
   ========================================================= */

/* --- Desktop compact / petit laptop --- */
@media (max-width: 1200px) {
    .nav-links { gap: 18px; }
    .nav-item { font-size: 0.95rem; }
}

/* --- Tablette paysage : nav mobile + hero resserré --- */
@media (max-width: 992px) {
    :root { --header-h: 100px; }

    .menu-toggle { display: flex; }
    .nav-menu {
        display: flex; flex-direction: column; align-items: stretch;
        position: absolute; top: calc(100% + 14px); left: 0; right: 0;
        max-height: min(72vh, 620px);
        max-height: min(72dvh, 620px);
        background-color: rgba(255, 255, 255, 0.98);
        backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
        border: 1px solid rgba(255, 255, 255, 0.8); border-radius: 24px;
        box-shadow: 0 20px 50px rgba(0, 0, 0, 0.15);
        padding: 16px;
        overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
        opacity: 0; visibility: hidden; transform: translateY(-12px);
        transition: opacity 0.35s ease, transform 0.35s var(--ease-out), visibility 0.35s;
        z-index: 999;
    }
    .nav-menu.open { opacity: 1; visibility: visible; transform: translateY(0); }
    .nav-links { flex-direction: column; align-items: stretch; gap: 2px; width: 100%; }
    .nav-links li { width: 100%; }
    .nav-item { width: 100%; padding: 14px 10px; font-size: 1.05rem; border-bottom: 1px solid rgba(0,0,0,0.06); }
    .nav-links > li:last-child > .nav-item { border-bottom: none; }
    .nav-item-switch { display: flex; width: 100%; justify-content: space-between; }
    .dropdown-trigger > .nav-item { display: flex; justify-content: space-between; align-items: center; cursor: pointer; }
    .dropdown-trigger > .nav-item::after {
        content: ''; width: 8px; height: 8px;
        border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
        transform: rotate(45deg); transition: transform 0.3s ease; margin-left: 12px; flex-shrink: 0;
    }
    .dropdown-trigger.open > .nav-item::after { transform: rotate(-135deg); }

    /* Accordéon : on neutralise TOUT le positionnement flottant du desktop.
       Sans le transform:none ci-dessous, le translateX(-50%) desktop reste actif
       et pousse le contenu du sous-menu hors du panneau. */
    .dropdown-trigger .dropdown-menu,
    .dropdown-trigger:hover .dropdown-menu,
    .dropdown-trigger.open .dropdown-menu {
        position: static;
        transform: none;
        opacity: 1; visibility: visible;
        width: 100%; max-width: 100%; display: block;
        background: transparent; border: none; box-shadow: none;
        backdrop-filter: none; -webkit-backdrop-filter: none; border-radius: 0;
        overflow: hidden;
        transition: max-height 0.4s ease, padding 0.4s ease;
    }
    .dropdown-trigger .dropdown-menu { max-height: 0; padding: 0; }
    .dropdown-trigger.open .dropdown-menu { max-height: 900px; padding: 4px 0 12px 10px; }
    .dropdown-column { margin-bottom: 8px; }
    .column-title { margin-bottom: 6px; font-size: 0.8rem; }
    .dropdown-column ul li { margin-bottom: 2px; }
    .dropdown-column ul li a { padding: 12px 10px; font-size: 0.92rem; }
    .cta-btn { display: block; text-align: center; width: 100%; margin-top: 14px; padding: 14px 26px; }

    .devis-shell { grid-template-columns: 1fr; }
}

/* Trois plaques côte à côte ne tiennent plus dès la tablette : deux
   colonnes d'abord, une seule ensuite. Cette règle avait disparu lors
   d'une réécriture du bloc — les plaques restaient sur trois colonnes
   jusqu'en 320 px. */
@media (max-width: 1024px) {
    .atelier { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 860px) {
    .section-head { grid-template-columns: 1fr; align-items: start; gap: 1rem; }
    .atelier { grid-template-columns: 1fr; gap: clamp(1.5rem, 5vw, 2.5rem); }
    /* L'ombre portée décalée doit maigrir avec la largeur, sinon elle
       pousse la plaque hors du cadre. */
    .at-slab { box-shadow: 7px 7px 0 -3px var(--at-bg), 7px 7px 0 0 var(--graphite); }
    /* Les deux portes s'empilent : côte à côte sous 860 px, chacune
       devient une vignette trop basse pour porter son titre. Le format
       reste le 4/3 des images — les rogner en bandeau ferait perdre le
       sujet, qui est justement l'aménagement d'ensemble. */
    .gates { grid-template-columns: 1fr; max-width: 30rem; }
}

/* --- Mobile --- */
@media (max-width: 640px) {
    :root { --header-h: 84px; }

    .site-header { top: 12px; width: 94%; padding: 8px 14px; border-radius: 40px; }
    .logo-svg { width: 44px; }
    .logo-word { font-size: 1.05rem; }
    /* Sous cette largeur la baseline tomberait à 6 px : illisible, et elle
       pousse le nom hors du cadre. Le pictogramme et le nom suffisent. */
    .logo-baseline { display: none; }
    .nav-menu { max-height: min(70dvh, 560px); padding: 12px; }
    .nav-item { padding: 15px 10px; font-size: 1rem; }

    .title-xl { font-size: clamp(2.2rem, 11.5vw, 3.6rem); }
    .project-tag { font-size: 0.62rem; padding: 0.4rem 0.7rem; }
    .footer-bottom { flex-direction: column; gap: 1rem; text-align: center; }
    .footer-links { gap: 1.25rem; }
}

/* --- Très petits téléphones (iPhone SE, Galaxy S en 360 px) --- */
@media (max-width: 380px) {
    :root { --gutter: 1rem; --header-h: 78px; }
    .site-header { padding: 7px 12px; }
    .logo-svg { width: 38px; }
    .logo-word { font-size: 0.95rem; }
    .logo-container { gap: 8px; }
    .title-xl { font-size: clamp(2rem, 11vw, 2.6rem); }
    .qb-call, .qb-devis { font-size: 0.88rem; }
    .qb-call { padding: 0 0.9rem; }
}

/* --- Téléphones peu hauts ---
   On rend de la place en réduisant la largeur des portes, pas en écrasant
   leur format : une bande de 21/9 ne montrerait plus l'aménagement. */
@media (max-width: 640px) and (max-height: 720px) {
    .title-xl { font-size: clamp(1.9rem, 9.5vw, 2.4rem); }
    .gates { max-width: 20rem; }
    .hero-inner { gap: clamp(1.25rem, 3vh, 2rem); }
}


/* --- Configurateur de devis --- */
@media (max-width: 900px) {
    /* La photo devient un bandeau, le récapitulatif passe sous le formulaire
       et repasse en texte sombre sur fond clair. */
    .devis-shell { grid-template-columns: 1fr; grid-template-areas: "visual" "panel" "recap"; }
    .devis-visual { min-height: 0; aspect-ratio: 16 / 9; }
    .devis-recap {
        grid-area: recap; align-self: auto; color: var(--text-main);
        border-top: 1px solid rgba(0, 0, 0, 0.09);
        padding: clamp(1.5rem, 5vw, 2rem);
    }
    .recap { background: var(--bg-cream); border-color: rgba(0, 0, 0, 0.09); backdrop-filter: none; }
    .recap li { border-bottom-color: rgba(0, 0, 0, 0.08); }
    .recap-k { color: var(--text-muted); }
    .recap-v { color: rgba(0, 0, 0, 0.3); }
    .recap li.is-set .recap-v { color: var(--dv); }
    .devis-trust li { color: var(--text-muted); }
    .devis-trust svg { color: var(--dv); opacity: 1; }
    .fields { grid-template-columns: 1fr; gap: 1.5rem; }
    .devis-nav { flex-wrap: wrap; }
    .btn-next, .btn-send { flex: 1; margin-left: 0; }
}
@media (max-width: 640px) {
    .devis { padding-left: 0; padding-right: 0; padding-bottom: calc(var(--sp-xl) + 60px); }
    .devis-shell { border-radius: 0; border-left: none; border-right: none; }
    .opt { padding: 0.9rem 1rem; gap: 0.75rem; }
    .opt-title { font-size: 0.98rem; }
    .opt-sub { font-size: 0.78rem; }
    .chip span { min-height: 46px; padding: 0 1rem; font-size: 0.88rem; }
    .step-q { font-size: 1.22rem; }
}

/* --- Bannière du footer --- */
@media (max-width: 760px) {
    .footer-bottom { flex-direction: column; align-items: center; text-align: center; gap: 1rem; }
    /* Cycle un peu plus court : la bannière est plus étroite à parcourir */
    .gfr-banner { --gfr-loop: 11s; }
}

/* --- Filet pour les très petits écrans (320 px) --- */
@media (max-width: 340px) {
    :root { --gutter: 0.85rem; }
    .logo-svg { width: 34px; }
    .logo-word { font-size: 0.86rem; }
    .title-xl { font-size: clamp(1.75rem, 10.5vw, 2.2rem); }
    .section-h2 { font-size: clamp(1.9rem, 11vw, 2.4rem); }
    .footer-social { gap: 0.5rem; }
    .soc { width: 44px; height: 44px; }
    .footer-links { gap: 0.9rem; justify-content: center; }
    .chip span { padding: 0 0.85rem; font-size: 0.82rem; }
    .qb-call span { display: none; }
    .qb-call { padding: 0 0.85rem; }
}

/* --- Accessibilité : mouvement réduit --- */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
