/* ============================================================
   COREPLUMB — identite visuelle du template (coquille vide)
   AUCUNE couleur en dur ici hors voiles neutres. Uniquement les
   8 roles injectes par render.mjs dans :root.
   Roles : --marque --accent --fond --fond-2 --texte
           --texte-doux --bordure --sur-marque

   ADN releve a l'ingestion (src/app/globals.css + skin/primitives) :
   rayon de carte 24, pilule 10, conteneur 1280, section 100/64,
   titres tres serres (-.04em, interligne .96), eyebrow .14em,
   hero plein cadre a degrade lateral + carte laterale 420,
   cartes bordees a image 160, chips bordees, FAQ details/summary
   a "+" qui pivote, bande CTA sombre a lueur radiale.
   ============================================================ */

:root {
  --r-card: 24px;
  --r-img: 14px;
  --r-pill: 10px;
  --f-titre: "Plus Jakarta Sans", system-ui, sans-serif;
  --f-texte: "Inter", system-ui, sans-serif;
  --pad-section: 100px;
  --max: 1280px;
  --ombre: 0 30px 70px rgba(0, 0, 0, .10);
  --ombre-legere: 0 10px 30px rgba(0, 0, 0, .06);
}

* { box-sizing: border-box; }
html { scroll-behavior: auto; } /* auto, jamais smooth : le gate mesure sur une page qui doit etre immobile (defilement anime = boites relevees a un offset, capture a un autre) */
body {
  margin: 0;
  font-family: var(--f-texte);
  color: var(--texte);
  background: var(--fond);
  font-size: 17px;
  line-height: 1.65;
  overflow-x: hidden;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

/* ---------- primitives ---------- */
.co-wrap { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 28px; }
.sec { padding: var(--pad-section) 0; }
.sec--alt { background: var(--fond-2); }
.sec--fonce { background: var(--accent); color: var(--sur-marque); }
.sec--fonce h2, .sec--fonce h3 { color: var(--sur-marque); }
.sec--fonce .body { color: rgba(255, 255, 255, .70); }

.eyebrow {
  font-family: var(--f-titre);
  font-size: 13px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--marque); margin: 0 0 16px;
}
.eyebrow--tiret { display: inline-flex; align-items: center; gap: 12px; }
.eyebrow--tiret::before { content: ""; width: 28px; height: 2px; background: var(--marque); }

h1, h2, h3, h4 { font-family: var(--f-titre); font-weight: 800; margin: 0; }
h1 { font-size: clamp(34px, 4.4vw, 54px); line-height: .98; letter-spacing: -.04em; }
h2 { font-size: clamp(28px, 3vw, 40px); line-height: 1.06; letter-spacing: -.03em; }

/* La balise dit le plan du document, la taille dit la mise en page. Quand une
   page n ouvre sur aucun titre de premier rang, le moteur promeut le premier
   titre de sa section de tete : il change de balise, il ne doit pas changer de
   corps. Sans cette regle, un titre de section double de taille et vient
   recouvrir l etiquette posee au-dessus de lui. */
h1[data-rang="2"] { font-size: clamp(28px, 3vw, 40px); }
h3 { font-size: 22px; line-height: 1.24; letter-spacing: -.02em; font-weight: 700; }
h4 { font-size: 16px; letter-spacing: -.01em; }
.h-accent { color: var(--marque); }
.body { color: var(--texte-doux); margin: 0; }
.body--just { text-align: justify; }

.btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 12px 20px;
  background: var(--marque); color: var(--sur-marque);
  border-radius: var(--r-pill);
  font-family: var(--f-titre); font-weight: 700;
  font-size: 15px; letter-spacing: -.01em;
  border: 0; cursor: pointer;
  transition: background .18s ease, transform .18s ease;
}
.btn:hover { transform: translateY(-1px); }
.btn__arrow { transition: transform .18s ease; }
.btn:hover .btn__arrow { transform: translate(3px, -3px); }
.btn--clair { background: var(--fond); color: var(--marque); }
.btn--fantome { background: transparent; color: var(--texte); border: 1px solid var(--bordure); }
/* La porte d'appel posee a cote d'un bouton d'envoi tombe souvent sur un
   panneau sombre : elle se dessine donc CREUSE, a l'encre du panneau, pour
   ne pas s'y perdre ni voler la primaute au bouton d'envoi. */
.btn--creux { background: transparent; color: inherit; border: 1px solid currentColor; }

.carte {
  background: var(--fond);
  border: 1px solid var(--bordure);
  border-radius: var(--r-card);
  padding: 30px;
}
.carte--plein { background: var(--fond-2); border-color: transparent; }
.carte--ombre { box-shadow: var(--ombre-legere); }

.icone {
  width: 46px; height: 46px; border-radius: 12px;
  background: var(--marque); color: var(--sur-marque);
  display: grid; place-items: center; font-size: 19px; flex: none;
}
.icone--douce { background: var(--fond-2); color: var(--marque); }
.filet { height: 1px; background: var(--bordure); border: 0; margin: 22px 0; }

.chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px; border-radius: var(--r-pill);
  border: 1px solid var(--bordure); background: var(--fond);
  font-size: 14px; font-weight: 600; color: var(--texte);
  max-width: 100%; overflow-wrap: anywhere;
}
.chip__point { width: 7px; height: 7px; border-radius: 50%; background: var(--marque); flex: none; }
.chips { display: flex; flex-wrap: wrap; gap: 10px; }

.puces { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; color: var(--texte-doux); font-size: 16px; }
.puces li { display: flex; gap: 10px; align-items: flex-start; }
.puces li::before { content: "\2713"; color: var(--marque); font-weight: 800; flex: none; }

/* cadre image : la coquille n'embarque aucun visuel, seulement le cadre */
.frame {
  position: relative;
  border-radius: var(--r-img);
  overflow: hidden;
  background:
    repeating-linear-gradient(135deg, transparent 0 12px, rgba(0, 0, 0, .035) 12px 24px),
    var(--fond-2);
  display: grid; place-items: center;
  color: var(--texte-doux);
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  text-align: center; padding: 18px;
  min-height: 190px;
}
/* R5a — la photo ne commande JAMAIS la hauteur du cadre. Posee dans le flux,
   sa hauteur intrinseque pousse la boite et mange le ratio que le cadre
   declare : le cadre annonce 1.4 et rend 0.68 des que l epreuve pleine
   arrive. Hors flux en `inset: 0`, la forme reste celle du CADRE, a vide
   comme a plein — c est le gabarit qui tient la forme, pas la donnee. */
