/* ============================================================
   DRIVEHUB — feuille SOURCE de la coquille.
   dist/ est une SORTIE, ecrasee a chaque rendu : ne jamais l'editer.

   Idiome releve sur la reference EN LIGNE (drivehub-template.framer.website,
   1440x900) et non sur le clone src/ :
     - une barre utilitaire fine AU-DESSUS de l'entete, entete transparente
       posee sur la photo d'ouverture ;
     - ouverture plein ecran, photo sombre, titre tres large, deux appels
       (un plein, un en contour) ;
     - les surtitres s'ecrivent « • Libelle », point median puis libelle gris ;
     - deux regimes de tete de tranche : a gauche avec deux fleches de rail
       calees en haut a droite, ou centree ;
     - des RAILS horizontaux la ou les autres references empilent des cartes ;
     - les listes d'offre ne sont PAS des cartes : des colonnes separees par
       un filet fin qui court jusqu'aux bords, pastille carree noire en tete ;
     - des bandes photo pleine largeur, sans texte, qui coupent le rythme ;
     - un bloc immersif : grande image, degrade sombre en bas, texte dedans ;
     - un pied noir, et sous les colonnes de liens le nom de la marque en
       tres grand lettrage filigrane.

   8 variables de couleur, aucune autre. Aucun hex en dur.
   --sur-marque est calcule par render.mjs, jamais choisi ici.
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font: 400 16px/1.6 Geist, system-ui, sans-serif;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }

h1, h2, h3, h4 {
  margin: 0;
  font-family: 'Inter Tight', system-ui, sans-serif;
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.06;
}

h1 { font-size: clamp(40px, 6.4vw, 78px); }
h2 { font-size: clamp(28px, 3.7vw, 46px); }

/* 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, 3.7vw, 46px); }
h3 { font-size: clamp(20px, 2.1vw, 26px); line-height: 1.18; }
h4 { font-size: 18px; line-height: 1.25; }

p { margin: 0; }
a { color: inherit; }

.mot { color: var(--texte-doux); font-size: 16px; }
.mot + .mot { margin-top: 14px; }
.mot--fort { font-size: 17px; }

.meta {
  display: block;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--texte-doux);
}

.mention { margin-top: 26px; font-size: 13px; color: var(--texte-doux); }

/* --- le conteneur : large, la reference respire jusqu'aux bords --- */
.conteneur { width: min(1320px, 100% - 48px); margin-inline: auto; }

.bloc { padding: 96px 0; }
.bloc--serre { padding: 64px 0; }
.bloc--pale { background: var(--fond-2); }
.bloc--nuit { background:var(--texte);--sur-bande:var(--sur-texte,var(--fond)); color: var(--fond); }
.bloc--nuit .mot, .bloc--nuit .meta { color: var(--fond); opacity: 0.72; }
.bloc--plein { padding: 0; }

/* --- surtitre « • Libelle » : la signature typographique de la reference --- */
.surtitre {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--texte-doux);
}
.surtitre::before {
  content: '';
  width: 7px; height: 7px;
  border-radius: 50%;
  background:var(--marque);--sur-bande:var(--sur-marque);
  flex: 0 0 auto;
}
/* Sur les fonds photo (ouverture, appel final) et sur la bande de nuit, le
   surtitre passe en encre claire : le gris de lecture n'y tient pas. */
.bloc--nuit .surtitre,
.ouvre .surtitre,
.final .surtitre,
.immersif .surtitre { color: var(--fond); opacity: 0.86; }

/* --- appels : rayon faible, plein ou en contour --- */
.appui {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 15px 26px;
  border-radius: 8px;
  border: 1px solid transparent;
  background:var(--marque);--sur-bande:var(--sur-marque);
  color:var(--sur-bande,var(--sur-marque));
  font: 500 15px/1 Geist, system-ui, sans-serif;
  text-decoration: none;
  transition: opacity .18s ease, transform .18s ease;
}
.appui:hover { opacity: .88; transform: translateY(-1px); }
.appui__fl { font-size: 15px; }
.appui--clair { background: var(--fond); color: var(--texte); }
.appui--vide { background: transparent; border-color: var(--bordure); color: inherit; }
/* NORME COQUILLE, regle 7 — les deux portes d un point de conversion se
   posent cote a cote, jamais l une sans l autre. */
.portes { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.portes > * { min-width: 0; }
.portes .appui { flex: 0 1 auto; justify-content: center; }
.pied .portes { margin-top: 22px; }
.pied .appui--vide, .final .appui--vide { border-color: currentColor; }
.appui__cbn { font-size: 15px; }
.champ--long.portes .appui { flex: 1 1 auto; width: auto; }
.bloc--nuit .appui--vide { border-color: currentColor; }

/* --- tete de tranche --- */
.tete { display: flex; flex-wrap: wrap; gap: 24px 40px; align-items: flex-end; justify-content: space-between; }
.tete > * { min-width: 0; }
.tete__g { flex: 1 1 60%; min-width: min(100%, 320px); }
.tete__d { flex: 1 1 30%; min-width: min(100%, 260px); }
.tete h2 { margin-top: 16px; }
.tete--centre { flex-direction: column; align-items: center; text-align: center; }
.tete--centre .tete__g, .tete--centre .tete__d { flex: 1 1 100%; max-width: 760px; }
.tete + * { margin-top: 44px; }

/* --- barre utilitaire + entete --- */
.bandeau {
  background:var(--texte);--sur-bande:var(--sur-texte,var(--fond));
  color: var(--fond);
  font-size: 13px;
}
.bandeau__rang { display: flex; flex-wrap: wrap; gap: 10px 28px; padding: 11px 0; }
.bandeau__rang > * { min-width: 0; }
.bandeau a { text-decoration: none; opacity: .82; }
.bandeau a:hover { opacity: 1; }

.entete { position: sticky; top: 0; z-index: 40; background: var(--fond); border-bottom: 1px solid var(--bordure); }
.entete__rang { display: flex; align-items: center; gap: 28px; padding: 16px 0; }
.entete__nom {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: 'Inter Tight', system-ui, sans-serif;
  font-weight: 600; font-size: 21px; letter-spacing: -0.02em;
  text-decoration: none; flex: 0 0 auto;
}
.entete__disque { width: 26px; height: 26px; border-radius: 50%; background:var(--marque);--sur-bande:var(--sur-marque); flex: 0 0 auto; }
.entete__nav { display: flex; align-items: center; gap: 26px; margin-left: auto; }
.entete__nav > a, .deroul__tete {
  font-size: 15px; text-decoration: none; color: var(--texte-doux); cursor: pointer;
  white-space: nowrap;
}
.entete__nav > a:hover, .deroul__tete:hover { color: var(--texte); }
.entete__act { flex: 0 0 auto; }
.entete__bouton {
  display: none; margin-left: auto;
  background: transparent; border: 1px solid var(--bordure); border-radius: 8px;
  padding: 9px 13px; font-size: 17px; color: inherit; cursor: pointer;
}

/* deroulants : sans script, au survol et au focus */
/* La tete occupe TOUTE la hauteur de son entree : plus courte, elle laisse
   entre son bas et le haut du volet un vide que la souris traverse en
   descendant, et le volet se referme avant d'y arriver. */
.deroul { position: relative; display: flex; align-items: stretch; }
.deroul__tete { display: inline-flex; align-items: center; gap: 6px; align-self: stretch; }
.deroul__chev { font-size: 11px; }
.deroul__panneau {
  /* Le panneau est CENTRE sous sa tete : cale a gauche, une carte large sort de
     la fenetre des que l'entree est du cote droit de la barre. Le decalage sous
     le lien est le PADDING du panneau, jamais une marge — la souris doit passer
     du lien a la carte sans traverser de vide. */
  position: absolute; left: 50%; top: 100%;
  padding-top: 14px;
  opacity: 0; visibility: hidden; transform: translate(-50%, 6px);
  transition: opacity .16s ease, transform .16s ease;
  z-index: 5;
}
.deroul:hover .deroul__panneau,
.deroul:focus-within .deroul__panneau { opacity: 1; visibility: visible; transform: translate(-50%, 0); }
.deroul__grille {
  display: flex; align-items: flex-start; gap: 26px;
  background: var(--fond); border: 1px solid var(--bordure); border-radius: 12px;
  padding: 22px 26px;
  /* `width: max-content` : en position absolue, la largeur est un shrink-to-fit
     calcule sur la place restante A DROITE de `left: 50%` — soit la moitie de la
     tete, quelques dizaines de pixels. Sans lui, la carte retombe a son
     `min-width` et la vitrine sort du cadre. */
  width: max-content; min-width: 560px; max-width: min(94vw, 900px);
  box-shadow: 0 18px 40px rgba(0, 0, 0, .10);
}
.deroul__grille > * { min-width: 0; }
.deroul__col { flex: 0 0 auto; }
/* La vitrine : le visuel du volet, sur le cote. `flex: 0 0` et non `0 1` — une
   base compressible la reduirait a un mot par ligne des que les colonnes
   s'allongent. Hauteur FIXE sur le visuel, sinon le cadre etire tout le volet. */
.deroul__vit { flex: 0 0 240px; display: grid; gap: 8px; align-content: start; }
.deroul__vitPh { min-height: 0; height: 128px; width: 100%; border-radius: 12px; overflow: hidden; }
.deroul__vitPh img { width: 100%; height: 100%; object-fit: cover; }
.deroul__vitN { font-size: 16px; line-height: 1.3; color: var(--texte); }
.deroul__vitX { font-size: 14px; color: var(--texte-doux); line-height: 1.5; }
.deroul__vitZ { font-size: 14px; font-weight: 600; color:var(--encre-marque,var(--marque)); text-decoration: none; justify-self: start; }
.deroul__titre { display: block; font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--texte-doux); margin-bottom: 9px; }
.deroul__lien { display: block; padding: 5px 0; font-size: 15px; text-decoration: none; white-space: nowrap; }
.deroul__lien:hover { color:var(--encre-marque,var(--marque)); }

