/* ================================================================
   pompe-chaleur-nyon.ch — registre « LAITON & PRUNE » v3 (2026-08-23)
   ================================================================
   🔴 CETTE FEUILLE EST PRODUITE PAR `_build/peau.py`. Elle ne se rustine
   jamais à la main : toute retouche directe est perdue au prochain build.

   Remplace « Chantier & acier » (papier acier #e7ebee, photo de chaufferie
   dans le hero, IBM Plex Sans), qui remplaçait « Colonnes & cobalt »
   (didone, lettrine, filet de une), refusée par l'utilisateur. Deux peaux
   mortes sur ce site, une seule cause : du mobilier éditorial, puis une
   photo à la place d'une lumière.

   MÉCANIQUE : celle du #16 Lausanne, elle-même celle du #14 validée le
   22.08 — standard de clarté v9.19 + doctrine du blanc v9.14. La couleur
   quitte la page et se réfugie dans le hero ; l'action reprend une couleur,
   et elle est SEULE à la porter.

   LE GESTE, EN UNE PHRASE : la page est blanche, la lumière vit dans le
   hero, l'action est la seule couleur FROIDE. C'est la première peau du
   réseau dont le hero est chaud et l'action froide, et le premier CTA
   violet — choix contraint : les cinq voisins immédiats sont pris.

   LES ONZE INVARIANTS DE CLARTÉ, tous tenus ici :
    1. une seule couleur saturée, réservée à l'action : prune #5b21b6
    2. opposition de teinte identité<->action : 34,1° contre 264,4° = 130,3°
    3. fond de page blanc PUR (#ffffff), pas un near-blanc teinté
    4. encre du corps TEINTÉE (#463c2f, 10,78:1), jamais noire
    5. graisse display 300 / 600, jamais 800
    6. conteneur 1060 px, colonne de texte 68 caractères
    7. l'aurore s'arrête au hero
    8. le foyer d'ACTION est dans le quadrant opposé à la carte de devis
    9. le grain reste, peint une fois, en multiply
   10. le lavis blanc est un calque PLEIN CADRE, à 0 sur les quatre bords
   11. la carte de devis est au-dessus du pli à 320x568

   POLICES — choisies sur une planche de HUIT composées côte à côte, jamais
   au flair. Work Sans (titres, la bold la plus pleine du lot) + Public Sans
   (corps, la plus lisible à 17 px), sous-ensemblées au français et bornées
   à leurs graisses réelles : 59,4 Ko en 2 fichiers. Manrope et PlexMono
   SORTENT du site — c'était pourtant le corps des vingt sites.

   SIGNATURE : « la règle du voisin ». Conservée, et SORTIE de la carte de
   devis, où elle repoussait le CTA sous le pli.
================================================================ */
@font-face{font-family:'Work Sans';font-weight:300 700;font-display:swap;src:url(/fonts/worksans-var.woff2) format('woff2')}
@font-face{font-family:'Public Sans';font-weight:400 700;font-display:swap;src:url(/fonts/publicsans-var.woff2) format('woff2')}