.frame img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* ---------- grilles a nombre variable ----------
   Le nombre de cartes n'est JAMAIS fixe par le template : il vient des
   donnees. Mais le nombre de PISTES, lui, est toujours compte (R3) : une
   base en pourcentage plus un `flex-grow` laissait la derniere rangee
   s'etirer, et deux cartes de la meme grille finissaient a 395 et 602 px.
   `minmax(0, 1fr)` rend la piste compressible sans jamais la deformer. */
.g2, .g3, .g4 { display: grid; gap: 20px; align-items: stretch; }
.g2 > *, .g3 > *, .g4 > * { min-width: 0; }
.g2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.tete { max-width: 720px; margin: 0 0 44px; }
.tete--centre { margin: 0 auto 44px; text-align: center; }
.tete--large { max-width: 900px; }

/* ---------- header : barre pleine, pas de pilule flottante ---------- */
.hd {
  position: sticky; top: 0; z-index: 50;
  background: var(--fond); border-bottom: 1px solid var(--bordure);
}
.hd__inner {
  max-width: var(--max); margin: 0 auto; padding: 14px 28px;
  display: flex; align-items: center; gap: 32px;
}
.hd__logo { display: flex; align-items: center; gap: 11px; font-family: var(--f-titre); font-weight: 800; font-size: 21px; letter-spacing: -.03em; }
.hd__mark { width: 30px; height: 30px; border-radius: 9px; object-fit: cover; background: #fff; display: inline-block; flex: none; }
.hd__nav { display: flex; gap: 26px; margin-left: auto; font-size: 15px; font-weight: 600; }
.hd__nav a:hover, .hd__nav a.is-active { color: var(--marque); }
.hd__cta { flex: none; display: flex; align-items: center; gap: 10px; }
.hd__cta .btn { white-space: nowrap; }
/* Commande de menu : absente au bureau, elle remplace la nav sous 980px. */
.hd__bascule { display: none; margin-left: auto; width: 40px; height: 40px; padding: 0;
  border: 1px solid var(--bordure); border-radius: 10px; background: var(--fond);
  cursor: pointer; flex-direction: column; align-items: center; justify-content: center; gap: 5px; }
.hd__bascule i { display: block; width: 17px; height: 2px; border-radius: 2px; background: var(--texte); transition: transform .18s ease, opacity .18s ease; }
.hd--ouvert .hd__bascule i:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.hd--ouvert .hd__bascule i:nth-child(2) { opacity: 0; }
.hd--ouvert .hd__bascule i:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.drop { position: relative; }
.drop__tete { display: inline-flex; align-items: center; gap: 6px; }
.drop__chev { font-size: 10px; transition: transform .18s ease; }
.drop:hover .drop__chev { transform: rotate(180deg); }
/* Le volet est CENTRE sous sa tete : cale a gauche, un panneau large deborde
   la fenetre des que l entree est du cote droit de la barre. */
.drop__panneau { position: absolute; top: 100%; left: 50%; transform: translateX(-50%); padding-top: 18px; opacity: 0; visibility: hidden; transition: opacity .18s ease; z-index: 40; }
.drop:hover .drop__panneau, .drop:focus-within .drop__panneau { opacity: 1; visibility: visible; }
.drop__grille {
  background: var(--fond); border: 1px solid var(--bordure); border-radius: var(--r-card);
  box-shadow: var(--ombre); padding: 26px 30px;
  display: flex; align-items: flex-start; gap: 36px; white-space: nowrap;
  min-width: 620px; max-width: min(94vw, 900px);
}
/* Les colonnes gardent leur largeur naturelle : un `min-width: 0` ici
   ecraserait les libelles les uns sur les autres, le nowrap les faisant
   deborder de leur colonne. */
.drop__cols { display: flex; align-items: flex-start; gap: 36px; flex: 0 1 auto; }
.drop__col { display: grid; gap: 3px; align-content: start; flex: 0 0 auto; }
/* La vitrine : la carte coreplumb en reduction, filet compris. Son visuel a
   une hauteur FIXE, sinon le `min-height` du cadre etire tout le volet.
   `flex: 0 0` et non `0 1` : une base compressible reduirait la vitrine a un
   mot par ligne des que les colonnes s allongent. */
.drop__vit { flex: 0 0 250px; display: grid; gap: 8px; align-content: start; white-space: normal; }
.drop__vitPh { min-height: 0; height: 130px; width: 100%; border-radius: var(--r-card); }
.drop__vitN { font-size: 16px; line-height: 1.3; }
.drop__vitX { font-size: 14px; color: var(--texte-doux); line-height: 1.5; }
.drop__vitZ { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; color: var(--marque); }
.drop__titre { font-family: var(--f-titre); font-size: 11px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--marque); }
.drop__lien { display: flex; align-items: center; gap: 10px; padding: 6px 0; font-size: 15px; }
.drop__lien:hover { color: var(--marque); }

/* ---------- affiche : un aplat, le mot a gauche, la case a droite ----------
   Le releve du modele ne montre aucune scene pleine fenetre : un aplat sur
   toute la premiere fenetre, le mot dans les colonnes de gauche, une case de
   matiere dans les colonnes de droite, tendue sur la meme rangee. L'aplat est
   donc porte par la SECTION : l'encre claire repose sur une couleur de
   palette, jamais sur le cadre, et l'etat vide reste lisible (R4b).
   Les pistes de la rangee sont COMPTEES (R3) : douze au-dessus du palier,
   une seule en dessous. La case n'a pas de forme a elle au-dessus du palier
   (R5d) : elle est tendue sur la hauteur de la rangee, son bas s'aligne sur
   celui du mot, elle ne declare aucun aspect-ratio et tient un plancher.
   Sous le palier la rangee se replie et la case reprend la forme declaree
   dans slots.json (ratioReplie) — le plancher du grand ecran tombe alors,
   sinon il l'emporterait sur la forme repliee. */
.hero { position: relative; overflow: hidden; background: var(--marque); color: var(--sur-marque); }
.hero__inner {
  position: relative; z-index: 2;
  max-width: var(--max); margin: 0 auto; padding: 80px 28px 80px;
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: 24px; row-gap: 36px; align-items: stretch;
}
.hero__txt {
  grid-column: 1 / span 5; min-width: 0;
  display: flex; flex-direction: column; justify-content: center;
}
.hero__case { grid-column: 8 / span 5; min-width: 0; display: flex; }
.hero__case .frame {
  width: 100%; height: 100%; min-height: 600px;
  border-radius: var(--r-card);
}
.hero__pill {
  display: inline-flex; align-self: flex-start; align-items: center; gap: 10px;
  padding: 8px 16px; margin-bottom: 22px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .16);
  border: 1px solid rgba(255, 255, 255, .28);
  font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
}
.hero h1 { color: var(--sur-marque); }
.hero__sous { color: rgba(255, 255, 255, .82); margin: 20px 0 30px; font-size: 18px; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 12px; }