/* --- fil d'ariane --- */
.ariane { padding: 18px 0; border-bottom: 1px solid var(--bordure); font-size: 13px; color: var(--texte-doux); }
.ariane a { text-decoration: none; }
.ariane a:hover { color: var(--texte); }

/* --- ouverture : photo plein ecran, texte pose dessus --- */
/* NORME COQUILLE R4b — le mot d accent est de l ENCRE, et l encre lit son
   fond. En style en ligne il claquait `--marque` partout, y compris sur les
   fonds sombres (affiche, bande finale, bloc de nuit) ou une marque foncee
   descend sous 2:1. Il se declare donc en classe, et les emplacements
   sombres, qui vivent APRES la regle generique, lui rendent l accent clair. */
.titre__acc { color:var(--encre-marque,var(--marque)); }
.ouvre .titre__acc,
.final .titre__acc,
.bloc--nuit .titre__acc,
.immersif .titre__acc { color: var(--accent, currentColor); }

.ouvre { position: relative; min-height: min(88vh, 760px); display: flex; align-items: flex-end; color: var(--fond); overflow: hidden; }
.ouvre__fond { position: absolute; inset: 0; }
.ouvre__fond .vue { position: absolute; inset: 0; height: 100%; border-radius: 0; }
.ouvre__fond img { width: 100%; height: 100%; object-fit: cover; }
.ouvre__voile { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0,0,0,.30) 0%, rgba(0,0,0,.20) 42%, rgba(0,0,0,.78) 100%); }
.ouvre__mot { position: relative; padding: 132px 0 76px; max-width: 980px; }
.ouvre h1 { margin-top: 18px; }
.ouvre__sous { margin-top: 22px; max-width: 620px; font-size: 18px; opacity: .88; }
.ouvre__actes { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 34px; }
.ouvre__atouts { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 30px; }

.jetons { display: flex; flex-wrap: wrap; gap: 9px; }
.jetons:has(> .jeton--fiche) { display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); }
.jeton {
  display: inline-block; padding: 7px 14px; border-radius: 999px;
  border: 1px solid var(--bordure); font-size: 13px; color: var(--texte-doux);
}
.ouvre .jeton, .bloc--nuit .jeton { border-color: rgba(255,255,255,.45); color: inherit; }

/* --- cadre d'image commun --- */
.vue { position: relative; overflow: hidden; border-radius: 10px; background: var(--fond-2); }
.vue img { width: 100%; height: 100%; object-fit: cover; }
.vue > span {
  display: flex; align-items: center; justify-content: center;
  min-height: 220px; padding: 20px; text-align: center;
  font-size: 13px; color: var(--texte-doux);
}
/* Le cadre sans photo sert de repere de montage : derriere un voile sombre
   (ouverture, appel final, bloc immersif) il doit rester lisible. */
.ouvre .vue > span,
.final .vue > span,
.immersif .vue > span,
.vignette .vue > span,
.commune .vue > span { color: rgba(255, 255, 255, .82); }
/* NORME COQUILLE, R1/R3 — LA FORME DU CADRE EST TENUE PAR LE GABARIT.
   Le helper visuel ne rend pas la classe de forme : il ne pose que la cle
   d emplacement. La proportion se declare donc sur l emplacement lui-meme,
   un point d appel a la fois, APRES le bloc generique du cadre. */
[data-slot="vue--seo"]  { aspect-ratio: 21 / 9; }
[data-slot="vue--why"]  { aspect-ratio: 21 / 9; }
[data-slot="vue--map"]  { aspect-ratio: 21 / 9; }
[data-slot="vue--zon"]  { aspect-ratio: 1 / 1; }
[data-slot="vue--prd"]  { aspect-ratio: 3 / 4; }
[data-slot="vue--b2b"],
[data-slot="vue--pro"],
[data-slot="vue--rea"],
[data-slot="vue--gpr"],
[data-slot="vue--mai"],
[data-slot="vue--blg"],
[data-slot="vue--art"],
[data-slot="vue--artD"] { aspect-ratio: 16 / 10; }

/* --- rails horizontaux : le geste central de la reference --- */
.rail { overflow-x: auto; scrollbar-width: none; scroll-snap-type: x proximity; }
.rail::-webkit-scrollbar { display: none; }
.rail__piste { display: flex; gap: 20px; padding-bottom: 6px; }
.rail__piste > * { scroll-snap-align: start; }