:root{
  color-scheme:light only;               /* le meta ET :root — piège du #5 */
  /* les fonds : BLANC PUR. La couleur vit dans le hero, les filets, les survols. */
  --bg:#ffffff;--bg2:#ffffff;--ciel:#fffdf9;--creme:#fffcf5;
  /* l'encre : titres 18.2:1 · corps 10.78:1 · sourdine 6.86:1 */
  --enc:#1c1409;--enc2:#463c2f;--mut:#63594b;
  /* L'ACTION — prune. Elle ne porte QUE des a.cta et des button.cta. */
  --pru:#5b21b6;--pru-cl:#6d28d9;--pru-f:#4c1d95;
  --grad-act:linear-gradient(135deg,#6d28d9,#5b21b6 52%,#4c1d95);
  /* l'IDENTITÉ — laiton. Titres d'accent, filets, focus, puces, chiffres. */
  --bis:#8a5108;--bis-cl:#d99a2b;--amb:#f4c56a;--amb-t:#a9660d;
  --grad-t:linear-gradient(103deg,#7a4707 2%,#9d5c0b 46%,#b4720f 96%);
  /* le vert des subventions du #16 SORT : sur une page qui n'a qu'une couleur
     saturée, un deuxième foyer de teinte est exactement ce que la doctrine du
     blanc interdit. Les aides reprennent l'identité. */
  --ok:#8a5108;
  --line:#f5f0e7;--bord:#e9dfd0;--nuit:#1c1409;--nuit2:#120c04;
  --r:12px;--rr:16px;--rg:22px;
  /* LA MESURE DE LECTURE, en pixels et non en `ch`. Le `ch` dépend de la police
     de l'ÉLÉMENT : 68ch sur un h2 de Work Sans à 28 px fait 1 040 px, sur un
     paragraphe de Public Sans à 16,5 px il en fait 666. Deux blocs bornés au
     même `68ch` n'ont donc PAS la même largeur — et l'axe unique tombe. */
  --mes:666px;
  --o1:0 1px 3px rgba(90,60,20,.05),0 8px 20px -10px rgba(90,60,20,.14);
  --o2:0 3px 8px rgba(90,60,20,.06),0 24px 48px -18px rgba(90,60,20,.20);
  --grain-img:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.52'/%3E%3C/svg%3E");
  /* ⚠️ ✓ ★ → ≈ ne sont dans AUCUN .woff2 du réseau — MESURÉ, pas supposé.
     Chaque icône est un SVG. */
  --fleche:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 20' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 10h16M13.5 4l6 6-6 6'/%3E%3C/svg%3E");
  --coche:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a5108' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 12.4l5.1 5.1L19.6 6.4'/%3E%3C/svg%3E");
  --etoiles:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 18' fill='%23f0a500' stroke='%238a5108' stroke-width='1.1' stroke-linejoin='round'%3E%3Cpath transform='translate(0,0) scale(.9)' d='M10 1.4l2.55 5.17 5.7.83-4.13 4.02.98 5.68L10 14.42l-5.1 2.68.98-5.68L1.75 7.4l5.7-.83z'/%3E%3Cpath transform='translate(19.2,0) scale(.9)' d='M10 1.4l2.55 5.17 5.7.83-4.13 4.02.98 5.68L10 14.42l-5.1 2.68.98-5.68L1.75 7.4l5.7-.83z'/%3E%3Cpath transform='translate(38.4,0) scale(.9)' d='M10 1.4l2.55 5.17 5.7.83-4.13 4.02.98 5.68L10 14.42l-5.1 2.68.98-5.68L1.75 7.4l5.7-.83z'/%3E%3Cpath transform='translate(57.6,0) scale(.9)' d='M10 1.4l2.55 5.17 5.7.83-4.13 4.02.98 5.68L10 14.42l-5.1 2.68.98-5.68L1.75 7.4l5.7-.83z'/%3E%3Cpath transform='translate(76.8,0) scale(.9)' d='M10 1.4l2.55 5.17 5.7.83-4.13 4.02.98 5.68L10 14.42l-5.1 2.68.98-5.68L1.75 7.4l5.7-.83z'/%3E%3C/svg%3E");
}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{background:var(--bg2);color:var(--enc);font-family:'Public Sans',system-ui,sans-serif;font-size:16px;line-height:1.6}
img{max-width:100%;height:auto;display:block}
a{color:var(--amb-t)}
.skip{position:absolute;left:-999px;top:0;background:#fff;color:var(--enc);padding:10px 16px;z-index:200}
.skip:focus{left:0}
a:focus-visible,button:focus-visible,input:focus-visible,textarea:focus-visible,summary:focus-visible{outline:2px solid var(--bis);outline-offset:2px}
/* la peau « LA MARCHE ».
   Le #15 avait supprimé tout rayon et toute ombre : la profondeur venait d'un filet
   pleine largeur en tête de bloc. Ici on prend le chemin inverse, et c'est délibéré —
   une ville n'est pas un atelier d'horlogerie. Le filet devient un NEZ DE MARCHE :
   il ne court que sur le tiers gauche du bloc, et il s'étend sur toute la largeur au
   survol, comme une marche qu'on gravit. Le rayon revient (6 px, discret), et une
   seule ombre douce, portée bas, tient les cartes au-dessus du grès.
   ⚠️ `.card` et `.pum-card` sont exclues : elles portent déjà `.beam`, qui EST leur
   filet de tête. Les doubler produisait une barre de 8 px (vu au premier essai). */
.chip,.col-etape,.stat,.step,.faq-item,.art-card,.poste,.fiche div,.communes-grid a,.avi{position:relative;border-radius:6px}
.chip::after,.col-etape::after,.stat::after,.step::after,.faq-item::after,.art-card::after,.poste::after,.fiche div::after,.communes-grid a::after,.avi::after{content:'';position:absolute;left:0;width:34%;top:0;height:4px;background:var(--bis-cl);border-radius:6px;pointer-events:none;transition:width .28s ease,background .2s}
.chip:hover::after,.col-etape:hover::after,.stat:hover::after,.step:hover::after,.faq-item:hover::after,.art-card:hover::after,.poste:hover::after,.fiche div:hover::after,.communes-grid a:hover::after,.avi:hover::after{width:100%;background:var(--pru);border-radius:6px}
.wrap{width:min(1060px,100%);margin:0 auto;padding-left:24px;padding-right:24px}
/* la prose ne dépasse jamais 68 caractères : au-delà, la ligne décroche.
   ⚠️ posée SUR le conteneur, elle le rétrécirait (défaut n°11 du #14) — donc
   elle est posée sur les blocs de texte, à l'intérieur. */
.sec p:not(.lead):not(.srcline):not(.sig-lg):not(.presta-leg):not(.bande-src):not(.liens-util),
.sec>.wrap>ul:not(.communes-grid):not(.prestas){max-width:min(var(--mes),100%)}
@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}}

/* ---------------- header ---------------- */
.site-head{position:sticky;top:0;z-index:80;display:flex;align-items:center;gap:20px;padding:12px 26px;background:rgba(255,255,255,.92);backdrop-filter:blur(12px);border-bottom:1px solid var(--line);transition:border-color .25s}
.site-head.scrolle{border-bottom-color:var(--bis)}
.logo{font-family:'Work Sans';font-weight:700;font-size:20.5px;color:var(--enc);text-decoration:none;white-space:nowrap}
.logo-p{color:var(--amb-t)}
.nav{display:flex;gap:2px;margin-left:auto;flex-wrap:wrap}
.nav a{color:var(--enc2);text-decoration:none;font-size:14px;font-weight:700;padding:8px 11px;transition:background .18s,color .18s,transform .18s}
.nav a:hover{background:rgba(138,81,8,.09);color:var(--pru);transform:translateY(-1px)}
.nav a.on{color:var(--amb-t)}
.head-cta{font-weight:700;font-size:15px;color:#fff;text-decoration:none;background:var(--grad-act);padding:11px 20px;border-radius:999px;white-space:nowrap;box-shadow:0 8px 20px -8px rgba(91,33,182,.42);transition:transform .16s,box-shadow .16s}
.head-cta:hover{transform:translateY(-2px);background:var(--pru-cl)}
.burger{display:none;flex-direction:column;gap:5px;background:none;border:none;cursor:pointer;padding:8px}
.burger span{width:24px;height:2.5px;background:var(--enc);transition:transform .25s,opacity .25s}
@media (max-width:1080px){
  .nav{position:fixed;inset:57px 0 auto 0;background:rgba(255,255,255,.98);backdrop-filter:blur(14px);flex-direction:column;padding:18px 26px 24px;gap:4px;border-bottom:1px solid var(--line);transform:translateY(-130%);transition:transform .3s ease;margin:0}
  .nav.ouvert{transform:none}
  .nav a{font-size:16px;padding:12px 10px}
  .burger{display:flex}
  .burger.x span:nth-child(1){transform:translateY(7.5px) rotate(45deg)}
  .burger.x span:nth-child(2){opacity:0}
  .burger.x span:nth-child(3){transform:translateY(-7.5px) rotate(-45deg)}
  .head-cta{margin-left:auto}
}

/* ---------------- hero : calques de matière ---------------- */
.hero{position:relative;overflow:hidden;isolation:isolate;
  background:linear-gradient(177deg,#ffffff 0%,#ffffff 62%,#fffdf9 100%)}
/* ⚠️ `.hero-max` était en display:flex pour centrer verticalement le contenu.
   Depuis que la signature est une BANDE sœur de la grille, ce flex en faisait
   une deuxième colonne posée à droite du hero. Il n'a plus lieu d'être : le
   hero se cale en haut, comme la grille. */
.hero-max{display:block}
.hero-page{padding:0 0 8px}
/* L'AURORE, version chuchotée : 3 foyers glacier + 1 foyer carmin tenu EN BAS À
   GAUCHE, à l'opposé de la carte de devis. Sans ça, la couleur d'action baigne le
   CTA et l'invariant « une seule couleur saturée » ne veut plus rien dire. */
.foyers{position:absolute;inset:-20% -10%;z-index:1;pointer-events:none;overflow:hidden}
.foyers i{position:absolute;border-radius:50%;will-change:transform;backface-visibility:hidden}
.f1{width:52%;height:42%;left:-16%;top:-18%;
  background:radial-gradient(closest-side,rgba(253,214,130,0.28),rgba(253,214,130,0.10) 47%,transparent 75%);
  animation:d1 31s ease-in-out infinite alternate}
.f2{width:44%;height:38%;right:-14%;top:-16%;
  background:radial-gradient(closest-side,rgba(245,178,52,0.20),rgba(245,178,52,0.07) 47%,transparent 75%);
  animation:d3 35s ease-in-out infinite alternate}
.f3{width:46%;height:36%;left:-12%;bottom:-22%;
  background:radial-gradient(closest-side,rgba(251,191,86,0.19),rgba(251,191,86,0.07) 47%,transparent 75%);
  animation:d2 25s ease-in-out infinite alternate}
.f4{width:26%;height:24%;right:-6%;top:26%;
  background:radial-gradient(closest-side,rgba(255,236,190,0.16),rgba(255,236,190,0.06) 47%,transparent 75%);
  animation:d4 29s ease-in-out infinite alternate}
.fw{width:34%;height:30%;left:-10%;bottom:-18%;
  background:radial-gradient(closest-side,rgba(139,92,246,0.18),rgba(139,92,246,0.06) 47%,transparent 75%);
  animation:d5 27s ease-in-out infinite alternate}
@keyframes d1{to{transform:translate3d(6%,5%,0) scale(1.12)}}
@keyframes d2{to{transform:translate3d(-7%,7%,0) scale(1.09)}}
@keyframes d3{to{transform:translate3d(-5%,-7%,0) scale(1.14)}}
@keyframes d5{to{transform:translate3d(7%,-5%,0) scale(1.10)}}
@keyframes d4{to{transform:translate3d(-8%,4%,0) scale(1.18)}}
/* LE LAVIS — calque PLEIN CADRE du hero, jamais un ::before de colonne.
   33 − 0,82×38 = +1,8 % à gauche : il atteint 0 avant les quatre bords, donc
   aucune bordure verticale. C'est le défaut encore en production sur 4 sites. */
.voile{position:absolute;inset:0;z-index:4;pointer-events:none;
  background:radial-gradient(38% 42% at 33% 44%,rgba(255,255,255,.90),rgba(255,255,255,.46) 50%,transparent 82%)}
.grain{position:absolute;inset:0;z-index:5;pointer-events:none;opacity:.28;
  mix-blend-mode:multiply;background-image:var(--grain-img)}
/* align-items:START, jamais center : la carte fait ~1 100 px et la colonne de
   texte ~500. Centrée, elle laissait 400 à 600 px de VIDE sur les 75 pages. */
.hero-grid{position:relative;z-index:20;display:grid;grid-template-columns:1.06fr .94fr;gap:52px;align-items:start;padding-top:44px;padding-bottom:34px}

/* ---------------- hero : texte ---------------- */
.eyebrow{display:inline-block;font-size:13.5px;font-weight:700;letter-spacing:.02em;color:var(--bis);background:rgba(255,255,255,.74);border:1px solid var(--bord);padding:6px 13px;border-radius:999px;margin-bottom:12px}

.hero h1{font-family:'Work Sans';font-weight:500;letter-spacing:-.035em;font-size:clamp(34px,4.6vw,54px);line-height:1.06;margin:0 0 16px;text-wrap:balance}
.hero-page h1{font-size:clamp(30px,3.6vw,44px)}
.hero h1 .l{display:block}
.hero h1 .thin{font-weight:300;color:#5c5347}
.hero h1 .fat{font-weight:600}
.hero h1 .fat b{font-weight:600;background:var(--grad-t);-webkit-background-clip:text;background-clip:text;color:transparent}
.rv{display:inline-block;overflow:hidden;vertical-align:bottom;padding-bottom:.08em;margin-bottom:-.08em}
.rvi{display:inline-block;transform:translateY(115%);animation:rvUp .75s cubic-bezier(.2,.85,.25,1) forwards;animation-delay:calc(var(--d)*1ms)}
@keyframes rvUp{to{transform:none}}
.fini .rvi{transform:none!important;animation:none!important}
.sub{color:var(--enc2);max-width:34em;font-size:18px;line-height:1.6;margin-bottom:22px}
.live{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:10px}
.chip{background:#fff;border:1px solid var(--line);border-radius:16px;padding:11px 16px;box-shadow:var(--o1);min-width:172px;transition:transform .18s}
.chip:hover{transform:translateY(-3px)}
.chip small{display:block;font-size:12.5px;color:var(--mut);letter-spacing:.01em}
.chip b{font-family:'Work Sans';font-weight:600;font-size:22px;letter-spacing:-.03em;color:var(--enc);font-variant-numeric:tabular-nums}
.chip.a b{color:var(--amb-t)}
.chip.flash{animation:flashA 1s ease}
@keyframes flashA{0%{background-color:rgba(217,154,43,.28)}100%{background-color:rgba(255,255,255,.66)}}
.srcline{font-size:13px;line-height:1.55;color:var(--mut);margin-bottom:22px;max-width:44em}
.trust{list-style:none;display:grid;gap:9px;font-size:15.5px;line-height:1.5;color:var(--enc2);margin-bottom:26px}
.trust li{position:relative;padding-left:28px}
.trust li::before{content:'';position:absolute;left:0;top:.22em;width:19px;height:19px;background:var(--coche) no-repeat center/100%}
.warn{margin-top:14px;display:none;gap:9px;border:1px solid rgba(138,81,8,.45);border-left:3px solid var(--amb-t);background:rgba(255,251,244,.92);padding:10px 13px;font-size:13px;color:var(--amb-t);max-width:54ch}
.warn.on{display:flex;animation:flashA 1.1s ease}
/* l'alerte vit dans la colonne texte en desktop, dans la carte en empilé */
.warn-carte{margin:0 0 12px;max-width:none}
@media (min-width:1081px){.warn-carte{display:none!important}}
@media (max-width:1080px){.warn-col{display:none!important}}

/* ---------------- la carte de devis ---------------- */
.cardwrap{position:relative;will-change:transform}
.card{position:relative;border-radius:10px;box-shadow:0 18px 40px -28px rgba(70,60,47,.45);background-color:#fff;border:1px solid var(--line);padding:24px 24px 22px;backdrop-filter:blur(10px) saturate(1.1)}
.card>*{position:relative;z-index:2}
/* le « beam » du pilote devient un fil de bisse rectiligne, en trois segments */
.beam{position:absolute;left:0;right:0;top:0;height:4px;z-index:3;background:linear-gradient(90deg,var(--bis) 0 46%,var(--bis-cl) 46% 78%,var(--amb) 78% 100%);pointer-events:none}
.sheenbox{position:absolute;inset:0;z-index:1;overflow:hidden;pointer-events:none}
.sheenbox i{position:absolute;top:-12%;bottom:-12%;left:-58%;width:44%;background:linear-gradient(105deg,transparent,rgba(255,255,255,.06) 42%,rgba(255,255,255,.45) 50%,rgba(138,81,8,.08) 58%,transparent);transform:skewX(-12deg);animation:sheen 7s ease-in-out infinite;will-change:transform}
@keyframes sheen{0%,52%{transform:translateX(0) skewX(-12deg)}88%,100%{transform:translateX(420%) skewX(-12deg)}}
.card h3{font-family:'Work Sans';font-weight:700;font-size:20.5px;margin-bottom:2px}
.mini{font-family:'Work Sans';font-weight:600;font-size:13px;color:var(--amb-t);margin-bottom:16px;min-height:18px;font-variant-numeric:tabular-nums}
.fld{margin-bottom:13px}
.h-t{display:flex;justify-content:space-between;align-items:baseline;font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--enc2);margin-bottom:8px}
.h-t output{font-family:'Work Sans';font-weight:600;font-size:15px;color:var(--amb-t)}
input[type=range]{width:100%;appearance:none;height:6px;background:linear-gradient(90deg,var(--bis) var(--fill,40%),#ece2d2 var(--fill,40%));cursor:pointer}
input[type=range]::-webkit-slider-thumb{appearance:none;width:22px;height:22px;border-radius:50%;background:#fff;border:3px solid var(--bis);transition:transform .15s,box-shadow .3s}
input[type=range]:active::-webkit-slider-thumb,input[type=range]:focus::-webkit-slider-thumb{box-shadow:0 0 0 8px rgba(154,96,12,.18)}
input[type=range]::-webkit-slider-thumb:hover{transform:scale(1.15)}
input[type=range]::-moz-range-thumb{width:19px;height:19px;border-radius:50%;background:#fff;border:3px solid var(--bis)}
.puces{display:grid;grid-template-columns:repeat(4,1fr);gap:7px}
.puces button{font-family:'Public Sans';font-size:12.5px;font-weight:700;color:var(--enc2);background:rgba(255,255,255,.78);border:1px solid var(--bord);padding:9px 4px;cursor:pointer;transition:all .18s;min-width:0}
.puces button:hover{transform:translateY(-2px);border-color:var(--bis)}
.puces button.on{background:var(--bis);border-color:var(--bis);color:#fff;font-weight:700;box-shadow:none;animation:pop .28s cubic-bezier(.2,1.6,.4,1)}
@keyframes pop{0%{transform:scale(.94)}100%{transform:scale(1)}}
.sep{display:flex;align-items:center;gap:10px;font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--mut);margin:16px 0 12px}
.sep::before,.sep::after{content:'';flex:1;height:1px;background:var(--line)}
.idgrid{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin-bottom:10px}
.idgrid .full{grid-column:1/-1}
.idgrid>*{min-width:0}
.h-in{width:100%;font-family:'Public Sans';font-size:14.5px;color:var(--enc);background:rgba(255,255,255,.82);border:1px solid var(--bord);padding:12px 14px;transition:border-color .18s,box-shadow .18s,background .18s}
.h-in:hover{border-color:var(--bis)}
.h-in:focus{border-color:var(--bis);background:#fff;box-shadow:0 0 0 3px rgba(154,96,12,.2);outline:none}
.h-in::placeholder{color:#7d6e58}
textarea.h-in{resize:none;min-height:58px;line-height:1.5}
.hpot{position:absolute;left:-9999px;opacity:0}
.cta{display:block;width:100%;text-align:center;font-family:'Public Sans';font-weight:700;font-size:16.5px;color:#fff;background:var(--grad-act);border:none;border-radius:999px;padding:15px 22px;cursor:pointer;text-decoration:none;box-shadow:0 8px 20px -8px rgba(91,33,182,.42);transition:transform .16s,box-shadow .16s}
.cta:hover{transform:translateY(-2px);background:var(--pru-cl)}
.cta .fl{display:inline-block;transition:transform .18s}
.cta:hover .fl{transform:translateX(4px)}
.cta[disabled]{opacity:.6;cursor:wait;transform:none}
.alt{text-align:center;font-size:13px;color:var(--enc2);margin-top:11px}
.alt a{color:var(--amb-t);text-decoration:none;font-weight:700}
.lpd{font-size:11px;color:var(--mut);text-align:center;margin-top:8px}
.lpd a{color:var(--mut)}
.ok-msg{margin-top:12px;text-align:center;font-weight:700;color:var(--ok);background:rgba(138,81,8,.1);border:1px solid rgba(138,81,8,.4);padding:11px}
/* --- signature : « les trois étages du Valais central », sans aucun JS --- */

/* ---------------- sections ---------------- */
.sec{padding:104px 0}
.sec-tinte{background:var(--bg);position:relative}
.sec-tinte::before{content:'';position:absolute;inset:0;pointer-events:none;background:linear-gradient(180deg,rgba(255,255,255,.55),transparent 42%)}
.sec-tinte>.wrap{position:relative;z-index:1}
.sec h2{font-family:'Work Sans';font-weight:550;letter-spacing:-.03em;font-size:clamp(25px,2.9vw,36px);line-height:1.12;margin-bottom:14px;text-wrap:balance}
/* le repère : un segment de bisse, coupé par la prise d'eau */
.sec h2::before,.article h2::before{content:'';display:block;width:22px;height:6px;margin-bottom:9px;background:linear-gradient(var(--bis),var(--bis)) 0 2px/22px 2px no-repeat,linear-gradient(var(--amb-t),var(--amb-t)) 8px 0/2px 6px no-repeat}
.lead{color:var(--enc2);max-width:min(var(--mes),100%);margin-bottom:26px;font-size:16.5px}
.cols2{display:grid;grid-template-columns:1fr 1fr;gap:30px;margin-top:8px}
.cols2>*{min-width:0}
.cols2 p{color:var(--enc2)}
.cols2 strong,.lead strong{color:var(--enc)}
.cols3{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;margin:26px 0}
.col-etape{background:#fff;border:1px solid var(--line);padding:22px;transition:transform .18s}
.col-etape:hover{transform:translateY(-4px)}
.col-etape b{font-family:'Work Sans';font-weight:600;color:var(--amb-t);font-size:14px}
.col-etape h3{font-family:'Work Sans';font-weight:700;font-size:19.5px;margin:6px 0 8px}
.col-etape p{color:var(--enc2);font-size:14.5px}
.bande{background:linear-gradient(135deg,#2a1c06,var(--nuit));position:relative;overflow:hidden}
.bande::after{content:'';position:absolute;inset:0;opacity:.5;background:radial-gradient(120% 180% at 15% 50%,rgba(217,154,43,.20),transparent 60%)}
.bande-in{position:relative;z-index:1;display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;padding-top:16px;padding-bottom:16px;color:#ece2d2;font-weight:700;font-size:14px}
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-top:30px}
.stat{background:#fff;border:1px solid var(--line);padding:18px;text-align:center}
.stat b{display:block;font-family:'Work Sans';font-weight:600;font-size:27px;color:var(--amb-t);font-variant-numeric:tabular-nums}
.stat span{font-size:12.5px;color:var(--mut)}
.steps{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-top:24px}
.steps-v{grid-template-columns:1fr;max-width:760px}
.step{display:flex;gap:14px;align-items:flex-start;background:#fff;border:1px solid var(--line);padding:16px 18px;transition:transform .18s}
.step:hover{transform:translateY(-3px)}
.step b{flex:none;width:32px;height:32px;display:grid;place-items:center;border-radius:50%;background:var(--pru);color:#fff;font-family:'Work Sans';font-weight:600;font-size:14px}
.step span{font-size:14.5px;color:var(--enc2)}
.step strong{color:var(--enc)}
.encart{border:1px solid rgba(138,81,8,.40);border-left:4px solid var(--amb-t);background:rgba(255,251,244,.9);padding:16px 20px;margin-top:26px}
.encart p{color:var(--amb-t);font-size:14.5px}
.encart a{font-weight:700}

/* prestations (accueil) */
.prestas{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:28px}
.presta{position:relative;display:block;overflow:hidden;text-decoration:none;border-bottom:2px solid var(--bis);transition:transform .22s;isolation:isolate}
.presta:hover{transform:translateY(-5px)}
.presta img{width:100%;height:230px;object-fit:cover;transition:transform .5s ease}
.presta:hover img{transform:scale(1.05)}
.presta-txt{position:absolute;inset:auto 0 0 0;padding:44px 18px 16px;background:linear-gradient(180deg,transparent,rgba(17,20,25,.9) 55%);color:#fff}
.presta-txt b{font-family:'Work Sans';font-weight:700;font-size:19.5px;display:block}
.presta-txt span{display:block;font-size:13px;color:#e2d6c1;margin:3px 0 8px}
.presta-txt i{font-style:normal;font-size:13px;font-weight:700;color:#f4c56a;white-space:nowrap}

/* rangée image+texte (pages services) */
.row-img{display:grid;grid-template-columns:.9fr 1.1fr;gap:32px;align-items:center;margin-top:10px}
.row-img>*{min-width:0}
.row-img img{border-bottom:2px solid var(--bis);width:100%;height:100%;max-height:330px;object-fit:cover}
.row-img p{color:var(--enc2);margin-bottom:12px}
.row-img strong{color:var(--enc)}

/* ---------------- plan du site ----------------
   ⚠️ Cette page est une nouveauté v9.12 : elle n'existait pas dans la feuille du pilote,
   et elle n'avait donc AUCUNE règle. Ses listes de liens sortaient de l'écran en dessous
   de 600 px — un débordement invisible sur toutes les autres pages, et qu'aucun contrôle
   automatique ne voit (qa.py mesure le HTML, pas la mise en page).
   Le master impose ici « ancres = les noms, point » : une liste, pas un pavé optimisé. */
.plan-g{margin:0 0 34px}
.plan-g h2{display:flex;align-items:baseline;gap:10px;margin-bottom:14px}
.plan-g h2 small{font-family:'Work Sans';font-weight:600;font-size:12px;color:var(--mut);
  letter-spacing:.06em}
.plan-g nav{display:flex;flex-wrap:wrap;gap:8px 10px}
.plan-g nav a{display:inline-block;max-width:100%;padding:7px 12px;
  background:#fff;border:1px solid var(--line);border-bottom:2px solid var(--bis);
  color:var(--enc2);text-decoration:none;font-size:14px;line-height:1.25;
  overflow-wrap:anywhere;transition:border-color .18s,color .18s,transform .18s}
.plan-g nav a:hover{color:var(--pru);border-color:var(--pru);transform:translateY(-1px)}
@media (max-width:560px){
  .plan-g nav{gap:6px 8px}
  .plan-g nav a{font-size:13.5px;padding:6px 10px}
}

/* tableaux & postes */
.table-scroll{overflow-x:auto;margin-top:10px}
.tbl-wrap{max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;margin:22px 0}
.tbl-wrap .tbl{margin:0}
.tbl{width:100%;border-collapse:collapse;background:#fff;overflow:hidden;border:1px solid var(--line);border-bottom:2px solid var(--bis);min-width:560px}
.tbl th{background:var(--nuit);color:#f3ece0;text-align:left;font-size:13px;letter-spacing:.05em;padding:13px 16px}
.tbl td{padding:13px 16px;border-top:1px solid var(--line);color:var(--enc2);font-size:14.5px}
.tbl td:last-child{font-family:'Work Sans';font-weight:600;color:var(--enc);white-space:nowrap;font-variant-numeric:tabular-nums}
.poste{display:flex;flex-direction:column;gap:8px;background:#fff;border:1px solid var(--line);border-radius:12px;padding:22px 22px 20px;text-decoration:none;color:inherit;min-width:0;box-shadow:0 10px 26px -20px rgba(44,33,16,.35);transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease}
.poste:hover{transform:translateY(-3px);border-color:var(--bis);box-shadow:0 18px 36px -22px rgba(154,96,12,.45)}
.poste b{font-family:'Work Sans';font-weight:700;color:var(--enc);font-size:19px;line-height:1.22;text-wrap:balance}
.poste p{font-size:14.5px;color:var(--enc2);margin:0}
.poste span{font-size:13.5px;color:var(--enc2)}

/* fiche commune */
.fiche{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:16px}
.fiche div{background:#fff;border:1px solid var(--line);padding:12px 14px}
.fiche small{display:block;font-size:10px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--mut)}
.fiche b{font-size:15px}
.communes-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:10px;margin-top:8px}
.communes-grid a{display:flex;justify-content:space-between;align-items:baseline;gap:8px;background:#fff;border:1px solid var(--line);padding:11px 14px;text-decoration:none;color:var(--enc);font-weight:700;font-size:14px;transition:transform .16s,border-color .16s}
.communes-grid a:hover{transform:translateY(-2px);border-color:var(--bis)}
.communes-grid small{font-family:'Work Sans';font-weight:600;font-size:10.5px;color:var(--mut)}

/* FAQ */
.sec-faq{background:var(--bg)}
.faq-list{max-width:820px;margin-top:22px}
.faq-item{background:#fff;border:1px solid var(--line);margin-bottom:12px;transition:border-color .2s}
.faq-item[open]{border-color:var(--bord)}
.faq-item summary{list-style:none;cursor:pointer;padding:16px 46px 16px 18px;font-weight:700;font-size:15.5px;position:relative;transition:color .18s}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary::after{content:'+';position:absolute;right:18px;top:50%;transform:translateY(-50%);font-family:'Work Sans';font-weight:400;font-size:26px;color:var(--amb-t);transition:transform .25s}
.faq-item[open] summary::after{transform:translateY(-50%) rotate(45deg)}
.faq-item summary:hover{color:var(--amb-t)}
.faq-a{padding:0 18px 16px;color:var(--enc2);font-size:14.5px}

/* blog */
.arts{display:grid;grid-template-columns:repeat(2,1fr);gap:18px;margin-top:24px}
.art-card{display:block;background:#fff;border:1px solid var(--line);padding:22px;text-decoration:none;transition:transform .18s}
.art-card:hover{transform:translateY(-4px)}
.art-card b{font-family:'Work Sans';font-weight:700;font-size:19.5px;color:var(--enc);display:block;margin-bottom:8px}
.art-card p{color:var(--enc2);font-size:14px;margin-bottom:10px}
.art-card i{font-style:normal;font-weight:700;font-size:13.5px;color:var(--amb-t)}
.article .wrap-art{max-width:780px}
.article h1{font-family:'Work Sans';font-weight:700;font-size:clamp(30px,3.65vw,43px);line-height:1.06;margin-bottom:18px;text-wrap:balance}
.article h2{font-family:'Work Sans';font-weight:700;font-size:clamp(21.5px,2.45vw,28px);margin:30px 0 10px}
.article p{color:var(--enc2);margin-bottom:14px}
.article strong{color:var(--enc)}
/* ⚠️ Ce <p> est posé HORS de tout conteneur par gen.py : sans largeur ni marge
   auto, il se calait sur le bord de la page. HTML valide, donc invisible pour
   tous les bancs — c'est le défaut n°12 relevé sur le #14. */
.art-retour{width:min(1060px,100%);margin:26px auto 0;padding:0 24px;font-weight:700}
/* la même flèche, tournée : pour un retour elle pointe à gauche et vient avant */
.fl-g{margin:0 .34em 0 0;transform:scaleX(-1)}
.article .art-note{font-size:13.5px;color:var(--mut);border-left:3px solid var(--bis);padding:10px 14px;background:#fff;margin-bottom:18px}

/* CTA final */
.sec-cta{background:linear-gradient(135deg,var(--nuit),var(--nuit2));position:relative;overflow:hidden}
.sec-cta::before{content:'';position:absolute;width:44vw;height:44vw;left:-14%;top:-38%;border-radius:50%;background:radial-gradient(closest-side,rgba(217,154,43,.26),rgba(217,154,43,.09) 48%,transparent 74%);animation:d2 25s ease-in-out infinite alternate}

.cta-fin{position:relative;z-index:1;text-align:center;padding-top:12px;padding-bottom:12px}
.cta-fin h2{color:#fdf8ef;font-family:'Work Sans';font-weight:550;letter-spacing:-.03em;font-size:clamp(25px,2.9vw,36px);margin-bottom:10px}
.cta-fin h2::before{margin:0 auto 11px;background:linear-gradient(#d99a2b,#d99a2b) 0 2px/22px 2px no-repeat,linear-gradient(var(--bis-cl),var(--bis-cl)) 8px 0/2px 6px no-repeat}
.cta-fin p{color:#e2d6c1;max-width:56ch;margin:0 auto 22px}
.cta-lien{display:inline-block;width:auto}
.cta-fin .alt{color:#cbbb9f}
.cta-fin .alt a{color:var(--bis-cl)}

/* footer */
.site-foot{background:var(--nuit2);color:#dbcdb4}
.foot-grid{display:grid;grid-template-columns:1.2fr 1fr 1.4fr;gap:36px;padding-top:48px;padding-bottom:30px}
.site-foot .logo{color:#f3ece0;font-size:22.5px}
.site-foot .logo-p{color:var(--bis-cl)}
.foot-txt{font-size:13.5px;margin-top:10px;color:#cbbb9f}
.foot-txt a{color:#ece2d2;text-decoration:none}
.site-foot h4{font-size:11px;letter-spacing:.15em;text-transform:uppercase;color:#c0ae90;margin-bottom:12px}
.foot-nav{display:grid;gap:7px}
.foot-nav a{color:#dbcdb4;text-decoration:none;font-size:13.5px;transition:color .15s}
.foot-nav a:hover{color:var(--bis-cl)}
.foot-nav-com{grid-template-columns:repeat(2,1fr)}
.foot-legal{border-top:1px solid #3a2b13;padding-top:16px;padding-bottom:22px;font-size:12px;color:#cbbb9f}
.foot-legal a{color:#dbcdb4}

/* sticky CTA mobile */
.sticky-cta{position:fixed;left:0;right:0;bottom:0;z-index:70;padding:10px 16px calc(10px + env(safe-area-inset-bottom));background:rgba(243,245,249,.94);backdrop-filter:blur(10px);border-top:1px solid var(--line);transform:translateY(110%);transition:transform .3s ease;display:none}
.sticky-cta .cta{width:100%}
.sticky-cta.vu{transform:none}
@media (max-width:760px){.sticky-cta{display:block}}

/* ---------------- popup « Partez avec votre chiffre » ---------------- */
.pum{position:fixed;inset:0;z-index:120;display:flex;align-items:center;justify-content:center;padding:20px;background:rgba(17,20,25,.5);backdrop-filter:blur(6px);opacity:0;transition:opacity .3s ease}
.pum.vu{opacity:1}
.pum-card{position:relative;border-radius:10px;box-shadow:0 22px 48px -30px rgba(70,60,47,.5);width:min(430px,100%);background-color:#fff;border:1px solid var(--line);padding:24px;transform:translateY(18px) scale(.97);transition:transform .35s cubic-bezier(.2,1.1,.3,1)}
.pum.vu .pum-card{transform:none}
/* la popup n'a pas d'élément .beam : on lui pose le même fil de bisse */
.pum-card::before{content:'';position:absolute;left:0;right:0;top:0;height:4px;z-index:3;background:linear-gradient(90deg,var(--pru) 0 34%,var(--bis) 34% 67%,var(--amb) 67% 100%);pointer-events:none}
.pum-x{position:absolute;top:10px;right:10px;width:36px;height:36px;border:none;background:none;cursor:pointer;font-size:22px;line-height:1;color:var(--mut);border-radius:50%;transition:background .15s,color .15s;z-index:4}
.pum-x:hover{background:rgba(28,20,9,.08);color:var(--enc)}
.pum-eti{font-family:'Work Sans';font-weight:600;font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--bis);margin-bottom:8px}
.pum-card h3{font-family:'Work Sans';font-weight:700;font-size:23.5px;line-height:1.12;margin-bottom:6px}
.pum-chiffre{font-family:'Work Sans';font-weight:600;font-size:15px;color:var(--amb-t);background:rgba(138,81,8,.08);border:1px solid rgba(138,81,8,.38);padding:9px 13px;margin:10px 0 6px;font-variant-numeric:tabular-nums}
.pum-p{font-size:13.5px;color:var(--enc2);margin-bottom:14px}
.pum-grid{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin-bottom:11px}
.pum-grid>*{min-width:0}
.pum-full{grid-column:1/-1}
.pum-grid textarea{resize:none;min-height:52px;line-height:1.45}
.pum-card .lpd{margin-top:9px}
.pum-ok{text-align:center;padding:16px 0 6px;font-weight:700;color:var(--ok)}
@media (max-width:600px){
  .pum{align-items:flex-end;padding:0}
  .pum-card{width:100%;padding-bottom:calc(24px + env(safe-area-inset-bottom));transform:translateY(100%)}
  .pum-card::after{left:0;bottom:0}
}
@media (prefers-reduced-motion:reduce){.pum,.pum-card{transition:none!important}}



/* ---------------- les prestations en images ----------------
   .prestas / .presta existaient déjà dans ce fichier et n'étaient appelés
   par AUCUNE page. On les réveille, en auto-fit pour tenir 3 ou 4 cartes. */
.prestas{grid-template-columns:repeat(auto-fit,minmax(228px,1fr))}
.presta{border-radius:12px}
.presta-leg{display:block;font-size:12.5px;color:var(--mut);margin-top:8px;line-height:1.45}

/* ---------------- responsive ---------------- */
@media (max-width:1080px){
  .hero-grid{grid-template-columns:1fr;gap:32px}
  .hero-max{min-height:0}

  /* en empilé, pas de résultat AVANT l'outil : les chips et la ligne source disparaissent,
     le résultat vit dans la carte (ligne ≈ kW · CHF) */
  .hero .live,.hero .srcline{display:none}
  .prestas{grid-template-columns:repeat(2,1fr)}
  .stats{grid-template-columns:repeat(2,1fr)}
  .steps{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:760px){
  .wrap{padding-left:18px;padding-right:18px}
  /* en-tête : Outfit a l'œil plus grand et la chasse plus étroite — on desserre */
  .site-head{gap:10px;padding:12px 16px}
  .logo{font-size:17px}
  .head-cta{padding:9px 12px;font-size:13px}
  /* le débord du fil d'eau reste sous la marge : aucun défilement horizontal */
  .card::after,.pum-card::after,.chip::after,.col-etape::after,.stat::after,.step::after,.faq-item::after,.art-card::after,.poste::after,.fiche div::after,.communes-grid a::after{left:-10px}
  .card:hover::after,.pum-card:hover::after,.chip:hover::after,.col-etape:hover::after,.stat:hover::after,.step:hover::after,.faq-item:hover::after,.art-card:hover::after,.poste:hover::after,.fiche div:hover::after,.communes-grid a:hover::after{left:-15px}
  .sec{padding:46px 0}
  .hero-grid{padding-top:36px;padding-bottom:40px}
  .cols2,.cols3,.postes,.arts,.row-img{grid-template-columns:1fr}
  .row-img img{max-height:240px}
  .prestas{grid-template-columns:1fr}
  .steps{grid-template-columns:1fr}
  .fiche{grid-template-columns:1fr 1fr}
  .foot-grid{grid-template-columns:1fr;gap:26px}
  .bande-in{justify-content:flex-start;gap:8px 18px;font-size:13px}
}

/* le bandeau du seuil se replie : 3 colonnes -> 1, sinon 991 px de haut a 375 px */
@media (max-width:900px){
  .seuil-in{grid-template-columns:1fr;gap:16px;padding:24px 0}
  .seuil-n{font-size:clamp(30px,9vw,40px);display:flex;align-items:baseline;gap:10px}
  .seuil-n small{margin-top:0}
  .seuil-l{justify-self:start}
}

/* ==================================================================
   LOT 0 — LES 21 CLASSES QUI ÉTAIENT APPELÉES SANS UNE SEULE RÈGLE
   Relevé le 2026-08-22. Le navigateur en voyait 17 sur l'accueil ; le
   contrôle statique de qa.py, qui lit les 75 pages, en a trouvé 4 de
   plus sur les communes et les quartiers — c'est la leçon du lot :
   un contrôle qui ne regarde qu'UNE page ne contrôle qu'une page.
   `part*`, `sec-part` : 71 pages · `bande-info`, `bande-src`,
   `liste-check` : 39 pages · `avis`, `et` : 16 pages.
   Un composant sans CSS est du HTML VALIDE : il ne déborde pas, il ne
   casse aucun contraste, donc tous les bancs le déclaraient vert.
   Les jetons ci-dessous sont ceux de la peau ACTUELLE — le lot 1
   (« Glacier & carmin ») les remplace, la structure reste.
   ================================================================== */

/* -- utilitaire : le texte que seul un lecteur d'écran doit lire ---- */
.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 bloc partenaire « Qui viendra chez vous » ------------------- */
.sec-part{border-top:1px solid var(--line)}
.part{display:grid;grid-template-columns:250px 1fr;gap:38px;align-items:start;
  background:#fff;border:1px solid var(--line);border-radius:12px;padding:30px 32px;
  box-shadow:0 20px 44px -34px rgba(44,33,16,.42)}
.part-id{display:flex;flex-direction:column;gap:14px;padding-right:28px;
  border-right:1px solid var(--line)}
.part-id picture,.part-id img{display:block}
.part-id img{width:92px;height:92px;object-fit:contain}
.part-id>img{margin-bottom:2px}
.part-nap{font-size:14px;line-height:1.65;color:var(--enc2);margin:0}
.part-nap b{display:block;font-family:'Work Sans';font-weight:700;font-size:17.5px;
  color:var(--enc);margin-bottom:3px}
.ide{display:inline-block;margin-top:7px;font-family:'Work Sans';font-weight:600;
  font-size:11.5px;letter-spacing:.06em;color:var(--enc2);background:var(--ciel);
  border-radius:5px;padding:3px 8px}
.part-txt>h2{margin-top:0}
.part-txt>p{max-width:min(var(--mes),100%)}
.part-l{list-style:none;margin:16px 0 0;padding:0;display:grid;gap:13px;max-width:min(var(--mes),100%)}
.part-l li{position:relative;padding-left:24px;font-size:15px;color:var(--enc2);
  line-height:1.62}
.part-l li::before{content:'';position:absolute;left:0;top:.6em;width:10px;height:10px;
  border-radius:3px;background:var(--bis)}
.part-l b{color:var(--enc)}
.part-lien{margin-top:20px;padding-top:14px;border-top:1px solid var(--line);
  font-size:13.5px;color:var(--mut);max-width:min(var(--mes),100%)}

/* -- les avis (ceux d'IMI, jamais les nôtres — cadrage dans le .lead) */
.avis{display:grid;grid-template-columns:repeat(auto-fit,minmax(310px,1fr));gap:18px;
  margin-top:22px}
.avi{margin:0;background:#fff;border:1px solid var(--line);padding:24px 24px 20px}
.avi p{font-size:15px;line-height:1.62;color:var(--enc2);margin:0}
.avi cite{display:block;margin-top:14px;font-style:normal;font-size:13px;
  color:var(--mut)}
/* ⚠️ ★ n'est dans AUCUN de nos .woff2 : les étoiles sont un SVG, pas un caractère. */
.et{display:block;width:96px;height:18px;margin:0 0 13px;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 18' fill='%23f0a500' stroke='%238a5108' stroke-width='1.1' stroke-linejoin='round'%3E%3Cpath transform='translate(0.0,0) scale(.9)' d='M10 1.4l2.55 5.17 5.7.83-4.13 4.02.98 5.68L10 14.42l-5.1 2.68.98-5.68L1.75 7.4l5.7-.83z'/%3E%3Cpath transform='translate(19.2,0) scale(.9)' d='M10 1.4l2.55 5.17 5.7.83-4.13 4.02.98 5.68L10 14.42l-5.1 2.68.98-5.68L1.75 7.4l5.7-.83z'/%3E%3Cpath transform='translate(38.4,0) scale(.9)' d='M10 1.4l2.55 5.17 5.7.83-4.13 4.02.98 5.68L10 14.42l-5.1 2.68.98-5.68L1.75 7.4l5.7-.83z'/%3E%3Cpath transform='translate(57.599999999999994,0) scale(.9)' d='M10 1.4l2.55 5.17 5.7.83-4.13 4.02.98 5.68L10 14.42l-5.1 2.68.98-5.68L1.75 7.4l5.7-.83z'/%3E%3Cpath transform='translate(76.8,0) scale(.9)' d='M10 1.4l2.55 5.17 5.7.83-4.13 4.02.98 5.68L10 14.42l-5.1 2.68.98-5.68L1.75 7.4l5.7-.83z'/%3E%3C/svg%3E") no-repeat left center;background-size:auto 100%}

/* -- « De la question au chauffage neuf, en 4 étapes » -------------- */
.cols4{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;margin-top:26px}
/* le numéro était COLLÉ au titre : « 1Votre chiffre, tout de suite » */
.col-etape .num{display:inline-grid;place-items:center;width:32px;height:32px;
  border-radius:9px;background:var(--ciel);color:var(--bis);font-family:'Work Sans';
  font-weight:700;font-size:16.5px;margin-bottom:11px}
.col-etape b{display:block}

/* -- le pied ------------------------------------------------------- */
.foot-com{min-width:0}
.foot-part{margin-top:16px;padding-top:14px;border-top:1px solid #3a2b13}
.foot-part b{color:#ece2d2}

/* -- la grille de liens, version resserrée (guides, questions) ------ */
.petites{grid-template-columns:repeat(auto-fill,minmax(232px,1fr))}
.petites a{font-size:13.5px;font-weight:600;padding:10px 13px}

/* -- « Ce qui s'applique chez vous » — 39 communes et quartiers ------
      C'est le bloc le plus utile du site : le droit qui s'applique au
      bâtiment du lecteur. Il sortait en prose nue, à pleine largeur.  */
.bande-info{background:var(--ciel);border:1px solid var(--line);border-left:4px solid var(--bis);
  border-radius:10px;padding:24px 26px 20px}
.bande-info>h3{font-family:'Work Sans';font-weight:700;font-size:20px;margin:0 0 14px;
  color:var(--enc)}
.liste-check{list-style:none;margin:0;padding:0;display:grid;gap:14px}
.liste-check li{position:relative;padding-left:28px;font-size:15px;line-height:1.62;
  color:var(--enc2)}
/* la coche est un SVG : ✓ n'est dans aucun de nos .woff2 non plus */
.liste-check li::before{content:'';position:absolute;left:0;top:.28em;width:18px;height:18px;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Ccircle cx='10' cy='10' r='9' fill='%230b5ea8'/%3E%3Cpath d='M5.6 10.3l2.9 2.9 5.9-6' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center/100%}
.liste-check b{color:var(--enc)}
.bande-src{margin:18px 0 0;padding-top:14px;border-top:1px solid var(--bord);
  font-size:12.5px;line-height:1.55;color:var(--enc2)}

/* -- le plan du site ----------------------------------------------- */
.plan{max-width:1000px}

/* -- la carte de devis des pages intérieures ------------------------ */

/* -- .go : posée par main.js quand le configurateur est vivant.
      C'est un CROCHET D'ÉTAT, pas un composant : elle n'a pas de règle,
      et elle est déclarée telle quelle dans le contrôle de qa.py.      */

@media (max-width:900px){
  .part{grid-template-columns:1fr;gap:24px;padding:24px 22px}
  .part-id{flex-direction:row;align-items:center;gap:18px;padding:0 0 18px;
    border-right:0;border-bottom:1px solid var(--line)}
  .part-id img{width:72px;height:72px}
  .cols4{grid-template-columns:repeat(2,1fr)}
  .bande-info{padding:20px 20px 17px}
}
@media (max-width:560px){
  .cols4{grid-template-columns:1fr}
  .avis{grid-template-columns:1fr}
}

/* ==================================================================
   LOT 2 — LA BARRE DE CONFIANCE DU HERO
   Demande n°1 de l'utilisateur : les cinq étoiles et le logo Google dès
   le hero. Trois garde-fous, écrits ici pour qu'on ne les défasse pas :
   ① le badge NOMME IMI lui-même — l'attribution n'est jamais reléguée
      dans une note plus bas ;
   ② il n'est PAS cliquable : aucun lien vers IMI nulle part (interdit
      n°4 du dossier — un lead qui appelle IMI en direct n'est pas
      commissionné) ;
   ③ AUCUN aggregateRating dans le JSON-LD (interdit n°2 : un rating
      auto-attribué est hors règles Google, et une action manuelle
      frapperait le pattern des 20 sites, pas une page).
   ================================================================== */
.gbadge{display:flex;align-items:center;gap:12px;margin:0 0 20px;padding:10px 15px;
  background:#fff;border:1px solid var(--bord);border-radius:14px;
  box-shadow:var(--o1);max-width:max-content}
.glogo{flex:0 0 auto;width:21px;height:21px}
.gnote{display:flex;flex-direction:column;gap:1px;min-width:0}
.gline{display:flex;align-items:center;gap:8px}
.gstars{display:block;width:88px;height:16.5px;background:var(--etoiles) no-repeat left center;
  background-size:auto 100%}
.gval{font-family:'Work Sans';font-weight:600;font-size:16px;line-height:1;
  letter-spacing:-.02em;color:var(--enc)}
.gsrc{font-size:12.5px;line-height:1.4;color:var(--mut)}
.gsrc b{color:var(--enc2);font-weight:700}

/* la phrase de cadrage COMPLÈTE (dossier IMI § 7.3) — elle vit dans le bloc
   partenaire, ce qui autorise le badge du hero à être compact sur mobile. */
.imi-avis{margin:0 0 14px;padding:10px 14px;background:#fffdf9;border:1px solid var(--line);
  border-radius:10px;font-size:13px;line-height:1.5;color:var(--mut)}
.imi-avis b{color:var(--enc)}

/* ------------- LA BANDE DE PREUVE : la photo de chantier et l'entreprise -------
   Elle remplace le décompte : c'est exactement ce que les six premiers de la
   SERP ont et que nous n'avions pas. */
.preuve{background:#fff;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.preuve-in{display:grid;grid-template-columns:1fr 1.06fr;gap:40px;
  padding-top:44px;padding-bottom:46px;align-items:start}
.shot{margin:0}
.shot img{width:100%;height:auto;border-radius:16px;box-shadow:var(--o2)}
.shot figcaption{margin-top:11px;font-size:12.5px;line-height:1.5;color:var(--mut)}
.shot figcaption b{color:var(--enc2);font-weight:700}

/* ------------- LA SIGNATURE : le seuil du chauffage à distance ---------------
   Elle se re-dérive du site, elle ne se recopie jamais avec la peau. Deux
   conditions CUMULATIVES, et c'est le « ET » qui est l'information.
   ⚠️ Le « ET » est en GLACIER, jamais en carmin : la couleur d'action ne sort
   pas d'un a.cta ou d'un button.cta. */
.sigband{position:relative;z-index:20;border-top:1px solid var(--bord);
  padding-top:26px;padding-bottom:46px}
.sig{display:grid;grid-template-columns:470px minmax(0,1fr);gap:40px;align-items:start}
.sig-t{grid-column:1/-1;display:block;font-size:12.5px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--bis);margin-bottom:14px}
.seuils{display:grid;grid-template-columns:1fr auto 1fr;gap:12px;align-items:stretch}
.plaque{background:#fff;border:1px solid var(--line);border-radius:12px;
  padding:13px 15px 12px;box-shadow:var(--o1);position:relative;overflow:hidden}
.plaque::before{content:'';position:absolute;left:0;top:0;width:38%;height:3px;
  background:var(--grad-t)}
.plaque b{display:block;font-family:'Work Sans';font-weight:600;font-size:27px;
  letter-spacing:-.035em;line-height:1.05;color:var(--bis);font-variant-numeric:tabular-nums}
.plaque span{display:block;font-size:13px;line-height:1.35;color:var(--enc2);margin-top:3px}
.plaque em{display:block;font-style:normal;font-size:12px;line-height:1.35;
  color:var(--mut);margin-top:5px}
.et-lien{align-self:center;font:700 12px/1 'Public Sans',system-ui,sans-serif;letter-spacing:.1em;
  color:var(--bis);border:1px solid var(--bord);background:#fff;border-radius:999px;
  padding:7px 9px}
.sig-lg{margin:0;font-size:14.5px;line-height:1.62;color:var(--enc2);max-width:44em;
  align-self:center}
.sig-lg b{color:var(--enc);font-weight:700}
.sig-lg i{font-style:italic}

@media (max-width:1000px){
  .sig{grid-template-columns:minmax(0,1fr);gap:16px}
  .sig-lg{align-self:start}
  .preuve-in{grid-template-columns:1fr;gap:28px}
}
@media (max-width:560px){
  .seuils{grid-template-columns:1fr;gap:9px}
  .et-lien{justify-self:start}
  /* le badge Google passe sur UNE ligne : il coûte 90 px au-dessus de la carte,
     et la carte doit rester au-dessus du pli. La phrase de cadrage complète, elle,
     vit dans le bloc partenaire — elle n'est pas perdue. */
  .gbadge{gap:9px;padding:8px 12px;margin-bottom:14px}
  .gnote{flex-direction:row;align-items:center;gap:9px;flex-wrap:wrap}
  .gsrc{font-size:11.5px;flex:1 1 100%}
  .gsrc .greleve,.gsrc .gplus{display:none}
  .eyebrow{background:none;border:0;padding:0;font-size:12.5px;margin-bottom:9px}
}


/* ==================================================================
   LA CARTE DE DEVIS RESTE AU-DESSUS DU PLI
   Mesuré au banc après la refonte : le témoin remonté dans la colonne de
   gauche avait poussé la carte à 1 144 px sur 390 et 1 377 px sur 320.
   ⚠️ Sous `display:contents`, TOUT enfant porte un `order` explicite —
   sinon il vaut 0 et repasse devant. C'est le piège n°2 du #14.
   ================================================================== */
@media (max-width:1080px){
  .hero-grid{grid-template-columns:1fr;gap:30px}
  .hero-grid>div:first-child{display:contents}
  .eyebrow{order:1}
  .gbadge{order:2}
  .hero h1{order:3}
  .sub{order:4}
  .cardwrap{order:5}
  .live{order:6;margin-top:20px}
  .srcline{order:7}
  .trust{order:8}
  .rsx-hero{order:9;max-width:none}
  .warn-col{order:10}
}
/* le complément de périmètre de l'eyebrow : il tient sur une ligne au large,
   il s'escamote au serré. Sans règle, il ne s'escamotait pas — et c'est le
   contrôle « classe sans CSS » du lot 0 qui l'a vu, dans la même session. */
.eb-plus{display:inline}

@media (max-width:560px){
  .eb-plus{display:none}
  /* la carte passe AVANT le sous-titre : à 320 px, chaque objet au-dessus
     d'elle se paie. La note Google reste au-dessus — c'est tout l'intérêt
     de l'avoir mise là. */
  .cardwrap{order:4}
  .sub{order:5}
}

/* la flèche : « → » n'est dans AUCUN .woff2 du réseau — mesuré, pas supposé.
   En masque, elle hérite de currentColor et suit donc la couleur du lien. */
.fl{display:inline-block;width:1.05em;height:.8em;margin-left:.34em;vertical-align:-.04em;
  background:currentColor;
  -webkit-mask:var(--fleche) no-repeat center/contain;mask:var(--fleche) no-repeat center/contain}

/* ==================================================================
   LE RYTHME DE LA PROSE
   Les paragraphes se touchaient : le corps du site n'avait AUCUNE
   marge entre deux <p>, et les h2 collaient à la dernière ligne du
   paragraphe précédent. Ça se voit à l'œil, jamais au banc.
   ⚠️ Le découpage (paragraphe médian 341 → < 200 caractères) et les
   ~200 intertitres à écrire sont le LOT 5 — ici on ne règle que
   l'espacement.
   ================================================================== */
.sec p + p,.sec p + ul,.sec ul + p,.sec p + ol,.sec ol + p{margin-top:.95em}
.sec h2{margin-top:2.15em}
.sec > .wrap > h2:first-child,.sec h2:first-child{margin-top:0}
.sec h3{margin-top:1.7em;margin-bottom:.5em;font-family:'Work Sans';font-weight:600;
  letter-spacing:-.02em;font-size:20px;color:var(--enc)}
/* ces blocs ont leur propre rythme : on ne leur impose pas celui de la prose */
.card p + p,.rsx p + p,.avi p + p,.preuve p + p,.plaque p + p,
.foot-txt + .foot-txt,.chip p + p{margin-top:0}
.card h3,.avi h3,.presta-txt h3{margin-top:0}

@media (max-width:420px){
  /* le texte d'exemple tient sur 3 lignes à 390 px : sans ça, il est COUPÉ */
  textarea.h-in{min-height:78px}
}

/* ==================================================================
   LES ILLUSTRATIONS
   Avant le 23.08, 74 pages sur 75 ne portaient AUCUNE photographie —
   4 photos pour 161 350 mots de corps, quand le premier de la SERP
   est à une image pour 58 mots.
   ⚠️ `width` et `height` sont écrits sur chaque <img> : sans eux la
   page saute au chargement, et c'est le genre de défaut qu'aucun banc
   ne voit parce qu'il ne dure qu'une seconde.
   ================================================================== */
.ill{margin:26px 0;max-width:min(var(--mes),100%)}
.ill img{width:100%;height:auto;border-radius:12px;box-shadow:var(--o1)}
.ill figcaption{margin-top:9px;font-size:12.5px;line-height:1.5;color:var(--mut)}
/* ⚠️ --bord (#e9dfd0) sur blanc mesure 1,2:1 : la ligne de crédit était
   ILLISIBLE. Et un crédit illisible ne remplit pas la condition de la
   licence. Elle passe à --mut, 5,65:1. */
.ill-cr{display:block;margin-top:2px;font-size:11.5px;color:var(--mut)}
.ill-large{max-width:none}
.ill-lieu img{aspect-ratio:4/3;object-fit:cover}
.illband{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:22px}
.illband .ill{margin:0;max-width:none}
.illband .ill img{aspect-ratio:4/3;object-fit:cover}
.sec-ill{padding-top:0}
/* la page des crédits : une liste, pas une galerie */
.credits{list-style:none;margin:0;padding:0;display:grid;gap:14px}
.credits li{display:grid;grid-template-columns:96px 1fr;gap:16px;align-items:start;
  padding-bottom:14px;border-bottom:1px solid var(--line)}
.credits img{width:96px;height:72px;object-fit:cover;border-radius:8px}
.credits b{display:block;font-size:14.5px;color:var(--enc)}
.credits span{font-size:13px;color:var(--enc2)}
.credits em{display:block;font-style:normal;font-size:12.5px;color:var(--mut);margin-top:3px}
@media (max-width:560px){
  .credits li{grid-template-columns:1fr}
  .credits img{width:100%;height:auto;aspect-ratio:4/3}
}

/* le renvoi de corps vers une page voisine — il compte comme un lien ENTRANT,
   là où un lien de pied de page ne prouve que l'existence d'un menu. */
.art-suite{margin:22px 0 0;padding:13px 16px;background:#fffcf5;border:1px solid var(--line);
  border-left:3px solid var(--bis);border-radius:0 10px 10px 0;font-size:14.5px;
  line-height:1.55;color:var(--enc2);max-width:min(var(--mes),100%)}

/* ==========================================================================
   LA MATIÈRE — verre, profondeur, glow, mouvement.  (maquette du 23.08, ⓪→⑩)
   Tout est en CSS : zéro image, zéro librairie, aucune requête de plus.
   LES TROIS RÈGLES QUI BORNENT CETTE COUCHE, et qui ne se négocient pas :
     ① rien ne part de `opacity:0`. Le scroll-reveal du 19.08 avait laissé
        23 éléments invisibles ET invisibles au contrôle de contraste, qui
        annonçait « 0 échec » ;
     ② aucune transparence derrière le formulaire de devis ;
     ③ le halo de la carte est OR, jamais prune — sinon la couleur d'action
        baigne son propre bouton et la doctrine du blanc s'effondre.
   ========================================================================== */
@property --ang{syntax:'<angle>';initial-value:0deg;inherits:false}

:root{
  --verre:linear-gradient(158deg,rgba(255,255,255,.95),rgba(255,253,249,.72));
  --verre-b:rgba(234,224,209,.85);
  --arete:inset 0 1px 0 rgba(255,255,255,.96);
  --o3:0 6px 14px rgba(90,60,20,.08),0 34px 64px -22px rgba(90,60,20,.26);
  --glow:rgba(91,33,182,.44);
}

/* ⓪ LE LAVIS, élargi et remonté à .96 : le texte est sur du blanc PUR, et c'est
   là que se gagne le contraste. Il atteint 0 AVANT les quatre bords
   (44 - .82 × 48 = +5,6 % à gauche) — aucune bordure verticale. C'est le défaut
   encore en production sur #11, #13, #18 et #19. */
.voile{background:radial-gradient(48% 52% at 34% 44%,rgba(255,255,255,.96),
  rgba(255,255,255,.58) 52%,transparent 84%)}

/* ① L'HORIZON — la lumière vient du haut, l'assise est chaude en bas. C'est ce
   qui donne la profondeur sans ajouter un seul foyer animé. */
.hero::before{content:'';position:absolute;inset:0;z-index:2;pointer-events:none;
  background:
    radial-gradient(128% 62% at 50% -18%,rgba(255,255,255,.96),transparent 60%),
    radial-gradient(16% 24% at 93% 3%,rgba(245,178,52,.32),transparent 70%),
    radial-gradient(14% 20% at 1% 22%,rgba(253,214,130,.34),transparent 72%),
    radial-gradient(17% 23% at -1% 98%,rgba(139,92,246,.24),transparent 72%),
    radial-gradient(12% 18% at 99% 62%,rgba(167,139,250,.17),transparent 74%),
    radial-gradient(13% 19% at 63% 17%,rgba(253,224,150,.32),transparent 74%)}

/* ② LA TEXTURE — PAS de trame de lignes. Une première version posait des fils à
   45° : à l'écran ça redevenait du PAPIER RAYÉ, trait pour trait le motif qui a
   fait refuser CINQ peaux du réseau. La matière vient donc de choses qui ne
   dessinent rien : le grain monte à .33, le dégradé de verre, l'éclat de bord
   des surfaces — et la LUMIÈRE qui traverse. */
.grain{opacity:.33}
.hero::after{content:'';position:absolute;inset:0;z-index:3;pointer-events:none;
  background:linear-gradient(104deg,transparent 27%,rgba(255,255,255,.74) 44%,
    rgba(255,249,236,.34) 53%,transparent 69%);
  background-size:250% 100%;animation:rai 26s ease-in-out infinite alternate}
@keyframes rai{to{background-position:100% 0}}

/* ③ LE VERRE — sur les surfaces POSÉES du hero, jamais sur la carte de devis.
   Trois marqueurs, toujours les trois ensemble : un dégradé de translucidité
   (jamais un aplat à opacité), une arête claire en haut, une ombre TEINTÉE de
   la famille (jamais grise). */
.eyebrow,.gbadge,.hero .chip,.plaque{
  background:radial-gradient(118% 88% at 8% 0%,rgba(255,255,255,.96),transparent 56%),var(--verre);
  border-color:var(--verre-b);
  box-shadow:var(--arete),var(--o1);
  backdrop-filter:blur(9px) saturate(1.35);
  -webkit-backdrop-filter:blur(9px) saturate(1.35)}
.hero .chip,.plaque{transition:transform .18s ease,box-shadow .18s ease}
.hero .chip:hover,.plaque:hover{transform:translateY(-2px);box-shadow:var(--arete),var(--o2)}

/* ④ LA CARTE — opaque (invariant ②), mais posée sur un halo OR et cerclée d'un
   anneau conique qui tourne. L'anneau remplace le liseré fixe du #16. */
.cardwrap{position:relative}
.cardwrap::before{content:'';position:absolute;inset:-6% -5% -8%;z-index:-1;
  pointer-events:none;border-radius:44px;filter:blur(20px);
  background:radial-gradient(54% 48% at 52% 46%,rgba(180,114,15,.62),transparent 72%)}
.card{box-shadow:var(--o3),var(--arete),0 0 40px -4px rgba(217,154,43,.40)}
.card::before{content:'';position:absolute;inset:0;border-radius:inherit;
  padding:1.6px;pointer-events:none;
  background:conic-gradient(from var(--ang),
    rgba(217,154,43,.98),rgba(255,255,255,0) 24%,rgba(255,255,255,0) 58%,
    rgba(154,96,12,.72) 84%,rgba(217,154,43,.98));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
  animation:tour 18s linear infinite}
@keyframes tour{to{--ang:360deg}}

/* ⑤ LE CTA — la seule couleur saturée de la page, donc le seul glow. Un éclat le
   balaie au survol, et la flèche avance. */
.cta{position:relative;overflow:hidden;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.26),0 12px 30px -10px var(--glow),
    0 0 46px -14px rgba(109,40,217,.58)}
.cta::after{content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg,transparent 24%,rgba(255,255,255,.32) 46%,transparent 64%);
  transform:translateX(-135%);transition:transform .62s ease}
.cta:hover::after,.cta.survol::after{transform:translateX(135%)}
.cta:hover,.cta.survol{transform:translateY(-2px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.32),0 22px 48px -12px var(--glow),
    0 0 64px -12px rgba(109,40,217,.72)}
.cta:active{transform:translateY(0);box-shadow:0 6px 14px -8px var(--glow)}
.cta .fl,.cta .ico{transition:transform .22s ease;position:relative;z-index:1}
.cta:hover .fl,.cta:hover .ico,.cta.survol .fl{transform:translateX(4px)}
.cta>*{position:relative;z-index:1}

/* ⑥ L'ÉCLAT du mot d'accroche. Le stop le plus clair est MESURÉ : la première
   version finissait à 2,44:1 sur blanc, sur le H1. */
.hero h1 .fat b{background:linear-gradient(103deg,#6b3d05 0%,#8a5108 30%,#b4720f 50%,#8a5108 70%,#6b3d05 100%);background-size:280% 100%;
  -webkit-background-clip:text;background-clip:text;color:transparent;
  animation:eclat 9s ease-in-out infinite;white-space:nowrap}
@keyframes eclat{0%,100%{background-position:0% 50%}50%{background-position:100% 50%}}

/* ⑦ Le mouvement continue hors du hero, sinon la page retombe à plat. */
.shot img,.ill img{transition:transform .38s ease,box-shadow .38s ease}
.shot:hover img{transform:translateY(-3px);box-shadow:var(--o3)}

/* ⑧ Le flou coûte cher sur mobile : sous 560 px on rend les surfaces opaques. */
@media (max-width:560px){
  .eyebrow,.gbadge,.hero .chip,.plaque{backdrop-filter:none;-webkit-backdrop-filter:none;
    background:rgba(255,255,255,.94)}
  .cardwrap::before{filter:blur(18px)}
}

/* ⑨ Et tout se coupe si la machine le demande. La règle générale
   `prefers-reduced-motion` du haut de feuille porte déjà `animation:none`, mais
   elle ne couvre pas `.cta::after`, qui est un objet POSÉ, pas une animation. */
@media (prefers-reduced-motion:reduce){
  .cta::after{display:none}
  .hero h1 .fat b{background-position:0 50%}
}


/* ==========================================================================
   CE QUI EST PROPRE AU #10 — la signature, la relance, les figures.
   ========================================================================== */

/* --- Trois défauts vus À L'ÉCRAN, invisibles à tous les bancs -------------
   ① l'`<output>` du curseur héritait du `text-transform:uppercase` de son
      label : la surface s'affichait « 160 M² », avec un M capital ;
   ② le H1 du #16 monte à 54 px et cassait « Changez de chauffage. » en deux
      lignes ; la maquette validée le borne à 46 ;
   ③ « 30 secondes » se coupait entre les deux mots sur les trois candidates —
      c'est traité par `white-space:nowrap` dans la couche de matière. */
.h-t output{text-transform:none;font-size:16px}
.hero h1{font-size:clamp(30px,3.5vw,46px)}

/* --- L'ENCADRÉ CANTONAL -------------------------------------------------
   ⚠️ Deux défauts vus À L'ÉCRAN, aucun visible au banc :
   ① il était peint en BLEU GLACIER sur BLEU PÂLE — des `rgba()` du #16 que ni
      le remappage de jetons ni le tableau d'hexadécimaux ne pouvaient voir ;
   ② son corps de texte était en OR et ses `<strong>` en encre foncée :
      l'emphase était donc à l'ENVERS, et le paragraphe se lisait comme un
      texte à moitié surligné. Le laiton reste sur le titre et sur le filet. */
.encart p{color:var(--enc2)}
.encart p strong,.encart p b{color:var(--enc)}
.encart h3{color:var(--bis);margin-bottom:10px}
/* ⚠️ Et ses liens aussi : `--amb-t` sur le crème de l'encadré donne 4,45:1.
   Cinq CENTIÈMES sous AA — invisibles à un calcul sur les jetons, immédiats
   dès qu'on compose les calques. Même remède que pour `.liens-util a`. */
.encart a{color:var(--bis)}
/* ⚠️ Et l'avertissement du configurateur, pour la même raison : `--amb-t` sur
   son fond crème donne 3,57:1. Il ne s'affiche que sur les pages qui
   pré-sélectionnent « Électrique » — donc il n'apparaissait dans aucune des
   captures regardées jusque-là, et seul un balayage de TOUTES les pages à
   TOUTES les largeurs pouvait le trouver. */
.warn{color:var(--bis)}
.encart h3::before{display:none}

/* 🔴 LA POPUP NE S'OUVRAIT PAS SOUS 600 px — ET C'EST LE SEUL ENDROIT OÙ ELLE
   SERT VRAIMENT. Son déclencheur mobile est le scroll à 60 %, donc elle ne se
   montre QUE là ; et là, elle restait à `translateY(100%)`, c'est-à-dire
   entièrement sous le pli. Mesuré à 320, 375 et 390 px : le haut de la carte
   tombait exactement sur la hauteur de l'écran, aux trois largeurs.
   Cause : dans `@media (max-width:600px)`, la feuille du #16 repose
   `.pum-card{transform:translateY(100%)}` comme état FERMÉ — et cette règle
   l'emporte sur `.pum.vu .pum-card{transform:none}` déclarée plus haut. C'est le
   piège n°1 du réseau, « une règle reportée garde son sélecteur », dans sa
   version media-query. On repose donc l'état OUVERT dans la même requête.
   ⚠️ Et on borne la hauteur : à 320×568, la carte fait 705 px. Sans
   `max-height` + défilement propre, le bouton d'envoi reste hors de l'écran
   même une fois la carte remontée. */
@media (max-width:600px){
  .pum{align-items:flex-end}
  .pum.vu .pum-card{transform:none}
  .pum-card{max-height:calc(100dvh - 12px);overflow-y:auto;-webkit-overflow-scrolling:touch}
}

/* 🔴 LE CTA D'EN-TÊTE A ÉTÉ AVALÉ PAR LE CTA DE LA CARTE. En lui donnant la
   classe `cta` — pour que le contrôle « la couleur d'action n'habille que des
   CTA » cesse de le dénoncer à tort —, il a hérité de `width:100%` et de
   `justify-content:center` : une pilule d'un demi-écran en haut de page, qui
   poussait la navigation sur deux lignes. Le standard prévoit DEUX tailles de
   CTA et une seule intention : on remet la taille compacte, on garde la classe.
   Vu à l'écran, sur la première capture qui a suivi le correctif. */
.head-cta{width:auto;display:inline-flex;flex:0 0 auto;padding:11px 20px;font-size:15px;
  margin-left:auto;overflow:visible}
.head-cta::after{display:none}

/* --- LA SIGNATURE : « la règle du voisin » -------------------------------
   Elle est CONSERVÉE du site — elle est vraie, elle est unique dans le réseau,
   et elle se dérive du district : bâti jeune, PPE, parcelles serrées.
   ⚠️ Elle vivait DANS la carte de devis, où elle repoussait le CTA sous le pli
   (défaut payé cash sur le #15 : bouton à 1465 px sur mobile). Elle passe dans
   une bande `.sigband` sœur de la grille du hero.
   ⚠️ Sans `grid-row` EXPLICITE, l'étiquette était auto-placée EN DERNIER : le
   titre du bloc se retrouvait sous sa propre légende. */
.sig{align-items:start;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);
  column-gap:40px;row-gap:14px}
.sig-t{grid-column:1/-1;grid-row:1;margin-bottom:4px}
.sig-intro{grid-column:1;grid-row:2;margin:0 0 12px;font-size:14.5px;line-height:1.55;
  color:var(--enc2)}
.sig-intro b{color:var(--bis);font-weight:700}
.sig-lg{grid-column:1;grid-row:3;max-width:none;align-self:start}
.seuils{grid-column:2;grid-row:2/span 2;align-self:start;grid-template-columns:1fr 1fr}
.plaque{display:flex;flex-direction:column}
/* Le palier DS III-IV est HACHURÉ : le degré de sensibilité ne se lit pas depuis
   un site web, il se lit dans le règlement communal — et c'est celui du VOISIN
   qui compte. L'honnêteté épistémique reste un élément graphique. */
.plaque.hach{background:
  repeating-linear-gradient(135deg,rgba(255,255,255,.92) 0 7px,rgba(230,216,196,.85) 7px 8px)}
.plaque .bar{display:block;height:6px;width:var(--w);margin-top:auto;border-radius:3px;
  background:var(--bis);opacity:.9}
.plaque.hach .bar{background:repeating-linear-gradient(135deg,var(--amb-t) 0 5px,transparent 5px 9px);
  outline:1px solid var(--amb-t);outline-offset:-1px}
/* ⚠️ MESURÉ SUR LE COMPOSITE, pas sur le jeton : `--amb-t` donne 4,57:1 sur du
   blanc, mais la plaque hachurée n'est PAS blanche — ses bandes descendent à
   `rgba(230,216,196,.85)`, et la légende y tombait à 3,43:1. C'est exactement le
   défaut que seul un contrôle qui compose les calques peut voir. */
.plaque.hach em{color:#7a4707}
.plaque span,.plaque em{margin-bottom:8px}
/* 🔴 ET LA GRILLE ELLE-MÊME N'ÉTAIT PAS REMISE À UNE COLONNE. La feuille de
   base la replie bien (`@media (max-width:1000px){.sig{grid-template-columns:
   minmax(0,1fr)}}`), mais la redéclaration de la signature vit PLUS BAS dans le
   fichier, à spécificité égale — et à spécificité égale, c'est la dernière qui
   gagne, media query ou pas. Résultat mesuré à 390 px : les enfants passaient
   bien tous en colonne 1, mais la grille gardait DEUX pistes, donc la colonne 1
   ne faisait que **146 px sur 339** — vingt caractères par ligne, et la moitié
   droite de la bande vide, sur les 87 pages. C'est le piège de l'ordre, pas
   celui de la spécificité : il ne se voit qu'en REGARDANT un vrai 390 px. */
@media (max-width:1000px){
  .sig{grid-template-columns:minmax(0,1fr);column-gap:0}
  .sig-t,.sig-intro,.seuils,.sig-lg{grid-column:1;grid-row:auto}
}
@media (max-width:560px){.sig-intro{margin-bottom:9px}.seuils{grid-template-columns:1fr}}

/* --- LA RELANCE DE MILIEU DE PAGE : devis ET appel -----------------------
   Les pages font 1'300 à 1'530 mots : la carte est en haut, le CTA final tout en
   bas, et entre les deux il y avait un couloir sans aucune sortie. Fond OPAQUE :
   aucune transparence derrière une action. */
.sec-relance{padding-top:0}
.relance{display:grid;grid-template-columns:1.25fr .75fr;gap:30px;align-items:center;
  background:#fff;border:1px solid var(--line);border-radius:var(--rg,20px);
  padding:26px 30px;box-shadow:var(--o1)}
.relance-mini{margin:26px 0;padding:22px 24px;grid-template-columns:1.15fr .85fr}
.relance-eti{font-size:11.5px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--bis);margin-bottom:6px}
.relance-t{font-family:var(--disp);font-weight:600;font-size:21px;letter-spacing:-.02em;
  color:var(--enc);margin-bottom:7px}
.relance-txt h2{margin-bottom:7px}
.relance-txt p{font-size:15px;color:var(--enc2);margin:0;max-width:56ch}
.relance-act{display:flex;flex-direction:column;gap:10px;align-items:stretch}
.relance-act .cta{justify-content:center}
.relance-p{font-size:12.5px;color:var(--mut);margin:0;text-align:center}
@media (max-width:820px){.relance{grid-template-columns:1fr;gap:20px}}

/* --- LA DEUXIÈME VOIE : le téléphone, VISIBLE ----------------------------
   Pas seulement une ligne de texte sous le bouton. Il est en encre et contour :
   un seul objet vif par écran, et c'est le CTA. */
.cta-tel{display:inline-flex;align-items:center;justify-content:center;gap:9px;
  font-weight:700;font-size:15.5px;text-decoration:none;color:var(--enc);
  background:#fff;border:1.5px solid var(--bord);border-radius:999px;padding:11px 20px;
  transition:transform .16s,border-color .16s}
.cta-tel:hover{transform:translateY(-2px);border-color:var(--bis)}
.tel-bloc{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-top:22px}
.tel-txt{font-size:13.5px;line-height:1.5;color:var(--mut)}
.tel-txt b{color:var(--enc2)}

/* ⚠️ LE BANDEAU COLLANT RECOUVRE LE PIED. Mesuré à 390 px : 84 px de bouton
   par-dessus la ligne des mentions légales, donc par-dessus les deux liens que
   la loi oblige à rendre accessibles. Le corps réserve la place. */
@media (max-width:820px){
  body{padding-bottom:88px}
}

/* ==========================================================================
   LA COLONNE UNIQUE, ASSUMÉE.  (2026-08-23, 3e passe — l'espacement, ②)
   ==========================================================================
   🔴 LA 2ᵉ PASSE A ÉCHOUÉ, ET IL FAUT DIRE POURQUOI. Elle avait sorti les
   figures du flux pour les poser en `float:right` de 320 px dans la marge —
   le « margin note zone » de la mise en page éditoriale. L'intention était
   juste : la gouttière de droite était vide sur toute la hauteur des pages.
   Le procédé, lui, ne l'était pas. **Un flottant ne se pilote pas.** On ne
   peut pas lui dire « ne te pose que s'il y a 300 px de texte à ta droite » :
   il se referme au premier `clear:both`, et tout objet large en porte un.
   Relevé à 1440 px sur l'état sortant :

     /blog/radiateurs-ou-chauffage-au-sol/  9 figures orphelines, dont 4 a 0 %
     /prix-pompe-a-chaleur/                 7
     /climatisation/                        6
     /geothermie-sol-eau/                   5

   « Orpheline » = moins de 55 % de la hauteur de la figure longée par du
   texte. Quatre étaient à ZÉRO : 261 à 299 px d'image seule dans la marge,
   face à du blanc. C'est exactement ce que l'utilisateur montrait sur
   capture, deux fois de suite, pendant que les neuf outils passaient à zéro.

   ➡️ ON TRANCHE : la gouttière est ABANDONNÉE. Une seule colonne de lecture,
   centrée, et les figures dedans, à sa largeur. Ce qui disparaît avec elle :
   le `float`, les quinze `clear:both` qui n'existaient que pour le contenir,
   la fermeture `::after` des conteneurs, le `:has()` qui rétrécissait à
   760 px, et la colonne d'article élargie à 1000 px pour le loger.

   ET LE VRAI DÉFAUT DE FOND, QUE LA GOUTTIÈRE MASQUAIT : le conteneur fait
   1060 px, la prose 666, mais les DEUX étaient calées à GAUCHE. La page
   avait donc un demi-écran blanc d'un seul côté — un déséquilibre, pas une
   marge. Un blanc SYMÉTRIQUE se lit comme une marge et ne se voit pas ; un
   blanc d'un seul côté se lit comme une page inachevée. Tout enfant du
   conteneur est désormais borné à la mesure de lecture ET centré sur le
   MÊME axe que les objets larges — un seul axe, jamais deux bords gauches
   (défaut n°11 du #14, payé le 22.08).
   ========================================================================== */
.sec{padding:64px 0}
/* Deux bandes ont leur propre rembourrage INTERNE, qui s'ajoute à celui de la
   section : le bloc de conversion final (`.cta-fin`, 12 px) et la relance de
   milieu de page (`.relance`, 26 px). Sur ces deux-là, la section rend ce
   qu'elle prête — sinon on mesure 220 px là où le dessin en demande 128. */
.sec-cta{padding-top:48px}
.cta-fin{padding-top:0}
.sec-relance{padding-top:22px;padding-bottom:56px}
/* ⚠️ UNE SECTION ENTIÈRE POUR UN ENCADRÉ DE SEPT LIENS. Mesuré à 390 px sur
   `/prix-pompe-a-chaleur/` : 64 px de rembourrage bas de la FAQ + 64 px de
   rembourrage haut + 22 px de marge = 150 px de blanc entre la dernière
   question et « À lire aussi ». Deux blocs qui vont ensemble, séparés comme
   deux sujets. La section qui ne porte QUE cet encadré ne prend plus de
   rembourrage haut. */
.sec:has(>.wrap>.liens-util:only-child){padding-top:0}
/* ⚠️ Un h2 qui OUVRE son conteneur n'a jamais besoin d'une marge haute : c'est
   le rembourrage du conteneur qui fait ce travail. La règle `margin-top:2.15em`
   du #16 est faite pour un h2 au MILIEU d'une prose ; posée sur un h2 d'ouverture
   elle s'ajoutait au rembourrage et creusait 285 px. Elle descend aussi de 2,15
   à 1,6 em : entre deux sujets d'une même section, 58 px suffisent à séparer. */
.sec h2{margin-top:1.6em}
.sec h2:first-child,.article h2:first-child,
.sec>.wrap>*:first-child>h2:first-child,.relance-txt h2{margin-top:0}
.cta-fin h2,.chant-t{margin-top:0}

/* --- LA COLONNE COURTE D'UNE PAGE DE LIEU --------------------------------
   Même défaut, même remède, et c'est le plus répandu du site : il est sur les
   57 pages de lieu. La colonne de droite (encadré cantonal, fiche, photo) finit
   383 px plus haut que la colonne de prose — un quart d'écran blanc en bas à
   droite, mesuré sur `/prangins/`. La DERNIÈRE figure de la colonne prend la
   place qui reste, bornée par `--nh` comme partout ailleurs. Si le fichier ne
   suffit pas, le blanc restant est le prix du fichier, et il se dit. */
.sec>.wrap>.cols2:not([data-rev])>div:last-child{display:flex;flex-direction:column}
.sec>.wrap>.cols2:not([data-rev])>div:last-child>figure:last-child{
  flex:1 1 auto;display:flex;flex-direction:column;min-height:0}
.sec>.wrap>.cols2:not([data-rev])>div:last-child>figure:last-child img{
  flex:1 1 auto;height:auto;min-height:220px;aspect-ratio:auto;object-fit:cover;
  max-height:var(--nh)}

/* --- LE BLOC PARTENAIRE : LA PHOTO SUIT SA COLONNE ------------------------
   Mesuré sur l'accueil : la photo de soudure sort à 472 x 422 (légende
   comprise) face à une colonne de texte de 803 px. Soit **381 px de blanc sous
   la photo, sur toutes les pages du site** — le bloc est partout. `align-items:
   start` était le bon réglage quand les deux colonnes étaient d'égale hauteur ;
   il ne l'est plus. La photo prend la hauteur de sa rangée et se recadre. */
.preuve-in{align-items:stretch}
.preuve-in>.shot{display:flex;flex-direction:column;min-height:0}
.preuve-in>.shot img{flex:1 1 auto;height:auto;min-height:300px;aspect-ratio:auto;
  object-fit:cover;max-height:var(--nh)}

/* --- LE RYTHME APRÈS UN BLOC ---------------------------------------------
   🔴 LA RÈGLE DE RYTHME NE CONNAISSAIT QUE LES BALISES QU'ELLE NOMMAIT.
   `.sec p+p,.sec p+ul,.sec ul+p…` : dès qu'un objet d'un AUTRE type se pose
   entre deux paragraphes — un tableau, une grille de postes, un `.cols2`
   empilé — la chaîne d'adjacence est rompue et le paragraphe suivant se colle
   au bloc, à MOINS DE 8 px. Relevé sur douze pages : 4 fois après un
   `.table-scroll`, 2 après `.steps`, 2 après `.postes`, 1 après un `.cols2`.
   Ça ne se voit pas au banc — il cherche des écarts TROP GRANDS — et ça se
   voit tout de suite à l'écran : deux blocs qui se touchent se lisent comme un
   seul. On raisonne donc par FAMILLE de balise, pas par liste de classes : ce
   qui suit un conteneur reprend le rythme de la prose. Les marges s'écrasent
   (`.ill` en porte déjà 26) — la plus grande gagne, rien ne se cumule. */
.sec>.wrap>:is(div,figure,nav,table,aside,form)+:is(p,ul,ol),
.article .wrap-art>:is(div,figure,nav,table,aside,form)+:is(p,ul,ol){margin-top:.95em}
/* `.postes` n'avait NI grille NI marge : quatre cartes de pourcentage empilées
   sur 387 px de haut, collées au paragraphe suivant. Deux pistes à la mesure,
   quatre dans une bande. */
.postes{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  gap:16px;margin-top:26px}
/* Et le `.cols2` empilé n'avait plus de marge basse : `>div>*:last-child
   {margin-bottom:0}` la retire, et c'était justement celle qui le séparait de
   la suite. Elle se remet sur le bloc, où elle ne peut plus disparaître. */
.sec>.wrap>.cols2[data-rev]{margin-bottom:26px}

/* --- L'AXE UNIQUE --------------------------------------------------------
   Tout enfant DIRECT d'un conteneur est borné à la mesure et centré. Les
   objets larges — grilles de cartes, tableaux, bandes — reprennent la pleine
   largeur du conteneur, centrés sur ce même axe. Deux largeurs, un seul axe.
   ⚠️ `min(var(--mes),100%)` évite une media query : sous la mesure, le bloc
   prend la largeur disponible et le centrage ne fait rien. */
.sec>.wrap>*,.article .wrap-art>*{
  max-width:min(var(--mes),100%);margin-left:auto;margin-right:auto}
/* CE QUI A LE DROIT DE DÉBORDER, et rien d'autre. Le tri ne se fait pas « par
   type de bloc » mais sur UNE question : de quelle largeur ce bloc a-t-il
   besoin pour que sa plus petite colonne reste lisible ?
     .stats   4 pistes -> 158 px à la mesure : illisible, il déborde
     .steps   4 pistes -> 150 px : il déborde
     .cols3   3 pistes -> 207 px : il déborde
     .cols2   2 pistes -> 323 px de PROSE, soit 38 caractères : il déborde
     .avis    auto-fit 310 -> 2 cartes de 324 px : il tient à la mesure
     .arts    2 pistes -> 324 px pour un titre et deux lignes : il tient
   ⚠️ C'est la correction du premier regard porté sur la nouvelle mise en page :
   le h2 « Ce que disent leurs clients » sortait à 384 px du bord pendant que
   ses deux cartes d'avis sortaient à 209 — un titre EN RETRAIT sur son propre
   contenu. Deux cartes n'ont jamais eu besoin de 1'022 px. */
/* 🔴 4e PASSE — ET LA LISTE S'EST OUVERTE. Une GRILLE DE CARTES est une bande,
   quelle que soit sa largeur idéale : si elle reste à la mesure pendant que sa
   voisine prend le conteneur, la page gagne un bord gauche de plus. Mesuré sur
   l'accueil : le titre passait de 194 px (« Comment ça marche ») à 345 (« De la
   question au chauffage neuf ») puis revenait à 194 (« Du bord du lac ») — une
   dent de scie sur six sections. `.stats`, `.cols4`, `.steps`, `.postes`,
   `.prestas`, `.avis`, `.arts` et `.faq-grid` rejoignent donc les bandes.
   ⚠️ ET C'EST LEUR ÉCHELLE QUI S'ADAPTE, PAS L'INVERSE : `.steps` passe de
   `minmax(260px)` à `minmax(228px)` pour sortir en 4 x 235 dans le conteneur au
   lieu de 3 pistes et une orpheline. */
/* 🔴 ET UNE BANDE NE DÉBORDE QUE DANS UNE SECTION QUI EN OUVRE UNE. C'est la
   deuxième moitié de la 4e passe, et c'est le contrôle n°3 du banc qui l'a
   imposée : sur `/prix-pompe-a-chaleur/`, `.stats`, `.table-scroll`, `.postes`
   et `.steps` sortaient à 208 px pendant que la prose de LEUR section sortait à
   380 — trois bords gauches isolés, nommés par le banc, à 1440 comme à 1920.
   Un bloc pleine largeur et un bloc centré à la mesure sont tous les deux
   SYMÉTRIQUES, et c'est exactement leur cohabitation qui fabrique le second
   bord (leçon de la 3e passe, écrite dans le n°3 lui-même). Donc : une section
   a UNE largeur et UN bord. Ou elle ouvre sur une bande, et tout s'y cale à
   gauche sur la bande ; ou elle est de la prose, et tout y prend la mesure —
   la bande arrivée au 12e enfant comprise. Les tableaux gardent leur
   `.table-scroll` : à la mesure, ils défilent au lieu de casser l'axe. */
/* et les grilles qui RENTRENT dans la mesure y rentrent pour de bon : leurs
   pistes deviennent élastiques, sinon quatre cartouches de 158 px se
   présentent comme quatre colonnes de deux mots. */
/* ⚠️ ET LE MINIMUM SE LIT SUR LE CONTENU, PAS SUR LA PLACE. Première valeur
   essayée : 142 px pour `.steps`. Les quatre étapes sortaient alors en quatre
   colonnes de deux mots — « 30 secondes en ligne. 3 questions, une fourchette
   honnête » sur douze lignes. Une étape porte une phrase entière : il lui faut
   une mesure de lecture, donc 2 x 326 et non 4 x 142. Les cartouches `.stats`,
   eux, ne portent qu'un nombre et trois mots : 158 px leur suffisent. */
/* 🔴 DEUX COLONNES DE PROSE, C'EST UNE CASSURE DE LECTURE, PAS UNE MISE EN
   PAGE. Sur `/climatisation/` et `/prix-pompe-a-chaleur/`, un `.cols2` portait
   deux paragraphes de 90 mots surmontés chacun d'un h3 : l'œil descend la
   colonne de gauche, remonte de 300 px pour prendre la droite, et les deux
   intertitres ne sont pas à la même hauteur. Le bloc sortait en plus à 1'022 px
   pendant que la prose autour sortait à 666 — le deuxième bord gauche, encore.
   ⚠️ LE TRI SE FAIT SUR `[data-rev]`, ET CE N'EST PAS UN HASARD : les `.cols2`
   des pages de LIEU sont écrits par `gen.py` sans cet attribut, ceux des pages
   de prestation et de guide par les `data_*.py` avec. Sur une page de lieu la
   grille est VOULUE (photo + intro à gauche, encadré cantonal + fiche à
   droite) : elle ne bouge pas. */
.sec>.wrap>.cols2[data-rev]{max-width:min(var(--mes),100%);grid-template-columns:1fr;gap:0}
.cols2[data-rev]>div>*:last-child{margin-bottom:0}
.cols2[data-rev]>div+div{margin-top:18px}

.stats,.cols4{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
.steps{grid-template-columns:repeat(auto-fit,minmax(228px,1fr))}
/* `.prestas` n'est PAS dans cette liste : il porte déjà son échelle complète
   plus bas (3 pistes au-dessus de 1080, 2 en dessous, 1 sur mobile), et à la
   mesure ses trois cartes font 208 px — regardé, c'est juste. Une règle qui
   ne gagne jamais est une règle morte : elle ne se laisse pas traîner. */
/* 🔴 UN TITRE NE SE MET PAS EN RETRAIT SUR SON PROPRE CONTENU. C'est le seul
   défaut que l'axe unique fabrique, et il se voit tout de suite : sur `/mies/`,
   le h2 « Votre projet à Mies » sortait à 384 px pendant que la grille qu'il
   annonce sortait à 209. Deux objets qui vont ensemble, décalés de 175 px.
   Dans une section qui porte une bande LARGE, le titre et le chapô s'alignent
   donc sur elle. Le chapô garde sa mesure — un chapô de 1'022 px de large ne se
   lit pas — mais il se cale à gauche au lieu de se centrer.
   ⚠️ D'où la variation de bord d'une section à l'autre, et elle est ASSUMÉE :
   une section à bande large est calée à gauche ET remplie jusqu'au bord droit
   par sa bande ; une section de prose pure est centrée, donc symétrique. Les
   deux se lisent comme une intention. Ce qui ne se lit pas comme une intention,
   c'est un titre décalé de 175 px sur ses propres cartes. */
/* ⚠️ ET C'EST *TOUT* L'ENFANT DIRECT QUI SE RECALE, PAS SEULEMENT LE TITRE.
   Première version : `h2` et `p` seulement. Les figures, les listes et les
   cartes d'avis de la même section restaient CENTRÉES à 384 px pendant que
   le titre passait à 209 — c'est-à-dire deux bords gauches DANS UNE MÊME
   SECTION, exactement le défaut qu'on voulait supprimer, et un cran pire
   que celui qu'on corrigeait. Le seul `h2` garde en plus `max-width:none` :
   un titre n'a pas de mesure de lecture, une prose oui. */
/* 🔴 4e PASSE — ET LA RECALIBRATION NE VAUT QUE SI LA BANDE *OUVRE* LA SECTION.
   La règle de la 3e passe se déclenchait sur la seule PRÉSENCE d'une bande, où
   qu'elle soit. Sur un guide, UN `.relance-mini` posé au 31e enfant d'un article
   de 6'741 px faisait basculer les 63 enfants à gauche : la colonne de 666 px
   se collait au bord et laissait **346 px de blanc sur toute la hauteur de la
   page**, d'un seul côté. C'est le défaut que l'utilisateur montre en capture
   depuis trois passes, et aucun des douze contrôles ne le voyait — ils mesurent
   des écarts entre objets, jamais le vide À CÔTÉ d'une colonne.
   Un titre n'est en retrait sur ses cartes que si les cartes SUIVENT le titre.
   La bande doit donc être dans l'OUVERTURE de la section — h2, chapô, bande —
   soit les quatre premiers enfants. Au-delà, la section est de la prose qui
   contient une bande : elle reste centrée, et la bande déborde des deux côtés.
   ⚠️ Le seuil est un RANG, pas une hauteur : c'est ce que l'œil lit. */
.sec>.wrap:has(>:is(.cols2:not([data-rev]),.cols3,.cols4,.stats,.steps,.postes,.prestas,
  .avis,.arts,.faq-grid,.chant,.chant-g,.communes-grid,.tbl-wrap,
  .table-scroll,.tbl,.row-img,.preuve-in,.relance,.hero-g,.ill-large):nth-child(-n+4))>*{margin-left:0;margin-right:auto}
.sec>.wrap:has(>:is(.cols2:not([data-rev]),.cols3,.cols4,.stats,.steps,.postes,.prestas,
  .avis,.arts,.faq-grid,.chant,.chant-g,.communes-grid,.tbl-wrap,
  .table-scroll,.tbl,.row-img,.preuve-in,.relance,.hero-g,.ill-large):nth-child(-n+4))>h2{max-width:none}
/* ⚠️ ET DANS CES SECTIONS-LÀ, UN BLOC BORNÉ PREND LA BANDE. Une prose calée à
   gauche laisse du blanc à sa droite, et c'est une marge — son bord droit est
   dentelé, l'œil ne le suit pas. Une BOÎTE, elle, a un bord droit net : posée à
   666 px sous un tableau de 1'012, elle se lit comme une colonne inachevée.
   Mesuré sur `/prix-pompe-a-chaleur/` : l'encadré « Un exemple, en entier » et
   la photo du module intérieur laissaient 308 px de vide sur 570 px de hauteur.
   La photo est bornée par son FICHIER (`--nw`, la largeur réelle x 1,05, le
   seuil du contrôle de netteté) : une image ne se tire jamais au-delà. */
.sec>.wrap:has(>:is(.cols2:not([data-rev]),.cols3,.cols4,.stats,.steps,.postes,.prestas,
  .avis,.arts,.faq-grid,.chant,.chant-g,.communes-grid,.tbl-wrap,
  .table-scroll,.tbl,.row-img,.preuve-in,.relance,.hero-g,.ill-large):nth-child(-n+4))>:is(.cols2,.cols3,.cols4,.stats,.steps,.postes,.prestas,
  .avis,.arts,.faq-grid,.chant,.chant-g,.communes-grid,.tbl-wrap,.table-scroll,
  .tbl,.row-img,.preuve-in,.relance,.hero-g,.ill-large,
  .encart,.liens-util,.faq-list){max-width:100%}
/* ⚠️ ET `figure` N'EST PAS DANS CETTE LISTE : `:is(...)` prend la spécificité
   d'une CLASSE (0,1,0), un sélecteur de TYPE ne pèse que (0,0,1). Mettre
   `figure` dans le `:is` faisait gagner `max-width:100%` sur la laisse
   `min(100%,var(--nw))` de la ligne suivante — et `chaudiere-mazout-2.webp`
   sortait à 1'012 px pour un fichier de 800, agrandi 1,26 fois. La règle qui
   borne une image doit être la PLUS SPÉCIFIQUE, sinon elle ne borne rien. */
.sec>.wrap:has(>:is(.cols2:not([data-rev]),.cols3,.cols4,.stats,.steps,.postes,.prestas,
  .avis,.arts,.faq-grid,.chant,.chant-g,.communes-grid,.tbl-wrap,
  .table-scroll,.tbl,.row-img,.preuve-in,.relance,.hero-g,.ill-large):nth-child(-n+4))>figure{max-width:min(100%,var(--nw,100%))}

/* et la liste de FAQ, qui portait un 820 px hérité du #16 : elle est de la
   prose, elle prend la mesure de la prose. */
.faq-list{max-width:min(var(--mes),100%)}
/* 🔴 LA FAQ DES PAGES DE LIEU ÉTAIT LE PLUS GROS TROU RESTANT, et c'est le
   contrôle n°8 corrigé qui l'a sorti — 204 à 223 px sur `/prangins/`,
   `/la-givrine/` et `/nyon/`. Le bloc est une grille `300px | 1fr` : une photo
   à gauche, les questions à droite. Sur une page de lieu il n'y a que DEUX
   questions — 292 px de liste face à 330 px de photo et de légende, donc un
   quart d'écran blanc en bas à droite. Et le h2 sortait à 398 px pendant que la
   grille sortait à 217 : le deuxième bord gauche, encore.
   La grille tombe. La photo et les questions s'empilent dans la colonne, à la
   mesure, sur le même axe que le titre. Une grille dont une piste est vide sur
   la moitié de sa hauteur n'est pas une grille, c'est un trou. */
/* ⚠️ 4e PASSE — LA MESURE RÉGLAIT L'AXE, PAS LE TROU. Le bloc revient à la
   bande (sinon la section est la seule de la page à ne pas y être), et le trou
   se traite là où il est vraiment : la piste de la photo passe de 300 à 260 px,
   et les deux pistes se centrent l'une sur l'autre. Une photo de 260 px fait
   195 px de haut ; deux questions à 700 px en font 140. Le reste — 55 px de
   part et d'autre — n'est plus un quart d'écran, c'est une respiration.
   ⚠️ Et l'empilement a été ESSAYÉ, puis abandonné en le REGARDANT : à la mesure,
   la photo du collecteur sort à 666 px de large et 500 px de haut au-dessus de
   deux questions — une affiche pour un bloc secondaire. Les deux pistes
   restent ; ce qui est corrigé, c'est la largeur du bloc et donc son axe. */
/* La colonne d'article revient à la largeur du conteneur commun : elle avait
   été poussée à 1000 px uniquement pour loger la gouttière. */
.article .wrap-art{width:min(1060px,100%);max-width:none}
/* ⚠️ `.art-retour` du #16 se recentrait tout seul (`width:min(1060px,100%)`
   + `margin:auto` + son propre `padding`) : dans une colonne d'article, il
   se retrouvait décalé de 124 px vers la droite, seul de son espèce. Il
   s'aligne sur la colonne qu'il termine. */
.article .art-retour{width:auto;padding-left:0;padding-right:0}

/* --- LES FIGURES DU CORPS -------------------------------------------------
   ⚠️ PIÈGE N°5 DU RÉSEAU : `overflow:hidden` sur une `<figure>` COUPE la
   légende. Le rayon est donc porté par l'image, jamais par la figure. */
.ill{margin:26px 0}
.ill img{width:100%;height:auto;border-radius:14px;box-shadow:var(--o1)}
.ill figcaption{margin-top:10px;font-size:12.5px;line-height:1.5;color:var(--mut)}
.ill-cr{color:var(--mut);opacity:.85}
.ill-lieu img{aspect-ratio:16/9;object-fit:cover}
.ill-large{max-width:none}
.fig-duo{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin:26px 0}
.fig-duo .ill{margin:0}
@media (max-width:640px){.fig-duo{grid-template-columns:1fr}}

/* Le titre d'une carte de prestation est lui aussi un `<h3>` : même raison,
   même apparence. Le filet décoratif des h3 de prose n'a rien à y faire. */
.presta-txt h3{font-family:var(--disp);font-weight:600;font-size:17px;letter-spacing:-.015em;
  color:#fff;margin:0 0 3px;line-height:1.25}
.presta-txt h3::before{display:none}

/* --- LES ÉTOILES D'UN AVIS ------------------------------------------------
   ⚠️ DEUX DÉFAUTS VUS À L'ÉCRAN, aucun visible au banc :
   ① `.et` portait un FOND de cinq étoiles en data-URI, hérité du #16 où il est
      le seul dessin — mais ici `etoiles()` pose DÉJÀ cinq SVG en ligne dedans.
      La page en dessinait donc DIX, superposées : cinq noires par-dessus cinq
      dorées, et seule la dernière dorée dépassait. Le fond part.
   ② les SVG en ligne suivent `currentColor`, qui vaut l'encre du bloc : les
      étoiles sortaient EN NOIR. Elles prennent la couleur qu'elles doivent
      avoir, et un contour plus sombre pour tenir sur fond clair. */
.et{background:none;display:inline-flex;gap:2px;width:auto;height:auto;
  color:#e0a72a;line-height:0;margin:0 0 13px}
.et svg{filter:drop-shadow(0 0 .4px rgba(122,71,7,.75))}

/* Six cartes de prestation dans une grille de QUATRE : la seconde rangée en
   portait deux et laissait la moitié de la ligne vide. Trois colonnes font
   3 × 2, et les vignettes y respirent mieux. */
@media (min-width:1080px){.prestas{grid-template-columns:repeat(3,1fr)}}

/* --- L'INDEX DES GUIDES : quatorze cartes, chacune avec sa photo -----------
   ⚠️ `overflow:hidden` va sur l'IMAGE, jamais sur la carte : sur une `<figure>`
   il coupe la légende (piège n°5 du réseau), et sur une carte il coupe le
   focus-ring du lien. */
.art-card{display:flex;flex-direction:column;padding:0;overflow:visible}
.art-card img{width:100%;aspect-ratio:16/9;object-fit:cover;border-radius:6px 6px 0 0}
.art-txt{display:block;padding:16px 18px 18px}
.art-txt h3{font-family:var(--disp);font-weight:600;font-size:17.5px;
  letter-spacing:-.015em;color:var(--enc);margin-bottom:6px;line-height:1.25}
.art-txt h3::before{display:none}
.art-txt span{display:block;font-size:13.5px;line-height:1.5;color:var(--enc2);margin-bottom:10px}
.art-txt i{font-style:normal;font-size:13.5px;font-weight:700;color:var(--bis);
  display:inline-flex;align-items:center;gap:6px}

/* --- LA FAQ ET SA PHOTO ---------------------------------------------------
   Le bloc FAQ pesait jusqu'à 800 mots sans un seul visuel. La figure se pose à
   GAUCHE des questions, en colonne : entre deux réponses, elle couperait la
   lecture au lieu de l'aérer. Elle passe au-dessus sous 900 px. */
.faq-grid{display:grid;grid-template-columns:260px minmax(0,1fr);gap:32px;align-items:stretch}
.faq-grid .ill{margin:0}
/* ⚠️ ET UNE PHOTO ÉTIRÉE SE BORNE PAR SON FICHIER, EN HAUTEUR AUSSI. Le
   contrôle de netteté ne regardait que la LARGEUR : `imi-soudure.webp` sortait
   à 472 x 735 px pour un fichier de 720 x 540, soit **x1,36 agrandi par la
   hauteur**, et le banc annonçait « 0 flou ». `--nh` est la même laisse que
   `--nw`, sur l'autre axe. Le blanc résiduel est le prix du fichier : il se
   règle en remplaçant la photo, pas en tirant dessus.
   🔴 ET LA PHOTO SUIT LA HAUTEUR DE LA LISTE, elle ne flotte pas dedans. Une
   piste de 260 px face à DIX questions laissait 150 px de blanc au-dessus ET
   en dessous d'une photo de 195 px ; face à DEUX, elle en laissait 130 d'un
   seul côté. Une hauteur fixe ne peut pas répondre aux deux. La photo prend
   donc la hauteur de sa rangée et se recadre — c'est le seul objet de la page
   dont le sujet supporte d'être coupé. Le plancher de 190 px protège le cas
   inverse : deux questions ne doivent pas produire une meurtrière. */
.faq-grid>.ill{display:flex;flex-direction:column;min-height:0}
.faq-grid>.ill img{flex:1 1 auto;height:auto;min-height:190px;aspect-ratio:auto;
  object-fit:cover;max-height:var(--nh)}
.ill-faq img{aspect-ratio:4/3;object-fit:cover}
@media (max-width:900px){
  .faq-grid{grid-template-columns:1fr;gap:20px}
  .faq-grid .ill{max-width:520px}
}

/* La figure de la colonne cantonale : elle vit dans une colonne étroite, donc
   elle se recadre en paysage large plutôt que de tirer la colonne en hauteur. */
.ill-canton{margin:18px 0 22px}
.ill-canton img{aspect-ratio:16/9;object-fit:cover}

/* ⚠️ UNE RESPIRATION N'EST PAS UNE OUVERTURE. Vues à l'écran, les respirations
   sortaient à 890 px de large, en 16/9 : trois « diapositives » séparées par
   quatre paragraphes courts, et le guide se lisait comme une galerie. Une
   respiration se pose DANS la colonne de texte, à 620 px, et en 3/2 — elle
   accompagne la lecture au lieu de l'interrompre. La photo d'OUVERTURE, elle,
   garde la pleine largeur : c'est son rôle. */
/* ⚠️ Et elles ne sont plus DÉCALÉES non plus. À la 2e passe elles étaient calées
   à gauche dans un conteneur de 1060 px, parce qu'à l'époque la colonne l'était
   aussi. Maintenant que TOUT est centré sur le même axe, une figure calée à
   gauche serait le seul objet de la page à ne pas l'être — c'est-à-dire le
   deuxième bord gauche que la 2e passe voulait éviter. Elle prend la mesure de
   lecture, exactement, et le même axe que le paragraphe qui la précède. */
.ill-resp{max-width:min(var(--mes),100%)}
/* ⚠️ LE RECADRAGE SE CHOISIT SUR LA HAUTEUR QU'IL COÛTE, pas sur le goût. À
   666 px de large : 4/3 = 500 px, 3/2 = 444, 16/9 = 375. Le 16/9 serait le plus
   calme, mais il retranche un quart de la hauteur d'un original en 4/3 — et sur
   ce jeu-là les originaux sont des GROS PLANS techniques (un compresseur, un
   collecteur, une plaque de remplissage). Un recadrage centré y coupe le sujet.
   Le 3/2 est le compromis mesuré : il retranche peu, et il tient la page. */
.ill-resp img{aspect-ratio:3/2;object-fit:cover}
/* La figure d'OUVERTURE prend la même largeur et le même recadrage que les
   autres. Elle gardait la pleine largeur du conteneur tant que la colonne était
   calée à gauche : une ouverture plus large qu'un texte CENTRÉ ne fait plus une
   ouverture, elle fait un deuxième bord. */
.sec>.wrap>figure.ill img,.article .wrap-art>figure.ill img{
  aspect-ratio:3/2;object-fit:cover}
.sec>.wrap>figure.ill-large img,.article .wrap-art>figure.ill-large img,
.chant-g img,.ill-lieu img,.ill-canton img{aspect-ratio:auto}
.ill-lieu img,.ill-canton img{aspect-ratio:16/9}
.chant-g img{aspect-ratio:4/3}

/* --- « Leurs chantiers », sur l'accueil ----------------------------------
   `.sec-chantiers` n'est pas décoratif : c'est le marqueur qui permet à
   `lourdeur.py` de reconnaître cette bande comme du GABARIT et de ne pas la
   compter comme quatre visuels que la page ne possède pas. */
.sec-chantiers{padding-top:0}
.chant{margin-top:30px}
.chant-t{font-family:var(--disp);font-weight:600;font-size:19px;margin-bottom:14px}
.chant-g{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
.chant-g .ill{margin:0}
.chant-g img{aspect-ratio:4/3;object-fit:cover}
.chant-g figcaption{font-size:12px}
.chant-src{margin-top:14px;font-size:12.5px;line-height:1.5;color:var(--mut)}
@media (max-width:900px){.chant-g{grid-template-columns:repeat(2,1fr)}}
@media (max-width:520px){.chant-g{grid-template-columns:1fr}}

/* --- LES CINQ CLASSES QUE LE RETRAIT DES BLOCS DU #16 A LAISSÉES NUES -----
   `.part-id-h` vivait DANS le bloc « témoin de réseau » que ce script supprime :
   en le retirant on a déshabillé le bloc partenaire, dont le logo se serait
   retrouvé centré au-dessus du nom. `.carte-t` n'existait que dans la maquette.
   Les trois autres sont propres à ce site. */
.carte-t{font-family:var(--disp);font-weight:600;font-size:22px;letter-spacing:-.02em;
  color:var(--enc);margin-bottom:2px}
.ck{flex:0 0 auto;vertical-align:-2px}
.imi{min-width:0}
.sec-avis .lead{margin-bottom:20px}
/* ⚠️ `.part-id` est en `flex-direction:column` avec un filet à droite : sans
   remettre la direction ET le filet à zéro, la variante en ligne hérite de la
   colonne et le logo se centre au-dessus du nom. */
.part-id-h{display:flex;flex-direction:row;align-items:center;gap:16px;
  margin-bottom:16px;padding:0;border:0}
.part-id-h img{width:76px;height:76px;object-fit:contain;flex:0 0 auto}
.part-id-h .part-nap b{display:block;font-family:var(--disp);font-weight:600;font-size:21px;
  letter-spacing:-.025em;color:var(--enc);margin-bottom:3px}

/* --- divers gabarit ------------------------------------------------------ */
/* L'ancre de la carte de devis. Elle vivait sur `.card-in`, une classe posée sur
   le FORMULAIRE alors que l'ancre `#devis` est sur son enveloppe : le saut
   s'arrêtait donc sous l'en-tête collant. */
#devis{scroll-margin-top:96px}

.liens-util{margin-top:22px;padding:13px 16px;background:var(--creme);
  border:1px solid var(--line);border-radius:12px;font-size:14px;line-height:1.7}
.liens-util b{color:var(--enc)}
/* ⚠️ MESURÉ AU COMPOSITE : `--amb-t` donne 4,57:1 sur du BLANC, mais l'encadré
   est sur `--creme` — et les quatre liens y tombaient à 4,46:1, sous AA. Trois
   centièmes : c'est exactement le genre d'écart qu'un calcul sur les jetons ne
   voit jamais, et qu'un contrôle qui compose les calques voit tout de suite. */
.liens-util a{color:var(--bis)}
.promesse{font-size:12.5px;line-height:1.5;color:var(--mut);text-align:center;margin-top:10px}
.hach{background-image:repeating-linear-gradient(45deg,rgba(70,60,47,.30) 0 2px,transparent 2px 6px)}

/* ⚠️ PIÈGE N°2 DU RÉSEAU : sous `display:contents`, TOUT enfant de la colonne du
   hero porte un `order` explicite. Celui qui n'en a pas vaut 0 et passe DEVANT —
   sur le #19 la carte de devis tombait ainsi à 1149 px sur un écran de 320. */
@media (max-width:1080px){
  .tel-bloc{order:9;margin-top:16px}
  .warn-col{order:11}
}