/* ---------- le bandeau d'atouts, pose SOUS l'affiche ----------
   Au flanc du titre il coutait deux fois : il ecrivait du texte dans les
   colonnes que le releve donne a la matiere, et il etirait l'affiche au-dela
   d'un ecran. Descendu, il prend un sol a lui — sans quoi ses briques, dessinees
   pour du verre depoli sur une photo, deviennent blanc sur blanc. */
.hero-atouts { background: var(--fond-2); padding: 44px 0 48px; }
.hero-atouts__g {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px;
  align-items: stretch;
}
.hero__atout {
  display: flex; gap: 14px; align-items: flex-start; min-width: 0;
  background: var(--fond); color: var(--texte);
  border: 1px solid var(--bordure); border-radius: var(--r-card);
  padding: 22px;
}
.hero__atout h4 { margin-bottom: 4px; }
.hero__atout p { margin: 0; color: var(--texte-doux); font-size: 15px; }

/* ---------- cartes services : bordees, image 160 ---------- */
.svc {
  display: flex; flex-direction: column;
  background: var(--fond); border: 1px solid var(--bordure);
  border-radius: var(--r-card); padding: 18px;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.svc:hover { border-color: var(--marque); box-shadow: var(--ombre-legere); }
.svc .frame { height: 160px; min-height: 160px; margin-bottom: 18px; }
.svc__corps { padding: 0 6px 6px; display: flex; flex-direction: column; flex: 1; }
.svc h3 { margin-bottom: 10px; }
.svc__lien { margin-top: auto; padding-top: 18px; display: inline-flex; align-items: center; gap: 8px; font-family: var(--f-titre); font-weight: 700; font-size: 15px; color: var(--marque); }
.svc__fleche { transition: transform .18s ease; }
.svc:hover .svc__fleche { transform: translateX(5px); }

/* ---------- duo (intro, expertise, faq, certifications) ---------- */
.duo { display: flex; flex-wrap: wrap; gap: 56px; align-items: flex-start; }
.duo > * { flex: 1 1 380px; min-width: 0; }

/* ---------- blocs SEO alternes texte + image ---------- */
.bloc { display: flex; flex-wrap: wrap; gap: 50px; align-items: center; }
.bloc > * { flex: 1 1 380px; min-width: 0; }
.bloc__frame { min-height: 420px; border-radius: var(--r-card); }
.bloc--inv .bloc__frame { order: 2; }

.feats { display: flex; flex-wrap: wrap; gap: 24px; margin: 28px 0; }
.feat { flex: 1 1 45%; min-width: min(100%, 220px); display: flex; gap: 14px; align-items: flex-start; }
.feat h3 { font-size: 18px; }
.feat p { margin: 6px 0 0; color: var(--texte-doux); font-size: 15px; }

/* ---------- marques (bandeau defilant) ---------- */
.marquee { background: var(--fond-2); padding: 30px 0; overflow: hidden; }
.marquee__track { display: flex; gap: 60px; align-items: center; white-space: nowrap; animation: defile 40s linear infinite; }
.marquee__item { font-family: var(--f-titre); font-weight: 800; font-size: 19px; letter-spacing: -.02em; color: var(--texte-doux); flex: none; opacity: .75; }
@keyframes defile { to { transform: translateX(-50%); } }

/* ---------- secteurs B2B : rangees alternees ---------- */
.b2b { display: flex; flex-wrap: wrap; gap: 24px; align-items: stretch; margin-bottom: 24px; }
.b2b > * { min-width: 0; }
/* base en % + garde-fou en px : sans le second, l'element ne repasse jamais
   a la ligne et pousse le document a scroller sur les petites largeurs. */
.b2b__carte { flex: 1 1 55%; min-width: min(100%, 320px); background: var(--fond); border: 1px solid var(--bordure); border-radius: var(--r-card); padding: 34px; display: flex; flex-direction: column; }
.b2b .frame { flex: 1 1 35%; min-width: min(100%, 260px); min-height: 300px; border-radius: var(--r-card); }
.b2b--inv .frame { order: -1; }
.b2b__haut { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.b2b__num { font-family: var(--f-titre); font-weight: 800; font-size: 15px; letter-spacing: .1em; text-transform: uppercase; color: var(--marque); }
.rond {
  width: 40px; height: 40px; border-radius: 50%; flex: none;
  background: var(--marque); color: var(--sur-marque);
  display: grid; place-items: center; font-size: 17px;
}

/* ---------- zones : chips + bandeau d'images ---------- */
.zones { display: flex; flex-wrap: wrap; gap: 12px; }
.zone-chip {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 13px 20px; border-radius: var(--r-pill);
  border: 1px solid var(--bordure); background: var(--fond);
  font-family: var(--f-titre); font-weight: 700; font-size: 15px;
  transition: border-color .18s ease, color .18s ease;
}
.zone-chip:hover { border-color: var(--marque); color: var(--marque); }
.zone-chip span { font-weight: 500; font-size: 13px; color: var(--texte-doux); }
.zone-bande { display: flex; flex-wrap: wrap; gap: 20px; margin-top: 36px; }
.zone-bande .frame { flex: 1 1 30%; min-width: min(100%, 240px); height: 190px; min-height: 190px; border-radius: var(--r-card); }

/* ---------- process : etapes numerotees reliees ---------- */
.etapes { display: flex; flex-wrap: wrap; gap: 24px; }
.etape { flex: 1 1 22%; min-width: min(100%, 220px); position: relative; padding-top: 26px; }
.etape::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: var(--bordure); }
.etape::after { content: ""; position: absolute; top: -4px; left: 0; width: 10px; height: 10px; border-radius: 50%; background: var(--marque); }
.etape__num { font-family: var(--f-titre); font-weight: 800; font-size: 13px; letter-spacing: .14em; color: var(--marque); margin-bottom: 10px; }
.etape h3 { margin-bottom: 8px; }

/* ---------- chiffres : bande bordee ---------- */
.chiffres { position: relative; border-radius: var(--r-card); overflow: hidden; }
.chiffres .frame { min-height: 420px; border-radius: 0; }
.chiffres__bande {
  display: flex; flex-wrap: wrap;
  border: 1px solid var(--bordure); border-radius: var(--r-card);
  background: var(--fond); margin-top: -70px; position: relative; z-index: 2;
  width: calc(100% - 60px); margin-left: auto; margin-right: auto;
  box-shadow: var(--ombre);
}
.chiffre { flex: 1 1 22%; min-width: min(100%, 160px); padding: 26px 30px; border-left: 1px solid var(--bordure); }
.chiffre:first-child { border-left: 0; }
.chiffre b { display: block; font-family: var(--f-titre); font-weight: 800; font-size: 38px; line-height: 1; letter-spacing: -.03em; color: var(--marque); }
.chiffre span { font-size: 14px; color: var(--texte-doux); }

/* ---------- tarifs : bande bordee a colonnes ----------
   Meme idiome que la bande de chiffres (un seul panneau, colonnes separees
   par un filet), et non trois cartes posees cote a cote : c'est la facon
   dont la reference aligne des valeurs comparables. */
.tar { display: flex; flex-wrap: wrap; border: 1px solid var(--bordure); border-radius: var(--r-card); background: var(--fond); box-shadow: var(--ombre); overflow: hidden; }
.tar__c { flex: 1 1 30%; min-width: min(100%, 260px); padding: 34px 32px; border-left: 1px solid var(--bordure); display: flex; flex-direction: column; }
.tar__c:first-child { border-left: 0; }
.tar__p { font-family: var(--f-titre); font-weight: 800; font-size: 40px; line-height: 1; letter-spacing: -.03em; color: var(--marque); margin: 6px 0 0; }
.tar__u { display: block; font-size: 14px; color: var(--texte-doux); margin-top: 8px; }
.tar__c h3 { margin: 22px 0 0; }
.tar__x { margin-top: auto; padding-top: 24px; }

/* ---------- carte ultralocale ---------- */
.loc { display: flex; flex-wrap: wrap; gap: 24px; align-items: stretch; }
.loc > * { min-width: 0; }
.loc .frame { flex: 1 1 55%; min-width: min(100%, 300px); min-height: 380px; border-radius: var(--r-card); }
.loc__carte { flex: 1 1 32%; min-width: min(100%, 280px); background: var(--fond); border: 1px solid var(--bordure); border-radius: var(--r-card); padding: 32px; }
.loc__carte p { margin: 0 0 8px; }

/* ---------- avis ---------- */
.avis { display: flex; flex-direction: column; background: var(--fond); border: 1px solid var(--bordure); border-radius: var(--r-card); padding: 30px; }
.avis__etoiles { color: var(--marque); letter-spacing: 3px; font-size: 16px; margin-bottom: 14px; }
.avis__texte { color: var(--texte-doux); margin: 0 0 24px; }
.avis__pied { display: flex; align-items: center; gap: 14px; margin-top: auto; padding-top: 20px; border-top: 1px solid var(--bordure); }
.avis__av { width: 44px; height: 44px; border-radius: 50%; flex: none; background: var(--marque); color: var(--sur-marque); display: grid; place-items: center; font-family: var(--f-titre); font-weight: 800; font-size: 17px; }
.avis__nom { font-family: var(--f-titre); font-weight: 700; font-size: 15px; }
.avis__role { color: var(--texte-doux); font-size: 14px; }

/* ---------- faq : details/summary, "+" qui pivote, sans JS ---------- */
.faq { display: grid; gap: 12px; }
.faq-item { border: 1px solid var(--bordure); border-radius: var(--r-card); background: var(--fond); padding: 4px 26px; }
.faq-item summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: 20px;
  padding: 22px 0;
  font-family: var(--f-titre); font-weight: 700; font-size: 18px; letter-spacing: -.02em;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+"; margin-left: auto; flex: none;
  width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid var(--bordure); color: var(--marque);
  display: grid; place-items: center; font-size: 19px; font-weight: 400;
  transition: transform .2s ease, background .2s ease, color .2s ease;
}
.faq-item[open] summary::after { transform: rotate(45deg); background: var(--marque); color: var(--sur-marque); border-color: var(--marque); }
.faq-item p { color: var(--texte-doux); margin: 0 0 22px; padding-right: 52px; }