/* vignette de rail : photo haute, titre pose en bas sur l'image */
.vignette {
  position: relative; flex: 0 0 auto;
  width: min(78vw, 300px);
  border-radius: 10px; overflow: hidden; text-decoration: none; color: var(--fond);
}
.vignette .vue { border-radius: 0; aspect-ratio: 3 / 4; }
.vignette__voile { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0,0,0,0) 42%, rgba(0,0,0,.76) 100%); }
.vignette__mot { position: absolute; left: 20px; right: 20px; bottom: 18px; }
.vignette__mot h3 { font-size: 22px; }
.vignette__mot .mot { color: var(--fond); opacity: .8; font-size: 14px; margin-top: 6px; }
.vignette__fl { position: absolute; top: 16px; right: 16px; width: 34px; height: 34px; border-radius: 50%; background: var(--fond); color: var(--texte); display: flex; align-items: center; justify-content: center; font-size: 15px; }

/* --- cartes : image en tete, titre et valeur sur la MEME ligne --- */
.cartes { display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); gap: 22px; }
.cartes:has(> .carte--quart) { --n: 4; }
.cartes:has(> .carte--demi) { --n: 2; }
.cartes > * { min-width: 0; }

/* Le compte de duels varie selon la page (1 a plusieurs) : auto-fit evite
   la moitie de rangee vide qu'un --n fixe laisserait sur les pages a 1 item. */
.duels { display: grid; grid-template-columns: repeat(auto-fit, minmax(460px, 1fr)); gap: 40px; }
.carte {
  display: flex; flex-direction: column;
  min-width: 0; min-height: 0;
  background: var(--fond); border: 1px solid var(--bordure); border-radius: 12px;
  overflow: hidden; text-decoration: none;
  transition: border-color .18s ease, transform .18s ease;
}
.carte:hover { border-color:var(--encre-marque,var(--marque)); transform: translateY(-2px); }
.carte .vue { border-radius: 0; }
.carte__c { padding: 20px 22px 22px; display: flex; flex-direction: column; gap: 10px; flex: 1 1 auto; }
.carte__rang { display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: baseline; justify-content: space-between; }
.carte__rang > * { min-width: 0; }
.carte__valeur { font-family: 'Inter Tight', system-ui, sans-serif; font-weight: 600; font-size: 19px; white-space: nowrap; }
.carte__attrs { display: flex; flex-wrap: wrap; gap: 8px 18px; padding-top: 14px; border-top: 1px solid var(--bordure); margin-top: auto; }
.carte__attrs > * { min-width: 0; }
/* NORME COQUILLE T5 — jamais deux corps de texte dans un meme bloc mesure :
   la pastille appartient au dessin, pas au texte, elle se pose donc au
   gabarit et sort du flux mesure. */
.carte__attr { display: inline-flex; align-items: baseline; gap: 7px; font-size: 13px; line-height: 1.5; color: var(--texte-doux); min-width: 0; }
.carte__attr::before { content: "\25CF"; font-size: inherit; line-height: inherit; flex: 0 0 auto; }
.carte__fl { font-size: 14px; color:var(--encre-marque,var(--marque)); }
/* .carte--demi / .carte--quart ne portent plus de largeur : elles DECLARENT
   le nombre de pistes de leur grille (voir .cartes:has(...)). */

/* --- colonnes filetees : l'offre, sans cartes --- */
.filets { display: grid; grid-template-columns: repeat(var(--n, 4), minmax(0, 1fr)); border-top: 1px solid var(--bordure); }
.filets:has(> .filet--tiers) { --n: 3; }
.filets:has(> .filet--demi) { --n: 2; }
.filets > * { min-width: 0; }
.filet {
  min-width: 0; min-height: 0;
  padding: 34px 28px 34px 0;
  border-bottom: 1px solid var(--bordure);
  text-decoration: none;
  display: flex; flex-direction: column; gap: 12px;
}
.pastille {
  width: 42px; height: 42px; border-radius: 8px;
  background:var(--texte);--sur-bande:var(--sur-texte,var(--fond)); color: var(--fond);
  display: flex; align-items: center; justify-content: center; font-size: 17px;
  flex: 0 0 auto;
}
.filet__no { font-size: 12px; letter-spacing: .14em; color: var(--texte-doux); }
.filet__fl { margin-top: auto; padding-top: 12px; font-size: 14px; color:var(--encre-marque,var(--marque)); }
.filet:hover .filet__fl { text-decoration: underline; }
/* .filet--tiers / .filet--demi : declarent le compte de pistes, pas une largeur. */

/* --- bandes photo pleine largeur, sans texte --- */
.bande { width: 100%; }
.bande .vue { border-radius: 0; aspect-ratio: 32 / 9; }

/* --- logos : grille de cellules separees par des filets --- */
.logos { display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); border: 1px solid var(--bordure); border-radius: 12px; overflow: hidden; }
.logos > * { min-width: 0; }
.logos__c {
  min-width: 0; min-height: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 32px 20px; text-align: center;
  border-right: 1px solid var(--bordure); border-bottom: 1px solid var(--bordure);
  font-family: 'Inter Tight', system-ui, sans-serif; font-size: 19px; color: var(--texte-doux);
}

/* --- bloc immersif : image large, degrade bas, texte dedans --- */
.immersif { position: relative; border-radius: 14px; overflow: hidden; color: var(--fond); }
.immersif .vue { border-radius: 0; aspect-ratio: 21 / 9; }
.immersif .vue > span { min-height: 340px; }
.immersif__voile { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0,0,0,.06) 30%, rgba(0,0,0,.80) 100%); }
.immersif__mot { position: absolute; left: 0; right: 0; bottom: 0; padding: 40px 38px; max-width: 760px; }
.immersif__mot h2 { margin-top: 14px; }
.immersif__mot .mot { color: var(--fond); opacity: .84; margin-top: 14px; }
.immersif__actes { margin-top: 26px; }

/* --- parole : grandes cartes photo en rail --- */
.parole {
  flex: 0 0 auto; width: min(84vw, 380px);
  border: 1px solid var(--bordure); border-radius: 12px; padding: 26px;
  display: flex; flex-direction: column; gap: 14px;
  background: var(--fond);
}
.parole__et { color:var(--encre-marque,var(--marque)); letter-spacing: .18em; font-size: 14px; }
.parole__mot { font-size: 17px; line-height: 1.5; }
.parole__pied { display: flex; align-items: center; gap: 13px; margin-top: auto; padding-top: 16px; border-top: 1px solid var(--bordure); }
.parole__pied > * { min-width: 0; }
.parole__av {
  width: 44px; height: 44px; border-radius: 50%; flex: 0 0 auto;
  background:var(--marque);--sur-bande:var(--sur-marque); color:var(--sur-bande,var(--sur-marque));
  display: flex; align-items: center; justify-content: center;
  font-family: 'Inter Tight', system-ui, sans-serif; font-size: 17px;
}
.parole__nom { font-weight: 500; }
.parole__role { font-size: 13px; color: var(--texte-doux); }

/* --- compteurs : rangee filetee, chiffres tres larges --- */
.compte { display: grid; grid-template-columns: repeat(var(--n, 4), minmax(0, 1fr)); gap: 28px; }
.compte > * { min-width: 0; }
.compte__c { min-width: 0; min-height: 0; padding-left: 20px; border-left: 2px solid var(--marque); }
.compte__c b { display: block; font-family: 'Inter Tight', system-ui, sans-serif; font-size: clamp(34px, 4vw, 52px); font-weight: 600; letter-spacing: -.03em; }
.compte__c span { display: block; margin-top: 6px; font-size: 14px; color: var(--texte-doux); }

/* --- duos : deux colonnes, la photo d'un cote --- */
.duo { display: flex; flex-wrap: wrap; gap: 44px; align-items: center; }
.duo > * { min-width: 0; }
.duo > * { flex: 1 1 46%; min-width: min(100%, 340px); }
.duo--haut { align-items: flex-start; }
.duo--inv > *:first-child { order: 2; }

/* --- corps editorial : le role qui porte le poids SEO --- */
.essai { display: flex; flex-wrap: wrap; gap: 44px; align-items: center; }
.essai > * { min-width: 0; }
.essai > * { flex: 1 1 47%; min-width: min(100%, 330px); }
.essai + .essai { margin-top: 72px; }
.essai--inv > *:first-child { order: 2; }
.essai h2 { margin-top: 14px; }
.essai__mots { margin-top: 18px; }

.puces { list-style: none; margin: 18px 0 0; padding: 0; }
.puces li { position: relative; padding-left: 24px; margin-top: 10px; color: var(--texte-doux); }
.puces li::before { content: '\2192'; position: absolute; left: 0; color:var(--encre-marque,var(--marque)); }
.puces a { color: inherit; }

/* --- territoire --- */
.communes { display: grid; grid-template-columns: repeat(var(--n, 4), minmax(0, 1fr)); gap: 14px; }
.communes > * { min-width: 0; }
.commune {
  position: relative; min-width: 0; min-height: 0;
  border-radius: 10px; overflow: hidden; text-decoration: none; color: var(--fond);
}
.commune .vue { border-radius: 0; aspect-ratio: 4 / 3; }
.commune__voile { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0,0,0,.05) 40%, rgba(0,0,0,.74) 100%); }
.commune__n { position: absolute; left: 16px; right: 16px; bottom: 14px; font-family: 'Inter Tight', system-ui, sans-serif; font-size: 18px; }
.commune__tag { display: block; font-family: Geist, system-ui, sans-serif; font-size: 12px; opacity: .78; margin-top: 4px; }

.carto { position: relative; border-radius: 14px; overflow: hidden; }
.carto .vue { border-radius: 0; aspect-ratio: 21 / 9; }
.carto__panneau {
  position: absolute; left: 26px; bottom: 26px; max-width: min(92%, 380px);
  background: var(--fond); border-radius: 12px; padding: 24px 26px;
  box-shadow: 0 16px 40px rgba(0,0,0,.14);
}
.carto__lignes { display: flex; flex-direction: column; gap: 6px; margin: 14px 0 16px; }

/* --- methode : rangees numerotees a filet, pas de cartes --- */
.pas { display: flex; flex-wrap: wrap; gap: 18px 32px; padding: 30px 0; border-bottom: 1px solid var(--bordure); align-items: baseline; }
.pas > * { min-width: 0; }
.pas:first-child { border-top: 1px solid var(--bordure); }
.pas__no { flex: 0 0 auto; font-family: 'Inter Tight', system-ui, sans-serif; font-size: 15px; color:var(--encre-marque,var(--marque)); letter-spacing: .1em; }
.pas__t { flex: 1 1 30%; min-width: min(100%, 240px); }
.pas__d { flex: 1 1 48%; min-width: min(100%, 300px); }
.pas--appel { justify-content: space-between; align-items: center; }

/* --- urgence : bande sombre, numero tres large --- */
.veille { display: flex; flex-wrap: wrap; gap: 32px; align-items: center; justify-content: space-between; }
.veille > * { min-width: 0; }
.veille > * { flex: 1 1 46%; min-width: min(100%, 320px); }
.veille__tel {
  display: inline-block; margin-top: 20px; text-decoration: none;
  font-family: 'Inter Tight', system-ui, sans-serif; font-weight: 600;
  font-size: clamp(30px, 4vw, 46px); letter-spacing: -.02em;
}
.bloc--nuit .puces li { color: inherit; opacity: .82; }