/* ---------- cartes lien (maillage, realisations, blog) ---------- */
.lien-card { display: flex; flex-direction: column; background: var(--fond); border: 1px solid var(--bordure); border-radius: var(--r-card); overflow: hidden; }
.lien-card:hover { border-color: var(--marque); }
.lien-card .frame { border-radius: 0; height: 190px; min-height: 190px; }
.lien-card__corps { padding: 26px; display: flex; flex-direction: column; gap: 10px; }
.lien-card__meta { font-family: var(--f-titre); font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--marque); }

/* ---------- bande CTA sombre a lueur radiale ---------- */
.cta {
  position: relative; overflow: hidden;
  border-radius: var(--r-card); padding: 60px;
  background: var(--accent); color: var(--sur-marque);
  display: flex; flex-wrap: wrap; gap: 48px; align-items: center;
}
.cta > * { position: relative; z-index: 2; flex: 1 1 380px; min-width: 0; }
.cta__bg { position: absolute; inset: 0; z-index: 0; }
.cta__bg .frame { height: 100%; min-height: 0; border-radius: 0; opacity: .35; }
.cta__voile { position: absolute; inset: 0; z-index: 1; background: linear-gradient(120deg, color-mix(in srgb, var(--accent) 94%, transparent), color-mix(in srgb, var(--accent) 68%, transparent)); }
.cta__lueur { position: absolute; inset: 0; z-index: 1; background: radial-gradient(60% 80% at 20% 20%, color-mix(in srgb, var(--marque) 70%, transparent), transparent 70%); opacity: .3; }
.cta h2 { color: var(--sur-marque); }
.cta .body { color: rgba(255, 255, 255, .74); }
.cta__form { display: grid; gap: 10px; }
.cta__form input, .cta__form textarea {
  padding: 14px 18px; border-radius: var(--r-pill); border: 0;
  font-family: var(--f-texte); font-size: 16px; width: 100%;
}
.cta__form textarea { resize: vertical; }