/* --- avant / apres : photos superposees, curseur en surimpression --- */
.compare { position: relative; border-radius: 12px; overflow: hidden; aspect-ratio: 16 / 9; }
.compare__vue { position: absolute; inset: 0; }
.compare__vue .vue { position: absolute; inset: 0; height: 100%; border-radius: 0; }
.compare__vue--avant { clip-path: inset(0 calc(100% - var(--pos)) 0 0); }
.compare__lab {
  position: absolute; top: 16px; padding: 7px 13px; border-radius: 999px;
  background: rgba(0,0,0,.62); color: #FFF; font-size: 12px; letter-spacing: .06em;
}
.compare__lab--avant { left: 16px; }
.compare__lab--apres { right: 16px; }
.compare__barre { position: absolute; top: 0; bottom: 0; left: var(--pos); width: 2px; background: #FFF; transform: translateX(-1px); }
.compare__poignee {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 46px; height: 46px; border-radius: 50%; background: #FFF; color: #101010;
  display: flex; align-items: center; justify-content: center; font-size: 17px;
  box-shadow: 0 6px 18px rgba(0,0,0,.28);
}
.compare__range {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: ew-resize; -webkit-appearance: none; appearance: none; background: transparent;
}
/* poignee FINE (7 sept 2026) : une poignee large decale la valeur du pointeur sur une piste
   etroite (80 % du bloc -> 86 % a 390) ; la piste couvre le cadre, tout reste saisissable. */
.compare__range::-webkit-slider-thumb { -webkit-appearance: none; width: 2px; height: 100%; }
.compare__range::-moz-range-thumb { width: 2px; height: 100%; border: 0; background: transparent; }
.compare__range:focus-visible + .compare__lab { outline: 2px solid var(--marque); }
.compare__pied { display: flex; flex-wrap: wrap; gap: 18px 32px; justify-content: space-between; align-items: flex-start; margin-top: 20px; }
.compare__pied > * { min-width: 0; }
.compare__pied > * { flex: 1 1 48%; min-width: min(100%, 280px); }

/* --- questions --- */
.depli { border-bottom: 1px solid var(--bordure); }
.depli summary {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 22px 0; cursor: pointer; list-style: none;
  font-family: 'Inter Tight', system-ui, sans-serif; font-size: 19px; font-weight: 500;
}
.depli summary::-webkit-details-marker { display: none; }
.depli__plus { flex: 0 0 auto; font-size: 22px; color:var(--encre-marque,var(--marque)); }
.depli[open] .depli__plus { transform: rotate(45deg); }
.depli p { padding: 0 0 22px; color: var(--texte-doux); max-width: 780px; }

/* --- appel final : photo pleine largeur, mot cale en haut a gauche --- */
.final { position: relative; min-height: 460px; display: flex; align-items: flex-start; color: var(--fond); }
.final .vue { position: absolute; inset: 0; border-radius: 0; height: 100%; }
.final__voile { position: absolute; inset: 0; background: linear-gradient(120deg, rgba(0,0,0,.72) 0%, rgba(0,0,0,.32) 68%); }
.final__mot { position: relative; padding: 76px 0; max-width: 700px; }
.final__mot h2 { margin-top: 16px; }
.final__mot .mot { color: var(--fond); opacity: .86; margin-top: 16px; }
.final__form { display: grid; grid-template-columns: repeat(var(--n, 2), minmax(0, 1fr)); gap: 12px; margin-top: 28px; }
.final__form > * { min-width: 0; }
.final__form input, .final__form textarea {
  min-width: 0;
  padding: 14px 16px; border-radius: 8px; border: 1px solid rgba(255,255,255,.42);
  background: rgba(255,255,255,.10); color: inherit; font: inherit;
}
.final__form input::placeholder, .final__form textarea::placeholder { color: rgba(255,255,255,.72); }

/* --- contact --- */
.contact { display: flex; flex-wrap: wrap; gap: 40px; }
.contact > * { min-width: 0; }
.contact__coord { flex: 1 1 34%; min-width: min(100%, 280px); display: flex; flex-wrap: wrap; gap: 16px; }
.contact__coord > * { min-width: 0; }
.coord { flex: 1 1 100%; border: 1px solid var(--bordure); border-radius: 12px; padding: 22px; display: flex; flex-direction: column; gap: 8px; }
.coord__rond { width: 38px; height: 38px; border-radius: 8px; background: var(--fond-2); display: flex; align-items: center; justify-content: center; }
.coord__v { text-decoration: none; color: var(--texte-doux); font-size: 15px; }
.formulaire { flex: 1 1 58%; min-width: min(100%, 340px); display: grid; grid-template-columns: repeat(var(--n, 2), minmax(0, 1fr)); gap: 16px; align-content: start; }
.formulaire > * { min-width: 0; }
.champ { min-width: 0; display: flex; flex-direction: column; gap: 7px; font-size: 14px; color: var(--texte-doux); }
.champ--long { grid-column: 1 / -1; }
.champ input, .champ textarea {
  padding: 13px 15px; border: 1px solid var(--bordure); border-radius: 8px;
  background: var(--fond); color: var(--texte); font: inherit;
}

/* --- journal --- */
.article { display: flex; flex-wrap: wrap; gap: 48px; margin-top: 44px; align-items: flex-start; }
.article > * { min-width: 0; }
.article__som { flex: 1 1 26%; min-width: min(100%, 240px); position: sticky; top: 96px; border: 1px solid var(--bordure); border-radius: 12px; padding: 22px; }
.article__corps { flex: 1 1 64%; min-width: min(100%, 320px); max-width: 780px; }
.encadre { border-left: 3px solid var(--marque); background: var(--fond-2); border-radius: 0 10px 10px 0; padding: 22px 24px; }
.encadre h4 { margin-bottom: 10px; }

.legal { display: flex; flex-wrap: wrap; gap: 40px; }
.legal > * { min-width: 0; }
.legal > div { flex: 1 1 46%; min-width: min(100%, 320px); }

.prix { display: block; font-family: 'Inter Tight', system-ui, sans-serif; font-size: 30px; font-weight: 600; letter-spacing: -.02em; }
/* T5 — la mention d unite est un element FRERE du prix, jamais un corps
   etranger glisse dans le sien : deux corps dans un bloc = deux lignes
   mesurees sur une seule ligne rendue. */
.prix__u { display: block; font-size: 14px; font-weight: 400; line-height: 1.5; color: var(--texte-doux); margin-top: 2px; }

/* --- produits : facettes, grille, fiche, caracteristiques ---
   Rendus seulement quand la niche porte des produits. Le compte de colonnes
   vient des donnees : flex-wrap + base en pourcent, min-width:0 partout. */
.filtre { display: flex; flex-wrap: wrap; gap: 22px 40px; align-items: flex-end; }
.filtre > * { min-width: 0; }
.filtre__g { flex: 1 1 300px; }
.filtre__d { flex: 2 1 420px; display: flex; flex-wrap: wrap; gap: 10px; }
.filtre__l {
  display: inline-flex; align-items: center; max-width: 100%;
  padding: 11px 18px; border-radius: 8px;
  border: 1px solid var(--bordure); background: var(--fond);
  font-size: 14px; color: var(--texte); text-decoration: none;
  overflow-wrap: anywhere;
}
.filtre__l:hover { border-color:var(--encre-marque,var(--marque)); color:var(--encre-marque,var(--marque)); }
.filtre__l--ici { background:var(--texte);--sur-bande:var(--sur-texte,var(--fond)); border-color: var(--texte); color: var(--fond); }

/* Le pied de carte produit : prix a gauche, appel a droite, jamais colle. */
.carte__attrs--bas {
  gap: 14px 18px; align-items: center; justify-content: space-between;
}
.carte__attrs--bas > * { min-width: 0; }
.dep { display: block; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--texte-doux); margin-bottom: 4px; }
.carac__v {
  display: block; font-family: 'Inter Tight', system-ui, sans-serif;
  font-size: 22px; font-weight: 600; letter-spacing: -.01em; color: var(--texte);
}
/* Un libelle long ne pousse jamais l'appel hors de sa colonne. */
.appui { max-width: 100%; flex-wrap: wrap; overflow-wrap: anywhere; }

/* --- pied noir, filigrane geant --- */
.pied { background:var(--texte);--sur-bande:var(--sur-texte,var(--fond)); color: var(--fond); padding: 76px 0 0; overflow: hidden; }
.pied__haut { display: flex; flex-wrap: wrap; gap: 44px; justify-content: space-between; }
.pied__haut > * { min-width: 0; }
.pied__marque { flex: 1 1 28%; min-width: min(100%, 260px); }
.pied__nom { display: inline-flex; align-items: center; gap: 10px; font-family: 'Inter Tight', system-ui, sans-serif; font-size: 22px; font-weight: 600; }
.pied__marque .mot { color: var(--fond); opacity: .7; margin-top: 16px; }
.pied__cols { flex: 1 1 62%; min-width: min(100%, 300px); display: grid; grid-template-columns: repeat(var(--n, 4), minmax(0, 1fr)); gap: 32px; }
.pied__cols > * { min-width: 0; }
.pied__cols > div { min-width: 0; }
.pied h4 { font-size: 12px; letter-spacing: .13em; text-transform: uppercase; opacity: .6; margin-bottom: 14px; }
.pied ul { list-style: none; margin: 0; padding: 0; }
.pied li { margin-top: 9px; }
.pied a { text-decoration: none; opacity: .82; font-size: 15px; }
.pied a:hover { opacity: 1; }
.pied__nap { display: flex; flex-direction: column; gap: 9px; font-size: 15px; opacity: .82; }
.pied__nap i { font-style: normal; margin-right: 8px; }
.pied__bas { display: flex; flex-wrap: wrap; gap: 14px 26px; justify-content: space-between; padding: 30px 0; margin-top: 56px; border-top: 1px solid rgba(255,255,255,.16); font-size: 14px; opacity: .7; }
.pied__bas > * { min-width: 0; }
.pied__bas a { margin-left: 18px; }
.pied__filigrane {
  font-family: 'Inter Tight', system-ui, sans-serif; font-weight: 600;
  font-size: clamp(64px, 17vw, 250px); line-height: .82; letter-spacing: -.045em;
  color: rgba(255,255,255,.07);
  padding-bottom: 14px;
  white-space: nowrap; overflow: hidden; text-overflow: clip;
  user-select: none;
}

/* --- appoints ---
   Les classes que reclament les champs du socle : chacune loge un texte ou
   une photo qui serait autrement perdu au rendu. */

/* Un atout qui porte un propos n'est plus une etiquette : il devient une
   petite fiche. Le compte vient des donnees, jamais de la coquille. */