/* ---------- urgence ---------- */
/* Colonne centree etroite, jamais un duo texte / carte cote a cote. */
.urgence { max-width: 680px; margin-inline: auto; text-align: center; border: 1px solid var(--bordure); border-radius: var(--r-card); padding: clamp(28px, 4vw, 52px); background: var(--fond-2); }
.urgence h2 { margin-top: 6px; }
/* Pilule bordee a pastille flechee : l'entete de preuve du hero. */
.urgence__pilule { display: inline-flex; align-items: center; gap: 12px; padding: 6px 6px 6px 16px; border-radius: var(--r-pill); border: 1px solid var(--bordure); background: var(--fond); font-family: var(--f-titre); font-size: 13px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--marque); }
.urgence__pastille { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: var(--r-pill); background: var(--marque); color: var(--sur-marque); font-style: normal; font-size: 12px; }
.urgence__chapo { max-width: 520px; margin: 16px auto 0; }
.urgence__tel { display: inline-block; margin-top: 26px; font-family: var(--f-titre); font-weight: 800; font-size: clamp(30px, 4.6vw, 56px); line-height: 1; letter-spacing: -.04em; color: var(--marque); overflow-wrap: anywhere; }
/* Rangee de preuves a grands ecarts, centree : la bande de chiffres de
   TrustFeatures.tsx, reduite a du texte separe par une puce. */
.urgence__preuves { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 34px; margin-top: 22px; }
.urgence__preuves > * { min-width: 0; }
.urgence__preuve { position: relative; font-size: 14px; color: var(--texte-doux); }
.urgence__preuve + .urgence__preuve::before { content: "•"; position: absolute; left: -19px; opacity: .5; }
.urgence__act { margin-top: 28px; }

/* ---------- formulaire contact ---------- */
.contact { display: flex; flex-wrap: wrap; gap: 24px; align-items: flex-start; }
.contact > * { min-width: 0; }
.contact__form { flex: 1 1 55%; min-width: min(100%, 320px); }
.contact__col { flex: 1 1 32%; min-width: min(100%, 280px); display: grid; gap: 16px; }
/* R3 — pistes COMPTEES : en rangee flexible, un nombre impair de champs
   laissait le dernier s etirer sur toute la largeur (331/331 puis 679), soit
   deux largeurs pour une meme fratrie. Deux pistes egales, et ce qui doit
   traverser le declare. */
.champs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin-top: 24px; }
.champs > * { min-width: 0; }
.champ { display: grid; gap: 7px; font-size: 14px; color: var(--texte-doux); }
.champ--long, .champs > .champs__pied { grid-column: 1 / -1; }
.champs__pied { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.champ input, .champ textarea {
  padding: 13px 16px; border-radius: var(--r-pill); border: 1px solid var(--bordure);
  background: var(--fond); font-family: var(--f-texte); font-size: 16px; color: var(--texte); resize: vertical; width: 100%;
}
.champ input:focus, .champ textarea:focus { outline: 2px solid var(--marque); outline-offset: 1px; }

/* ---------- article ---------- */
.art__hero { min-height: 420px; border-radius: var(--r-card); margin-bottom: 50px; }
.art { display: flex; flex-wrap: wrap; gap: 50px; align-items: flex-start; }
.art__som { flex: 1 1 280px; min-width: 0; position: sticky; top: 100px; }
.art__som .puces li::before { content: "\2192"; }
.art__som a:hover { color: var(--marque); }
.art__corps { flex: 3 1 560px; min-width: 0; max-width: 780px; }

/* ---------- corps legal ---------- */
.legal { display: grid; gap: 16px; }
.legal__bloc { background: var(--fond); border: 1px solid var(--bordure); border-radius: var(--r-card); padding: 32px 36px; }

/* ---------- fil d'ariane ---------- */
.fil { font-size: 14px; color: var(--texte-doux); padding: 26px 0 0; }
.fil a:hover { color: var(--marque); }

/* ---------- footer ---------- */
.footer { background: var(--accent); color: var(--sur-marque); padding: 76px 0 26px; }
.footer h4 { font-size: 14px; letter-spacing: .12em; text-transform: uppercase; margin-bottom: 22px; color: var(--sur-marque); }
.footer a, .footer li, .footer .body { color: rgba(255, 255, 255, .68); }
.footer a:hover { color: var(--sur-marque); }
.footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; font-size: 15px; }
.footer__marque { display: flex; align-items: center; gap: 11px; font-family: var(--f-titre); font-weight: 800; font-size: 21px; letter-spacing: -.03em; color: var(--sur-marque); margin-bottom: 16px; }
.footer__nap { display: grid; gap: 14px; font-size: 15px; }
.footer__nap div { display: flex; gap: 12px; align-items: flex-start; }
.footer__nap i { color: var(--marque); font-style: normal; flex: none; }
.footer__bas { margin-top: 54px; padding-top: 22px; border-top: 1px solid rgba(255, 255, 255, .14); display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between; font-size: 14px; color: rgba(255, 255, 255, .5); }

/* ---------- avant / apres : curseur glissant ----------
   Les deux vues sont superposees, `--pos` decoupe celle d'avant.
   Le controle est un <input type=range> : clavier, tactile et souris
   marchent sans une ligne de JS specifique a l'appareil. */
.ab {
  position: relative; margin-bottom: 20px;
  aspect-ratio: 4 / 3; border-radius: var(--r-img); overflow: hidden;
  --pos: 50%; touch-action: pan-y;
}
.ab__vue { position: absolute; inset: 0; }
.ab__vue .frame { height: 100%; min-height: 0; border-radius: 0; }
.ab__vue--avant { clip-path: inset(0 calc(100% - var(--pos)) 0 0); }
.ab__lab {
  position: absolute; top: 12px; z-index: 3; padding: 6px 13px; border-radius: var(--r-pill);
  background: var(--fond); color: var(--texte); font-size: 11px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; pointer-events: none;
}
.ab__lab--avant { left: 12px; }
.ab__lab--apres { right: 12px; }
.ab__lab--fort { background: var(--marque); color: var(--sur-marque); }
.ab__barre {
  position: absolute; top: 0; bottom: 0; left: var(--pos); z-index: 4;
  width: 3px; margin-left: -1.5px; background: var(--fond);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .08); pointer-events: none;
  display: grid; place-items: center;
}
.ab__poignee {
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--marque); color: var(--sur-marque);
  display: grid; place-items: center; font-size: 18px;
  box-shadow: var(--ombre-legere); transition: transform .15s ease;
}
.ab:hover .ab__poignee { transform: scale(1.08); }
.ab__range {
  position: absolute; inset: 0; z-index: 5; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: ew-resize; appearance: none; background: transparent;
  /* La piste occupe tout le cadre : sans cette regle, un doigt pose dessus
     ne pourrait plus faire defiler la page verticalement. pan-y rend le
     defilement au navigateur et laisse le geste horizontal au curseur. */
  touch-action: pan-y;
}
.ab__range::-webkit-slider-thumb { appearance: none; width: 46px; height: 100%; cursor: ew-resize; }
.ab__range::-moz-range-thumb { width: 46px; height: 100%; border: 0; cursor: ew-resize; }
.ab__range:focus-visible ~ .ab__barre { outline: 2px solid var(--marque); outline-offset: 2px; }