.jeton--fiche {
  min-width: 0;
  display: flex; flex-direction: column; align-items: flex-start; gap: 5px;
  padding: 14px 17px; text-align: left; text-transform: none; letter-spacing: 0;
}
.jeton--fiche > * { min-width: 0; }
.jeton--fiche b { font-size: 15px; }
.jeton--fiche span { font-size: 13px; opacity: .82; }

/* Les appels d'une tranche, sous sa grille. */
.tete__b { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; }
/* Un paragraphe qui suit une tete, avant la grille. */
.mot--large { max-width: 780px; margin-top: 16px; }
/* Le libelle du lien d'une vignette. */
.vignette__lib { display: block; margin-top: 8px; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--fond); opacity: .85; }
/* La photo large d'une tranche, entre la tete et sa grille. */
.tete__vue { margin-top: 30px; }
.tete__vue .vue { min-height: 240px; }
/* La photo d'une etape du parcours. */
.pas__vue { margin-top: 14px; }
.pas__vue .vue { min-height: 130px; }
/* La photo d'une carte de maillage. */
.filet__vue { margin-bottom: 14px; }
.filet__vue .vue { min-height: 130px; }
/* L'encart de fin de FAQ : une carte a part, jamais une question deguisee. */
.encart {
  margin-top: 24px; padding: 22px 24px;
  border: 1px solid var(--bordure); border-radius: 10px;
  display: grid; gap: 10px; justify-items: flex-start;
}
.encart .tete__b { margin-top: 4px; }

/* ============================================================
   LES IDIOMES DE LA REFERENCE (releve du 2026-08-15, viewport 1440)
   ------------------------------------------------------------
   1. l'en-tete a deux etages : etiquette pleine largeur, titre en colonne
      etroite, appel renvoye a droite sur la ligne du titre ;
   2. la rangee a filet : pleine largeur, coupee 50/50, filet de 1px ;
   3. le rang de jetons ; 4. le carrousel plein bord ;
   5. le visuel hors cadre ; 6. le pied a colonne de marque ;
   7. la tete d'article 50/50 ; 8. le formulaire photo a gauche.
   ============================================================ */

/* --- 1. en-tete a deux etages --- */
.teteD { display: flex; flex-direction: column; }
.teteD__ligne {
  display: flex; flex-wrap: wrap; gap: 18px 40px;
  align-items: flex-end; justify-content: space-between; margin-top: 14px;
}
.teteD__ligne > * { min-width: 0; }
.teteD__t { flex: 1 1 600px; max-width: 600px; }
.teteD__b { flex: 0 0 auto; display: flex; flex-wrap: wrap; gap: 12px; }
.teteD__b > * { min-width: 0; }
.teteD__chapo { margin-top: 18px; max-width: 600px; }
.teteD + * { margin-top: 44px; }

/* --- 2. la rangee a filet --- */
.rangs { display: flex; flex-direction: column; border-top: 1px solid var(--bordure); }
.rangs > * { min-width: 0; }
.rang {
  display: flex; flex-wrap: wrap; gap: 20px 40px;
  padding: 34px 0; border-bottom: 1px solid var(--bordure);
}
.rang > * { min-width: 0; }
.rang__g { flex: 1 1 46%; min-width: min(100%, 280px); display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
.rang__d { flex: 1 1 46%; min-width: min(100%, 280px); }
.rang__t { font-size: 24px; }
.rang__vue { width: 100%; margin-top: 4px; }
.rang__vue .vue { min-height: 150px; }
.rang--court { padding: 24px 0; align-items: baseline; }
.rang--court .rang__g { flex-direction: row; align-items: center; gap: 14px; }
.rang--court .rang__t { font-size: 19px; }
.rang__d .puces { margin-top: 12px; }
.rang__d .jetons { margin-top: 14px; }
.rangs--hautJoint { border-top: 0; }
.rangs--coord { margin-top: 56px; }
.rangs--coord .coord__v { display: block; }
.mot--pied { margin-top: 30px; }
.prix--droite { margin-bottom: 6px; }

/* --- l'essai SEO : rangee a filet + bande photo hors cadre --- */
.essaiD { padding: 22px 0 0; border-top: 1px solid var(--bordure); }
.essaiD + .essaiD { margin-top: 56px; }
.essaiD__t { font-size: clamp(26px, 2.6vw, 38px); max-width: 600px; }
.essaiD__a { margin-top: 6px; }
.essaiD__bande { margin-top: 30px; }
.essaiD__bande .vue { border-radius: 10px; min-height: 200px; }
.essaiD--pale .essaiD__bande .vue { border-radius: 10px; }

/* --- 3. le rang de jetons --- */
.jetons--rang { gap: 12px; }

/* --- 4. le carrousel plein bord : la piste deborde le cadre a droite --- */
.rail--bord { margin-top: 44px; padding-inline: max(24px, calc((100% - 1320px) / 2)); }
.tuileZ {
  flex: 0 0 auto; width: min(74vw, 300px);
  display: flex; flex-direction: column; gap: 8px;
  padding: 22px 22px 0; text-decoration: none; color: inherit;
  border: 1px solid var(--bordure); border-radius: 12px; overflow: hidden;
  position: relative; background: var(--fond);
}
.tuileZ:hover { border-color:var(--encre-marque,var(--marque)); }
.tuileZ__n { font-family: 'Inter Tight', system-ui, sans-serif; font-size: 20px; }
.tuileZ__tag { font-size: 13px; color: var(--texte-doux); }
.tuileZ__fl { position: absolute; top: 20px; right: 20px; color:var(--encre-marque,var(--marque)); }
.tuileZ .vue { margin-top: 12px; border-radius: 10px 10px 0 0; }

/* --- 5. le visuel hors cadre --- */
.horsCadre { width: 100%; margin-bottom: 34px; }
.horsCadre .vue { border-radius: 0; min-height: 240px; }

/* --- les matieres : cellules d'un damier, photo en fond --- */
.cases { display: grid; grid-template-columns: repeat(var(--n, 4), minmax(0, 1fr)); gap: 1px; background: var(--bordure); border: 1px solid var(--bordure); }
.cases > * { min-width: 0; }
.case {
  position: relative; min-width: 0; min-height: 0;
  background: var(--fond); overflow: hidden; isolation: isolate;
}
.case__fond { position: absolute; inset: 0; opacity: .18; }
.case__fond .vue { position: absolute; inset: 0; height: 100%; border-radius: 0; aspect-ratio: auto; }
.case__mot { position: relative; padding: 26px 24px 30px; display: flex; flex-direction: column; gap: 10px; }
.case__mot h4 { font-size: 18px; }

/* --- 8. le formulaire : photo a gauche, champs par paires --- */
.prise { display: flex; flex-wrap: wrap; gap: 44px; align-items: stretch; }
.prise > * { min-width: 0; }
.prise__vue { flex: 1 1 46%; min-width: min(100%, 300px); }
.prise__vue .vue { height: 100%; min-height: 320px; }
.prise .formulaire { flex: 1 1 46%; min-width: min(100%, 300px); align-content: flex-start; }
.champ--note { color: var(--texte-doux); font-size: 13px; }
.champ--long .appui { width: 100%; justify-content: center; }

/* --- 7. l'article : tete 50/50, corps en colonne unique --- */
.artD__tete { display: flex; flex-wrap: wrap; gap: 24px 44px; align-items: center; }
.artD__tete > * { min-width: 0; }
.artD__g { flex: 1 1 46%; min-width: min(100%, 300px); }
.artD__d { flex: 1 1 46%; min-width: min(100%, 300px); }
.artD__t { margin-top: 16px; max-width: 460px; font-size: clamp(32px, 3.6vw, 46px); }
.artD__date { margin-top: 16px; }
.artD__fil { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--bordure); }
.artD__fil > * { min-width: 0; }
.artD__filT { font-size: 12px; letter-spacing: .13em; text-transform: uppercase; color: var(--texte-doux); }
.artD__fil a { font-size: 14px; text-decoration: none; color:var(--encre-marque,var(--marque)); }
.artD__corps { max-width: 700px; margin: 56px auto 0; }