/* ---------- catalogue et fiche de reference ----------
   Les facettes sont des LIENS mis en pilules : elles se lisent comme une
   navigation, pas comme des boutons de tri. min-width:0 partout, un
   libelle long ne doit jamais pousser la rangee hors du cadre. */
.fac { display: flex; flex-wrap: wrap; gap: 12px; }
.fac__i {
  display: inline-flex; align-items: center; min-width: 0;
  padding: 11px 22px; border-radius: var(--r-pill);
  border: 1px solid var(--bordure); background: var(--fond);
  color: var(--texte); font-size: 15px; font-weight: 500;
}
a.fac__i:hover { border-color: var(--marque); color: var(--marque); }
.fac__i--ici { background: var(--marque); border-color: var(--marque); color: var(--sur-marque); font-weight: 700; }
.prod__prix { margin-top: 18px; }
.prod__pied { margin-top: auto; padding-top: 22px; }
/* La fiche technique se lit comme un releve numerote : un panneau encadre,
   un rang devant chaque ligne, la valeur alignee a droite. */
.specs__panneau {
  padding: 12px 30px; border: 1px solid var(--bordure); border-radius: 18px;
  background: var(--fond);
}
.specs { display: flex; flex-wrap: wrap; column-gap: 56px; margin: 0; }
.spec__n {
  display: inline-block; min-width: 26px; margin-right: 10px;
  font-style: normal; font-weight: 700; font-size: 13px; color: var(--marque);
}
.spec {
  flex: 1 1 46%; min-width: min(100%, 280px);
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 20px; padding: 16px 0; border-bottom: 1px solid var(--bordure);
}
.spec dt { color: var(--texte-doux); font-size: 15px; min-width: 0; }
.spec dd { margin: 0; font-weight: 700; text-align: right; min-width: 0; }

/* ---------- appoints : les pieces montees par la coquille ---------- */
.actes { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 34px; }
.actes > * { min-width: 0; }
.etape__vue { width: 100%; border-radius: 12px; overflow: hidden; margin: 14px 0 6px; }
.etape__vue .frame { min-height: 0; aspect-ratio: 8 / 5; }
.etape__vue img { width: 100%; height: 100%; object-fit: cover; display: block; }
.frame--puce {
  width: 22px; height: 22px; min-height: 0; flex: none;
  border-radius: 999px; overflow: hidden; margin-right: 4px;
}
.frame--puce img { width: 100%; height: 100%; object-fit: cover; display: block; }
.frame--puce span { font-size: 0; }
.zone-chip { min-width: 0; }
.avis__titre { margin-bottom: 10px; font-size: 18px; }

/* ---------- points d'arret natifs CorePlumb : 1080, 980, 640 ---------- */
@media (max-width: 1080px) {
  /* Sous le palier declare dans slots.json, la rangee se replie en UNE
     colonne : la case n'est plus tendue, elle reprend sa forme declaree
     (ratioReplie) et le plancher du grand ecran tombe — sinon il l'emporte
     sur la forme repliee et R5a devient infaisable. */
  .hero__inner { padding: 72px 24px 80px; grid-template-columns: minmax(0, 1fr); }
  .hero__txt, .hero__case { grid-column: 1 / -1; }
  .hero__case .frame { min-height: 0; height: auto; aspect-ratio: 3 / 2; }
  .art__som { position: static; }
}

@media (max-width: 980px) {
  :root { --pad-section: 72px; }
  .g3, .g4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hero-atouts__g { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .duo, .bloc { gap: 34px; }
  .zone-bande .frame:nth-child(3) { display: none; }
  .chiffres__bande { margin-top: -40px; width: calc(100% - 32px); }
  .cta { padding: 44px 36px; }
  .b2b__carte, .b2b .frame { flex-basis: 100%; }
  .b2b--inv .frame { order: 0; }
  /* La nav se replie derriere la commande au lieu de disparaitre : le
     panneau se pose sous la barre, les deroulants y sont deplies en flux
     (au doigt le survol n'existe pas). */
  .hd__bascule { display: flex; }
  .hd__nav { display: none; position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; gap: 2px; margin: 0; padding: 10px 28px 18px;
    background: var(--fond); border-bottom: 1px solid var(--bordure); box-shadow: var(--ombre);
    max-height: calc(100vh - 90px); overflow-y: auto; }
  .hd--ouvert .hd__nav { display: flex; }
  .hd__nav > a, .drop__tete { padding: 9px 0; }
  .drop { position: static; }
  .drop__chev { display: none; }
  .drop__panneau { position: static; transform: none; opacity: 1; visibility: visible; padding: 0 0 6px 14px; }
  .drop__grille { display: block; gap: 8px; padding: 0; background: none;
    border: 0; box-shadow: none; white-space: normal; min-width: 0; max-width: none; }
  .drop__cols { display: block; }
  /* La vitrine est un confort d ecran large : au doigt, elle pousserait les
     liens hors de vue. Le volet redescend a la liste seule. */
  .drop__vit { display: none; }
  .drop__lien { display: block; padding: 6px 0; }
}

@media (max-width: 640px) {
  :root { --pad-section: 56px; }
  .co-wrap, .hd__inner { padding-left: 18px; padding-right: 18px; }
  .hero__inner { padding: 56px 18px 60px; }
  .g2, .g3, .g4 { grid-template-columns: minmax(0, 1fr); }
  .hero-atouts__g { grid-template-columns: minmax(0, 1fr); }
  .etape, .feat { flex-basis: 100%; }
  .champs { grid-template-columns: minmax(0, 1fr); }
  .zone-bande .frame:nth-child(3) { display: block; }
  .chiffres__bande { margin-top: 0; width: 100%; }
  .chiffre, .tar__c { border-left: 0; border-top: 1px solid var(--bordure); }
  .chiffre:first-child, .tar__c:first-child { border-top: 0; }
  .cta { padding: 30px 22px; }
  .carte, .svc, .avis, .loc__carte, .b2b__carte, .urgence, .legal__bloc { padding: 22px; }
  .faq-item { padding: 2px 18px; }
  .faq-item p { padding-right: 0; }
  /* Le panneau du deroulant reste AFFICHE : replie dans le menu, il porte
     le seul acces aux pages enfants. */
  .marquee { padding: 22px 0; }
  .art__hero { min-height: 240px; margin-bottom: 32px; }
  .hd__logo { font-size: 18px; }
  /* regle 7 au telephone : les deux portes restent cote a cote, c'est le
     libelle qui se serre — jamais la paire qui disparait. */
  .hd__cta { gap: 6px; }
  .hd__cta .btn { font-size: 12px; padding: 9px 10px; max-width: 15ch; overflow: hidden; text-overflow: ellipsis; }
  .hd__cta .btn__arrow { display: none; }
}

/* ================= SIGNATURES DE FORME =================
   Traits releves EN LIGNE sur coreplumb.framer.website. CSS pur.
   Documentation lisible : coreplumb/signatures.md */

/* SIGNATURE — LE DISQUE EST LE SECOND RAYON DU MODELE (100% x36, juste
   derriere 8px x44) : la reference ne connait AUCUNE pilule allongee, elle
   passe directement de l arete a 8px au cercle parfait. */
.rond, .icone, .etape__num, .b2b__num, .avis__av, .chip__point, .svc__fleche { border-radius: 100%; }

/* SIGNATURE — l ECHELLE FERMEE : 8px, 12px, 16px, et rien d autre au-dessus
   sauf trois exceptions a 32px. Aucun rayon intermediaire, aucun grand
   arrondi generalise. */
.chip, .fac__i, .spec__n, .tar__u { border-radius: 8px; }
.carte, .svc, .avis, .etape, .b2b__carte, .loc__carte { border-radius: 12px; }
.frame, .bloc__frame, .drop__vit, .hero__carte { border-radius: 16px; }
.cta, .chiffres__bande, .specs__panneau { border-radius: 32px; }

/* SIGNATURE — LE MODELE EST STRICTEMENT PLAT : le releve ne trouve AUCUN
   degrade sur toute la page d accueil. La profondeur ne vient donc que du
   halo doux et du contour, jamais d un voile de couleur. */
.hero__voile, .cta__voile { background: color-mix(in srgb, var(--texte) 46%, transparent); }

/* SIGNATURE — le HALO DOUX ET LARGE, presque sans chute (`0 1px 20px`, x4).
   La piece ne se detache pas : elle diffuse. */
.carte, .svc, .avis, .loc__carte { box-shadow: 0 1px 20px 0 color-mix(in srgb, var(--texte) 10%, transparent); }

/* SIGNATURE — le CONTOUR INTERNE net d un pixel, en regles distinctes. */
.carte { position: relative; }
.carte::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--texte) 10%, transparent);
}
.svc { position: relative; }
.svc::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--texte) 8%, transparent);
}
.etape { position: relative; }
.etape::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--texte) 7%, transparent);
}
.b2b__carte { position: relative; }
.b2b__carte::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--texte) 7%, transparent);
}