/* --- 6. le pied a colonne de marque : le copyright sous le logo --- */
.pied__rang { display: flex; flex-wrap: wrap; gap: 44px; justify-content: space-between; }
.pied__rang > * { min-width: 0; }
.pied__id { flex: 1 1 30%; min-width: min(100%, 260px); }
.pied__cop { display: block; margin-top: 12px; font-size: 14px; opacity: .62; }
.pied__pasts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.pied__pasts > * { min-width: 0; }
.pied__past {
  display: inline-flex; align-items: center; padding: 7px 13px;
  border: 1px solid rgba(255,255,255,.22); border-radius: 999px;
  font-size: 13px; overflow-wrap: anywhere;
}
.pied__id .mot { color: var(--fond); opacity: .7; margin-top: 20px; }
.pied__rang + .pied__filigrane { margin-top: 62px; }

/* --- replis --- */
@media (max-width: 1000px) {
  /* Le panneau se pose SOUS le plan des 1000px, pas des 720 : entre les
     deux, la vignette 21/9 devient plus courte que le panneau, et
     `.carto { overflow: hidden }` tranchait sa premiere ligne. Il reste
     POSITIONNE — en `static` il perdrait son z-index et passerait sous la
     vue, qui est en `position: relative`. La remontee de 20px est voulue. */
  .carto__panneau { position: relative; left: 0; bottom: 0; z-index: 1;
    box-shadow: none; border: 1px solid var(--bordure); max-width: none; margin-top: -20px; }
  .entete__nav {
    display: none; position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--fond); border-bottom: 1px solid var(--bordure);
    padding: 10px 24px 20px;
  }
  /* Le pilote est la CLASSE posee par app.js, pas un attribut : le
     selecteur `[data-ouvert]` ne repondait a rien et le menu mobile ne
     s'ouvrait jamais — la nav etait donc inatteignable sous 1000px. */
  .entete--ouvert .entete__nav { display: flex; }
  .entete__nav > a, .deroul__tete { padding: 12px 0; border-bottom: 1px solid var(--bordure); }
  .entete__bouton { display: inline-block; }
  .entete__act { display: none; }
  /* Au doigt, le volet est a plat sous sa tete : l'entree redevient une colonne. */
  .deroul { display: block; }
  .deroul__panneau { position: static; opacity: 1; visibility: visible; transform: none; padding-top: 0; }
  .deroul__grille { border: 0; box-shadow: none; padding: 6px 0 12px;
    flex-direction: column; width: auto; min-width: 0; max-width: none; gap: 12px; }
  /* La vitrine est un confort d'ecran large : au doigt, elle pousserait les
     liens hors de vue. Le volet redescend a la liste seule. */
  .deroul__vit { display: none; }
  .article__som { position: static; }
  /* NORME COQUILLE R3 — le compte de pistes se DECLARE a chaque palier,
     il ne se devine pas du remplissage. */
  .cartes, .cartes:has(> .carte--quart), .cartes:has(> .carte--demi),
  .filets, .filets:has(> .filet--tiers), .filets:has(> .filet--demi),
  .logos, .compte, .cases, .communes, .pied__cols,
  .jetons:has(> .jeton--fiche) { --n: 2; }
}

@media (max-width: 720px) {
  .bloc { padding: 62px 0; }
  .bloc--serre { padding: 46px 0; }
  .conteneur { width: min(1320px, 100% - 32px); }
  .ouvre__mot { padding: 104px 0 56px; }
  .immersif__mot { padding: 26px 22px; }
  .immersif .vue { aspect-ratio: 4 / 5; }
  .final .vue, .carto .vue, .bande .vue { aspect-ratio: 4 / 3; }
  .filet { padding-right: 0; }
  .pas--appel { align-items: flex-start; }
  /* Sous 720, la rangee a filet se replie a plat : les deux moities
     s'empilent, le filet reste la seule separation. */
  .rang, .rang--court { padding: 24px 0; }
  .rang--court .rang__g { flex-direction: row; }
  .horsCadre .vue { aspect-ratio: 4 / 3; min-height: 0; }
  .prise__vue .vue { min-height: 220px; }
  .artD__corps { margin-top: 40px; }
  .essaiD__bande .vue { aspect-ratio: 4 / 3; }
  .rail--bord { padding-inline: 16px; }
  /* R3, palier telephone : une seule piste, sauf le territoire qui en garde
     deux (vignettes carrees, lisibles a 170px). */
  .cartes, .cartes:has(> .carte--quart), .cartes:has(> .carte--demi),
  .filets, .filets:has(> .filet--tiers), .filets:has(> .filet--demi),
  .logos, .compte, .cases, .pied__cols, .formulaire, .final__form,
  .jetons:has(> .jeton--fiche) { --n: 1; }
  .communes { --n: 2; }
}

/* ================= SIGNATURES DE FORME =================
   Traits releves EN LIGNE sur drivehub-template.framer.website, portes ici en
   CSS pur. Documentation lisible : drivehub/signatures.md */

/* SIGNATURE — le VOILE A VINGT-ET-UN ARRETS (99 occurrences, deux teintes).
   La reference ne fond jamais en trois arrets : elle suit une courbe. */
.ouvre__voile, .immersif__voile {
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--texte) 100%, transparent) 0%,
    color-mix(in srgb, var(--texte) 95%, transparent) 3%,
    color-mix(in srgb, var(--texte) 88%, transparent) 6%,
    color-mix(in srgb, var(--texte) 79%, transparent) 9%,
    color-mix(in srgb, var(--texte) 69%, transparent) 12%,
    color-mix(in srgb, var(--texte) 59%, transparent) 15%,
    color-mix(in srgb, var(--texte) 49%, transparent) 18%,
    color-mix(in srgb, var(--texte) 39%, transparent) 21%,
    color-mix(in srgb, var(--texte) 31%, transparent) 24%,
    color-mix(in srgb, var(--texte) 24%, transparent) 27%,
    color-mix(in srgb, var(--texte) 18%, transparent) 30%,
    color-mix(in srgb, var(--texte) 13%, transparent) 34%,
    color-mix(in srgb, var(--texte) 9%, transparent) 38%,
    color-mix(in srgb, var(--texte) 6%, transparent) 43%,
    color-mix(in srgb, var(--texte) 4%, transparent) 48%,
    color-mix(in srgb, var(--texte) 2%, transparent) 54%,
    color-mix(in srgb, var(--texte) 1%, transparent) 60%,
    transparent 90%);
}
.vignette__voile, .commune__voile {
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--texte) 96%, transparent) 0%,
    color-mix(in srgb, var(--texte) 79%, transparent) 9%,
    color-mix(in srgb, var(--texte) 59%, transparent) 15%,
    color-mix(in srgb, var(--texte) 39%, transparent) 21%,
    color-mix(in srgb, var(--texte) 24%, transparent) 27%,
    color-mix(in srgb, var(--texte) 13%, transparent) 34%,
    color-mix(in srgb, var(--texte) 6%, transparent) 43%,
    color-mix(in srgb, var(--texte) 2%, transparent) 54%,
    transparent 80%);
}

/* SIGNATURE — le RAYON UNIQUE DE 10px (x42) et la PILULE de 99px (x6).
   Rien entre les deux : la piece est franche ou totalement filee. */
.carte, .tuile, .vignette, .filet__vue, .pas__vue, .compte__c { border-radius: 10px; }
.jeton, .pastille, .commune__tag, .filtre__l { border-radius: 99px; }

/* SIGNATURE — les COINS BAS SEULS (0 0 10px 10px, x3) : la piece qui se glisse
   sous une autre n arrondit que ce qui depasse. */
.carte__attrs--bas, .vignette__lib, .parole__pied { border-radius: 0 0 10px 10px; }

/* SIGNATURE — le CONTOUR INTERNE net d un pixel (x2), pose par un pseudo pour
   ne pas ecraser le fond de la piece. */
.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);
}
.tuile { position: relative; }
.tuile::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);
}
.compte__c { position: relative; }
.compte__c::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);
}
.filet__vue { position: relative; }
.filet__vue::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) 12%, transparent);
}

/* SIGNATURE — l ombre COURTE et FRACTIONNAIRE (.20/.18 puis .17/.14). */
.carte, .compte__c {
  box-shadow:
    0 .36px .36px -1.25px color-mix(in srgb, var(--texte) 20%, transparent),
    0 1.37px 1.37px -2.5px color-mix(in srgb, var(--texte) 18%, transparent),
    0 6px 6px -3.75px color-mix(in srgb, var(--texte) 7%, transparent);
}

/* SIGNATURE — la vue se LEVE par le bas (masque unique, aucun clip-path
   sur toute la reference). */
.ouvre__fond {
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 24%, #000 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 24%, #000 100%);
}
.prise__vue {
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 18%, #000 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 18%, #000 100%);
}


/* MOBILE — debordement mesure le 7 septembre 2026 (gate honnete, pages renovation-maison-le-mans).
   Le cadre du bandeau final est absolu (inset 0, height 100 %) et recevait un aspect-ratio 4/3 au
   mobile : largeur = hauteur x 4/3 = 805px pour 430. Le cadre whyUs (21/9) prenait 560px dans une
   colonne de 398. Un cadre ne depasse jamais sa colonne. */
@media (max-width: 1100px) {
  .final .vue { aspect-ratio: auto; width: 100%; max-width: 100%; }
  .tete__vue, .vue--why, [data-slot="vue--why"] { width: 100%; max-width: 100%; }
  .tete__vue .vue { min-height: 0; } /* (8 sept) sinon 240px de plancher cassent le 21/9 declare (R5a 1.49 pour 2.33) */
  /* entete a 1024 : la paire d appels (Devis, Appeler) a 1096px pour 1024 ; la paire cede et se serre */
  .entete__rang { min-width: 0; }
  .entete__act { flex: 0 1 auto; min-width: 0; gap: 8px; }
  .entete__act .appui { min-width: 0; padding-inline: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
/* avantApres : `minmax(460px, 1fr)` forcait 460px dans une colonne de 398 (pages service a 430). */
.duels { grid-template-columns: repeat(auto-fit, minmax(min(460px, 100%), 1fr)); }
.vue { max-width: 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 */

/* >>> NORME COQUILLE — teinte des cadres porteurs (pose par _lib/teinter-cadres.mjs) */
/* Cadres PORTEURS : de l encre claire repose reellement dessus (mesure du
   2026-08-23 sur 3 page(s), 1440 et 390 px). Leur etat vide prend
   le sol de leur section, assombri d un cran, pour que cette encre reste
   lisible sans plaquer une dalle etrangere a la palette ; tous les autres
   cadres gardent le clair par defaut. Ne pas editer a la main : remesurer.

   Un cadre porteur SE TAIT. Sa legende est centree ; de l encre repose
   deja dessus, par definition — l ecrire, c est la poser en travers du
   titre. C est la collision qu on voyait sur le hero pleine fenetre de
   template-14 : « EMPLACEMENT VISUEL — ... » ecrit sur le paragraphe.
   Le libelle reste porte en aria-label, il n est pas perdu. */
[data-slot="vue--cta"]:not(:has(img)):not(:has(video)) {
  --cadre-vide-fond: #171b20;
  --cadre-vide-trame: rgba(255, 255, 255, .05);
  --cadre-vide-encre: rgba(255, 255, 255, .82);
  --cadre-vide-filet: rgba(255, 255, 255, .10);
}
[data-slot="vue--cta"]:not(:has(img)):not(:has(video)) > * {
  font-size: 0 !important;
}
[data-slot="vue--hro"]:not(:has(img)):not(:has(video)) {
  --cadre-vide-fond: #171b20;
  --cadre-vide-trame: rgba(255, 255, 255, .05);
  --cadre-vide-encre: rgba(255, 255, 255, .82);
  --cadre-vide-filet: rgba(255, 255, 255, .10);
}
[data-slot="vue--hro"]:not(:has(img)):not(:has(video)) > * {
  font-size: 0 !important;
}
[data-slot="vue--svc"]:not(:has(img)):not(:has(video)) {
  --cadre-vide-fond: #171b20;
  --cadre-vide-trame: rgba(255, 255, 255, .05);
  --cadre-vide-encre: rgba(255, 255, 255, .82);
  --cadre-vide-filet: rgba(255, 255, 255, .10);
}
[data-slot="vue--svc"]:not(:has(img)):not(:has(video)) > * {
  font-size: 0 !important;
}
[data-slot="vue--xpt"]:not(:has(img)):not(:has(video)) {
  --cadre-vide-fond: #171b20;
  --cadre-vide-trame: rgba(255, 255, 255, .05);
  --cadre-vide-encre: rgba(255, 255, 255, .82);
  --cadre-vide-filet: rgba(255, 255, 255, .10);
}
[data-slot="vue--xpt"]:not(:has(img)):not(:has(video)) > * {
  font-size: 0 !important;
}
/* <<< NORME COQUILLE — teinte des cadres porteurs */

/* contraste-source — bandes sombres : chacune declare son encre (--sur-bande) ; marque en texte : --encre-marque. */
/* contraste-bandes (2026-09-14) — marque utilisee comme TEXTE sur fond clair.
   L encre lit --encre-marque, CALCULEE dans shell/render.mjs (encreLisible contre --fond puis
   --fond-2) : meme teinte, assombrie seulement si la palette ne passe pas 4,5:1. La marque brute
   reste la marque pour les aplats, filets et CTA. */

/* Maillage interne : le lien « Voir → » d une piste a filet posee sur une bande claire (pas la bande
   de nuit). Demo 2 (or #B57505) : 3,81 sur blanc -> 4,5 et plus. */
.bloc:not(.bloc--nuit) .filet .filet__fl { color: var(--encre-marque); }

/* Etoiles d avis (arbitrage Mixte : encre assombrie en gardant la teinte, pas un decor) sur la
   carte de parole qui peint --fond, dans la bande pale. Demo 2 : 3,81 (blanc) / 3,38 (--fond-2)
   -> 4,5 et plus. */
.parole .parole__et { color: var(--encre-marque); }