/* SIGNATURE — la file ne s efface pas, elle S ATTENUE A 10 POUR CENT sur
   deux virgule cinq pour cent de largeur, aux deux bouts. Le contenu reste
   lisible jusqu au bord : c est un adoucissement, pas un fondu. */
.marquee__track {
  -webkit-mask-image: linear-gradient(to right, rgba(0,0,0,.1) 0%, #000 2.5%, #000 97.5%, rgba(0,0,0,.1) 100%);
  mask-image: linear-gradient(to right, rgba(0,0,0,.1) 0%, #000 2.5%, #000 97.5%, rgba(0,0,0,.1) 100%);
}
.zone-bande {
  -webkit-mask-image: linear-gradient(to right, rgba(0,0,0,.1) 0%, #000 2.5%, #000 97.5%, rgba(0,0,0,.1) 100%);
  mask-image: linear-gradient(to right, rgba(0,0,0,.1) 0%, #000 2.5%, #000 97.5%, rgba(0,0,0,.1) 100%);
}

/* >>> NORME COQUILLE — cadre vide (pose par _lib/poser-cadre-vide.mjs) */
/* ============================================================
   NORME COQUILLE — LE CADRE VIDE PORTE SON ENCRE (R4b)
   ------------------------------------------------------------
   R4 dit depuis toujours que le cadre VIDE et le cadre REMPLI sont deux
   etats TENABLES. Seule la moitie basse etait mesuree : « le cadre vide ne
   s effondre pas sous 24 px ». Personne ne mesurait la moitie haute : « le
   cadre vide reste tenable quand il est GRAND ».

   C est la faute qu Angelo a vue le 22 aout 2026. Il n a pas vu une
   composition fausse — les bandes de reference le prouvent : le hero de
   roofer est bien une photo plein cadre avec le texte ecrit dessus, et le
   cadre de plumbfixx mesure 5,5 colonnes sur 12 la ou le modele en prend 7.
   Il a vu l ETAT VIDE : un mur blanc de 800 x 750 px portant une lettre
   perdue. La coquille n embarque aucune photo — c est la regle — donc l
   etat vide n est pas un accident de fixture, c est l etat NORMAL d une
   coquille au repos. Il devait etre dessine, il ne l avait jamais ete.

   Ce fichier le dessine, UNE fois, pour toutes les coquilles. Il ne touche
   ni `display`, ni `position`, ni `overflow`, ni aucune boite : la
   geometrie de chaque modele est deja jugee par F1/F2 et par R2/R3, on n y
   revient pas. Il ne pose que de la peinture et de l encre.

   Le crochet est volontairement AGRAMMATICAL : `[data-slot]` sans image
   dedans. Les sept coquilles nomment leur cadre `kr-vue--nue`, `pf-ph--nu`,
   `ig--nu`, ou ne le nomment pas du tout — s appuyer sur ces noms, c est
   ecrire sept correctifs a la main, puis trente-sept. `data-slot` est pose
   par R1 sur TOUS les cadres de TOUTES les coquilles : c est le seul point
   d appui qui passe a l echelle.

   Les quatre couleurs sont des variables : la fabrique les change comme elle
   change une palette.

   LA TEINTE SE DECIDE PAR CADRE, PAS PAR COQUILLE. C est la faute qu Angelo
   a vue le 22 aout 2026 sur plumfixx : la coquille avait ete teintee SOMBRE
   en bloc, parce que son hero ecrit en blanc — sauf que ce blanc repose sur
   l aplat bleu de la SECTION, pas sur le cadre. Le placeholder lateral, qui
   ne porte aucune encre, devenait une dalle noire de 800 x 750 px au milieu
   d une page claire. Un placeholder qui ne porte rien n a aucune raison
   d etre sombre.

   Le defaut est donc CLAIR : un emplacement en attente se lit comme une
   carte grise, c est la convention de tout le metier, et c est la version
   qu Angelo avait validee. Seuls les cadres PORTEURS — ceux sur lesquels de
   l encre repose vraiment, hero pleine fenetre sous son voile — prennent la
   teinte que leur encre exige. Ces cadres-la sont trouves par la MESURE, pas
   a la main : `_lib/teinter-cadres.mjs` ouvre les pages rendues, regarde
   quelle encre tombe dans quel cadre, et ecrit la liste en queue du
   `style.css` de la coquille. R4b verifie ensuite le resultat sur les pixels.
   ============================================================ */

:root {
  --cadre-vide-fond: #e6e9ec;
  --cadre-vide-trame: rgba(0, 0, 0, .045);
  --cadre-vide-encre: rgba(17, 22, 28, .68);
  --cadre-vide-filet: rgba(0, 0, 0, .10);
}

[data-slot]:not(:has(img)):not(:has(video)) {
  background-color: var(--cadre-vide-fond);
  /* Une trame diagonale : sans elle un aplat sombre se lit comme une panne
     d affichage. Avec elle, il se lit comme un emplacement en attente. */
  background-image: repeating-linear-gradient(135deg,
    transparent 0 13px, var(--cadre-vide-trame) 13px 14px);
  box-shadow: inset 0 0 0 1px var(--cadre-vide-filet);
  color: var(--cadre-vide-encre);
  /* SEULE propriete de boite de cette feuille, et elle ne vit que sur l etat
     VIDE : elle disparait des que la fabrique injecte une photo. Elle sert a
     une chose — permettre a la legende de savoir si son cadre est assez large
     pour la porter (voir le @container plus bas). Sans elle, la meme legende
     s ecrit dans une pastille de zone de 28 px et dans un hero de 800 px. */
  container-type: inline-size;
}

/* L intitule. Les gabarits y mettent tantot l alt complet, tantot la seule
   initiale du sujet — et cette initiale, dans un cadre de hero, sort a
   78 px : une lettre geante a la derive, c est ce qui faisait « casse ».
   On la ramene a la taille d une legende, quelle que soit la taille du
   cadre : une legende ne grandit pas avec son cadre.

   Et par defaut elle se TAIT. Un cadre ne porte une legende que s il est
   assez large pour l ecrire sur une ligne lisible : une pastille de zone de
   28 px, un cadre de maillage de 84 px, ne portent pas de phrase — ils
   tiennent leur aplat. Ecrite quand meme, la legende s y empile en colonne
   d une lettre : c est exactement ce que T5 appelle un serrage, et la pose
   du cadre vide en avait fabrique 306 sur heatfix2, 256 sur roofivo, 220 sur
   electria. Le libelle n est pas perdu pour autant : les gabarits le portent
   deja en `aria-label`, il reste lu par les lecteurs d ecran et par le gate.

   Le seuil est en unites de conteneur, pas de fenetre : c est la largeur du
   CADRE qui decide, pas celle de l ecran. Un hero garde sa legende a 390 px
   de fenetre ; une pastille ne l a jamais, meme a 1440. */
[data-slot]:not(:has(img)):not(:has(video)) > * {
  font-size: 0 !important;
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--cadre-vide-encre);
  -webkit-text-fill-color: var(--cadre-vide-encre);
  opacity: 1;
  max-width: 34ch;
  text-align: center;
  text-shadow: none;
}

/* 260 px : en dessous, une legende de 34ch a 11 px ne tient pas deux mots par
   ligne — le seuil est celui de T5, pas un gout. Au-dessus, elle s ecrit. */
@container (min-width: 260px) {
  [data-slot]:not(:has(img)):not(:has(video)) > * {
    font-size: clamp(11px, .95vw, 14px) !important;
  }
}
/* <<< NORME COQUILLE — cadre vide */


/* === CONTRAT GRILLE (factory, chantier 20/08, #1/#2) — services taille égale + avant/après 3-col === */
.g3 > * { flex-grow: 0 !important; }
.g2 > * { flex: 0 1 calc(33.333% - 20px) !important; min-width: min(240px, 100%) !important; }

/* === LOGO MARQUE (factory) : vrai logo.svg en lockup avec le nom dans le header === */
.zx-brandlogo{height:1.7em;width:auto;max-height:40px;vertical-align:middle;margin-right:.5em;object-fit:contain;border-radius:6px;flex:0 0 auto}
.zx-send{display:inline-block;margin-top:.6rem;padding:.85em 1.7em;border:0;border-radius:8px;background:var(--accent,var(--marque,#141414));color:var(--sur-marque,#fff);font:inherit;font-weight:700;line-height:1;cursor:pointer}
.zx-send:hover{filter:brightness(1.08)}
.zx-marques{padding:1.5rem 1rem;background:var(--fond,#f6f6f6);border-top:1px solid rgba(0,0,0,.06);border-bottom:1px solid rgba(0,0,0,.06)}
.zx-marques__in{max-width:1100px;margin:0 auto;text-align:center}
.zx-marques__t{margin:0 0 .9rem;font-size:.75rem;letter-spacing:.09em;text-transform:uppercase;color:var(--texte,#333);opacity:.55}
.zx-marques__u{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:1.6rem 2.4rem}
.zx-marques__u img{height:34px;width:auto;object-fit:contain;filter:grayscale(1);opacity:.7;transition:.2s}
.zx-marques__u img:hover{filter:none;opacity:1}
.zx-marques__u span{font-weight:700;color:var(--texte,#333);opacity:.55}
.zx-certs{padding:3rem 1rem;background:var(--sur-marque,#fff)}
.zx-certs__in{max-width:1100px;margin:0 auto}
.zx-certs__e{margin:0 0 .3rem;font-size:.75rem;letter-spacing:.09em;text-transform:uppercase;color:var(--accent,#c62828);font-weight:700}
.zx-certs__h{margin:0 0 1.6rem;font-size:1.9rem;color:var(--texte,#1a1a1a)}
.zx-certs__u{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:1.1rem}
.zx-certs__i{display:flex;gap:.8rem;align-items:flex-start;padding:1.1rem;background:var(--fond,#f7f7f7);border-radius:12px}
.zx-certs__ic{flex:0 0 auto;width:26px;height:26px;border-radius:50%;background:var(--accent,#c62828);color:#fff;display:flex;align-items:center;justify-content:center;font-size:.85rem;font-weight:700}
.zx-certs__t{margin:0 0 .2rem;font-weight:700;color:var(--texte,#1a1a1a)}
.zx-certs__x{margin:0;font-size:.9rem;line-height:1.4;color:var(--texte,#555);opacity:.8}
